aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97_bus.c1
-rw-r--r--sound/aoa/codecs/Makefile4
-rw-r--r--sound/aoa/codecs/onyx.c (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.c)12
-rw-r--r--sound/aoa/codecs/onyx.h (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.h)0
-rw-r--r--sound/aoa/codecs/tas-basstreble.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h)0
-rw-r--r--sound/aoa/codecs/tas-gain-table.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h)0
-rw-r--r--sound/aoa/codecs/tas.c (renamed from sound/aoa/codecs/snd-aoa-codec-tas.c)8
-rw-r--r--sound/aoa/codecs/tas.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas.h)0
-rw-r--r--sound/aoa/codecs/toonie.c (renamed from sound/aoa/codecs/snd-aoa-codec-toonie.c)2
-rw-r--r--sound/aoa/core/Makefile8
-rw-r--r--sound/aoa/core/alsa.c (renamed from sound/aoa/core/snd-aoa-alsa.c)4
-rw-r--r--sound/aoa/core/alsa.h (renamed from sound/aoa/core/snd-aoa-alsa.h)0
-rw-r--r--sound/aoa/core/core.c (renamed from sound/aoa/core/snd-aoa-core.c)2
-rw-r--r--sound/aoa/core/gpio-feature.c (renamed from sound/aoa/core/snd-aoa-gpio-feature.c)2
-rw-r--r--sound/aoa/core/gpio-pmf.c (renamed from sound/aoa/core/snd-aoa-gpio-pmf.c)0
-rw-r--r--sound/aoa/fabrics/Makefile2
-rw-r--r--sound/aoa/fabrics/layout.c (renamed from sound/aoa/fabrics/snd-aoa-fabric-layout.c)2
-rw-r--r--sound/aoa/soundbus/core.c2
-rw-r--r--sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-control.c)0
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-core.c)10
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus.h2
-rw-r--r--sound/aoa/soundbus/i2sbus/interface.h (renamed from sound/aoa/soundbus/i2sbus/i2sbus-interface.h)0
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-pcm.c)0
-rw-r--r--sound/aoa/soundbus/soundbus.h2
-rw-r--r--sound/arm/pxa2xx-ac97-lib.c39
-rw-r--r--sound/arm/pxa2xx-ac97.c5
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c2
-rw-r--r--sound/arm/pxa2xx-pcm.h2
-rw-r--r--sound/core/Kconfig21
-rw-r--r--sound/core/Makefile2
-rw-r--r--sound/core/control.c8
-rw-r--r--sound/core/device.c4
-rw-r--r--sound/core/hrtimer.c154
-rw-r--r--sound/core/info.c17
-rw-r--r--sound/core/init.c80
-rw-r--r--sound/core/jack.c9
-rw-r--r--sound/core/memalloc.c48
-rw-r--r--sound/core/oss/pcm_oss.c2
-rw-r--r--sound/core/pcm_lib.c48
-rw-r--r--sound/core/pcm_misc.c1
-rw-r--r--sound/core/pcm_native.c25
-rw-r--r--sound/core/rawmidi.c12
-rw-r--r--sound/core/rtctimer.c2
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c9
-rw-r--r--sound/core/timer.c3
-rw-r--r--sound/drivers/Kconfig2
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/drivers/pcsp/pcsp.c7
-rw-r--r--sound/drivers/pcsp/pcsp.h3
-rw-r--r--sound/drivers/pcsp/pcsp_input.c4
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c167
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/drivers/vx/vx_pcm.c2
-rw-r--r--sound/i2c/other/tea575x-tuner.c47
-rw-r--r--sound/isa/Kconfig2
-rw-r--r--sound/isa/ad1848/ad1848.c6
-rw-r--r--sound/isa/adlib.c12
-rw-r--r--sound/isa/cs423x/cs4231.c8
-rw-r--r--sound/isa/cs423x/cs4236.c8
-rw-r--r--sound/isa/es1688/es1688.c9
-rw-r--r--sound/isa/gus/gusclassic.c13
-rw-r--r--sound/isa/gus/gusextreme.c19
-rw-r--r--sound/isa/sb/sb8.c8
-rw-r--r--sound/oss/ac97_codec.c2
-rw-r--r--sound/oss/aedsp16.c2
-rw-r--r--sound/oss/au1550_ac97.c2
-rw-r--r--sound/oss/dmasound/dmasound.h4
-rw-r--r--sound/oss/dmasound/dmasound_atari.c9
-rw-r--r--sound/oss/dmasound/dmasound_core.c14
-rw-r--r--sound/oss/dmasound/dmasound_q40.c16
-rw-r--r--sound/oss/kahlua.c2
-rw-r--r--sound/oss/msnd.h2
-rw-r--r--sound/oss/sh_dac_audio.c2
-rw-r--r--sound/oss/sound_config.h20
-rw-r--r--sound/oss/soundcard.c15
-rw-r--r--sound/oss/swarm_cs4297a.c2
-rw-r--r--sound/oss/vwsnd.c2
-rw-r--r--sound/oss/waveartist.c8
-rw-r--r--sound/pci/Kconfig3
-rw-r--r--sound/pci/ac97/ac97_codec.c8
-rw-r--r--sound/pci/ac97/ac97_patch.c9
-rw-r--r--sound/pci/ad1889.c2
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au88x0.c3
-rw-r--r--sound/pci/bt87x.c3
-rw-r--r--sound/pci/ca0106/ca0106.h30
-rw-r--r--sound/pci/ca0106/ca0106_main.c551
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c263
-rw-r--r--sound/pci/cs4281.c4
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
-rw-r--r--sound/pci/cs5530.c4
-rw-r--r--sound/pci/cs5535audio/Makefile3
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c12
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h39
-rw-r--r--sound/pci/cs5535audio/cs5535audio_olpc.c179
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c15
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c497
-rw-r--r--sound/pci/emu10k1/emumixer.c46
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/hda/Kconfig1
-rw-r--r--sound/pci/hda/hda_beep.c1
-rw-r--r--sound/pci/hda/hda_codec.c67
-rw-r--r--sound/pci/hda/hda_codec.h10
-rw-r--r--sound/pci/hda/hda_intel.c42
-rw-r--r--sound/pci/hda/hda_proc.c18
-rw-r--r--sound/pci/hda/patch_analog.c6
-rw-r--r--sound/pci/hda/patch_atihdmi.c8
-rw-r--r--sound/pci/hda/patch_conexant.c114
-rw-r--r--sound/pci/hda/patch_intelhdmi.c8
-rw-r--r--sound/pci/hda/patch_nvhdmi.c10
-rw-r--r--sound/pci/hda/patch_realtek.c55
-rw-r--r--sound/pci/hda/patch_sigmatel.c739
-rw-r--r--sound/pci/hda/patch_via.c72
-rw-r--r--sound/pci/ice1712/ice1712.c6
-rw-r--r--sound/pci/ice1712/ice1724.c25
-rw-r--r--sound/pci/intel8x0.c1
-rw-r--r--sound/pci/maestro3.c2
-rw-r--r--sound/pci/mixart/mixart.c7
-rw-r--r--sound/pci/mixart/mixart_core.c2
-rw-r--r--sound/pci/oxygen/oxygen.c4
-rw-r--r--sound/pci/pcxhr/Makefile2
-rw-r--r--sound/pci/pcxhr/pcxhr.c563
-rw-r--r--sound/pci/pcxhr/pcxhr.h76
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c293
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h5
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c158
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c820
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h56
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c556
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme9652/hdsp.c31
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_irq.c2
-rw-r--r--sound/ppc/pmac.c2
-rw-r--r--sound/ppc/snd_ps3.c96
-rw-r--r--sound/ppc/snd_ps3.h1
-rw-r--r--sound/ppc/tumbler.c3
-rw-r--r--sound/soc/Kconfig13
-rw-r--r--sound/soc/Makefile12
-rw-r--r--sound/soc/at32/Kconfig34
-rw-r--r--sound/soc/at32/Makefile11
-rw-r--r--sound/soc/at32/at32-pcm.c492
-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/at91/Kconfig27
-rw-r--r--sound/soc/at91/Makefile11
-rw-r--r--sound/soc/at91/at91-pcm.c434
-rw-r--r--sound/soc/at91/at91-pcm.h72
-rw-r--r--sound/soc/at91/at91-ssc.c791
-rw-r--r--sound/soc/at91/at91-ssc.h27
-rw-r--r--sound/soc/at91/eti_b1_wm8731.c349
-rw-r--r--sound/soc/atmel/Kconfig43
-rw-r--r--sound/soc/atmel/Makefile15
-rw-r--r--sound/soc/atmel/atmel-pcm.c494
-rw-r--r--sound/soc/atmel/atmel-pcm.h86
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c790
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h121
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c (renamed from sound/soc/at32/playpaq_wm8510.c)23
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c328
-rw-r--r--sound/soc/au1x/dbdma2.c5
-rw-r--r--sound/soc/au1x/psc-ac97.c16
-rw-r--r--sound/soc/au1x/psc-i2s.c18
-rw-r--r--sound/soc/au1x/sample-ac97.c4
-rw-r--r--sound/soc/blackfin/Kconfig38
-rw-r--r--sound/soc/blackfin/Makefile3
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c115
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c179
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h35
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c8
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c240
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c12
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c96
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h4
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c14
-rw-r--r--sound/soc/codecs/Kconfig88
-rw-r--r--sound/soc/codecs/Makefile16
-rw-r--r--sound/soc/codecs/ac97.c10
-rw-r--r--sound/soc/codecs/ad1980.c25
-rw-r--r--sound/soc/codecs/ad73311.c115
-rw-r--r--sound/soc/codecs/ad73311.h90
-rw-r--r--sound/soc/codecs/ak4535.c20
-rw-r--r--sound/soc/codecs/cs4270.c38
-rw-r--r--sound/soc/codecs/l3.c91
-rw-r--r--sound/soc/codecs/pcm3008.c212
-rw-r--r--sound/soc/codecs/pcm3008.h25
-rw-r--r--sound/soc/codecs/ssm2602.c58
-rw-r--r--sound/soc/codecs/tlv320aic23.c864
-rw-r--r--sound/soc/codecs/tlv320aic23.h122
-rw-r--r--sound/soc/codecs/tlv320aic26.c22
-rw-r--r--sound/soc/codecs/tlv320aic3x.c187
-rw-r--r--sound/soc/codecs/tlv320aic3x.h60
-rw-r--r--sound/soc/codecs/twl4030.c1312
-rw-r--r--sound/soc/codecs/twl4030.h226
-rw-r--r--sound/soc/codecs/uda134x.c668
-rw-r--r--sound/soc/codecs/uda134x.h36
-rw-r--r--sound/soc/codecs/uda1380.c30
-rw-r--r--sound/soc/codecs/wm8350.c1583
-rw-r--r--sound/soc/codecs/wm8350.h20
-rw-r--r--sound/soc/codecs/wm8510.c130
-rw-r--r--sound/soc/codecs/wm8510.h1
-rw-r--r--sound/soc/codecs/wm8580.c136
-rw-r--r--sound/soc/codecs/wm8580.h1
-rw-r--r--sound/soc/codecs/wm8728.c585
-rw-r--r--sound/soc/codecs/wm8728.h30
-rw-r--r--sound/soc/codecs/wm8731.c26
-rw-r--r--sound/soc/codecs/wm8750.c20
-rw-r--r--sound/soc/codecs/wm8753.c114
-rw-r--r--sound/soc/codecs/wm8753.h4
-rw-r--r--sound/soc/codecs/wm8900.c263
-rw-r--r--sound/soc/codecs/wm8900.h6
-rw-r--r--sound/soc/codecs/wm8903.c272
-rw-r--r--sound/soc/codecs/wm8903.h5
-rw-r--r--sound/soc/codecs/wm8971.c20
-rw-r--r--sound/soc/codecs/wm8990.c44
-rw-r--r--sound/soc/codecs/wm8990.h4
-rw-r--r--sound/soc/codecs/wm9712.c15
-rw-r--r--sound/soc/codecs/wm9713.c51
-rw-r--r--sound/soc/davinci/Kconfig10
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c33
-rw-r--r--sound/soc/davinci/davinci-i2s.c257
-rw-r--r--sound/soc/davinci/davinci-pcm.c32
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c161
-rw-r--r--sound/soc/fsl/Kconfig3
-rw-r--r--sound/soc/fsl/fsl_dma.c14
-rw-r--r--sound/soc/fsl/fsl_ssi.c24
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c36
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c8
-rw-r--r--sound/soc/fsl/soc-of-simple.c12
-rw-r--r--sound/soc/omap/Kconfig44
-rw-r--r--sound/soc/omap/Makefile10
-rw-r--r--sound/soc/omap/n810.c16
-rw-r--r--sound/soc/omap/omap-mcbsp.c239
-rw-r--r--sound/soc/omap/omap-mcbsp.h16
-rw-r--r--sound/soc/omap/omap-pcm.c18
-rw-r--r--sound/soc/omap/omap2evm.c151
-rw-r--r--sound/soc/omap/omap3beagle.c149
-rw-r--r--sound/soc/omap/omap3pandora.c324
-rw-r--r--sound/soc/omap/osk5912.c232
-rw-r--r--sound/soc/omap/overo.c148
-rw-r--r--sound/soc/omap/sdp3430.c152
-rw-r--r--sound/soc/pxa/Kconfig22
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c52
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c9
-rw-r--r--sound/soc/pxa/palm27x.c269
-rw-r--r--sound/soc/pxa/poodle.c12
-rw-r--r--sound/soc/pxa/pxa-ssp.c931
-rw-r--r--sound/soc/pxa/pxa-ssp.h47
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c44
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c82
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c18
-rw-r--r--sound/soc/pxa/spitz.c68
-rw-r--r--sound/soc/pxa/tosa.c44
-rw-r--r--sound/soc/pxa/zylonite.c219
-rw-r--r--sound/soc/s3c24xx/Kconfig5
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c8
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c81
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c38
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c32
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c35
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c12
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c373
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c8
-rw-r--r--sound/soc/sh/dma-sh7760.c12
-rw-r--r--sound/soc/sh/hac.c19
-rw-r--r--sound/soc/sh/sh7760-ac97.c6
-rw-r--r--sound/soc/sh/ssi.c30
-rw-r--r--sound/soc/soc-core.c947
-rw-r--r--sound/soc/soc-dapm.c244
-rw-r--r--sound/sound_core.c14
-rw-r--r--sound/sparc/amd7930.c85
-rw-r--r--sound/sparc/cs4231.c201
-rw-r--r--sound/sparc/dbri.c91
-rw-r--r--sound/usb/caiaq/caiaq-control.c73
-rw-r--r--sound/usb/caiaq/caiaq-device.c6
-rw-r--r--sound/usb/caiaq/caiaq-device.h1
-rw-r--r--sound/usb/caiaq/caiaq-midi.c32
-rw-r--r--sound/usb/usbaudio.c8
-rw-r--r--sound/usb/usbmidi.c41
-rw-r--r--sound/usb/usbmixer.c5
-rw-r--r--sound/usb/usbquirks.h30
-rw-r--r--sound/usb/usx2y/us122l.c17
-rw-r--r--sound/usb/usx2y/usb_stream.c3
-rw-r--r--sound/usb/usx2y/usbusx2y.c6
292 files changed, 19440 insertions, 7080 deletions
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index 7fa37e15f196..a351dd0a09c7 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <sound/ac97_codec.h>
18 19
19/* 20/*
20 * Let drivers decide whether they want to support given codec from their 21 * Let drivers decide whether they want to support given codec from their
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
index 31cbe68fd42f..c3ee77fc4b2d 100644
--- a/sound/aoa/codecs/Makefile
+++ b/sound/aoa/codecs/Makefile
@@ -1,3 +1,7 @@
1snd-aoa-codec-onyx-objs := onyx.o
2snd-aoa-codec-tas-objs := tas.o
3snd-aoa-codec-toonie-objs := toonie.o
4
1obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o 5obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
2obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o 6obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
3obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o 7obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/onyx.c
index 6a3837d480e5..15500b9d2da0 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -37,7 +37,7 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); 38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
39 39
40#include "snd-aoa-codec-onyx.h" 40#include "onyx.h"
41#include "../aoa.h" 41#include "../aoa.h"
42#include "../soundbus/soundbus.h" 42#include "../soundbus/soundbus.h"
43 43
@@ -292,7 +292,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
292static struct snd_kcontrol_new capture_source_control = { 292static struct snd_kcontrol_new capture_source_control = {
293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
294 /* If we name this 'Input Source', it properly shows up in 294 /* If we name this 'Input Source', it properly shows up in
295 * alsamixer as a selection, * but it's shown under the 295 * alsamixer as a selection, * but it's shown under the
296 * 'Playback' category. 296 * 'Playback' category.
297 * If I name it 'Capture Source', it shows up in strange 297 * If I name it 'Capture Source', it shows up in strange
298 * ways (two bools of which one can be selected at a 298 * ways (two bools of which one can be selected at a
@@ -477,7 +477,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
477 477
478 ucontrol->value.iec958.status[3] = 0x3f; 478 ucontrol->value.iec958.status[3] = 0x3f;
479 ucontrol->value.iec958.status[4] = 0x0f; 479 ucontrol->value.iec958.status[4] = 0x0f;
480 480
481 return 0; 481 return 0;
482} 482}
483 483
@@ -682,7 +682,7 @@ static int onyx_usable(struct codec_info_item *cii,
682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE); 683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
685 analog_enabled = 685 analog_enabled =
686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT)) 686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT); 687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
688 mutex_unlock(&onyx->mutex); 688 mutex_unlock(&onyx->mutex);
@@ -882,7 +882,7 @@ static int onyx_init_codec(struct aoa_codec *codec)
882 msleep(1); 882 msleep(1);
883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
884 msleep(1); 884 msleep(1);
885 885
886 if (onyx_register_init(onyx)) { 886 if (onyx_register_init(onyx)) {
887 printk(KERN_ERR PFX "failed to initialise onyx registers\n"); 887 printk(KERN_ERR PFX "failed to initialise onyx registers\n");
888 return -ENODEV; 888 return -ENODEV;
@@ -1069,7 +1069,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
1069 1069
1070 /* if that didn't work, try desperate mode for older 1070 /* if that didn't work, try desperate mode for older
1071 * machines that have stuff missing from the device tree */ 1071 * machines that have stuff missing from the device tree */
1072 1072
1073 if (!of_device_is_compatible(busnode, "k2-i2c")) 1073 if (!of_device_is_compatible(busnode, "k2-i2c"))
1074 return -ENODEV; 1074 return -ENODEV;
1075 1075
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/onyx.h
index ffd20254ff76..ffd20254ff76 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.h
+++ b/sound/aoa/codecs/onyx.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/tas-basstreble.h
index 69b61136fd54..69b61136fd54 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
+++ b/sound/aoa/codecs/tas-basstreble.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/tas-gain-table.h
index 4cfa6757715e..4cfa6757715e 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
+++ b/sound/aoa/codecs/tas-gain-table.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/tas.c
index 6c515b2b8bbd..008e0f85097d 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -71,9 +71,9 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
71MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
72MODULE_DESCRIPTION("tas codec driver for snd-aoa"); 72MODULE_DESCRIPTION("tas codec driver for snd-aoa");
73 73
74#include "snd-aoa-codec-tas.h" 74#include "tas.h"
75#include "snd-aoa-codec-tas-gain-table.h" 75#include "tas-gain-table.h"
76#include "snd-aoa-codec-tas-basstreble.h" 76#include "tas-basstreble.h"
77#include "../aoa.h" 77#include "../aoa.h"
78#include "../soundbus/soundbus.h" 78#include "../soundbus/soundbus.h"
79 79
@@ -880,7 +880,7 @@ static void tas_exit_codec(struct aoa_codec *codec)
880 return; 880 return;
881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); 881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
882} 882}
883 883
884 884
885static struct i2c_driver tas_driver; 885static struct i2c_driver tas_driver;
886 886
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/tas.h
index ae177e3466e6..ae177e3466e6 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.h
+++ b/sound/aoa/codecs/tas.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/toonie.c
index 3c7d1d8a9a6f..f13827e17562 100644
--- a/sound/aoa/codecs/snd-aoa-codec-toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -131,7 +131,7 @@ static int __init toonie_init(void)
131 toonie->codec.owner = THIS_MODULE; 131 toonie->codec.owner = THIS_MODULE;
132 toonie->codec.init = toonie_init_codec; 132 toonie->codec.init = toonie_init_codec;
133 toonie->codec.exit = toonie_exit_codec; 133 toonie->codec.exit = toonie_exit_codec;
134 134
135 if (aoa_codec_register(&toonie->codec)) { 135 if (aoa_codec_register(&toonie->codec)) {
136 kfree(toonie); 136 kfree(toonie);
137 return -EINVAL; 137 return -EINVAL;
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
index 62dc7287f663..a1596e88c718 100644
--- a/sound/aoa/core/Makefile
+++ b/sound/aoa/core/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_SND_AOA) += snd-aoa.o 1obj-$(CONFIG_SND_AOA) += snd-aoa.o
2snd-aoa-objs := snd-aoa-core.o \ 2snd-aoa-objs := core.o \
3 snd-aoa-alsa.o \ 3 alsa.o \
4 snd-aoa-gpio-pmf.o \ 4 gpio-pmf.o \
5 snd-aoa-gpio-feature.o 5 gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/alsa.c
index 17fe689ed287..617850463582 100644
--- a/sound/aoa/core/snd-aoa-alsa.c
+++ b/sound/aoa/core/alsa.c
@@ -6,7 +6,7 @@
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include "snd-aoa-alsa.h" 9#include "alsa.h"
10 10
11static int index = -1; 11static int index = -1;
12module_param(index, int, 0444); 12module_param(index, int, 0444);
@@ -64,7 +64,7 @@ int aoa_snd_device_new(snd_device_type_t type,
64{ 64{
65 struct snd_card *card = aoa_get_card(); 65 struct snd_card *card = aoa_get_card();
66 int err; 66 int err;
67 67
68 if (!card) return -ENOMEM; 68 if (!card) return -ENOMEM;
69 69
70 err = snd_device_new(card, type, device_data, ops); 70 err = snd_device_new(card, type, device_data, ops);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/alsa.h
index 9669e4489cab..9669e4489cab 100644
--- a/sound/aoa/core/snd-aoa-alsa.h
+++ b/sound/aoa/core/alsa.h
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/core.c
index 19fdae400687..10bec6c61382 100644
--- a/sound/aoa/core/snd-aoa-core.c
+++ b/sound/aoa/core/core.c
@@ -10,7 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include "../aoa.h" 12#include "../aoa.h"
13#include "snd-aoa-alsa.h" 13#include "alsa.h"
14 14
15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver"); 15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/gpio-feature.c
index 805dcbff2257..c93ad5dec66b 100644
--- a/sound/aoa/core/snd-aoa-gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 * 7 *
8 * This file contains the GPIO control routines for 8 * This file contains the GPIO control routines for
9 * direct (through feature calls) access to the GPIO 9 * direct (through feature calls) access to the GPIO
10 * registers. 10 * registers.
11 */ 11 */
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 5ca2220eac7d..5ca2220eac7d 100644
--- a/sound/aoa/core/snd-aoa-gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
index 55fc5e7e52cf..da37c10eca51 100644
--- a/sound/aoa/fabrics/Makefile
+++ b/sound/aoa/fabrics/Makefile
@@ -1 +1,3 @@
1snd-aoa-fabric-layout-objs += layout.o
2
1obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o 3obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/layout.c
index dea7abb082cd..ad60f5d10e82 100644
--- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -66,7 +66,7 @@ struct layout {
66 unsigned int layout_id; 66 unsigned int layout_id;
67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS]; 67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
68 int flags; 68 int flags;
69 69
70 /* if busname is not assigned, we use 'Master' below, 70 /* if busname is not assigned, we use 'Master' below,
71 * so that our layout table doesn't need to be filled 71 * so that our layout table doesn't need to be filled
72 * too much. 72 * too much.
diff --git a/sound/aoa/soundbus/core.c b/sound/aoa/soundbus/core.c
index f84f3e505788..fa8ab2815a98 100644
--- a/sound/aoa/soundbus/core.c
+++ b/sound/aoa/soundbus/core.c
@@ -176,7 +176,7 @@ int soundbus_add_one(struct soundbus_dev *dev)
176 return -EINVAL; 176 return -EINVAL;
177 } 177 }
178 178
179 snprintf(dev->ofdev.dev.bus_id, BUS_ID_SIZE, "soundbus:%x", ++devcount); 179 dev_set_name(&dev->ofdev.dev, "soundbus:%x", ++devcount);
180 dev->ofdev.dev.bus = &soundbus_bus_type; 180 dev->ofdev.dev.bus = &soundbus_bus_type;
181 return of_device_register(&dev->ofdev); 181 return of_device_register(&dev->ofdev);
182} 182}
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
index e57a5cf65655..1b949b2a4028 100644
--- a/sound/aoa/soundbus/i2sbus/Makefile
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -1,2 +1,2 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o 1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
2snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o 2snd-aoa-i2sbus-objs := core.o pcm.o control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d63..87beb4ad4d63 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-control.c
+++ b/sound/aoa/soundbus/i2sbus/control.c
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/core.c
index e6beb92c6933..be468edf3ecb 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -64,7 +64,7 @@ static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
64 struct dbdma_command_mem *r) 64 struct dbdma_command_mem *r)
65{ 65{
66 if (!r->space) return; 66 if (!r->space) return;
67 67
68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, 68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
69 r->size, r->space, r->bus_addr); 69 r->size, r->space, r->bus_addr);
70} 70}
@@ -159,7 +159,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
159 struct i2sbus_dev *dev; 159 struct i2sbus_dev *dev;
160 struct device_node *child = NULL, *sound = NULL; 160 struct device_node *child = NULL, *sound = NULL;
161 struct resource *r; 161 struct resource *r;
162 int i, layout = 0, rlen; 162 int i, layout = 0, rlen, ok = force;
163 static const char *rnames[] = { "i2sbus: %s (control)", 163 static const char *rnames[] = { "i2sbus: %s (control)",
164 "i2sbus: %s (tx)", 164 "i2sbus: %s (tx)",
165 "i2sbus: %s (rx)" }; 165 "i2sbus: %s (rx)" };
@@ -192,7 +192,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
192 layout = *layout_id; 192 layout = *layout_id;
193 snprintf(dev->sound.modalias, 32, 193 snprintf(dev->sound.modalias, 32,
194 "sound-layout-%d", layout); 194 "sound-layout-%d", layout);
195 force = 1; 195 ok = 1;
196 } 196 }
197 } 197 }
198 /* for the time being, until we can handle non-layout-id 198 /* for the time being, until we can handle non-layout-id
@@ -201,7 +201,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
201 * When there are two i2s busses and only one has a layout-id, 201 * When there are two i2s busses and only one has a layout-id,
202 * then this depends on the order, but that isn't important 202 * then this depends on the order, but that isn't important
203 * either as the second one in that case is just a modem. */ 203 * either as the second one in that case is just a modem. */
204 if (!force) { 204 if (!ok) {
205 kfree(dev); 205 kfree(dev);
206 return -ENODEV; 206 return -ENODEV;
207 } 207 }
@@ -247,7 +247,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
247 * but request_resource doesn't know about parents and 247 * but request_resource doesn't know about parents and
248 * contained resources... 248 * contained resources...
249 */ 249 */
250 dev->allocated_resource[i] = 250 dev->allocated_resource[i] =
251 request_mem_region(dev->resources[i].start, 251 request_mem_region(dev->resources[i].start,
252 dev->resources[i].end - 252 dev->resources[i].end -
253 dev->resources[i].start + 1, 253 dev->resources[i].start + 1,
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
index ff29654782c9..befefd99e271 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus.h
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -18,7 +18,7 @@
18#include <asm/pmac_feature.h> 18#include <asm/pmac_feature.h>
19#include <asm/dbdma.h> 19#include <asm/dbdma.h>
20 20
21#include "i2sbus-interface.h" 21#include "interface.h"
22#include "../soundbus.h" 22#include "../soundbus.h"
23 23
24struct i2sbus_control { 24struct i2sbus_control {
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/interface.h
index c6b5f5452d20..c6b5f5452d20 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
+++ b/sound/aoa/soundbus/i2sbus/interface.h
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 59bacd365733..59bacd365733 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
diff --git a/sound/aoa/soundbus/soundbus.h b/sound/aoa/soundbus/soundbus.h
index 622cd37a0118..a0f223c13f66 100644
--- a/sound/aoa/soundbus/soundbus.h
+++ b/sound/aoa/soundbus/soundbus.h
@@ -8,7 +8,7 @@
8#ifndef __SOUNDBUS_H 8#ifndef __SOUNDBUS_H
9#define __SOUNDBUS_H 9#define __SOUNDBUS_H
10 10
11#include <asm/of_device.h> 11#include <linux/of_device.h>
12#include <sound/pcm.h> 12#include <sound/pcm.h>
13#include <linux/list.h> 13#include <linux/list.h>
14 14
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c
index 99026dfb81ea..35afd0c33be5 100644
--- a/sound/arm/pxa2xx-ac97-lib.c
+++ b/sound/arm/pxa2xx-ac97-lib.c
@@ -22,7 +22,7 @@
22 22
23#include <asm/irq.h> 23#include <asm/irq.h>
24#include <mach/hardware.h> 24#include <mach/hardware.h>
25#include <mach/pxa-regs.h> 25#include <mach/regs-ac97.h>
26#include <mach/pxa2xx-gpio.h> 26#include <mach/pxa2xx-gpio.h>
27#include <mach/audio.h> 27#include <mach/audio.h>
28 28
@@ -50,7 +50,7 @@ unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
50 mutex_lock(&car_mutex); 50 mutex_lock(&car_mutex);
51 51
52 /* set up primary or secondary codec space */ 52 /* set up primary or secondary codec space */
53 if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS) 53 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
54 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; 54 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
55 else 55 else
56 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; 56 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
@@ -90,7 +90,7 @@ void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
90 mutex_lock(&car_mutex); 90 mutex_lock(&car_mutex);
91 91
92 /* set up primary or secondary codec space */ 92 /* set up primary or secondary codec space */
93 if ((cpu_is_pxa21x() || cpu_is_pxa25x()) && reg == AC97_GPIO_STATUS) 93 if (cpu_is_pxa25x() && reg == AC97_GPIO_STATUS)
94 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE; 94 reg_addr = ac97->num ? &SMC_REG_BASE : &PMC_REG_BASE;
95 else 95 else
96 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE; 96 reg_addr = ac97->num ? &SAC_REG_BASE : &PAC_REG_BASE;
@@ -200,7 +200,7 @@ static inline void pxa_ac97_cold_pxa3xx(void)
200bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97) 200bool pxa2xx_ac97_try_warm_reset(struct snd_ac97 *ac97)
201{ 201{
202#ifdef CONFIG_PXA25x 202#ifdef CONFIG_PXA25x
203 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 203 if (cpu_is_pxa25x())
204 pxa_ac97_warm_pxa25x(); 204 pxa_ac97_warm_pxa25x();
205 else 205 else
206#endif 206#endif
@@ -230,7 +230,7 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_try_warm_reset);
230bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97) 230bool pxa2xx_ac97_try_cold_reset(struct snd_ac97 *ac97)
231{ 231{
232#ifdef CONFIG_PXA25x 232#ifdef CONFIG_PXA25x
233 if (cpu_is_pxa21x() || cpu_is_pxa25x()) 233 if (cpu_is_pxa25x())
234 pxa_ac97_cold_pxa25x(); 234 pxa_ac97_cold_pxa25x();
235 else 235 else
236#endif 236#endif
@@ -301,7 +301,7 @@ EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_suspend);
301 301
302int pxa2xx_ac97_hw_resume(void) 302int pxa2xx_ac97_hw_resume(void)
303{ 303{
304 if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) { 304 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
305 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 305 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
306 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 306 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
307 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); 307 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
@@ -321,11 +321,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
321{ 321{
322 int ret; 322 int ret;
323 323
324 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); 324 if (cpu_is_pxa25x() || cpu_is_pxa27x()) {
325 if (ret < 0)
326 goto err;
327
328 if (cpu_is_pxa21x() || cpu_is_pxa25x() || cpu_is_pxa27x()) {
329 pxa_gpio_mode(GPIO31_SYNC_AC97_MD); 325 pxa_gpio_mode(GPIO31_SYNC_AC97_MD);
330 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD); 326 pxa_gpio_mode(GPIO30_SDATA_OUT_AC97_MD);
331 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD); 327 pxa_gpio_mode(GPIO28_BITCLK_AC97_MD);
@@ -339,7 +335,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
339 if (IS_ERR(ac97conf_clk)) { 335 if (IS_ERR(ac97conf_clk)) {
340 ret = PTR_ERR(ac97conf_clk); 336 ret = PTR_ERR(ac97conf_clk);
341 ac97conf_clk = NULL; 337 ac97conf_clk = NULL;
342 goto err_irq; 338 goto err_conf;
343 } 339 }
344 } 340 }
345 341
@@ -347,19 +343,30 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev)
347 if (IS_ERR(ac97_clk)) { 343 if (IS_ERR(ac97_clk)) {
348 ret = PTR_ERR(ac97_clk); 344 ret = PTR_ERR(ac97_clk);
349 ac97_clk = NULL; 345 ac97_clk = NULL;
350 goto err_irq; 346 goto err_clk;
351 } 347 }
352 348
353 return clk_enable(ac97_clk); 349 ret = clk_enable(ac97_clk);
350 if (ret)
351 goto err_clk2;
352
353 ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL);
354 if (ret < 0)
355 goto err_irq;
356
357 return 0;
354 358
355err_irq: 359err_irq:
356 GCR |= GCR_ACLINK_OFF; 360 GCR |= GCR_ACLINK_OFF;
361err_clk2:
362 clk_put(ac97_clk);
363 ac97_clk = NULL;
364err_clk:
357 if (ac97conf_clk) { 365 if (ac97conf_clk) {
358 clk_put(ac97conf_clk); 366 clk_put(ac97conf_clk);
359 ac97conf_clk = NULL; 367 ac97conf_clk = NULL;
360 } 368 }
361 free_irq(IRQ_AC97, NULL); 369err_conf:
362err:
363 return ret; 370 return ret;
364} 371}
365EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe); 372EXPORT_SYMBOL_GPL(pxa2xx_ac97_hw_probe);
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index cba71d867542..85cf591d4e11 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -22,6 +22,7 @@
22 22
23#include <mach/hardware.h> 23#include <mach/hardware.h>
24#include <mach/pxa-regs.h> 24#include <mach/pxa-regs.h>
25#include <mach/regs-ac97.h>
25#include <mach/audio.h> 26#include <mach/audio.h>
26 27
27#include "pxa2xx-pcm.h" 28#include "pxa2xx-pcm.h"
@@ -44,7 +45,7 @@ static struct snd_ac97_bus_ops pxa2xx_ac97_ops = {
44static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = { 45static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
45 .name = "AC97 PCM out", 46 .name = "AC97 PCM out",
46 .dev_addr = __PREG(PCDR), 47 .dev_addr = __PREG(PCDR),
47 .drcmr = &DRCMRTXPCDR, 48 .drcmr = &DRCMR(12),
48 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 49 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
49 DCMD_BURST32 | DCMD_WIDTH4, 50 DCMD_BURST32 | DCMD_WIDTH4,
50}; 51};
@@ -52,7 +53,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_out = {
52static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = { 53static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_in = {
53 .name = "AC97 PCM in", 54 .name = "AC97 PCM in",
54 .dev_addr = __PREG(PCDR), 55 .dev_addr = __PREG(PCDR),
55 .drcmr = &DRCMRRXPCDR, 56 .drcmr = &DRCMR(11),
56 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 57 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
57 DCMD_BURST32 | DCMD_WIDTH4, 58 DCMD_BURST32 | DCMD_WIDTH4,
58}; 59};
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 1c93eb77cb99..75a0d746fb60 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -194,7 +194,7 @@ int __pxa2xx_pcm_open(struct snd_pcm_substream *substream)
194 goto out; 194 goto out;
195 195
196 ret = -ENOMEM; 196 ret = -ENOMEM;
197 rtd = kmalloc(sizeof(*rtd), GFP_KERNEL); 197 rtd = kzalloc(sizeof(*rtd), GFP_KERNEL);
198 if (!rtd) 198 if (!rtd)
199 goto out; 199 goto out;
200 rtd->dma_desc_array = 200 rtd->dma_desc_array =
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h
index 5c4a4d38a083..65f86b56ba42 100644
--- a/sound/arm/pxa2xx-pcm.h
+++ b/sound/arm/pxa2xx-pcm.h
@@ -9,7 +9,7 @@
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12#include <asm/dma.h> 12#include <mach/dma.h>
13 13
14struct pxa2xx_runtime_data { 14struct pxa2xx_runtime_data {
15 int dma_ch; 15 int dma_ch;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 66348c92f88d..7bbdda041a99 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -95,6 +95,26 @@ config SND_SEQUENCER_OSS
95 this will be compiled as a module. The module will be called 95 this will be compiled as a module. The module will be called
96 snd-seq-oss. 96 snd-seq-oss.
97 97
98config SND_HRTIMER
99 tristate "HR-timer backend support"
100 depends on HIGH_RES_TIMERS
101 select SND_TIMER
102 help
103 Say Y here to enable HR-timer backend for ALSA timer. ALSA uses
104 the hrtimer as a precise timing source. The ALSA sequencer code
105 also can use this timing source.
106
107 To compile this driver as a module, choose M here: the module
108 will be called snd-hrtimer.
109
110config SND_SEQ_HRTIMER_DEFAULT
111 bool "Use HR-timer as default sequencer timer"
112 depends on SND_HRTIMER && SND_SEQUENCER
113 default y
114 help
115 Say Y here to use the HR-timer backend as the default sequencer
116 timer.
117
98config SND_RTCTIMER 118config SND_RTCTIMER
99 tristate "RTC Timer support" 119 tristate "RTC Timer support"
100 depends on RTC 120 depends on RTC
@@ -114,6 +134,7 @@ config SND_RTCTIMER
114config SND_SEQ_RTCTIMER_DEFAULT 134config SND_SEQ_RTCTIMER_DEFAULT
115 bool "Use RTC as default sequencer timer" 135 bool "Use RTC as default sequencer timer"
116 depends on SND_RTCTIMER && SND_SEQUENCER 136 depends on SND_RTCTIMER && SND_SEQUENCER
137 depends on !SND_SEQ_HRTIMER_DEFAULT
117 default y 138 default y
118 help 139 help
119 Say Y here to use the RTC timer as the default sequencer 140 Say Y here to use the RTC timer as the default sequencer
diff --git a/sound/core/Makefile b/sound/core/Makefile
index d57125a5687d..4229052e7b91 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -17,12 +17,14 @@ snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o
17 17
18snd-rawmidi-objs := rawmidi.o 18snd-rawmidi-objs := rawmidi.o
19snd-timer-objs := timer.o 19snd-timer-objs := timer.o
20snd-hrtimer-objs := hrtimer.o
20snd-rtctimer-objs := rtctimer.o 21snd-rtctimer-objs := rtctimer.o
21snd-hwdep-objs := hwdep.o 22snd-hwdep-objs := hwdep.o
22 23
23obj-$(CONFIG_SND) += snd.o 24obj-$(CONFIG_SND) += snd.o
24obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o 25obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
25obj-$(CONFIG_SND_TIMER) += snd-timer.o 26obj-$(CONFIG_SND_TIMER) += snd-timer.o
27obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
26obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o 28obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
27obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o 29obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
28obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o 30obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
diff --git a/sound/core/control.c b/sound/core/control.c
index 6d71f9a7ccbb..636b3b52ef8b 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -113,7 +113,6 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
113 unsigned int idx; 113 unsigned int idx;
114 114
115 ctl = file->private_data; 115 ctl = file->private_data;
116 fasync_helper(-1, file, 0, &ctl->fasync);
117 file->private_data = NULL; 116 file->private_data = NULL;
118 card = ctl->card; 117 card = ctl->card;
119 write_lock_irqsave(&card->ctl_files_rwlock, flags); 118 write_lock_irqsave(&card->ctl_files_rwlock, flags);
@@ -225,8 +224,13 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
225 kctl.id.iface = ncontrol->iface; 224 kctl.id.iface = ncontrol->iface;
226 kctl.id.device = ncontrol->device; 225 kctl.id.device = ncontrol->device;
227 kctl.id.subdevice = ncontrol->subdevice; 226 kctl.id.subdevice = ncontrol->subdevice;
228 if (ncontrol->name) 227 if (ncontrol->name) {
229 strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name)); 228 strlcpy(kctl.id.name, ncontrol->name, sizeof(kctl.id.name));
229 if (strcmp(ncontrol->name, kctl.id.name) != 0)
230 snd_printk(KERN_WARNING
231 "Control name '%s' truncated to '%s'\n",
232 ncontrol->name, kctl.id.name);
233 }
230 kctl.id.index = ncontrol->index; 234 kctl.id.index = ncontrol->index;
231 kctl.count = ncontrol->count ? ncontrol->count : 1; 235 kctl.count = ncontrol->count ? ncontrol->count : 1;
232 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 236 access = ncontrol->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
diff --git a/sound/core/device.c b/sound/core/device.c
index c58d8227254c..a67dfac08c03 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -98,7 +98,7 @@ int snd_device_free(struct snd_card *card, void *device_data)
98 kfree(dev); 98 kfree(dev);
99 return 0; 99 return 0;
100 } 100 }
101 snd_printd("device free %p (from %p), not found\n", device_data, 101 snd_printd("device free %p (from %pF), not found\n", device_data,
102 __builtin_return_address(0)); 102 __builtin_return_address(0));
103 return -ENXIO; 103 return -ENXIO;
104} 104}
@@ -135,7 +135,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
135 } 135 }
136 return 0; 136 return 0;
137 } 137 }
138 snd_printd("device disconnect %p (from %p), not found\n", device_data, 138 snd_printd("device disconnect %p (from %pF), not found\n", device_data,
139 __builtin_return_address(0)); 139 __builtin_return_address(0));
140 return -ENXIO; 140 return -ENXIO;
141} 141}
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
new file mode 100644
index 000000000000..34c7d48f5061
--- /dev/null
+++ b/sound/core/hrtimer.c
@@ -0,0 +1,154 @@
1/*
2 * ALSA timer back-end using hrtimer
3 * Copyright (C) 2008 Takashi Iwai
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/hrtimer.h>
25#include <sound/core.h>
26#include <sound/timer.h>
27
28MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
29MODULE_DESCRIPTION("ALSA hrtimer backend");
30MODULE_LICENSE("GPL");
31
32MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_HRTIMER));
33
34#define NANO_SEC 1000000000UL /* 10^9 in sec */
35static unsigned int resolution;
36
37struct snd_hrtimer {
38 struct snd_timer *timer;
39 struct hrtimer hrt;
40};
41
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer;
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks);
48 return HRTIMER_RESTART;
49}
50
51static int snd_hrtimer_open(struct snd_timer *t)
52{
53 struct snd_hrtimer *stime;
54
55 stime = kmalloc(sizeof(*stime), GFP_KERNEL);
56 if (!stime)
57 return -ENOMEM;
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t;
60 stime->hrt.function = snd_hrtimer_callback;
61 t->private_data = stime;
62 return 0;
63}
64
65static int snd_hrtimer_close(struct snd_timer *t)
66{
67 struct snd_hrtimer *stime = t->private_data;
68
69 if (stime) {
70 hrtimer_cancel(&stime->hrt);
71 kfree(stime);
72 t->private_data = NULL;
73 }
74 return 0;
75}
76
77static int snd_hrtimer_start(struct snd_timer *t)
78{
79 struct snd_hrtimer *stime = t->private_data;
80
81 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
82 HRTIMER_MODE_REL);
83 return 0;
84}
85
86static int snd_hrtimer_stop(struct snd_timer *t)
87{
88 struct snd_hrtimer *stime = t->private_data;
89
90 hrtimer_cancel(&stime->hrt);
91 return 0;
92}
93
94static struct snd_timer_hardware hrtimer_hw = {
95 .flags = SNDRV_TIMER_HW_AUTO,
96 .open = snd_hrtimer_open,
97 .close = snd_hrtimer_close,
98 .start = snd_hrtimer_start,
99 .stop = snd_hrtimer_stop,
100};
101
102/*
103 * entry functions
104 */
105
106static struct snd_timer *mytimer;
107
108static int __init snd_hrtimer_init(void)
109{
110 struct snd_timer *timer;
111 struct timespec tp;
112 int err;
113
114 hrtimer_get_res(CLOCK_MONOTONIC, &tp);
115 if (tp.tv_sec > 0 || !tp.tv_nsec) {
116 snd_printk(KERN_ERR
117 "snd-hrtimer: Invalid resolution %u.%09u",
118 (unsigned)tp.tv_sec, (unsigned)tp.tv_nsec);
119 return -EINVAL;
120 }
121 resolution = tp.tv_nsec;
122
123 /* Create a new timer and set up the fields */
124 err = snd_timer_global_new("hrtimer", SNDRV_TIMER_GLOBAL_HRTIMER,
125 &timer);
126 if (err < 0)
127 return err;
128
129 timer->module = THIS_MODULE;
130 strcpy(timer->name, "HR timer");
131 timer->hw = hrtimer_hw;
132 timer->hw.resolution = resolution;
133 timer->hw.ticks = NANO_SEC / resolution;
134
135 err = snd_timer_global_register(timer);
136 if (err < 0) {
137 snd_timer_global_free(timer);
138 return err;
139 }
140 mytimer = timer; /* remember this */
141
142 return 0;
143}
144
145static void __exit snd_hrtimer_exit(void)
146{
147 if (mytimer) {
148 snd_timer_global_free(mytimer);
149 mytimer = NULL;
150 }
151}
152
153module_init(snd_hrtimer_init);
154module_exit(snd_hrtimer_exit);
diff --git a/sound/core/info.c b/sound/core/info.c
index 527b207462b0..70fa87189f36 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -653,6 +653,23 @@ int snd_info_card_register(struct snd_card *card)
653} 653}
654 654
655/* 655/*
656 * called on card->id change
657 */
658void snd_info_card_id_change(struct snd_card *card)
659{
660 mutex_lock(&info_mutex);
661 if (card->proc_root_link) {
662 snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
663 card->proc_root_link = NULL;
664 }
665 if (strcmp(card->id, card->proc_root->name))
666 card->proc_root_link = proc_symlink(card->id,
667 snd_proc_root,
668 card->proc_root->name);
669 mutex_unlock(&info_mutex);
670}
671
672/*
656 * de-register the card proc file 673 * de-register the card proc file
657 * called from init.c 674 * called from init.c
658 */ 675 */
diff --git a/sound/core/init.c b/sound/core/init.c
index 8af467df9245..0d5520c415d3 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -264,8 +264,11 @@ static int snd_disconnect_release(struct inode *inode, struct file *file)
264 } 264 }
265 spin_unlock(&shutdown_lock); 265 spin_unlock(&shutdown_lock);
266 266
267 if (likely(df)) 267 if (likely(df)) {
268 if ((file->f_flags & FASYNC) && df->disconnected_f_op->fasync)
269 df->disconnected_f_op->fasync(-1, file, 0);
268 return df->disconnected_f_op->release(inode, file); 270 return df->disconnected_f_op->release(inode, file);
271 }
269 272
270 panic("%s(%p, %p) failed!", __func__, inode, file); 273 panic("%s(%p, %p) failed!", __func__, inode, file);
271} 274}
@@ -530,6 +533,65 @@ static void choose_default_id(struct snd_card *card)
530 } 533 }
531} 534}
532 535
536#ifndef CONFIG_SYSFS_DEPRECATED
537static ssize_t
538card_id_show_attr(struct device *dev,
539 struct device_attribute *attr, char *buf)
540{
541 struct snd_card *card = dev_get_drvdata(dev);
542 return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)");
543}
544
545static ssize_t
546card_id_store_attr(struct device *dev, struct device_attribute *attr,
547 const char *buf, size_t count)
548{
549 struct snd_card *card = dev_get_drvdata(dev);
550 char buf1[sizeof(card->id)];
551 size_t copy = count > sizeof(card->id) - 1 ?
552 sizeof(card->id) - 1 : count;
553 size_t idx;
554 int c;
555
556 for (idx = 0; idx < copy; idx++) {
557 c = buf[idx];
558 if (!isalnum(c) && c != '_' && c != '-')
559 return -EINVAL;
560 }
561 memcpy(buf1, buf, copy);
562 buf1[copy] = '\0';
563 mutex_lock(&snd_card_mutex);
564 if (!snd_info_check_reserved_words(buf1)) {
565 __exist:
566 mutex_unlock(&snd_card_mutex);
567 return -EEXIST;
568 }
569 for (idx = 0; idx < snd_ecards_limit; idx++) {
570 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1))
571 goto __exist;
572 }
573 strcpy(card->id, buf1);
574 snd_info_card_id_change(card);
575 mutex_unlock(&snd_card_mutex);
576
577 return count;
578}
579
580static struct device_attribute card_id_attrs =
581 __ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
582
583static ssize_t
584card_number_show_attr(struct device *dev,
585 struct device_attribute *attr, char *buf)
586{
587 struct snd_card *card = dev_get_drvdata(dev);
588 return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
589}
590
591static struct device_attribute card_number_attrs =
592 __ATTR(number, S_IRUGO, card_number_show_attr, NULL);
593#endif /* CONFIG_SYSFS_DEPRECATED */
594
533/** 595/**
534 * snd_card_register - register the soundcard 596 * snd_card_register - register the soundcard
535 * @card: soundcard structure 597 * @card: soundcard structure
@@ -549,9 +611,9 @@ int snd_card_register(struct snd_card *card)
549 return -EINVAL; 611 return -EINVAL;
550#ifndef CONFIG_SYSFS_DEPRECATED 612#ifndef CONFIG_SYSFS_DEPRECATED
551 if (!card->card_dev) { 613 if (!card->card_dev) {
552 card->card_dev = device_create_drvdata(sound_class, card->dev, 614 card->card_dev = device_create(sound_class, card->dev,
553 MKDEV(0, 0), NULL, 615 MKDEV(0, 0), card,
554 "card%i", card->number); 616 "card%i", card->number);
555 if (IS_ERR(card->card_dev)) 617 if (IS_ERR(card->card_dev))
556 card->card_dev = NULL; 618 card->card_dev = NULL;
557 } 619 }
@@ -573,6 +635,16 @@ int snd_card_register(struct snd_card *card)
573 if (snd_mixer_oss_notify_callback) 635 if (snd_mixer_oss_notify_callback)
574 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); 636 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
575#endif 637#endif
638#ifndef CONFIG_SYSFS_DEPRECATED
639 if (card->card_dev) {
640 err = device_create_file(card->card_dev, &card_id_attrs);
641 if (err < 0)
642 return err;
643 err = device_create_file(card->card_dev, &card_number_attrs);
644 if (err < 0)
645 return err;
646 }
647#endif
576 return 0; 648 return 0;
577} 649}
578 650
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 438445f77d6d..dd4a12dc09aa 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -109,6 +109,9 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
109 if (type & SND_JACK_MICROPHONE) 109 if (type & SND_JACK_MICROPHONE)
110 input_set_capability(jack->input_dev, EV_SW, 110 input_set_capability(jack->input_dev, EV_SW,
111 SW_MICROPHONE_INSERT); 111 SW_MICROPHONE_INSERT);
112 if (type & SND_JACK_MECHANICAL)
113 input_set_capability(jack->input_dev, EV_SW,
114 SW_JACK_PHYSICAL_INSERT);
112 115
113 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 116 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
114 if (err < 0) 117 if (err < 0)
@@ -151,6 +154,9 @@ EXPORT_SYMBOL(snd_jack_set_parent);
151 */ 154 */
152void snd_jack_report(struct snd_jack *jack, int status) 155void snd_jack_report(struct snd_jack *jack, int status)
153{ 156{
157 if (!jack)
158 return;
159
154 if (jack->type & SND_JACK_HEADPHONE) 160 if (jack->type & SND_JACK_HEADPHONE)
155 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, 161 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
156 status & SND_JACK_HEADPHONE); 162 status & SND_JACK_HEADPHONE);
@@ -160,6 +166,9 @@ void snd_jack_report(struct snd_jack *jack, int status)
160 if (jack->type & SND_JACK_MICROPHONE) 166 if (jack->type & SND_JACK_MICROPHONE)
161 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT, 167 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
162 status & SND_JACK_MICROPHONE); 168 status & SND_JACK_MICROPHONE);
169 if (jack->type & SND_JACK_MECHANICAL)
170 input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT,
171 status & SND_JACK_MECHANICAL);
163 172
164 input_sync(jack->input_dev); 173 input_sync(jack->input_dev);
165} 174}
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index a7b46ec72f32..1b3534d67686 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -33,9 +33,6 @@
33#include <linux/moduleparam.h> 33#include <linux/moduleparam.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <sound/memalloc.h> 35#include <sound/memalloc.h>
36#ifdef CONFIG_SBUS
37#include <asm/sbus.h>
38#endif
39 36
40 37
41MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>"); 38MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>, Jaroslav Kysela <perex@perex.cz>");
@@ -162,39 +159,6 @@ static void snd_free_dev_pages(struct device *dev, size_t size, void *ptr,
162} 159}
163#endif /* CONFIG_HAS_DMA */ 160#endif /* CONFIG_HAS_DMA */
164 161
165#ifdef CONFIG_SBUS
166
167static void *snd_malloc_sbus_pages(struct device *dev, size_t size,
168 dma_addr_t *dma_addr)
169{
170 struct sbus_dev *sdev = (struct sbus_dev *)dev;
171 int pg;
172 void *res;
173
174 if (WARN_ON(!dma_addr))
175 return NULL;
176 pg = get_order(size);
177 res = sbus_alloc_consistent(sdev, PAGE_SIZE * (1 << pg), dma_addr);
178 if (res != NULL)
179 inc_snd_pages(pg);
180 return res;
181}
182
183static void snd_free_sbus_pages(struct device *dev, size_t size,
184 void *ptr, dma_addr_t dma_addr)
185{
186 struct sbus_dev *sdev = (struct sbus_dev *)dev;
187 int pg;
188
189 if (ptr == NULL)
190 return;
191 pg = get_order(size);
192 dec_snd_pages(pg);
193 sbus_free_consistent(sdev, PAGE_SIZE * (1 << pg), ptr, dma_addr);
194}
195
196#endif /* CONFIG_SBUS */
197
198/* 162/*
199 * 163 *
200 * ALSA generic memory management 164 * ALSA generic memory management
@@ -231,11 +195,6 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
231 dmab->area = snd_malloc_pages(size, (unsigned long)device); 195 dmab->area = snd_malloc_pages(size, (unsigned long)device);
232 dmab->addr = 0; 196 dmab->addr = 0;
233 break; 197 break;
234#ifdef CONFIG_SBUS
235 case SNDRV_DMA_TYPE_SBUS:
236 dmab->area = snd_malloc_sbus_pages(device, size, &dmab->addr);
237 break;
238#endif
239#ifdef CONFIG_HAS_DMA 198#ifdef CONFIG_HAS_DMA
240 case SNDRV_DMA_TYPE_DEV: 199 case SNDRV_DMA_TYPE_DEV:
241 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); 200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
@@ -306,11 +265,6 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
306 case SNDRV_DMA_TYPE_CONTINUOUS: 265 case SNDRV_DMA_TYPE_CONTINUOUS:
307 snd_free_pages(dmab->area, dmab->bytes); 266 snd_free_pages(dmab->area, dmab->bytes);
308 break; 267 break;
309#ifdef CONFIG_SBUS
310 case SNDRV_DMA_TYPE_SBUS:
311 snd_free_sbus_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
312 break;
313#endif
314#ifdef CONFIG_HAS_DMA 268#ifdef CONFIG_HAS_DMA
315 case SNDRV_DMA_TYPE_DEV: 269 case SNDRV_DMA_TYPE_DEV:
316 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 270 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
@@ -419,7 +373,7 @@ static int snd_mem_proc_read(struct seq_file *seq, void *offset)
419 long pages = snd_allocated_pages >> (PAGE_SHIFT-12); 373 long pages = snd_allocated_pages >> (PAGE_SHIFT-12);
420 struct snd_mem_list *mem; 374 struct snd_mem_list *mem;
421 int devno; 375 int devno;
422 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG", "SBUS" }; 376 static char *types[] = { "UNKNOWN", "CONT", "DEV", "DEV-SG" };
423 377
424 mutex_lock(&list_mutex); 378 mutex_lock(&list_mutex);
425 seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n", 379 seq_printf(seq, "pages : %li bytes (%li pages per %likB)\n",
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 1af62b8b86c6..e17836680f49 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -2283,7 +2283,7 @@ static int snd_pcm_oss_open_file(struct file *file,
2283 int idx, err; 2283 int idx, err;
2284 struct snd_pcm_oss_file *pcm_oss_file; 2284 struct snd_pcm_oss_file *pcm_oss_file;
2285 struct snd_pcm_substream *substream; 2285 struct snd_pcm_substream *substream;
2286 unsigned int f_mode = file->f_mode; 2286 fmode_t f_mode = file->f_mode;
2287 2287
2288 if (rpcm_oss_file) 2288 if (rpcm_oss_file)
2289 *rpcm_oss_file = NULL; 2289 *rpcm_oss_file = NULL;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 6ea5cfb83998..921691080f35 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -908,12 +908,12 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
908EXPORT_SYMBOL(snd_pcm_hw_rule_add); 908EXPORT_SYMBOL(snd_pcm_hw_rule_add);
909 909
910/** 910/**
911 * snd_pcm_hw_constraint_mask 911 * snd_pcm_hw_constraint_mask - apply the given bitmap mask constraint
912 * @runtime: PCM runtime instance 912 * @runtime: PCM runtime instance
913 * @var: hw_params variable to apply the mask 913 * @var: hw_params variable to apply the mask
914 * @mask: the bitmap mask 914 * @mask: the bitmap mask
915 * 915 *
916 * Apply the constraint of the given bitmap mask to a mask parameter. 916 * Apply the constraint of the given bitmap mask to a 32-bit mask parameter.
917 */ 917 */
918int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, 918int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
919 u_int32_t mask) 919 u_int32_t mask)
@@ -928,12 +928,12 @@ int snd_pcm_hw_constraint_mask(struct snd_pcm_runtime *runtime, snd_pcm_hw_param
928} 928}
929 929
930/** 930/**
931 * snd_pcm_hw_constraint_mask64 931 * snd_pcm_hw_constraint_mask64 - apply the given bitmap mask constraint
932 * @runtime: PCM runtime instance 932 * @runtime: PCM runtime instance
933 * @var: hw_params variable to apply the mask 933 * @var: hw_params variable to apply the mask
934 * @mask: the 64bit bitmap mask 934 * @mask: the 64bit bitmap mask
935 * 935 *
936 * Apply the constraint of the given bitmap mask to a mask parameter. 936 * Apply the constraint of the given bitmap mask to a 64-bit mask parameter.
937 */ 937 */
938int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var, 938int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_param_t var,
939 u_int64_t mask) 939 u_int64_t mask)
@@ -949,7 +949,7 @@ int snd_pcm_hw_constraint_mask64(struct snd_pcm_runtime *runtime, snd_pcm_hw_par
949} 949}
950 950
951/** 951/**
952 * snd_pcm_hw_constraint_integer 952 * snd_pcm_hw_constraint_integer - apply an integer constraint to an interval
953 * @runtime: PCM runtime instance 953 * @runtime: PCM runtime instance
954 * @var: hw_params variable to apply the integer constraint 954 * @var: hw_params variable to apply the integer constraint
955 * 955 *
@@ -964,7 +964,7 @@ int snd_pcm_hw_constraint_integer(struct snd_pcm_runtime *runtime, snd_pcm_hw_pa
964EXPORT_SYMBOL(snd_pcm_hw_constraint_integer); 964EXPORT_SYMBOL(snd_pcm_hw_constraint_integer);
965 965
966/** 966/**
967 * snd_pcm_hw_constraint_minmax 967 * snd_pcm_hw_constraint_minmax - apply a min/max range constraint to an interval
968 * @runtime: PCM runtime instance 968 * @runtime: PCM runtime instance
969 * @var: hw_params variable to apply the range 969 * @var: hw_params variable to apply the range
970 * @min: the minimal value 970 * @min: the minimal value
@@ -995,7 +995,7 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
995 995
996 996
997/** 997/**
998 * snd_pcm_hw_constraint_list 998 * snd_pcm_hw_constraint_list - apply a list of constraints to a parameter
999 * @runtime: PCM runtime instance 999 * @runtime: PCM runtime instance
1000 * @cond: condition bits 1000 * @cond: condition bits
1001 * @var: hw_params variable to apply the list constraint 1001 * @var: hw_params variable to apply the list constraint
@@ -1031,7 +1031,7 @@ static int snd_pcm_hw_rule_ratnums(struct snd_pcm_hw_params *params,
1031} 1031}
1032 1032
1033/** 1033/**
1034 * snd_pcm_hw_constraint_ratnums 1034 * snd_pcm_hw_constraint_ratnums - apply ratnums constraint to a parameter
1035 * @runtime: PCM runtime instance 1035 * @runtime: PCM runtime instance
1036 * @cond: condition bits 1036 * @cond: condition bits
1037 * @var: hw_params variable to apply the ratnums constraint 1037 * @var: hw_params variable to apply the ratnums constraint
@@ -1064,7 +1064,7 @@ static int snd_pcm_hw_rule_ratdens(struct snd_pcm_hw_params *params,
1064} 1064}
1065 1065
1066/** 1066/**
1067 * snd_pcm_hw_constraint_ratdens 1067 * snd_pcm_hw_constraint_ratdens - apply ratdens constraint to a parameter
1068 * @runtime: PCM runtime instance 1068 * @runtime: PCM runtime instance
1069 * @cond: condition bits 1069 * @cond: condition bits
1070 * @var: hw_params variable to apply the ratdens constraint 1070 * @var: hw_params variable to apply the ratdens constraint
@@ -1095,7 +1095,7 @@ static int snd_pcm_hw_rule_msbits(struct snd_pcm_hw_params *params,
1095} 1095}
1096 1096
1097/** 1097/**
1098 * snd_pcm_hw_constraint_msbits 1098 * snd_pcm_hw_constraint_msbits - add a hw constraint msbits rule
1099 * @runtime: PCM runtime instance 1099 * @runtime: PCM runtime instance
1100 * @cond: condition bits 1100 * @cond: condition bits
1101 * @width: sample bits width 1101 * @width: sample bits width
@@ -1123,7 +1123,7 @@ static int snd_pcm_hw_rule_step(struct snd_pcm_hw_params *params,
1123} 1123}
1124 1124
1125/** 1125/**
1126 * snd_pcm_hw_constraint_step 1126 * snd_pcm_hw_constraint_step - add a hw constraint step rule
1127 * @runtime: PCM runtime instance 1127 * @runtime: PCM runtime instance
1128 * @cond: condition bits 1128 * @cond: condition bits
1129 * @var: hw_params variable to apply the step constraint 1129 * @var: hw_params variable to apply the step constraint
@@ -1154,7 +1154,7 @@ static int snd_pcm_hw_rule_pow2(struct snd_pcm_hw_params *params, struct snd_pcm
1154} 1154}
1155 1155
1156/** 1156/**
1157 * snd_pcm_hw_constraint_pow2 1157 * snd_pcm_hw_constraint_pow2 - add a hw constraint power-of-2 rule
1158 * @runtime: PCM runtime instance 1158 * @runtime: PCM runtime instance
1159 * @cond: condition bits 1159 * @cond: condition bits
1160 * @var: hw_params variable to apply the power-of-2 constraint 1160 * @var: hw_params variable to apply the power-of-2 constraint
@@ -1202,13 +1202,13 @@ void _snd_pcm_hw_params_any(struct snd_pcm_hw_params *params)
1202EXPORT_SYMBOL(_snd_pcm_hw_params_any); 1202EXPORT_SYMBOL(_snd_pcm_hw_params_any);
1203 1203
1204/** 1204/**
1205 * snd_pcm_hw_param_value 1205 * snd_pcm_hw_param_value - return @params field @var value
1206 * @params: the hw_params instance 1206 * @params: the hw_params instance
1207 * @var: parameter to retrieve 1207 * @var: parameter to retrieve
1208 * @dir: pointer to the direction (-1,0,1) or NULL 1208 * @dir: pointer to the direction (-1,0,1) or %NULL
1209 * 1209 *
1210 * Return the value for field PAR if it's fixed in configuration space 1210 * Return the value for field @var if it's fixed in configuration space
1211 * defined by PARAMS. Return -EINVAL otherwise 1211 * defined by @params. Return -%EINVAL otherwise.
1212 */ 1212 */
1213int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params, 1213int snd_pcm_hw_param_value(const struct snd_pcm_hw_params *params,
1214 snd_pcm_hw_param_t var, int *dir) 1214 snd_pcm_hw_param_t var, int *dir)
@@ -1271,13 +1271,13 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params,
1271 1271
1272 1272
1273/** 1273/**
1274 * snd_pcm_hw_param_first 1274 * snd_pcm_hw_param_first - refine config space and return minimum value
1275 * @pcm: PCM instance 1275 * @pcm: PCM instance
1276 * @params: the hw_params instance 1276 * @params: the hw_params instance
1277 * @var: parameter to retrieve 1277 * @var: parameter to retrieve
1278 * @dir: pointer to the direction (-1,0,1) or NULL 1278 * @dir: pointer to the direction (-1,0,1) or %NULL
1279 * 1279 *
1280 * Inside configuration space defined by PARAMS remove from PAR all 1280 * Inside configuration space defined by @params remove from @var all
1281 * values > minimum. Reduce configuration space accordingly. 1281 * values > minimum. Reduce configuration space accordingly.
1282 * Return the minimum. 1282 * Return the minimum.
1283 */ 1283 */
@@ -1317,13 +1317,13 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params,
1317 1317
1318 1318
1319/** 1319/**
1320 * snd_pcm_hw_param_last 1320 * snd_pcm_hw_param_last - refine config space and return maximum value
1321 * @pcm: PCM instance 1321 * @pcm: PCM instance
1322 * @params: the hw_params instance 1322 * @params: the hw_params instance
1323 * @var: parameter to retrieve 1323 * @var: parameter to retrieve
1324 * @dir: pointer to the direction (-1,0,1) or NULL 1324 * @dir: pointer to the direction (-1,0,1) or %NULL
1325 * 1325 *
1326 * Inside configuration space defined by PARAMS remove from PAR all 1326 * Inside configuration space defined by @params remove from @var all
1327 * values < maximum. Reduce configuration space accordingly. 1327 * values < maximum. Reduce configuration space accordingly.
1328 * Return the maximum. 1328 * Return the maximum.
1329 */ 1329 */
@@ -1345,11 +1345,11 @@ int snd_pcm_hw_param_last(struct snd_pcm_substream *pcm,
1345EXPORT_SYMBOL(snd_pcm_hw_param_last); 1345EXPORT_SYMBOL(snd_pcm_hw_param_last);
1346 1346
1347/** 1347/**
1348 * snd_pcm_hw_param_choose 1348 * snd_pcm_hw_param_choose - choose a configuration defined by @params
1349 * @pcm: PCM instance 1349 * @pcm: PCM instance
1350 * @params: the hw_params instance 1350 * @params: the hw_params instance
1351 * 1351 *
1352 * Choose one configuration from configuration space defined by PARAMS 1352 * Choose one configuration from configuration space defined by @params.
1353 * The configuration chosen is that obtained fixing in this order: 1353 * The configuration chosen is that obtained fixing in this order:
1354 * first access, first format, first subformat, min channels, 1354 * first access, first format, first subformat, min channels,
1355 * min rate, min period time, max buffer size, min tick time 1355 * min rate, min period time, max buffer size, min tick time
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 89b7f549bebd..ea2bf82c9373 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -319,6 +319,7 @@ EXPORT_SYMBOL(snd_pcm_format_physical_width);
319/** 319/**
320 * snd_pcm_format_size - return the byte size of samples on the given format 320 * snd_pcm_format_size - return the byte size of samples on the given format
321 * @format: the format to check 321 * @format: the format to check
322 * @samples: sampling rate
322 * 323 *
323 * Returns the byte size of the given samples for the format, or a 324 * Returns the byte size of the given samples for the format, or a
324 * negative error code if unknown format. 325 * negative error code if unknown format.
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e61e12506ded..a789efc9df39 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -875,10 +875,8 @@ static struct action_ops snd_pcm_action_start = {
875}; 875};
876 876
877/** 877/**
878 * snd_pcm_start 878 * snd_pcm_start - start all linked streams
879 * @substream: the PCM substream instance 879 * @substream: the PCM substream instance
880 *
881 * Start all linked streams.
882 */ 880 */
883int snd_pcm_start(struct snd_pcm_substream *substream) 881int snd_pcm_start(struct snd_pcm_substream *substream)
884{ 882{
@@ -926,12 +924,11 @@ static struct action_ops snd_pcm_action_stop = {
926}; 924};
927 925
928/** 926/**
929 * snd_pcm_stop 927 * snd_pcm_stop - try to stop all running streams in the substream group
930 * @substream: the PCM substream instance 928 * @substream: the PCM substream instance
931 * @state: PCM state after stopping the stream 929 * @state: PCM state after stopping the stream
932 * 930 *
933 * Try to stop all running streams in the substream group. 931 * The state of each stream is then changed to the given state unconditionally.
934 * The state of each stream is changed to the given value after that unconditionally.
935 */ 932 */
936int snd_pcm_stop(struct snd_pcm_substream *substream, int state) 933int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
937{ 934{
@@ -941,11 +938,10 @@ int snd_pcm_stop(struct snd_pcm_substream *substream, int state)
941EXPORT_SYMBOL(snd_pcm_stop); 938EXPORT_SYMBOL(snd_pcm_stop);
942 939
943/** 940/**
944 * snd_pcm_drain_done 941 * snd_pcm_drain_done - stop the DMA only when the given stream is playback
945 * @substream: the PCM substream 942 * @substream: the PCM substream
946 * 943 *
947 * Stop the DMA only when the given stream is playback. 944 * After stopping, the state is changed to SETUP.
948 * The state is changed to SETUP.
949 * Unlike snd_pcm_stop(), this affects only the given stream. 945 * Unlike snd_pcm_stop(), this affects only the given stream.
950 */ 946 */
951int snd_pcm_drain_done(struct snd_pcm_substream *substream) 947int snd_pcm_drain_done(struct snd_pcm_substream *substream)
@@ -1065,10 +1061,9 @@ static struct action_ops snd_pcm_action_suspend = {
1065}; 1061};
1066 1062
1067/** 1063/**
1068 * snd_pcm_suspend 1064 * snd_pcm_suspend - trigger SUSPEND to all linked streams
1069 * @substream: the PCM substream 1065 * @substream: the PCM substream
1070 * 1066 *
1071 * Trigger SUSPEND to all linked streams.
1072 * After this call, all streams are changed to SUSPENDED state. 1067 * After this call, all streams are changed to SUSPENDED state.
1073 */ 1068 */
1074int snd_pcm_suspend(struct snd_pcm_substream *substream) 1069int snd_pcm_suspend(struct snd_pcm_substream *substream)
@@ -1088,10 +1083,9 @@ int snd_pcm_suspend(struct snd_pcm_substream *substream)
1088EXPORT_SYMBOL(snd_pcm_suspend); 1083EXPORT_SYMBOL(snd_pcm_suspend);
1089 1084
1090/** 1085/**
1091 * snd_pcm_suspend_all 1086 * snd_pcm_suspend_all - trigger SUSPEND to all substreams in the given pcm
1092 * @pcm: the PCM instance 1087 * @pcm: the PCM instance
1093 * 1088 *
1094 * Trigger SUSPEND to all substreams in the given pcm.
1095 * After this call, all streams are changed to SUSPENDED state. 1089 * After this call, all streams are changed to SUSPENDED state.
1096 */ 1090 */
1097int snd_pcm_suspend_all(struct snd_pcm *pcm) 1091int snd_pcm_suspend_all(struct snd_pcm *pcm)
@@ -1313,11 +1307,9 @@ static struct action_ops snd_pcm_action_prepare = {
1313}; 1307};
1314 1308
1315/** 1309/**
1316 * snd_pcm_prepare 1310 * snd_pcm_prepare - prepare the PCM substream to be triggerable
1317 * @substream: the PCM substream instance 1311 * @substream: the PCM substream instance
1318 * @file: file to refer f_flags 1312 * @file: file to refer f_flags
1319 *
1320 * Prepare the PCM substream to be triggerable.
1321 */ 1313 */
1322static int snd_pcm_prepare(struct snd_pcm_substream *substream, 1314static int snd_pcm_prepare(struct snd_pcm_substream *substream,
1323 struct file *file) 1315 struct file *file)
@@ -2177,7 +2169,6 @@ static int snd_pcm_release(struct inode *inode, struct file *file)
2177 if (snd_BUG_ON(!substream)) 2169 if (snd_BUG_ON(!substream))
2178 return -ENXIO; 2170 return -ENXIO;
2179 pcm = substream->pcm; 2171 pcm = substream->pcm;
2180 fasync_helper(-1, file, 0, &substream->runtime->fasync);
2181 mutex_lock(&pcm->open_mutex); 2172 mutex_lock(&pcm->open_mutex);
2182 snd_pcm_release_substream(substream); 2173 snd_pcm_release_substream(substream);
2183 kfree(pcm_file); 2174 kfree(pcm_file);
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index c4995c9f5730..002777ba336a 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -148,8 +148,10 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
148 148
149static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up) 149static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *substream,int up)
150{ 150{
151 if (!substream->opened)
152 return;
151 if (up) { 153 if (up) {
152 tasklet_hi_schedule(&substream->runtime->tasklet); 154 tasklet_schedule(&substream->runtime->tasklet);
153 } else { 155 } else {
154 tasklet_kill(&substream->runtime->tasklet); 156 tasklet_kill(&substream->runtime->tasklet);
155 substream->ops->trigger(substream, 0); 157 substream->ops->trigger(substream, 0);
@@ -158,6 +160,8 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
158 160
159static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up) 161static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
160{ 162{
163 if (!substream->opened)
164 return;
161 substream->ops->trigger(substream, up); 165 substream->ops->trigger(substream, up);
162 if (!up && substream->runtime->event) 166 if (!up && substream->runtime->event)
163 tasklet_kill(&substream->runtime->tasklet); 167 tasklet_kill(&substream->runtime->tasklet);
@@ -857,6 +861,8 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
857 int result = 0, count1; 861 int result = 0, count1;
858 struct snd_rawmidi_runtime *runtime = substream->runtime; 862 struct snd_rawmidi_runtime *runtime = substream->runtime;
859 863
864 if (!substream->opened)
865 return -EBADFD;
860 if (runtime->buffer == NULL) { 866 if (runtime->buffer == NULL) {
861 snd_printd("snd_rawmidi_receive: input is not active!!!\n"); 867 snd_printd("snd_rawmidi_receive: input is not active!!!\n");
862 return -EINVAL; 868 return -EINVAL;
@@ -902,7 +908,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
902 } 908 }
903 if (result > 0) { 909 if (result > 0) {
904 if (runtime->event) 910 if (runtime->event)
905 tasklet_hi_schedule(&runtime->tasklet); 911 tasklet_schedule(&runtime->tasklet);
906 else if (snd_rawmidi_ready(substream)) 912 else if (snd_rawmidi_ready(substream))
907 wake_up(&runtime->sleep); 913 wake_up(&runtime->sleep);
908 } 914 }
@@ -1126,6 +1132,8 @@ int snd_rawmidi_transmit_ack(struct snd_rawmidi_substream *substream, int count)
1126int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream, 1132int snd_rawmidi_transmit(struct snd_rawmidi_substream *substream,
1127 unsigned char *buffer, int count) 1133 unsigned char *buffer, int count)
1128{ 1134{
1135 if (!substream->opened)
1136 return -EBADFD;
1129 count = snd_rawmidi_transmit_peek(substream, buffer, count); 1137 count = snd_rawmidi_transmit_peek(substream, buffer, count);
1130 if (count < 0) 1138 if (count < 0)
1131 return count; 1139 return count;
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 51e64e30dd3b..0851cd13e303 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -118,7 +118,7 @@ static void rtctimer_tasklet(unsigned long data)
118 */ 118 */
119static void rtctimer_interrupt(void *private_data) 119static void rtctimer_interrupt(void *private_data)
120{ 120{
121 tasklet_hi_schedule(private_data); 121 tasklet_schedule(private_data);
122} 122}
123 123
124 124
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index ee0f8405ab35..bf09a5ad1865 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -43,7 +43,9 @@ int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE; 43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
44int seq_default_timer_card = -1; 44int seq_default_timer_card = -1;
45int seq_default_timer_device = 45int seq_default_timer_device =
46#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT 46#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT
47 SNDRV_TIMER_GLOBAL_HRTIMER
48#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT)
47 SNDRV_TIMER_GLOBAL_RTC 49 SNDRV_TIMER_GLOBAL_RTC
48#else 50#else
49 SNDRV_TIMER_GLOBAL_SYSTEM 51 SNDRV_TIMER_GLOBAL_SYSTEM
diff --git a/sound/core/sound.c b/sound/core/sound.c
index c0685e2f0afa..7872a02f6ca9 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -152,6 +152,10 @@ static int __snd_open(struct inode *inode, struct file *file)
152 } 152 }
153 old_fops = file->f_op; 153 old_fops = file->f_op;
154 file->f_op = fops_get(mptr->f_ops); 154 file->f_op = fops_get(mptr->f_ops);
155 if (file->f_op == NULL) {
156 file->f_op = old_fops;
157 return -ENODEV;
158 }
155 if (file->f_op->open) 159 if (file->f_op->open)
156 err = file->f_op->open(inode, file); 160 err = file->f_op->open(inode, file);
157 if (err) { 161 if (err) {
@@ -274,9 +278,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
274 return minor; 278 return minor;
275 } 279 }
276 snd_minors[minor] = preg; 280 snd_minors[minor] = preg;
277 preg->dev = device_create_drvdata(sound_class, device, 281 preg->dev = device_create(sound_class, device, MKDEV(major, minor),
278 MKDEV(major, minor), 282 private_data, "%s", name);
279 private_data, "%s", name);
280 if (IS_ERR(preg->dev)) { 283 if (IS_ERR(preg->dev)) {
281 snd_minors[minor] = NULL; 284 snd_minors[minor] = NULL;
282 mutex_unlock(&sound_mutex); 285 mutex_unlock(&sound_mutex);
diff --git a/sound/core/timer.c b/sound/core/timer.c
index e582face89d2..796532081e81 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -743,7 +743,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
743 spin_unlock_irqrestore(&timer->lock, flags); 743 spin_unlock_irqrestore(&timer->lock, flags);
744 744
745 if (use_tasklet) 745 if (use_tasklet)
746 tasklet_hi_schedule(&timer->task_queue); 746 tasklet_schedule(&timer->task_queue);
747} 747}
748 748
749/* 749/*
@@ -1263,7 +1263,6 @@ static int snd_timer_user_release(struct inode *inode, struct file *file)
1263 if (file->private_data) { 1263 if (file->private_data) {
1264 tu = file->private_data; 1264 tu = file->private_data;
1265 file->private_data = NULL; 1265 file->private_data = NULL;
1266 fasync_helper(-1, file, 0, &tu->fasync);
1267 if (tu->timeri) 1266 if (tu->timeri)
1268 snd_timer_close(tu->timeri); 1267 snd_timer_close(tu->timeri);
1269 kfree(tu->queue); 1268 kfree(tu->queue);
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 255fd18b9aec..0bcf14640fde 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -163,7 +163,7 @@ config SND_ML403_AC97CR
163 163
164config SND_AC97_POWER_SAVE 164config SND_AC97_POWER_SAVE
165 bool "AC97 Power-Saving Mode" 165 bool "AC97 Power-Saving Mode"
166 depends on SND_AC97_CODEC && EXPERIMENTAL 166 depends on SND_AC97_CODEC
167 default n 167 default n
168 help 168 help
169 Say Y here to enable the aggressive power-saving support of 169 Say Y here to enable the aggressive power-saving support of
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index e5e749f3e0ef..73be7e14a603 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -51,7 +51,7 @@ static int emu10k1_playback_constraints(struct snd_pcm_runtime *runtime)
51 if (err < 0) 51 if (err < 0)
52 return err; 52 return err;
53 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX); 53 err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 256, UINT_MAX);
54 if (err) < 0) 54 if (err < 0)
55 return err; 55 return err;
56 return 0; 56 return 0;
57} 57}
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index ecdbeb6d3603..7783843ca9ae 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1153,7 +1153,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1153 /* get irq */ 1153 /* get irq */
1154 irq = platform_get_irq(pfdev, 0); 1154 irq = platform_get_irq(pfdev, 0);
1155 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, 1155 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED,
1156 pfdev->dev.bus_id, (void *)ml403_ac97cr)) { 1156 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
1157 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1157 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1158 "unable to grab IRQ %d\n", 1158 "unable to grab IRQ %d\n",
1159 irq); 1159 irq);
@@ -1166,7 +1166,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1166 ml403_ac97cr->irq); 1166 ml403_ac97cr->irq);
1167 irq = platform_get_irq(pfdev, 1); 1167 irq = platform_get_irq(pfdev, 1);
1168 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, 1168 if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED,
1169 pfdev->dev.bus_id, (void *)ml403_ac97cr)) { 1169 dev_name(&pfdev->dev), (void *)ml403_ac97cr)) {
1170 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1170 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1171 "unable to grab IRQ %d\n", 1171 "unable to grab IRQ %d\n",
1172 irq); 1172 irq);
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 1899cf0685bc..a4049eb94d35 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -96,7 +96,6 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
96 return -EINVAL; 96 return -EINVAL;
97 97
98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
99 pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ;
100 pcsp_chip.timer.function = pcsp_do_timer; 99 pcsp_chip.timer.function = pcsp_do_timer;
101 100
102 card = snd_card_new(index, id, THIS_MODULE, 0); 101 card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -188,10 +187,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
188 187
189static void pcsp_stop_beep(struct snd_pcsp *chip) 188static void pcsp_stop_beep(struct snd_pcsp *chip)
190{ 189{
191 spin_lock_irq(&chip->substream_lock); 190 pcsp_sync_stop(chip);
192 if (!chip->playback_substream) 191 pcspkr_stop_sound();
193 pcspkr_stop_sound();
194 spin_unlock_irq(&chip->substream_lock);
195} 192}
196 193
197#ifdef CONFIG_PM 194#ifdef CONFIG_PM
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 1d661f795e8c..cdef2664218f 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -62,6 +62,8 @@ struct snd_pcsp {
62 unsigned short port, irq, dma; 62 unsigned short port, irq, dma;
63 spinlock_t substream_lock; 63 spinlock_t substream_lock;
64 struct snd_pcm_substream *playback_substream; 64 struct snd_pcm_substream *playback_substream;
65 unsigned int fmt_size;
66 unsigned int is_signed;
65 size_t playback_ptr; 67 size_t playback_ptr;
66 size_t period_ptr; 68 size_t period_ptr;
67 atomic_t timer_active; 69 atomic_t timer_active;
@@ -77,6 +79,7 @@ struct snd_pcsp {
77extern struct snd_pcsp pcsp_chip; 79extern struct snd_pcsp pcsp_chip;
78 80
79extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle); 81extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
82extern void pcsp_sync_stop(struct snd_pcsp *chip);
80 83
81extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); 84extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
82extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); 85extern int snd_pcsp_new_mixer(struct snd_pcsp *chip);
diff --git a/sound/drivers/pcsp/pcsp_input.c b/sound/drivers/pcsp/pcsp_input.c
index cd9b83e7f7d1..0444cdeb4bec 100644
--- a/sound/drivers/pcsp/pcsp_input.c
+++ b/sound/drivers/pcsp/pcsp_input.c
@@ -24,13 +24,13 @@ static void pcspkr_do_sound(unsigned int count)
24 spin_lock_irqsave(&i8253_lock, flags); 24 spin_lock_irqsave(&i8253_lock, flags);
25 25
26 if (count) { 26 if (count) {
27 /* enable counter 2 */
28 outb_p(inb_p(0x61) | 3, 0x61);
29 /* set command for counter 2, 2 byte write */ 27 /* set command for counter 2, 2 byte write */
30 outb_p(0xB6, 0x43); 28 outb_p(0xB6, 0x43);
31 /* select desired HZ */ 29 /* select desired HZ */
32 outb_p(count & 0xff, 0x42); 30 outb_p(count & 0xff, 0x42);
33 outb((count >> 8) & 0xff, 0x42); 31 outb((count >> 8) & 0xff, 0x42);
32 /* enable counter 2 */
33 outb_p(inb_p(0x61) | 3, 0x61);
34 } else { 34 } else {
35 /* disable counter 2 */ 35 /* disable counter 2 */
36 outb(inb_p(0x61) & 0xFC, 0x61); 36 outb(inb_p(0x61) & 0xFC, 0x61);
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index e341f3f83b6a..84cc2658c05b 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/moduleparam.h> 10#include <linux/moduleparam.h>
11#include <linux/interrupt.h>
11#include <sound/pcm.h> 12#include <sound/pcm.h>
12#include <asm/io.h> 13#include <asm/io.h>
13#include "pcsp.h" 14#include "pcsp.h"
@@ -19,61 +20,57 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
19 20
20#define DMIX_WANTS_S16 1 21#define DMIX_WANTS_S16 1
21 22
22enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) 23/*
24 * Call snd_pcm_period_elapsed in a tasklet
25 * This avoids spinlock messes and long-running irq contexts
26 */
27static void pcsp_call_pcm_elapsed(unsigned long priv)
28{
29 if (atomic_read(&pcsp_chip.timer_active)) {
30 struct snd_pcm_substream *substream;
31 substream = pcsp_chip.playback_substream;
32 if (substream)
33 snd_pcm_period_elapsed(substream);
34 }
35}
36
37static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
38
39/* write the port and returns the next expire time in ns;
40 * called at the trigger-start and in hrtimer callback
41 */
42static unsigned long pcsp_timer_update(struct hrtimer *handle)
23{ 43{
24 unsigned char timer_cnt, val; 44 unsigned char timer_cnt, val;
25 int fmt_size, periods_elapsed;
26 u64 ns; 45 u64 ns;
27 size_t period_bytes, buffer_bytes;
28 struct snd_pcm_substream *substream; 46 struct snd_pcm_substream *substream;
29 struct snd_pcm_runtime *runtime; 47 struct snd_pcm_runtime *runtime;
30 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); 48 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
49 unsigned long flags;
31 50
32 if (chip->thalf) { 51 if (chip->thalf) {
33 outb(chip->val61, 0x61); 52 outb(chip->val61, 0x61);
34 chip->thalf = 0; 53 chip->thalf = 0;
35 if (!atomic_read(&chip->timer_active)) 54 if (!atomic_read(&chip->timer_active))
36 return HRTIMER_NORESTART; 55 return 0;
37 hrtimer_forward(&chip->timer, chip->timer.expires, 56 return chip->ns_rem;
38 ktime_set(0, chip->ns_rem));
39 return HRTIMER_RESTART;
40 } 57 }
41 58
42 spin_lock_irq(&chip->substream_lock);
43 /* Takashi Iwai says regarding this extra lock:
44
45 If the irq handler handles some data on the DMA buffer, it should
46 do snd_pcm_stream_lock().
47 That protects basically against all races among PCM callbacks, yes.
48 However, there are two remaining issues:
49 1. The substream pointer you try to lock isn't protected _before_
50 this lock yet.
51 2. snd_pcm_period_elapsed() itself acquires the lock.
52 The requirement of another lock is because of 1. When you get
53 chip->playback_substream, it's not protected.
54 Keeping this lock while snd_pcm_period_elapsed() assures the substream
55 is still protected (at least, not released). And the other status is
56 handled properly inside snd_pcm_stream_lock() in
57 snd_pcm_period_elapsed().
58
59 */
60 if (!chip->playback_substream)
61 goto exit_nr_unlock1;
62 substream = chip->playback_substream;
63 snd_pcm_stream_lock(substream);
64 if (!atomic_read(&chip->timer_active)) 59 if (!atomic_read(&chip->timer_active))
65 goto exit_nr_unlock2; 60 return 0;
61 substream = chip->playback_substream;
62 if (!substream)
63 return 0;
66 64
67 runtime = substream->runtime; 65 runtime = substream->runtime;
68 fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
69 /* assume it is mono! */ 66 /* assume it is mono! */
70 val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; 67 val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
71 if (snd_pcm_format_signed(runtime->format)) 68 if (chip->is_signed)
72 val ^= 0x80; 69 val ^= 0x80;
73 timer_cnt = val * CUR_DIV() / 256; 70 timer_cnt = val * CUR_DIV() / 256;
74 71
75 if (timer_cnt && chip->enable) { 72 if (timer_cnt && chip->enable) {
76 spin_lock(&i8253_lock); 73 spin_lock_irqsave(&i8253_lock, flags);
77 if (!nforce_wa) { 74 if (!nforce_wa) {
78 outb_p(chip->val61, 0x61); 75 outb_p(chip->val61, 0x61);
79 outb_p(timer_cnt, 0x42); 76 outb_p(timer_cnt, 0x42);
@@ -82,12 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
82 outb(chip->val61 ^ 2, 0x61); 79 outb(chip->val61 ^ 2, 0x61);
83 chip->thalf = 1; 80 chip->thalf = 1;
84 } 81 }
85 spin_unlock(&i8253_lock); 82 spin_unlock_irqrestore(&i8253_lock, flags);
86 } 83 }
87 84
85 chip->ns_rem = PCSP_PERIOD_NS();
86 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
87 chip->ns_rem -= ns;
88 return ns;
89}
90
91enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
92{
93 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
94 struct snd_pcm_substream *substream;
95 int periods_elapsed, pointer_update;
96 size_t period_bytes, buffer_bytes;
97 unsigned long ns;
98 unsigned long flags;
99
100 pointer_update = !chip->thalf;
101 ns = pcsp_timer_update(handle);
102 if (!ns)
103 return HRTIMER_NORESTART;
104
105 /* update the playback position */
106 substream = chip->playback_substream;
107 if (!substream)
108 return HRTIMER_NORESTART;
109
88 period_bytes = snd_pcm_lib_period_bytes(substream); 110 period_bytes = snd_pcm_lib_period_bytes(substream);
89 buffer_bytes = snd_pcm_lib_buffer_bytes(substream); 111 buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
90 chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; 112
113 spin_lock_irqsave(&chip->substream_lock, flags);
114 chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
91 periods_elapsed = chip->playback_ptr - chip->period_ptr; 115 periods_elapsed = chip->playback_ptr - chip->period_ptr;
92 if (periods_elapsed < 0) { 116 if (periods_elapsed < 0) {
93#if PCSP_DEBUG 117#if PCSP_DEBUG
@@ -102,40 +126,30 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
102 * or ALSA will BUG on us. */ 126 * or ALSA will BUG on us. */
103 chip->playback_ptr %= buffer_bytes; 127 chip->playback_ptr %= buffer_bytes;
104 128
105 snd_pcm_stream_unlock(substream);
106
107 if (periods_elapsed) { 129 if (periods_elapsed) {
108 snd_pcm_period_elapsed(substream);
109 chip->period_ptr += periods_elapsed * period_bytes; 130 chip->period_ptr += periods_elapsed * period_bytes;
110 chip->period_ptr %= buffer_bytes; 131 chip->period_ptr %= buffer_bytes;
111 } 132 }
133 spin_unlock_irqrestore(&chip->substream_lock, flags);
112 134
113 spin_unlock_irq(&chip->substream_lock); 135 if (periods_elapsed)
136 tasklet_schedule(&pcsp_pcm_tasklet);
114 137
115 if (!atomic_read(&chip->timer_active)) 138 hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
116 return HRTIMER_NORESTART;
117 139
118 chip->ns_rem = PCSP_PERIOD_NS();
119 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
120 chip->ns_rem -= ns;
121 hrtimer_forward(&chip->timer, chip->timer.expires, ktime_set(0, ns));
122 return HRTIMER_RESTART; 140 return HRTIMER_RESTART;
123
124exit_nr_unlock2:
125 snd_pcm_stream_unlock(substream);
126exit_nr_unlock1:
127 spin_unlock_irq(&chip->substream_lock);
128 return HRTIMER_NORESTART;
129} 141}
130 142
131static void pcsp_start_playing(struct snd_pcsp *chip) 143static int pcsp_start_playing(struct snd_pcsp *chip)
132{ 144{
145 unsigned long ns;
146
133#if PCSP_DEBUG 147#if PCSP_DEBUG
134 printk(KERN_INFO "PCSP: start_playing called\n"); 148 printk(KERN_INFO "PCSP: start_playing called\n");
135#endif 149#endif
136 if (atomic_read(&chip->timer_active)) { 150 if (atomic_read(&chip->timer_active)) {
137 printk(KERN_ERR "PCSP: Timer already active\n"); 151 printk(KERN_ERR "PCSP: Timer already active\n");
138 return; 152 return -EIO;
139 } 153 }
140 154
141 spin_lock(&i8253_lock); 155 spin_lock(&i8253_lock);
@@ -145,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip)
145 atomic_set(&chip->timer_active, 1); 159 atomic_set(&chip->timer_active, 1);
146 chip->thalf = 0; 160 chip->thalf = 0;
147 161
148 hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); 162 ns = pcsp_timer_update(&pcsp_chip.timer);
163 if (!ns)
164 return -EIO;
165
166 hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
167 return 0;
149} 168}
150 169
151static void pcsp_stop_playing(struct snd_pcsp *chip) 170static void pcsp_stop_playing(struct snd_pcsp *chip)
@@ -164,26 +183,35 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
164 spin_unlock(&i8253_lock); 183 spin_unlock(&i8253_lock);
165} 184}
166 185
186/*
187 * Force to stop and sync the stream
188 */
189void pcsp_sync_stop(struct snd_pcsp *chip)
190{
191 local_irq_disable();
192 pcsp_stop_playing(chip);
193 local_irq_enable();
194 hrtimer_cancel(&chip->timer);
195 tasklet_kill(&pcsp_pcm_tasklet);
196}
197
167static int snd_pcsp_playback_close(struct snd_pcm_substream *substream) 198static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
168{ 199{
169 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 200 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
170#if PCSP_DEBUG 201#if PCSP_DEBUG
171 printk(KERN_INFO "PCSP: close called\n"); 202 printk(KERN_INFO "PCSP: close called\n");
172#endif 203#endif
173 if (atomic_read(&chip->timer_active)) { 204 pcsp_sync_stop(chip);
174 printk(KERN_ERR "PCSP: timer still active\n");
175 pcsp_stop_playing(chip);
176 }
177 spin_lock_irq(&chip->substream_lock);
178 chip->playback_substream = NULL; 205 chip->playback_substream = NULL;
179 spin_unlock_irq(&chip->substream_lock);
180 return 0; 206 return 0;
181} 207}
182 208
183static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream, 209static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
184 struct snd_pcm_hw_params *hw_params) 210 struct snd_pcm_hw_params *hw_params)
185{ 211{
212 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
186 int err; 213 int err;
214 pcsp_sync_stop(chip);
187 err = snd_pcm_lib_malloc_pages(substream, 215 err = snd_pcm_lib_malloc_pages(substream,
188 params_buffer_bytes(hw_params)); 216 params_buffer_bytes(hw_params));
189 if (err < 0) 217 if (err < 0)
@@ -193,9 +221,11 @@ static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
193 221
194static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) 222static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
195{ 223{
224 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
196#if PCSP_DEBUG 225#if PCSP_DEBUG
197 printk(KERN_INFO "PCSP: hw_free called\n"); 226 printk(KERN_INFO "PCSP: hw_free called\n");
198#endif 227#endif
228 pcsp_sync_stop(chip);
199 return snd_pcm_lib_free_pages(substream); 229 return snd_pcm_lib_free_pages(substream);
200} 230}
201 231
@@ -211,8 +241,12 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
211 snd_pcm_lib_period_bytes(substream), 241 snd_pcm_lib_period_bytes(substream),
212 substream->runtime->periods); 242 substream->runtime->periods);
213#endif 243#endif
244 pcsp_sync_stop(chip);
214 chip->playback_ptr = 0; 245 chip->playback_ptr = 0;
215 chip->period_ptr = 0; 246 chip->period_ptr = 0;
247 chip->fmt_size =
248 snd_pcm_format_physical_width(substream->runtime->format) >> 3;
249 chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
216 return 0; 250 return 0;
217} 251}
218 252
@@ -225,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
225 switch (cmd) { 259 switch (cmd) {
226 case SNDRV_PCM_TRIGGER_START: 260 case SNDRV_PCM_TRIGGER_START:
227 case SNDRV_PCM_TRIGGER_RESUME: 261 case SNDRV_PCM_TRIGGER_RESUME:
228 pcsp_start_playing(chip); 262 return pcsp_start_playing(chip);
229 break;
230 case SNDRV_PCM_TRIGGER_STOP: 263 case SNDRV_PCM_TRIGGER_STOP:
231 case SNDRV_PCM_TRIGGER_SUSPEND: 264 case SNDRV_PCM_TRIGGER_SUSPEND:
232 pcsp_stop_playing(chip); 265 pcsp_stop_playing(chip);
@@ -241,7 +274,11 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
241 *substream) 274 *substream)
242{ 275{
243 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 276 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
244 return bytes_to_frames(substream->runtime, chip->playback_ptr); 277 unsigned int pos;
278 spin_lock(&chip->substream_lock);
279 pos = chip->playback_ptr;
280 spin_unlock(&chip->substream_lock);
281 return bytes_to_frames(substream->runtime, pos);
245} 282}
246 283
247static struct snd_pcm_hardware snd_pcsp_playback = { 284static struct snd_pcm_hardware snd_pcsp_playback = {
@@ -278,9 +315,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
278 return -EBUSY; 315 return -EBUSY;
279 } 316 }
280 runtime->hw = snd_pcsp_playback; 317 runtime->hw = snd_pcsp_playback;
281 spin_lock_irq(&chip->substream_lock);
282 chip->playback_substream = substream; 318 chip->playback_substream = substream;
283 spin_unlock_irq(&chip->substream_lock);
284 return 0; 319 return 0;
285} 320}
286 321
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 473b07f6ae85..14e3354be43a 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -548,7 +548,7 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev)
548 (chip->chip_status & VX_STAT_IS_STALE)) 548 (chip->chip_status & VX_STAT_IS_STALE))
549 return IRQ_NONE; 549 return IRQ_NONE;
550 if (! vx_test_and_ack(chip)) 550 if (! vx_test_and_ack(chip))
551 tasklet_hi_schedule(&chip->tq); 551 tasklet_schedule(&chip->tq);
552 return IRQ_HANDLED; 552 return IRQ_HANDLED;
553} 553}
554 554
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 27de574c08f7..6644d0034fba 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -823,7 +823,7 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
823 * we trigger the pipe using tasklet, so that the interrupts are 823 * we trigger the pipe using tasklet, so that the interrupts are
824 * issued surely after the trigger is completed. 824 * issued surely after the trigger is completed.
825 */ 825 */
826 tasklet_hi_schedule(&pipe->start_tq); 826 tasklet_schedule(&pipe->start_tq);
827 chip->pcm_running++; 827 chip->pcm_running++;
828 pipe->running = 1; 828 pipe->running = 1;
829 break; 829 break;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index 83e90057270e..9d98a6658ac9 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -18,7 +18,7 @@
18 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * 20 *
21 */ 21 */
22 22
23#include <asm/io.h> 23#include <asm/io.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
@@ -84,13 +84,12 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea)
84 * Linux Video interface 84 * Linux Video interface
85 */ 85 */
86 86
87static int snd_tea575x_ioctl(struct inode *inode, struct file *file, 87static long snd_tea575x_ioctl(struct file *file,
88 unsigned int cmd, unsigned long data) 88 unsigned int cmd, unsigned long data)
89{ 89{
90 struct video_device *dev = video_devdata(file); 90 struct snd_tea575x *tea = video_drvdata(file);
91 struct snd_tea575x *tea = video_get_drvdata(dev);
92 void __user *arg = (void __user *)data; 91 void __user *arg = (void __user *)data;
93 92
94 switch(cmd) { 93 switch(cmd) {
95 case VIDIOCGCAP: 94 case VIDIOCGCAP:
96 { 95 {
@@ -111,9 +110,9 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
111 case VIDIOCGTUNER: 110 case VIDIOCGTUNER:
112 { 111 {
113 struct video_tuner v; 112 struct video_tuner v;
114 if (copy_from_user(&v, arg,sizeof(v))!=0) 113 if (copy_from_user(&v, arg,sizeof(v))!=0)
115 return -EFAULT; 114 return -EFAULT;
116 if (v.tuner) /* Only 1 tuner */ 115 if (v.tuner) /* Only 1 tuner */
117 return -EINVAL; 116 return -EINVAL;
118 v.rangelow = (87*16000); 117 v.rangelow = (87*16000);
119 v.rangehigh = (108*16000); 118 v.rangehigh = (108*16000);
@@ -145,24 +144,24 @@ static int snd_tea575x_ioctl(struct inode *inode, struct file *file,
145 snd_tea575x_set_freq(tea); 144 snd_tea575x_set_freq(tea);
146 return 0; 145 return 0;
147 case VIDIOCGAUDIO: 146 case VIDIOCGAUDIO:
148 { 147 {
149 struct video_audio v; 148 struct video_audio v;
150 memset(&v, 0, sizeof(v)); 149 memset(&v, 0, sizeof(v));
151 strcpy(v.name, "Radio"); 150 strcpy(v.name, "Radio");
152 if(copy_to_user(arg,&v, sizeof(v))) 151 if(copy_to_user(arg,&v, sizeof(v)))
153 return -EFAULT; 152 return -EFAULT;
154 return 0; 153 return 0;
155 } 154 }
156 case VIDIOCSAUDIO: 155 case VIDIOCSAUDIO:
157 { 156 {
158 struct video_audio v; 157 struct video_audio v;
159 if(copy_from_user(&v, arg, sizeof(v))) 158 if(copy_from_user(&v, arg, sizeof(v)))
160 return -EFAULT; 159 return -EFAULT;
161 if (tea->ops->mute) 160 if (tea->ops->mute)
162 tea->ops->mute(tea, 161 tea->ops->mute(tea,
163 (v.flags & 162 (v.flags &
164 VIDEO_AUDIO_MUTE) ? 1 : 0); 163 VIDEO_AUDIO_MUTE) ? 1 : 0);
165 if(v.audio) 164 if(v.audio)
166 return -EINVAL; 165 return -EINVAL;
167 return 0; 166 return 0;
168 } 167 }
@@ -175,6 +174,21 @@ static void snd_tea575x_release(struct video_device *vfd)
175{ 174{
176} 175}
177 176
177static int snd_tea575x_exclusive_open(struct file *file)
178{
179 struct snd_tea575x *tea = video_drvdata(file);
180
181 return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
182}
183
184static int snd_tea575x_exclusive_release(struct file *file)
185{
186 struct snd_tea575x *tea = video_drvdata(file);
187
188 clear_bit(0, &tea->in_use);
189 return 0;
190}
191
178/* 192/*
179 * initialize all the tea575x chips 193 * initialize all the tea575x chips
180 */ 194 */
@@ -193,9 +207,10 @@ void snd_tea575x_init(struct snd_tea575x *tea)
193 tea->vd.release = snd_tea575x_release; 207 tea->vd.release = snd_tea575x_release;
194 video_set_drvdata(&tea->vd, tea); 208 video_set_drvdata(&tea->vd, tea);
195 tea->vd.fops = &tea->fops; 209 tea->vd.fops = &tea->fops;
210 tea->in_use = 0;
196 tea->fops.owner = tea->card->module; 211 tea->fops.owner = tea->card->module;
197 tea->fops.open = video_exclusive_open; 212 tea->fops.open = snd_tea575x_exclusive_open;
198 tea->fops.release = video_exclusive_release; 213 tea->fops.release = snd_tea575x_exclusive_release;
199 tea->fops.ioctl = snd_tea575x_ioctl; 214 tea->fops.ioctl = snd_tea575x_ioctl;
200 if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) { 215 if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 0) {
201 snd_printk(KERN_ERR "unable to register tea575x tuner\n"); 216 snd_printk(KERN_ERR "unable to register tea575x tuner\n");
@@ -225,11 +240,11 @@ static int __init alsa_tea575x_module_init(void)
225{ 240{
226 return 0; 241 return 0;
227} 242}
228 243
229static void __exit alsa_tea575x_module_exit(void) 244static void __exit alsa_tea575x_module_exit(void)
230{ 245{
231} 246}
232 247
233module_init(alsa_tea575x_module_init) 248module_init(alsa_tea575x_module_init)
234module_exit(alsa_tea575x_module_exit) 249module_exit(alsa_tea575x_module_exit)
235 250
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig
index 660beb41f767..ce0aa044e274 100644
--- a/sound/isa/Kconfig
+++ b/sound/isa/Kconfig
@@ -211,7 +211,7 @@ config SND_GUSCLASSIC
211 211
212config SND_GUSEXTREME 212config SND_GUSEXTREME
213 tristate "Gravis UltraSound Extreme" 213 tristate "Gravis UltraSound Extreme"
214 select SND_HWDEP 214 select SND_OPL3_LIB
215 select SND_MPU401_UART 215 select SND_MPU401_UART
216 select SND_PCM 216 select SND_PCM
217 help 217 help
diff --git a/sound/isa/ad1848/ad1848.c b/sound/isa/ad1848/ad1848.c
index b68d20edc20f..223a6c038819 100644
--- a/sound/isa/ad1848/ad1848.c
+++ b/sound/isa/ad1848/ad1848.c
@@ -70,15 +70,15 @@ static int __devinit snd_ad1848_match(struct device *dev, unsigned int n)
70 return 0; 70 return 0;
71 71
72 if (port[n] == SNDRV_AUTO_PORT) { 72 if (port[n] == SNDRV_AUTO_PORT) {
73 snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); 73 dev_err(dev, "please specify port\n");
74 return 0; 74 return 0;
75 } 75 }
76 if (irq[n] == SNDRV_AUTO_IRQ) { 76 if (irq[n] == SNDRV_AUTO_IRQ) {
77 snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); 77 dev_err(dev, "please specify irq\n");
78 return 0; 78 return 0;
79 } 79 }
80 if (dma1[n] == SNDRV_AUTO_DMA) { 80 if (dma1[n] == SNDRV_AUTO_DMA) {
81 snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); 81 dev_err(dev, "please specify dma1\n");
82 return 0; 82 return 0;
83 } 83 }
84 return 1; 84 return 1;
diff --git a/sound/isa/adlib.c b/sound/isa/adlib.c
index efa8c80d05b6..374b7177e111 100644
--- a/sound/isa/adlib.c
+++ b/sound/isa/adlib.c
@@ -36,7 +36,7 @@ static int __devinit snd_adlib_match(struct device *dev, unsigned int n)
36 return 0; 36 return 0;
37 37
38 if (port[n] == SNDRV_AUTO_PORT) { 38 if (port[n] == SNDRV_AUTO_PORT) {
39 snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); 39 dev_err(dev, "please specify port\n");
40 return 0; 40 return 0;
41 } 41 }
42 return 1; 42 return 1;
@@ -55,13 +55,13 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
55 55
56 card = snd_card_new(index[n], id[n], THIS_MODULE, 0); 56 card = snd_card_new(index[n], id[n], THIS_MODULE, 0);
57 if (!card) { 57 if (!card) {
58 snd_printk(KERN_ERR "%s: could not create card\n", dev->bus_id); 58 dev_err(dev, "could not create card\n");
59 return -EINVAL; 59 return -EINVAL;
60 } 60 }
61 61
62 card->private_data = request_region(port[n], 4, CRD_NAME); 62 card->private_data = request_region(port[n], 4, CRD_NAME);
63 if (!card->private_data) { 63 if (!card->private_data) {
64 snd_printk(KERN_ERR "%s: could not grab ports\n", dev->bus_id); 64 dev_err(dev, "could not grab ports\n");
65 error = -EBUSY; 65 error = -EBUSY;
66 goto out; 66 goto out;
67 } 67 }
@@ -73,13 +73,13 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
73 73
74 error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3); 74 error = snd_opl3_create(card, port[n], port[n] + 2, OPL3_HW_AUTO, 1, &opl3);
75 if (error < 0) { 75 if (error < 0) {
76 snd_printk(KERN_ERR "%s: could not create OPL\n", dev->bus_id); 76 dev_err(dev, "could not create OPL\n");
77 goto out; 77 goto out;
78 } 78 }
79 79
80 error = snd_opl3_hwdep_new(opl3, 0, 0, NULL); 80 error = snd_opl3_hwdep_new(opl3, 0, 0, NULL);
81 if (error < 0) { 81 if (error < 0) {
82 snd_printk(KERN_ERR "%s: could not create FM\n", dev->bus_id); 82 dev_err(dev, "could not create FM\n");
83 goto out; 83 goto out;
84 } 84 }
85 85
@@ -87,7 +87,7 @@ static int __devinit snd_adlib_probe(struct device *dev, unsigned int n)
87 87
88 error = snd_card_register(card); 88 error = snd_card_register(card);
89 if (error < 0) { 89 if (error < 0) {
90 snd_printk(KERN_ERR "%s: could not register card\n", dev->bus_id); 90 dev_err(dev, "could not register card\n");
91 goto out; 91 goto out;
92 } 92 }
93 93
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c
index ddd289120aa8..f019d449e2d6 100644
--- a/sound/isa/cs423x/cs4231.c
+++ b/sound/isa/cs423x/cs4231.c
@@ -74,15 +74,15 @@ static int __devinit snd_cs4231_match(struct device *dev, unsigned int n)
74 return 0; 74 return 0;
75 75
76 if (port[n] == SNDRV_AUTO_PORT) { 76 if (port[n] == SNDRV_AUTO_PORT) {
77 snd_printk(KERN_ERR "%s: please specify port\n", dev->bus_id); 77 dev_err(dev, "please specify port\n");
78 return 0; 78 return 0;
79 } 79 }
80 if (irq[n] == SNDRV_AUTO_IRQ) { 80 if (irq[n] == SNDRV_AUTO_IRQ) {
81 snd_printk(KERN_ERR "%s: please specify irq\n", dev->bus_id); 81 dev_err(dev, "please specify irq\n");
82 return 0; 82 return 0;
83 } 83 }
84 if (dma1[n] == SNDRV_AUTO_DMA) { 84 if (dma1[n] == SNDRV_AUTO_DMA) {
85 snd_printk(KERN_ERR "%s: please specify dma1\n", dev->bus_id); 85 dev_err(dev, "please specify dma1\n");
86 return 0; 86 return 0;
87 } 87 }
88 return 1; 88 return 1;
@@ -133,7 +133,7 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n)
133 mpu_port[n], 0, mpu_irq[n], 133 mpu_port[n], 0, mpu_irq[n],
134 mpu_irq[n] >= 0 ? IRQF_DISABLED : 0, 134 mpu_irq[n] >= 0 ? IRQF_DISABLED : 0,
135 NULL) < 0) 135 NULL) < 0)
136 printk(KERN_WARNING "%s: MPU401 not detected\n", dev->bus_id); 136 dev_warn(dev, "MPU401 not detected\n");
137 } 137 }
138 138
139 snd_card_set_dev(card, dev); 139 snd_card_set_dev(card, dev);
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index 91f9c15d3e30..019c9401663e 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -488,19 +488,19 @@ static int __devinit snd_cs423x_isa_match(struct device *pdev,
488 return 0; 488 return 0;
489 489
490 if (port[dev] == SNDRV_AUTO_PORT) { 490 if (port[dev] == SNDRV_AUTO_PORT) {
491 snd_printk(KERN_ERR "%s: please specify port\n", pdev->bus_id); 491 dev_err(pdev, "please specify port\n");
492 return 0; 492 return 0;
493 } 493 }
494 if (cport[dev] == SNDRV_AUTO_PORT) { 494 if (cport[dev] == SNDRV_AUTO_PORT) {
495 snd_printk(KERN_ERR "%s: please specify cport\n", pdev->bus_id); 495 dev_err(pdev, "please specify cport\n");
496 return 0; 496 return 0;
497 } 497 }
498 if (irq[dev] == SNDRV_AUTO_IRQ) { 498 if (irq[dev] == SNDRV_AUTO_IRQ) {
499 snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); 499 dev_err(pdev, "please specify irq\n");
500 return 0; 500 return 0;
501 } 501 }
502 if (dma1[dev] == SNDRV_AUTO_DMA) { 502 if (dma1[dev] == SNDRV_AUTO_DMA) {
503 snd_printk(KERN_ERR "%s: please specify dma1\n", pdev->bus_id); 503 dev_err(pdev, "please specify dma1\n");
504 return 0; 504 return 0;
505 } 505 }
506 return 1; 506 return 1;
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c
index f88639ea64b2..b46377139cf8 100644
--- a/sound/isa/es1688/es1688.c
+++ b/sound/isa/es1688/es1688.c
@@ -88,16 +88,14 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
88 if (irq[n] == SNDRV_AUTO_IRQ) { 88 if (irq[n] == SNDRV_AUTO_IRQ) {
89 irq[n] = snd_legacy_find_free_irq(possible_irqs); 89 irq[n] = snd_legacy_find_free_irq(possible_irqs);
90 if (irq[n] < 0) { 90 if (irq[n] < 0) {
91 snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", 91 dev_err(dev, "unable to find a free IRQ\n");
92 dev->bus_id);
93 return -EBUSY; 92 return -EBUSY;
94 } 93 }
95 } 94 }
96 if (dma8[n] == SNDRV_AUTO_DMA) { 95 if (dma8[n] == SNDRV_AUTO_DMA) {
97 dma8[n] = snd_legacy_find_free_dma(possible_dmas); 96 dma8[n] = snd_legacy_find_free_dma(possible_dmas);
98 if (dma8[n] < 0) { 97 if (dma8[n] < 0) {
99 snd_printk(KERN_ERR "%s: unable to find a free DMA\n", 98 dev_err(dev, "unable to find a free DMA\n");
100 dev->bus_id);
101 return -EBUSY; 99 return -EBUSY;
102 } 100 }
103 } 101 }
@@ -147,8 +145,7 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
147 145
148 if (snd_opl3_create(card, chip->port, chip->port + 2, 146 if (snd_opl3_create(card, chip->port, chip->port + 2,
149 OPL3_HW_OPL3, 0, &opl3) < 0) 147 OPL3_HW_OPL3, 0, &opl3) < 0)
150 printk(KERN_WARNING "%s: opl3 not detected at 0x%lx\n", 148 dev_warn(dev, "opl3 not detected at 0x%lx\n", chip->port);
151 dev->bus_id, chip->port);
152 else { 149 else {
153 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL); 150 error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
154 if (error < 0) 151 if (error < 0)
diff --git a/sound/isa/gus/gusclassic.c b/sound/isa/gus/gusclassic.c
index 8f914b37bf89..426532a4d730 100644
--- a/sound/isa/gus/gusclassic.c
+++ b/sound/isa/gus/gusclassic.c
@@ -90,24 +90,21 @@ static int __devinit snd_gusclassic_create(struct snd_card *card,
90 if (irq[n] == SNDRV_AUTO_IRQ) { 90 if (irq[n] == SNDRV_AUTO_IRQ) {
91 irq[n] = snd_legacy_find_free_irq(possible_irqs); 91 irq[n] = snd_legacy_find_free_irq(possible_irqs);
92 if (irq[n] < 0) { 92 if (irq[n] < 0) {
93 snd_printk(KERN_ERR "%s: unable to find a free IRQ\n", 93 dev_err(dev, "unable to find a free IRQ\n");
94 dev->bus_id);
95 return -EBUSY; 94 return -EBUSY;
96 } 95 }
97 } 96 }
98 if (dma1[n] == SNDRV_AUTO_DMA) { 97 if (dma1[n] == SNDRV_AUTO_DMA) {
99 dma1[n] = snd_legacy_find_free_dma(possible_dmas); 98 dma1[n] = snd_legacy_find_free_dma(possible_dmas);
100 if (dma1[n] < 0) { 99 if (dma1[n] < 0) {
101 snd_printk(KERN_ERR "%s: unable to find a free DMA1\n", 100 dev_err(dev, "unable to find a free DMA1\n");
102 dev->bus_id);
103 return -EBUSY; 101 return -EBUSY;
104 } 102 }
105 } 103 }
106 if (dma2[n] == SNDRV_AUTO_DMA) { 104 if (dma2[n] == SNDRV_AUTO_DMA) {
107 dma2[n] = snd_legacy_find_free_dma(possible_dmas); 105 dma2[n] = snd_legacy_find_free_dma(possible_dmas);
108 if (dma2[n] < 0) { 106 if (dma2[n] < 0) {
109 snd_printk(KERN_ERR "%s: unable to find a free DMA2\n", 107 dev_err(dev, "unable to find a free DMA2\n");
110 dev->bus_id);
111 return -EBUSY; 108 return -EBUSY;
112 } 109 }
113 } 110 }
@@ -174,8 +171,8 @@ static int __devinit snd_gusclassic_probe(struct device *dev, unsigned int n)
174 171
175 error = -ENODEV; 172 error = -ENODEV;
176 if (gus->max_flag || gus->ess_flag) { 173 if (gus->max_flag || gus->ess_flag) {
177 snd_printk(KERN_ERR "%s: GUS Classic or ACE soundcard was " 174 dev_err(dev, "GUS Classic or ACE soundcard was "
178 "not detected at 0x%lx\n", dev->bus_id, gus->gf1.port); 175 "not detected at 0x%lx\n", gus->gf1.port);
179 goto out; 176 goto out;
180 } 177 }
181 178
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c
index da13185eb0a0..7ad4c3b41a84 100644
--- a/sound/isa/gus/gusextreme.c
+++ b/sound/isa/gus/gusextreme.c
@@ -106,16 +106,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
106 if (irq[n] == SNDRV_AUTO_IRQ) { 106 if (irq[n] == SNDRV_AUTO_IRQ) {
107 irq[n] = snd_legacy_find_free_irq(possible_irqs); 107 irq[n] = snd_legacy_find_free_irq(possible_irqs);
108 if (irq[n] < 0) { 108 if (irq[n] < 0) {
109 snd_printk(KERN_ERR "%s: unable to find a free IRQ " 109 dev_err(dev, "unable to find a free IRQ for ES1688\n");
110 "for ES1688\n", dev->bus_id);
111 return -EBUSY; 110 return -EBUSY;
112 } 111 }
113 } 112 }
114 if (dma8[n] == SNDRV_AUTO_DMA) { 113 if (dma8[n] == SNDRV_AUTO_DMA) {
115 dma8[n] = snd_legacy_find_free_dma(possible_dmas); 114 dma8[n] = snd_legacy_find_free_dma(possible_dmas);
116 if (dma8[n] < 0) { 115 if (dma8[n] < 0) {
117 snd_printk(KERN_ERR "%s: unable to find a free DMA " 116 dev_err(dev, "unable to find a free DMA for ES1688\n");
118 "for ES1688\n", dev->bus_id);
119 return -EBUSY; 117 return -EBUSY;
120 } 118 }
121 } 119 }
@@ -143,16 +141,14 @@ static int __devinit snd_gusextreme_gus_card_create(struct snd_card *card,
143 if (gf1_irq[n] == SNDRV_AUTO_IRQ) { 141 if (gf1_irq[n] == SNDRV_AUTO_IRQ) {
144 gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs); 142 gf1_irq[n] = snd_legacy_find_free_irq(possible_irqs);
145 if (gf1_irq[n] < 0) { 143 if (gf1_irq[n] < 0) {
146 snd_printk(KERN_ERR "%s: unable to find a free IRQ " 144 dev_err(dev, "unable to find a free IRQ for GF1\n");
147 "for GF1\n", dev->bus_id);
148 return -EBUSY; 145 return -EBUSY;
149 } 146 }
150 } 147 }
151 if (dma1[n] == SNDRV_AUTO_DMA) { 148 if (dma1[n] == SNDRV_AUTO_DMA) {
152 dma1[n] = snd_legacy_find_free_dma(possible_dmas); 149 dma1[n] = snd_legacy_find_free_dma(possible_dmas);
153 if (dma1[n] < 0) { 150 if (dma1[n] < 0) {
154 snd_printk(KERN_ERR "%s: unable to find a free DMA " 151 dev_err(dev, "unable to find a free DMA for GF1\n");
155 "for GF1\n", dev->bus_id);
156 return -EBUSY; 152 return -EBUSY;
157 } 153 }
158 } 154 }
@@ -278,8 +274,8 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
278 274
279 error = -ENODEV; 275 error = -ENODEV;
280 if (!gus->ess_flag) { 276 if (!gus->ess_flag) {
281 snd_printk(KERN_ERR "%s: GUS Extreme soundcard was not " 277 dev_err(dev, "GUS Extreme soundcard was not "
282 "detected at 0x%lx\n", dev->bus_id, gus->gf1.port); 278 "detected at 0x%lx\n", gus->gf1.port);
283 goto out; 279 goto out;
284 } 280 }
285 gus->codec_flag = 1; 281 gus->codec_flag = 1;
@@ -310,8 +306,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
310 306
311 if (snd_opl3_create(card, es1688->port, es1688->port + 2, 307 if (snd_opl3_create(card, es1688->port, es1688->port + 2,
312 OPL3_HW_OPL3, 0, &opl3) < 0) 308 OPL3_HW_OPL3, 0, &opl3) < 0)
313 printk(KERN_ERR "%s: opl3 not detected at 0x%lx\n", 309 dev_warn(dev, "opl3 not detected at 0x%lx\n", es1688->port);
314 dev->bus_id, es1688->port);
315 else { 310 else {
316 error = snd_opl3_hwdep_new(opl3, 0, 2, NULL); 311 error = snd_opl3_hwdep_new(opl3, 0, 2, NULL);
317 if (error < 0) 312 if (error < 0)
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 336a34277907..ea06877be4b1 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -85,11 +85,11 @@ static int __devinit snd_sb8_match(struct device *pdev, unsigned int dev)
85 if (!enable[dev]) 85 if (!enable[dev])
86 return 0; 86 return 0;
87 if (irq[dev] == SNDRV_AUTO_IRQ) { 87 if (irq[dev] == SNDRV_AUTO_IRQ) {
88 snd_printk(KERN_ERR "%s: please specify irq\n", pdev->bus_id); 88 dev_err(pdev, "please specify irq\n");
89 return 0; 89 return 0;
90 } 90 }
91 if (dma8[dev] == SNDRV_AUTO_DMA) { 91 if (dma8[dev] == SNDRV_AUTO_DMA) {
92 snd_printk(KERN_ERR "%s: please specify dma8\n", pdev->bus_id); 92 dev_err(pdev, "please specify dma8\n");
93 return 0; 93 return 0;
94 } 94 }
95 return 1; 95 return 1;
@@ -140,8 +140,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
140 break; 140 break;
141 } 141 }
142 } 142 }
143 if (i >= ARRAY_SIZE(possible_ports)) 143 if (i >= ARRAY_SIZE(possible_ports)) {
144 err = -EINVAL;
144 goto _err; 145 goto _err;
146 }
145 } 147 }
146 acard->chip = chip; 148 acard->chip = chip;
147 149
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c
index b63839e8f9bd..456a1b4d7832 100644
--- a/sound/oss/ac97_codec.c
+++ b/sound/oss/ac97_codec.c
@@ -30,7 +30,7 @@
30 ************************************************************************** 30 **************************************************************************
31 * 31 *
32 * History 32 * History
33 * May 02, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 33 * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
34 * Removed non existant WM9700 34 * Removed non existant WM9700
35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711 35 * Added support for WM9705, WM9708, WM9709, WM9710, WM9711
36 * WM9712 and WM9717 36 * WM9712 and WM9717
diff --git a/sound/oss/aedsp16.c b/sound/oss/aedsp16.c
index a0274f3dac08..3ee9900ffd7b 100644
--- a/sound/oss/aedsp16.c
+++ b/sound/oss/aedsp16.c
@@ -157,7 +157,7 @@
157 157
158 Started Fri Mar 17 16:13:18 MET 1995 158 Started Fri Mar 17 16:13:18 MET 1995
159 159
160 v0.1 (ALPHA, was an user-level program called AudioExcelDSP16.c) 160 v0.1 (ALPHA, was a user-level program called AudioExcelDSP16.c)
161 - Initial code. 161 - Initial code.
162 v0.2 (ALPHA) 162 v0.2 (ALPHA)
163 - Cleanups. 163 - Cleanups.
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c
index 23018a7c063a..81e1f443d094 100644
--- a/sound/oss/au1550_ac97.c
+++ b/sound/oss/au1550_ac97.c
@@ -93,7 +93,7 @@ static struct au1550_state {
93 spinlock_t lock; 93 spinlock_t lock;
94 struct mutex open_mutex; 94 struct mutex open_mutex;
95 struct mutex sem; 95 struct mutex sem;
96 mode_t open_mode; 96 fmode_t open_mode;
97 wait_queue_head_t open_wait; 97 wait_queue_head_t open_wait;
98 98
99 struct dmabuf { 99 struct dmabuf {
diff --git a/sound/oss/dmasound/dmasound.h b/sound/oss/dmasound/dmasound.h
index d978b0096564..1308d8d34186 100644
--- a/sound/oss/dmasound/dmasound.h
+++ b/sound/oss/dmasound/dmasound.h
@@ -129,7 +129,7 @@ typedef struct {
129 int (*mixer_ioctl)(u_int, u_long); /* optional */ 129 int (*mixer_ioctl)(u_int, u_long); /* optional */
130 int (*write_sq_setup)(void); /* optional */ 130 int (*write_sq_setup)(void); /* optional */
131 int (*read_sq_setup)(void); /* optional */ 131 int (*read_sq_setup)(void); /* optional */
132 int (*sq_open)(mode_t); /* optional */ 132 int (*sq_open)(fmode_t); /* optional */
133 int (*state_info)(char *, size_t); /* optional */ 133 int (*state_info)(char *, size_t); /* optional */
134 void (*abort_read)(void); /* optional */ 134 void (*abort_read)(void); /* optional */
135 int min_dsp_speed; 135 int min_dsp_speed;
@@ -235,7 +235,7 @@ struct sound_queue {
235 */ 235 */
236 int active; 236 int active;
237 wait_queue_head_t action_queue, open_queue, sync_queue; 237 wait_queue_head_t action_queue, open_queue, sync_queue;
238 int open_mode; 238 int non_blocking;
239 int busy, syncing, xruns, died; 239 int busy, syncing, xruns, died;
240}; 240};
241 241
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 285239d64b82..57d9f154c88b 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -143,7 +143,7 @@ static int AtaMixerIoctl(u_int cmd, u_long arg);
143static int TTMixerIoctl(u_int cmd, u_long arg); 143static int TTMixerIoctl(u_int cmd, u_long arg);
144static int FalconMixerIoctl(u_int cmd, u_long arg); 144static int FalconMixerIoctl(u_int cmd, u_long arg);
145static int AtaWriteSqSetup(void); 145static int AtaWriteSqSetup(void);
146static int AtaSqOpen(mode_t mode); 146static int AtaSqOpen(fmode_t mode);
147static int TTStateInfo(char *buffer, size_t space); 147static int TTStateInfo(char *buffer, size_t space);
148static int FalconStateInfo(char *buffer, size_t space); 148static int FalconStateInfo(char *buffer, size_t space);
149 149
@@ -851,8 +851,9 @@ static int __init AtaIrqInit(void)
851 mfp.tim_dt_a = 1; /* Cause interrupt after first event. */ 851 mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
852 mfp.tim_ct_a = 8; /* Turn on event counting. */ 852 mfp.tim_ct_a = 8; /* Turn on event counting. */
853 /* Register interrupt handler. */ 853 /* Register interrupt handler. */
854 request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound", 854 if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
855 AtaInterrupt); 855 AtaInterrupt))
856 return 0;
856 mfp.int_en_a |= 0x20; /* Turn interrupt on. */ 857 mfp.int_en_a |= 0x20; /* Turn interrupt on. */
857 mfp.int_mk_a |= 0x20; 858 mfp.int_mk_a |= 0x20;
858 return 1; 859 return 1;
@@ -1461,7 +1462,7 @@ static int AtaWriteSqSetup(void)
1461 return 0 ; 1462 return 0 ;
1462} 1463}
1463 1464
1464static int AtaSqOpen(mode_t mode) 1465static int AtaSqOpen(fmode_t mode)
1465{ 1466{
1466 write_sq_ignore_int = 1; 1467 write_sq_ignore_int = 1;
1467 return 0 ; 1468 return 0 ;
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 95fc5c681755..793b7f478433 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -212,7 +212,7 @@ static int irq_installed;
212#endif /* MODULE */ 212#endif /* MODULE */
213 213
214/* control over who can modify resources shared between play/record */ 214/* control over who can modify resources shared between play/record */
215static mode_t shared_resource_owner; 215static fmode_t shared_resource_owner;
216static int shared_resources_initialised; 216static int shared_resources_initialised;
217 217
218 /* 218 /*
@@ -603,7 +603,7 @@ static ssize_t sq_write(struct file *file, const char __user *src, size_t uLeft,
603 while (uLeft) { 603 while (uLeft) {
604 while (write_sq.count >= write_sq.max_active) { 604 while (write_sq.count >= write_sq.max_active) {
605 sq_play(); 605 sq_play();
606 if (write_sq.open_mode & O_NONBLOCK) 606 if (write_sq.non_blocking)
607 return uWritten > 0 ? uWritten : -EAGAIN; 607 return uWritten > 0 ? uWritten : -EAGAIN;
608 SLEEP(write_sq.action_queue); 608 SLEEP(write_sq.action_queue);
609 if (signal_pending(current)) 609 if (signal_pending(current))
@@ -668,7 +668,7 @@ static inline void sq_init_waitqueue(struct sound_queue *sq)
668 668
669#if 0 /* blocking open() */ 669#if 0 /* blocking open() */
670static inline void sq_wake_up(struct sound_queue *sq, struct file *file, 670static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
671 mode_t mode) 671 fmode_t mode)
672{ 672{
673 if (file->f_mode & mode) { 673 if (file->f_mode & mode) {
674 sq->busy = 0; /* CHECK: IS THIS OK??? */ 674 sq->busy = 0; /* CHECK: IS THIS OK??? */
@@ -677,7 +677,7 @@ static inline void sq_wake_up(struct sound_queue *sq, struct file *file,
677} 677}
678#endif 678#endif
679 679
680static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode, 680static int sq_open2(struct sound_queue *sq, struct file *file, fmode_t mode,
681 int numbufs, int bufsize) 681 int numbufs, int bufsize)
682{ 682{
683 int rc = 0; 683 int rc = 0;
@@ -718,7 +718,7 @@ static int sq_open2(struct sound_queue *sq, struct file *file, mode_t mode,
718 return rc; 718 return rc;
719 } 719 }
720 720
721 sq->open_mode = file->f_mode; 721 sq->non_blocking = file->f_flags & O_NONBLOCK;
722 } 722 }
723 return rc; 723 return rc;
724} 724}
@@ -891,10 +891,10 @@ static int sq_release(struct inode *inode, struct file *file)
891 is the owner - if we have problems. 891 is the owner - if we have problems.
892*/ 892*/
893 893
894static int shared_resources_are_mine(mode_t md) 894static int shared_resources_are_mine(fmode_t md)
895{ 895{
896 if (shared_resource_owner) 896 if (shared_resource_owner)
897 return (shared_resource_owner & md ) ; 897 return (shared_resource_owner & md) != 0;
898 else { 898 else {
899 shared_resource_owner = md ; 899 shared_resource_owner = md ;
900 return 1 ; 900 return 1 ;
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 1855b14d90c3..99bcb21c2281 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -371,8 +371,9 @@ static void Q40Free(void *ptr, unsigned int size)
371static int __init Q40IrqInit(void) 371static int __init Q40IrqInit(void)
372{ 372{
373 /* Register interrupt handler. */ 373 /* Register interrupt handler. */
374 request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, 374 if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
375 "DMA sound", Q40Interrupt); 375 "DMA sound", Q40Interrupt))
376 return 0;
376 377
377 return(1); 378 return(1);
378} 379}
@@ -401,6 +402,7 @@ static void Q40PlayNextFrame(int index)
401 u_char *start; 402 u_char *start;
402 u_long size; 403 u_long size;
403 u_char speed; 404 u_char speed;
405 int error;
404 406
405 /* used by Q40Play() if all doubts whether there really is something 407 /* used by Q40Play() if all doubts whether there really is something
406 * to be played are already wiped out. 408 * to be played are already wiped out.
@@ -419,11 +421,13 @@ static void Q40PlayNextFrame(int index)
419 master_outb( 0,SAMPLE_ENABLE_REG); 421 master_outb( 0,SAMPLE_ENABLE_REG);
420 free_irq(Q40_IRQ_SAMPLE, Q40Interrupt); 422 free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
421 if (dmasound.soft.stereo) 423 if (dmasound.soft.stereo)
422 request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0, 424 error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
423 "Q40 sound", Q40Interrupt); 425 "Q40 sound", Q40Interrupt);
424 else 426 else
425 request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0, 427 error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
426 "Q40 sound", Q40Interrupt); 428 "Q40 sound", Q40Interrupt);
429 if (error && printk_ratelimit())
430 pr_err("Couldn't register sound interrupt\n");
427 431
428 master_outb( speed, SAMPLE_RATE_REG); 432 master_outb( speed, SAMPLE_RATE_REG);
429 master_outb( 1,SAMPLE_CLEAR_REG); 433 master_outb( 1,SAMPLE_CLEAR_REG);
diff --git a/sound/oss/kahlua.c b/sound/oss/kahlua.c
index eb9bc365530d..c180598f1710 100644
--- a/sound/oss/kahlua.c
+++ b/sound/oss/kahlua.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Initialisation code for Cyrix/NatSemi VSA1 softaudio 2 * Initialisation code for Cyrix/NatSemi VSA1 softaudio
3 * 3 *
4 * (C) Copyright 2003 Red Hat Inc <alan@redhat.com> 4 * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk>
5 * 5 *
6 * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems. 6 * XpressAudio(tm) is used on the Cyrix MediaGX (now NatSemi Geode) systems.
7 * The older version (VSA1) provides fairly good soundblaster emulation 7 * The older version (VSA1) provides fairly good soundblaster emulation
diff --git a/sound/oss/msnd.h b/sound/oss/msnd.h
index 61b3955481c5..c8be47ec2b7e 100644
--- a/sound/oss/msnd.h
+++ b/sound/oss/msnd.h
@@ -211,7 +211,7 @@ typedef struct multisound_dev {
211 211
212 /* State variables */ 212 /* State variables */
213 enum { msndClassic, msndPinnacle } type; 213 enum { msndClassic, msndPinnacle } type;
214 mode_t mode; 214 fmode_t mode;
215 unsigned long flags; 215 unsigned long flags;
216#define F_RESETTING 0 216#define F_RESETTING 0
217#define F_HAVEDIGITAL 1 217#define F_HAVEDIGITAL 1
diff --git a/sound/oss/sh_dac_audio.c b/sound/oss/sh_dac_audio.c
index b493660deb36..e5d423994918 100644
--- a/sound/oss/sh_dac_audio.c
+++ b/sound/oss/sh_dac_audio.c
@@ -26,7 +26,7 @@
26#include <asm/cpu/dac.h> 26#include <asm/cpu/dac.h>
27#include <asm/cpu/timer.h> 27#include <asm/cpu/timer.h>
28#include <asm/machvec.h> 28#include <asm/machvec.h>
29#include <asm/hp6xx.h> 29#include <mach/hp6xx.h>
30#include <asm/hd64461.h> 30#include <asm/hd64461.h>
31 31
32#define MODNAME "sh_dac_audio" 32#define MODNAME "sh_dac_audio"
diff --git a/sound/oss/sound_config.h b/sound/oss/sound_config.h
index 1a00a3210616..55271fbe7f49 100644
--- a/sound/oss/sound_config.h
+++ b/sound/oss/sound_config.h
@@ -110,24 +110,16 @@ struct channel_info {
110#define OPEN_WRITE PCM_ENABLE_OUTPUT 110#define OPEN_WRITE PCM_ENABLE_OUTPUT
111#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE) 111#define OPEN_READWRITE (OPEN_READ|OPEN_WRITE)
112 112
113#if OPEN_READ == FMODE_READ && OPEN_WRITE == FMODE_WRITE
114
115static inline int translate_mode(struct file *file)
116{
117 return file->f_mode;
118}
119
120#else
121
122static inline int translate_mode(struct file *file) 113static inline int translate_mode(struct file *file)
123{ 114{
124 return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) | 115 if (OPEN_READ == (__force int)FMODE_READ &&
125 ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0); 116 OPEN_WRITE == (__force int)FMODE_WRITE)
117 return (__force int)(file->f_mode & (FMODE_READ | FMODE_WRITE));
118 else
119 return ((file->f_mode & FMODE_READ) ? OPEN_READ : 0) |
120 ((file->f_mode & FMODE_WRITE) ? OPEN_WRITE : 0);
126} 121}
127 122
128#endif
129
130
131#include "sound_calls.h" 123#include "sound_calls.h"
132#include "dev_table.h" 124#include "dev_table.h"
133 125
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 7d89c081a086..61aaedae6b7e 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -560,19 +560,18 @@ static int __init oss_init(void)
560 sound_dmap_flag = (dmabuf > 0 ? 1 : 0); 560 sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
561 561
562 for (i = 0; i < ARRAY_SIZE(dev_list); i++) { 562 for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
563 device_create_drvdata(sound_class, NULL, 563 device_create(sound_class, NULL,
564 MKDEV(SOUND_MAJOR, dev_list[i].minor), 564 MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL,
565 NULL, "%s", dev_list[i].name); 565 "%s", dev_list[i].name);
566 566
567 if (!dev_list[i].num) 567 if (!dev_list[i].num)
568 continue; 568 continue;
569 569
570 for (j = 1; j < *dev_list[i].num; j++) 570 for (j = 1; j < *dev_list[i].num; j++)
571 device_create_drvdata(sound_class, NULL, 571 device_create(sound_class, NULL,
572 MKDEV(SOUND_MAJOR, 572 MKDEV(SOUND_MAJOR,
573 dev_list[i].minor + (j*0x10)), 573 dev_list[i].minor + (j*0x10)),
574 NULL, 574 NULL, "%s%d", dev_list[i].name, j);
575 "%s%d", dev_list[i].name, j);
576 } 575 }
577 576
578 if (sound_nblocks >= 1024) 577 if (sound_nblocks >= 1024)
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 044453a4ee5b..41562ecde5bb 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -295,7 +295,7 @@ struct cs4297a_state {
295 struct mutex open_mutex; 295 struct mutex open_mutex;
296 struct mutex open_sem_adc; 296 struct mutex open_sem_adc;
297 struct mutex open_sem_dac; 297 struct mutex open_sem_dac;
298 mode_t open_mode; 298 fmode_t open_mode;
299 wait_queue_head_t open_wait; 299 wait_queue_head_t open_wait;
300 wait_queue_head_t open_wait_adc; 300 wait_queue_head_t open_wait_adc;
301 wait_queue_head_t open_wait_dac; 301 wait_queue_head_t open_wait_dac;
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index dcbb3f739e61..78b8acc7c3b9 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -1509,7 +1509,7 @@ typedef struct vwsnd_dev {
1509 struct mutex open_mutex; 1509 struct mutex open_mutex;
1510 struct mutex io_mutex; 1510 struct mutex io_mutex;
1511 struct mutex mix_mutex; 1511 struct mutex mix_mutex;
1512 mode_t open_mode; 1512 fmode_t open_mode;
1513 wait_queue_head_t open_wait; 1513 wait_queue_head_t open_wait;
1514 1514
1515 lithium_t lith; 1515 lithium_t lith;
diff --git a/sound/oss/waveartist.c b/sound/oss/waveartist.c
index c47842fad657..2c63bb9da74a 100644
--- a/sound/oss/waveartist.c
+++ b/sound/oss/waveartist.c
@@ -1483,16 +1483,14 @@ static void __exit unload_waveartist(struct address_info *hw)
1483#define VNC_HANDSET_DETECT 0x40 1483#define VNC_HANDSET_DETECT 0x40
1484#define VNC_DISABLE_AUTOSWITCH 0x80 1484#define VNC_DISABLE_AUTOSWITCH 0x80
1485 1485
1486extern spinlock_t gpio_lock;
1487
1488static inline void 1486static inline void
1489vnc_mute_spkr(wavnc_info *devc) 1487vnc_mute_spkr(wavnc_info *devc)
1490{ 1488{
1491 unsigned long flags; 1489 unsigned long flags;
1492 1490
1493 spin_lock_irqsave(&gpio_lock, flags); 1491 spin_lock_irqsave(&nw_gpio_lock, flags);
1494 cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE); 1492 nw_cpld_modify(CPLD_UNMUTE, devc->spkr_mute_state ? 0 : CPLD_UNMUTE);
1495 spin_unlock_irqrestore(&gpio_lock, flags); 1493 spin_unlock_irqrestore(&nw_gpio_lock, flags);
1496} 1494}
1497 1495
1498static void 1496static void
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index caebf296b62b..6e3a1848447c 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -208,7 +208,8 @@ config SND_OXYGEN
208 * AuzenTech X-Meridian 208 * AuzenTech X-Meridian
209 * Bgears b-Enspirer 209 * Bgears b-Enspirer
210 * Club3D Theatron DTS 210 * Club3D Theatron DTS
211 * HT-Omega Claro 211 * HT-Omega Claro (plus)
212 * HT-Omega Claro halo (XT)
212 * Razer Barracuda AC-1 213 * Razer Barracuda AC-1
213 * Sondigo Inferno 214 * Sondigo Inferno
214 215
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 6704acbca8c0..e2b843b4f9d0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -175,7 +175,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, 175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, 176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL}, 177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL}, 178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712,WM9715", patch_wolfson11, NULL},
179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF}, 179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL }, 180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL },
181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL }, 181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
@@ -1927,9 +1927,9 @@ static int snd_ac97_dev_register(struct snd_device *device)
1927 ac97->dev.bus = &ac97_bus_type; 1927 ac97->dev.bus = &ac97_bus_type;
1928 ac97->dev.parent = ac97->bus->card->dev; 1928 ac97->dev.parent = ac97->bus->card->dev;
1929 ac97->dev.release = ac97_device_release; 1929 ac97->dev.release = ac97_device_release;
1930 snprintf(ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s", 1930 dev_set_name(&ac97->dev, "%d-%d:%s",
1931 ac97->bus->card->number, ac97->num, 1931 ac97->bus->card->number, ac97->num,
1932 snd_ac97_get_short_name(ac97)); 1932 snd_ac97_get_short_name(ac97));
1933 if ((err = device_register(&ac97->dev)) < 0) { 1933 if ((err = device_register(&ac97->dev)) < 0) {
1934 snd_printk(KERN_ERR "Can't register ac97 bus\n"); 1934 snd_printk(KERN_ERR "Can't register ac97 bus\n");
1935 ac97->dev.bus = NULL; 1935 ac97->dev.bus = NULL;
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 6ce3cbe98a6a..81bc93e5f1e3 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -476,7 +476,7 @@ static int patch_yamaha_ymf753(struct snd_ac97 * ac97)
476} 476}
477 477
478/* 478/*
479 * May 2, 2003 Liam Girdwood <liam.girdwood@wolfsonmicro.com> 479 * May 2, 2003 Liam Girdwood <lrg@slimlogic.co.uk>
480 * removed broken wolfson00 patch. 480 * removed broken wolfson00 patch.
481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717. 481 * added support for WM9705,WM9708,WM9709,WM9710,WM9711,WM9712 and WM9717.
482 */ 482 */
@@ -2054,8 +2054,9 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
2054 .get = snd_ac97_ad1888_lohpsel_get, 2054 .get = snd_ac97_ad1888_lohpsel_get,
2055 .put = snd_ac97_ad1888_lohpsel_put 2055 .put = snd_ac97_ad1888_lohpsel_put
2056 }, 2056 },
2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), 2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), 2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
2059 AC97_AD_HPFD_SHIFT, 1, 1),
2059 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 2060 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
2060 { 2061 {
2061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2832,6 +2833,8 @@ static int patch_alc655(struct snd_ac97 * ac97)
2832 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2833 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2833 else 2834 else
2834 val |= (1 << 1); /* Pin 47 is spdif input pin */ 2835 val |= (1 << 1); /* Pin 47 is spdif input pin */
2836 /* this seems missing on some hardwares */
2837 ac97->ext_id |= AC97_EI_SPDIF;
2835 } 2838 }
2836 val &= ~(1 << 12); /* vref enable */ 2839 val &= ~(1 << 12); /* vref enable */
2837 snd_ac97_write_cache(ac97, 0x7a, val); 2840 snd_ac97_write_cache(ac97, 0x7a, val);
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index 92f3a976ef2e..a7f38e63303f 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -932,7 +932,7 @@ snd_ad1889_create(struct snd_card *card,
932 goto free_and_ret; 932 goto free_and_ret;
933 933
934 chip->bar = pci_resource_start(pci, 0); 934 chip->bar = pci_resource_start(pci, 0);
935 chip->iobase = ioremap_nocache(chip->bar, pci_resource_len(pci, 0)); 935 chip->iobase = pci_ioremap_bar(pci, 0);
936 if (chip->iobase == NULL) { 936 if (chip->iobase == NULL) {
937 printk(KERN_ERR PFX "unable to reserve region.\n"); 937 printk(KERN_ERR PFX "unable to reserve region.\n");
938 err = -EBUSY; 938 err = -EBUSY;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 085a52b8c807..226fe8237d31 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1609,7 +1609,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
1609 return err; 1609 return err;
1610 } 1610 }
1611 chip->addr = pci_resource_start(pci, 0); 1611 chip->addr = pci_resource_start(pci, 0);
1612 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); 1612 chip->remap_addr = pci_ioremap_bar(pci, 0);
1613 if (chip->remap_addr == NULL) { 1613 if (chip->remap_addr == NULL) {
1614 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 1614 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1615 snd_atiixp_free(chip); 1615 snd_atiixp_free(chip);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 2f106306c7fe..0e6e5cc1c501 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1252,7 +1252,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
1252 return err; 1252 return err;
1253 } 1253 }
1254 chip->addr = pci_resource_start(pci, 0); 1254 chip->addr = pci_resource_start(pci, 0);
1255 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci, 0)); 1255 chip->remap_addr = pci_ioremap_bar(pci, 0);
1256 if (chip->remap_addr == NULL) { 1256 if (chip->remap_addr == NULL) {
1257 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 1257 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1258 snd_atiixp_free(chip); 1258 snd_atiixp_free(chip);
diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
index 68368e490074..a36d4d1fd419 100644
--- a/sound/pci/au88x0/au88x0.c
+++ b/sound/pci/au88x0/au88x0.c
@@ -180,8 +180,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
180 if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0) 180 if ((err = pci_request_regions(pci, CARD_NAME_SHORT)) != 0)
181 goto regions_out; 181 goto regions_out;
182 182
183 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), 183 chip->mmio = pci_ioremap_bar(pci, 0);
184 pci_resource_len(pci, 0));
185 if (!chip->mmio) { 184 if (!chip->mmio) {
186 printk(KERN_ERR "MMIO area remap failed.\n"); 185 printk(KERN_ERR "MMIO area remap failed.\n");
187 err = -ENOMEM; 186 err = -ENOMEM;
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 3aa8d973540a..1aa1c0402540 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -749,8 +749,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
749 pci_disable_device(pci); 749 pci_disable_device(pci);
750 return err; 750 return err;
751 } 751 }
752 chip->mmio = ioremap_nocache(pci_resource_start(pci, 0), 752 chip->mmio = pci_ioremap_bar(pci, 0);
753 pci_resource_len(pci, 0));
754 if (!chip->mmio) { 753 if (!chip->mmio) {
755 snd_printk(KERN_ERR "cannot remap io memory\n"); 754 snd_printk(KERN_ERR "cannot remap io memory\n");
756 err = -ENOMEM; 755 err = -ENOMEM;
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 74175fc80c7f..14b8d9a91aae 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -664,10 +664,14 @@ struct snd_ca0106_pcm {
664struct snd_ca0106_details { 664struct snd_ca0106_details {
665 u32 serial; 665 u32 serial;
666 char * name; 666 char * name;
667 int ac97; 667 int ac97; /* ac97 = 0 -> Select MIC, Line in, TAD in, AUX in.
668 int gpio_type; 668 ac97 = 1 -> Default to AC97 in. */
669 int i2c_adc; 669 int gpio_type; /* gpio_type = 1 -> shared mic-in/line-in
670 int spi_dac; 670 gpio_type = 2 -> shared side-out/line-in. */
671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
672 controls, phone, mic, line-in and aux. */
673 int spi_dac; /* spi_dac=1 adds the mute switch for each analog
674 output, front, rear, etc. */
671}; 675};
672 676
673// definition of the chip-specific record 677// definition of the chip-specific record
@@ -686,11 +690,12 @@ struct snd_ca0106 {
686 spinlock_t emu_lock; 690 spinlock_t emu_lock;
687 691
688 struct snd_ac97 *ac97; 692 struct snd_ac97 *ac97;
689 struct snd_pcm *pcm; 693 struct snd_pcm *pcm[4];
690 694
691 struct snd_ca0106_channel playback_channels[4]; 695 struct snd_ca0106_channel playback_channels[4];
692 struct snd_ca0106_channel capture_channels[4]; 696 struct snd_ca0106_channel capture_channels[4];
693 u32 spdif_bits[4]; /* s/pdif out setup */ 697 u32 spdif_bits[4]; /* s/pdif out default setup */
698 u32 spdif_str_bits[4]; /* s/pdif out per-stream setup */
694 int spdif_enable; 699 int spdif_enable;
695 int capture_source; 700 int capture_source;
696 int i2c_capture_source; 701 int i2c_capture_source;
@@ -703,6 +708,11 @@ struct snd_ca0106 {
703 struct snd_ca_midi midi2; 708 struct snd_ca_midi midi2;
704 709
705 u16 spi_dac_reg[16]; 710 u16 spi_dac_reg[16];
711
712#ifdef CONFIG_PM
713#define NUM_SAVED_VOLUMES 9
714 unsigned int saved_vol[NUM_SAVED_VOLUMES];
715#endif
706}; 716};
707 717
708int snd_ca0106_mixer(struct snd_ca0106 *emu); 718int snd_ca0106_mixer(struct snd_ca0106 *emu);
@@ -721,3 +731,11 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
721 731
722int snd_ca0106_spi_write(struct snd_ca0106 * emu, 732int snd_ca0106_spi_write(struct snd_ca0106 * emu,
723 unsigned int data); 733 unsigned int data);
734
735#ifdef CONFIG_PM
736void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
737void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
738#else
739#define snd_ca0106_mixer_suspend(chip) do { } while (0)
740#define snd_ca0106_mixer_resume(chip) do { } while (0)
741#endif
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index a7d89662acf6..0e62205d4081 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 254 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 255 .gpio_type = 2,
256 .i2c_adc = 1, 256 .i2c_adc = 1,
257 .spi_dac = 2 } , 257 .spi_dac = 1 } ,
258 /* Shuttle XPC SD31P which has an onboard Creative Labs 258 /* Shuttle XPC SD31P which has an onboard Creative Labs
259 * Sound Blaster Live! 24-bit EAX 259 * Sound Blaster Live! 24-bit EAX
260 * high-definition 7.1 audio processor". 260 * high-definition 7.1 audio processor".
@@ -305,9 +305,15 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = {
305 SNDRV_PCM_INFO_BLOCK_TRANSFER | 305 SNDRV_PCM_INFO_BLOCK_TRANSFER |
306 SNDRV_PCM_INFO_MMAP_VALID), 306 SNDRV_PCM_INFO_MMAP_VALID),
307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, 307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
308#if 0 /* FIXME: looks like 44.1kHz capture causes noisy output on 48kHz */
308 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 309 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
309 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000), 310 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
310 .rate_min = 44100, 311 .rate_min = 44100,
312#else
313 .rates = (SNDRV_PCM_RATE_48000 |
314 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
315 .rate_min = 48000,
316#endif /* FIXME */
311 .rate_max = 192000, 317 .rate_max = 192000,
312 .channels_min = 2, 318 .channels_min = 2,
313 .channels_max = 2, 319 .channels_max = 2,
@@ -479,6 +485,15 @@ static const int spi_dacd_bit[] = {
479 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 485 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT,
480}; 486};
481 487
488static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
489{
490 if (chip->spdif_str_bits[idx] != chip->spdif_bits[idx]) {
491 chip->spdif_str_bits[idx] = chip->spdif_bits[idx];
492 snd_ca0106_ptr_write(chip, SPCS0 + idx, 0,
493 chip->spdif_str_bits[idx]);
494 }
495}
496
482/* open_playback callback */ 497/* open_playback callback */
483static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 498static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
484 int channel_id) 499 int channel_id)
@@ -524,6 +539,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
524 if (err < 0) 539 if (err < 0)
525 return err; 540 return err;
526 } 541 }
542
543 restore_spdif_bits(chip, channel_id);
544
527 return 0; 545 return 0;
528} 546}
529 547
@@ -535,6 +553,8 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
535 struct snd_ca0106_pcm *epcm = runtime->private_data; 553 struct snd_ca0106_pcm *epcm = runtime->private_data;
536 chip->playback_channels[epcm->channel_id].use = 0; 554 chip->playback_channels[epcm->channel_id].use = 0;
537 555
556 restore_spdif_bits(chip, epcm->channel_id);
557
538 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 558 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
539 const int reg = spi_dacd_reg[epcm->channel_id]; 559 const int reg = spi_dacd_reg[epcm->channel_id];
540 560
@@ -759,7 +779,6 @@ static int snd_ca0106_pcm_prepare_playback(struct snd_pcm_substream *substream)
759 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 779 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
760 SPCS_GENERATIONSTATUS | 0x00001200 | 780 SPCS_GENERATIONSTATUS | 0x00001200 |
761 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT ); 781 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT );
762 }
763#endif 782#endif
764 783
765 return 0; 784 return 0;
@@ -848,15 +867,18 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
848 struct snd_pcm_substream *s; 867 struct snd_pcm_substream *s;
849 u32 basic = 0; 868 u32 basic = 0;
850 u32 extended = 0; 869 u32 extended = 0;
851 int running=0; 870 u32 bits;
871 int running = 0;
852 872
853 switch (cmd) { 873 switch (cmd) {
854 case SNDRV_PCM_TRIGGER_START: 874 case SNDRV_PCM_TRIGGER_START:
855 running=1; 875 case SNDRV_PCM_TRIGGER_RESUME:
876 running = 1;
856 break; 877 break;
857 case SNDRV_PCM_TRIGGER_STOP: 878 case SNDRV_PCM_TRIGGER_STOP:
879 case SNDRV_PCM_TRIGGER_SUSPEND:
858 default: 880 default:
859 running=0; 881 running = 0;
860 break; 882 break;
861 } 883 }
862 snd_pcm_group_for_each_entry(s, substream) { 884 snd_pcm_group_for_each_entry(s, substream) {
@@ -866,22 +888,32 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
866 runtime = s->runtime; 888 runtime = s->runtime;
867 epcm = runtime->private_data; 889 epcm = runtime->private_data;
868 channel = epcm->channel_id; 890 channel = epcm->channel_id;
869 //snd_printk("channel=%d\n",channel); 891 /* snd_printk("channel=%d\n",channel); */
870 epcm->running = running; 892 epcm->running = running;
871 basic |= (0x1<<channel); 893 basic |= (0x1 << channel);
872 extended |= (0x10<<channel); 894 extended |= (0x10 << channel);
873 snd_pcm_trigger_done(s, substream); 895 snd_pcm_trigger_done(s, substream);
874 } 896 }
875 //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); 897 /* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */
876 898
877 switch (cmd) { 899 switch (cmd) {
878 case SNDRV_PCM_TRIGGER_START: 900 case SNDRV_PCM_TRIGGER_START:
879 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended)); 901 case SNDRV_PCM_TRIGGER_RESUME:
880 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic)); 902 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
903 bits |= extended;
904 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
905 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
906 bits |= basic;
907 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
881 break; 908 break;
882 case SNDRV_PCM_TRIGGER_STOP: 909 case SNDRV_PCM_TRIGGER_STOP:
883 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic)); 910 case SNDRV_PCM_TRIGGER_SUSPEND:
884 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended)); 911 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
912 bits &= ~basic;
913 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
914 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
915 bits &= ~extended;
916 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
885 break; 917 break;
886 default: 918 default:
887 result = -EINVAL; 919 result = -EINVAL;
@@ -1104,21 +1136,13 @@ static int snd_ca0106_ac97(struct snd_ca0106 *chip)
1104 return snd_ac97_mixer(pbus, &ac97, &chip->ac97); 1136 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
1105} 1137}
1106 1138
1139static void ca0106_stop_chip(struct snd_ca0106 *chip);
1140
1107static int snd_ca0106_free(struct snd_ca0106 *chip) 1141static int snd_ca0106_free(struct snd_ca0106 *chip)
1108{ 1142{
1109 if (chip->res_port != NULL) { /* avoid access to already used hardware */ 1143 if (chip->res_port != NULL) {
1110 // disable interrupts 1144 /* avoid access to already used hardware */
1111 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0); 1145 ca0106_stop_chip(chip);
1112 outl(0, chip->port + INTE);
1113 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1114 udelay(1000);
1115 // disable audio
1116 //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
1117 outl(0, chip->port + HCFG);
1118 /* FIXME: We need to stop and DMA transfers here.
1119 * But as I am not sure how yet, we cannot from the dma pages.
1120 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1121 */
1122 } 1146 }
1123 if (chip->irq >= 0) 1147 if (chip->irq >= 0)
1124 free_irq(chip->irq, chip); 1148 free_irq(chip->irq, chip);
@@ -1204,15 +1228,14 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
1204 return IRQ_HANDLED; 1228 return IRQ_HANDLED;
1205} 1229}
1206 1230
1207static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct snd_pcm **rpcm) 1231static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
1208{ 1232{
1209 struct snd_pcm *pcm; 1233 struct snd_pcm *pcm;
1210 struct snd_pcm_substream *substream; 1234 struct snd_pcm_substream *substream;
1211 int err; 1235 int err;
1212 1236
1213 if (rpcm) 1237 err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
1214 *rpcm = NULL; 1238 if (err < 0)
1215 if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
1216 return err; 1239 return err;
1217 1240
1218 pcm->private_data = emu; 1241 pcm->private_data = emu;
@@ -1239,7 +1262,6 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1239 pcm->info_flags = 0; 1262 pcm->info_flags = 0;
1240 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 1263 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1241 strcpy(pcm->name, "CA0106"); 1264 strcpy(pcm->name, "CA0106");
1242 emu->pcm = pcm;
1243 1265
1244 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 1266 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1245 substream; 1267 substream;
@@ -1261,8 +1283,7 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1261 return err; 1283 return err;
1262 } 1284 }
1263 1285
1264 if (rpcm) 1286 emu->pcm[device] = pcm;
1265 *rpcm = pcm;
1266 1287
1267 return 0; 1288 return 0;
1268} 1289}
@@ -1302,89 +1323,10 @@ static unsigned int i2c_adc_init[][2] = {
1302 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */ 1323 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
1303}; 1324};
1304 1325
1305static int __devinit snd_ca0106_create(int dev, struct snd_card *card, 1326static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1306 struct pci_dev *pci,
1307 struct snd_ca0106 **rchip)
1308{ 1327{
1309 struct snd_ca0106 *chip;
1310 struct snd_ca0106_details *c;
1311 int err;
1312 int ch; 1328 int ch;
1313 static struct snd_device_ops ops = { 1329 unsigned int def_bits;
1314 .dev_free = snd_ca0106_dev_free,
1315 };
1316
1317 *rchip = NULL;
1318
1319 if ((err = pci_enable_device(pci)) < 0)
1320 return err;
1321 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1322 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1323 printk(KERN_ERR "error to set 32bit mask DMA\n");
1324 pci_disable_device(pci);
1325 return -ENXIO;
1326 }
1327
1328 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1329 if (chip == NULL) {
1330 pci_disable_device(pci);
1331 return -ENOMEM;
1332 }
1333
1334 chip->card = card;
1335 chip->pci = pci;
1336 chip->irq = -1;
1337
1338 spin_lock_init(&chip->emu_lock);
1339
1340 chip->port = pci_resource_start(pci, 0);
1341 if ((chip->res_port = request_region(chip->port, 0x20,
1342 "snd_ca0106")) == NULL) {
1343 snd_ca0106_free(chip);
1344 printk(KERN_ERR "cannot allocate the port\n");
1345 return -EBUSY;
1346 }
1347
1348 if (request_irq(pci->irq, snd_ca0106_interrupt,
1349 IRQF_SHARED, "snd_ca0106", chip)) {
1350 snd_ca0106_free(chip);
1351 printk(KERN_ERR "cannot grab irq\n");
1352 return -EBUSY;
1353 }
1354 chip->irq = pci->irq;
1355
1356 /* This stores the periods table. */
1357 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
1358 snd_ca0106_free(chip);
1359 return -ENOMEM;
1360 }
1361
1362 pci_set_master(pci);
1363 /* read serial */
1364 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1365 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1366#if 1
1367 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
1368 pci->revision, chip->serial);
1369#endif
1370 strcpy(card->driver, "CA0106");
1371 strcpy(card->shortname, "CA0106");
1372
1373 for (c = ca0106_chip_details; c->serial; c++) {
1374 if (subsystem[dev]) {
1375 if (c->serial == subsystem[dev])
1376 break;
1377 } else if (c->serial == chip->serial)
1378 break;
1379 }
1380 chip->details = c;
1381 if (subsystem[dev]) {
1382 printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
1383 c->name, chip->serial, subsystem[dev]);
1384 }
1385
1386 sprintf(card->longname, "%s at 0x%lx irq %i",
1387 c->name, chip->port, chip->irq);
1388 1330
1389 outl(0, chip->port + INTE); 1331 outl(0, chip->port + INTE);
1390 1332
@@ -1402,31 +1344,22 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1402 * AN = 0 (Audio data) 1344 * AN = 0 (Audio data)
1403 * P = 0 (Consumer) 1345 * P = 0 (Consumer)
1404 */ 1346 */
1405 snd_ca0106_ptr_write(chip, SPCS0, 0, 1347 def_bits =
1406 chip->spdif_bits[0] = 1348 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1407 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1349 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1408 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1350 SPCS_GENERATIONSTATUS | 0x00001200 |
1409 SPCS_GENERATIONSTATUS | 0x00001200 | 1351 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1410 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 1352 if (!resume) {
1353 chip->spdif_str_bits[0] = chip->spdif_bits[0] = def_bits;
1354 chip->spdif_str_bits[1] = chip->spdif_bits[1] = def_bits;
1355 chip->spdif_str_bits[2] = chip->spdif_bits[2] = def_bits;
1356 chip->spdif_str_bits[3] = chip->spdif_bits[3] = def_bits;
1357 }
1411 /* Only SPCS1 has been tested */ 1358 /* Only SPCS1 has been tested */
1412 snd_ca0106_ptr_write(chip, SPCS1, 0, 1359 snd_ca0106_ptr_write(chip, SPCS1, 0, chip->spdif_str_bits[1]);
1413 chip->spdif_bits[1] = 1360 snd_ca0106_ptr_write(chip, SPCS0, 0, chip->spdif_str_bits[0]);
1414 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1361 snd_ca0106_ptr_write(chip, SPCS2, 0, chip->spdif_str_bits[2]);
1415 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1362 snd_ca0106_ptr_write(chip, SPCS3, 0, chip->spdif_str_bits[3]);
1416 SPCS_GENERATIONSTATUS | 0x00001200 |
1417 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1418 snd_ca0106_ptr_write(chip, SPCS2, 0,
1419 chip->spdif_bits[2] =
1420 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1421 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1422 SPCS_GENERATIONSTATUS | 0x00001200 |
1423 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1424 snd_ca0106_ptr_write(chip, SPCS3, 0,
1425 chip->spdif_bits[3] =
1426 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1427 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1428 SPCS_GENERATIONSTATUS | 0x00001200 |
1429 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1430 1363
1431 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000); 1364 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
1432 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000); 1365 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
@@ -1434,92 +1367,124 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1434 /* Write 0x8000 to AC97_REC_GAIN to mute it. */ 1367 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
1435 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS); 1368 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
1436 outw(0x8000, chip->port + AC97DATA); 1369 outw(0x8000, chip->port + AC97DATA);
1437#if 0 1370#if 0 /* FIXME: what are these? */
1438 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006); 1371 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
1439 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006); 1372 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
1440 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006); 1373 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
1441 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006); 1374 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
1442#endif 1375#endif
1443 1376
1444 //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */ 1377 /* OSS drivers set this. */
1378 /* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
1379
1445 /* Analog or Digital output */ 1380 /* Analog or Digital output */
1446 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); 1381 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1447 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ 1382 /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
1383 * Use 0x000f0000 for surround71
1384 */
1385 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000);
1386
1448 chip->spdif_enable = 0; /* Set digital SPDIF output off */ 1387 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1449 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ 1388 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/ /* Analogue out */
1450 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */ 1389 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/ /* Digital out */
1390
1391 /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1392 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000);
1393 /* (Mute) CAPTURE feedback into PLAYBACK volume.
1394 * Only lower 16 bits matter.
1395 */
1396 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff);
1397 /* SPDIF IN Volume */
1398 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000);
1399 /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1400 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000);
1451 1401
1452 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1453 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
1454 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
1455 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1456 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410); 1402 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
1457 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676); 1403 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
1458 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410); 1404 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
1459 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676); 1405 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
1460 for(ch = 0; ch < 4; ch++) { 1406
1461 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */ 1407 for (ch = 0; ch < 4; ch++) {
1408 /* Only high 16 bits matter */
1409 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030);
1462 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030); 1410 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
1463 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */ 1411#if 0 /* Mute */
1464 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */ 1412 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
1465 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */ 1413 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
1466 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */ 1414 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
1415 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
1416#endif
1467 } 1417 }
1468 if (chip->details->i2c_adc == 1) { 1418 if (chip->details->i2c_adc == 1) {
1469 /* Select MIC, Line in, TAD in, AUX in */ 1419 /* Select MIC, Line in, TAD in, AUX in */
1470 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1420 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1471 /* Default to CAPTURE_SOURCE to i2s in */ 1421 /* Default to CAPTURE_SOURCE to i2s in */
1472 chip->capture_source = 3; 1422 if (!resume)
1423 chip->capture_source = 3;
1473 } else if (chip->details->ac97 == 1) { 1424 } else if (chip->details->ac97 == 1) {
1474 /* Default to AC97 in */ 1425 /* Default to AC97 in */
1475 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4); 1426 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
1476 /* Default to CAPTURE_SOURCE to AC97 in */ 1427 /* Default to CAPTURE_SOURCE to AC97 in */
1477 chip->capture_source = 4; 1428 if (!resume)
1429 chip->capture_source = 4;
1478 } else { 1430 } else {
1479 /* Select MIC, Line in, TAD in, AUX in */ 1431 /* Select MIC, Line in, TAD in, AUX in */
1480 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1432 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1481 /* Default to Set CAPTURE_SOURCE to i2s in */ 1433 /* Default to Set CAPTURE_SOURCE to i2s in */
1482 chip->capture_source = 3; 1434 if (!resume)
1435 chip->capture_source = 3;
1483 } 1436 }
1484 1437
1485 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ 1438 if (chip->details->gpio_type == 2) {
1486 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1439 /* The SB0438 use GPIO differently. */
1440 /* FIXME: Still need to find out what the other GPIO bits do.
1441 * E.g. For digital spdif out.
1442 */
1487 outl(0x0, chip->port+GPIO); 1443 outl(0x0, chip->port+GPIO);
1488 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1444 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1489 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1445 outl(0x005f5301, chip->port+GPIO); /* Analog */
1490 } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ 1446 } else if (chip->details->gpio_type == 1) {
1491 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1447 /* The SB0410 and SB0413 use GPIO differently. */
1448 /* FIXME: Still need to find out what the other GPIO bits do.
1449 * E.g. For digital spdif out.
1450 */
1492 outl(0x0, chip->port+GPIO); 1451 outl(0x0, chip->port+GPIO);
1493 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1452 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1494 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1453 outl(0x005f5301, chip->port+GPIO); /* Analog */
1495 } else { 1454 } else {
1496 outl(0x0, chip->port+GPIO); 1455 outl(0x0, chip->port+GPIO);
1497 outl(0x005f03a3, chip->port+GPIO); /* Analog */ 1456 outl(0x005f03a3, chip->port+GPIO); /* Analog */
1498 //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */ 1457 /* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
1499 } 1458 }
1500 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */ 1459 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
1501 1460
1502 //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); 1461 /* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
1503 //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */ 1462 /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
1504 //outl(0x00000009, chip->port+HCFG); 1463 /* outl(0x00001409, chip->port+HCFG); */
1505 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1464 /* outl(0x00000009, chip->port+HCFG); */
1465 /* AC97 2.0, Enable outputs. */
1466 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
1506 1467
1507 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ 1468 if (chip->details->i2c_adc == 1) {
1469 /* The SB0410 and SB0413 use I2C to control ADC. */
1508 int size, n; 1470 int size, n;
1509 1471
1510 size = ARRAY_SIZE(i2c_adc_init); 1472 size = ARRAY_SIZE(i2c_adc_init);
1511 //snd_printk("I2C:array size=0x%x\n", size); 1473 /* snd_printk("I2C:array size=0x%x\n", size); */
1512 for (n=0; n < size; n++) { 1474 for (n = 0; n < size; n++)
1513 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); 1475 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0],
1514 } 1476 i2c_adc_init[n][1]);
1515 for (n=0; n < 4; n++) { 1477 for (n = 0; n < 4; n++) {
1516 chip->i2c_capture_volume[n][0]= 0xcf; 1478 chip->i2c_capture_volume[n][0] = 0xcf;
1517 chip->i2c_capture_volume[n][1]= 0xcf; 1479 chip->i2c_capture_volume[n][1] = 0xcf;
1518 } 1480 }
1519 chip->i2c_capture_source=2; /* Line in */ 1481 chip->i2c_capture_source = 2; /* Line in */
1520 //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ 1482 /* Enable Line-in capture. MIC in currently untested. */
1483 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1521 } 1484 }
1522 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ 1485
1486 if (chip->details->spi_dac == 1) {
1487 /* The SB0570 use SPI to control DAC. */
1523 int size, n; 1488 int size, n;
1524 1489
1525 size = ARRAY_SIZE(spi_dac_init); 1490 size = ARRAY_SIZE(spi_dac_init);
@@ -1531,9 +1496,112 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1531 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1496 chip->spi_dac_reg[reg] = spi_dac_init[n];
1532 } 1497 }
1533 } 1498 }
1499}
1500
1501static void ca0106_stop_chip(struct snd_ca0106 *chip)
1502{
1503 /* disable interrupts */
1504 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
1505 outl(0, chip->port + INTE);
1506 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1507 udelay(1000);
1508 /* disable audio */
1509 /* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
1510 outl(0, chip->port + HCFG);
1511 /* FIXME: We need to stop and DMA transfers here.
1512 * But as I am not sure how yet, we cannot from the dma pages.
1513 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1514 */
1515}
1516
1517static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1518 struct pci_dev *pci,
1519 struct snd_ca0106 **rchip)
1520{
1521 struct snd_ca0106 *chip;
1522 struct snd_ca0106_details *c;
1523 int err;
1524 static struct snd_device_ops ops = {
1525 .dev_free = snd_ca0106_dev_free,
1526 };
1527
1528 *rchip = NULL;
1529
1530 err = pci_enable_device(pci);
1531 if (err < 0)
1532 return err;
1533 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1534 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1535 printk(KERN_ERR "error to set 32bit mask DMA\n");
1536 pci_disable_device(pci);
1537 return -ENXIO;
1538 }
1539
1540 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1541 if (chip == NULL) {
1542 pci_disable_device(pci);
1543 return -ENOMEM;
1544 }
1545
1546 chip->card = card;
1547 chip->pci = pci;
1548 chip->irq = -1;
1549
1550 spin_lock_init(&chip->emu_lock);
1551
1552 chip->port = pci_resource_start(pci, 0);
1553 chip->res_port = request_region(chip->port, 0x20, "snd_ca0106");
1554 if (!chip->res_port) {
1555 snd_ca0106_free(chip);
1556 printk(KERN_ERR "cannot allocate the port\n");
1557 return -EBUSY;
1558 }
1559
1560 if (request_irq(pci->irq, snd_ca0106_interrupt,
1561 IRQF_SHARED, "snd_ca0106", chip)) {
1562 snd_ca0106_free(chip);
1563 printk(KERN_ERR "cannot grab irq\n");
1564 return -EBUSY;
1565 }
1566 chip->irq = pci->irq;
1567
1568 /* This stores the periods table. */
1569 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1570 1024, &chip->buffer) < 0) {
1571 snd_ca0106_free(chip);
1572 return -ENOMEM;
1573 }
1574
1575 pci_set_master(pci);
1576 /* read serial */
1577 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1578 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1579 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n",
1580 chip->model, pci->revision, chip->serial);
1581 strcpy(card->driver, "CA0106");
1582 strcpy(card->shortname, "CA0106");
1583
1584 for (c = ca0106_chip_details; c->serial; c++) {
1585 if (subsystem[dev]) {
1586 if (c->serial == subsystem[dev])
1587 break;
1588 } else if (c->serial == chip->serial)
1589 break;
1590 }
1591 chip->details = c;
1592 if (subsystem[dev]) {
1593 printk(KERN_INFO "snd-ca0106: Sound card name=%s, "
1594 "subsystem=0x%x. Forced to subsystem=0x%x\n",
1595 c->name, chip->serial, subsystem[dev]);
1596 }
1597
1598 sprintf(card->longname, "%s at 0x%lx irq %i",
1599 c->name, chip->port, chip->irq);
1534 1600
1535 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 1601 ca0106_init_chip(chip, 0);
1536 chip, &ops)) < 0) { 1602
1603 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1604 if (err < 0) {
1537 snd_ca0106_free(chip); 1605 snd_ca0106_free(chip);
1538 return err; 1606 return err;
1539 } 1607 }
@@ -1630,7 +1698,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1630 static int dev; 1698 static int dev;
1631 struct snd_card *card; 1699 struct snd_card *card;
1632 struct snd_ca0106 *chip; 1700 struct snd_ca0106 *chip;
1633 int err; 1701 int i, err;
1634 1702
1635 if (dev >= SNDRV_CARDS) 1703 if (dev >= SNDRV_CARDS)
1636 return -ENODEV; 1704 return -ENODEV;
@@ -1643,44 +1711,31 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1643 if (card == NULL) 1711 if (card == NULL)
1644 return -ENOMEM; 1712 return -ENOMEM;
1645 1713
1646 if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) { 1714 err = snd_ca0106_create(dev, card, pci, &chip);
1647 snd_card_free(card); 1715 if (err < 0)
1648 return err; 1716 goto error;
1649 } 1717 card->private_data = chip;
1650 1718
1651 if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) { 1719 for (i = 0; i < 4; i++) {
1652 snd_card_free(card); 1720 err = snd_ca0106_pcm(chip, i);
1653 return err; 1721 if (err < 0)
1654 } 1722 goto error;
1655 if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
1656 snd_card_free(card);
1657 return err;
1658 }
1659 if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
1660 snd_card_free(card);
1661 return err;
1662 }
1663 if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
1664 snd_card_free(card);
1665 return err;
1666 }
1667 if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */
1668 if ((err = snd_ca0106_ac97(chip)) < 0) {
1669 snd_card_free(card);
1670 return err;
1671 }
1672 } 1723 }
1673 if ((err = snd_ca0106_mixer(chip)) < 0) { 1724
1674 snd_card_free(card); 1725 if (chip->details->ac97 == 1) {
1675 return err; 1726 /* The SB0410 and SB0413 do not have an AC97 chip. */
1727 err = snd_ca0106_ac97(chip);
1728 if (err < 0)
1729 goto error;
1676 } 1730 }
1731 err = snd_ca0106_mixer(chip);
1732 if (err < 0)
1733 goto error;
1677 1734
1678 snd_printdd("ca0106: probe for MIDI channel A ..."); 1735 snd_printdd("ca0106: probe for MIDI channel A ...");
1679 if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) { 1736 err = snd_ca0106_midi(chip, CA0106_MIDI_CHAN_A);
1680 snd_card_free(card); 1737 if (err < 0)
1681 snd_printdd(" failed, err=0x%x\n",err); 1738 goto error;
1682 return err;
1683 }
1684 snd_printdd(" done.\n"); 1739 snd_printdd(" done.\n");
1685 1740
1686#ifdef CONFIG_PROC_FS 1741#ifdef CONFIG_PROC_FS
@@ -1689,14 +1744,17 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1689 1744
1690 snd_card_set_dev(card, &pci->dev); 1745 snd_card_set_dev(card, &pci->dev);
1691 1746
1692 if ((err = snd_card_register(card)) < 0) { 1747 err = snd_card_register(card);
1693 snd_card_free(card); 1748 if (err < 0)
1694 return err; 1749 goto error;
1695 }
1696 1750
1697 pci_set_drvdata(pci, card); 1751 pci_set_drvdata(pci, card);
1698 dev++; 1752 dev++;
1699 return 0; 1753 return 0;
1754
1755 error:
1756 snd_card_free(card);
1757 return err;
1700} 1758}
1701 1759
1702static void __devexit snd_ca0106_remove(struct pci_dev *pci) 1760static void __devexit snd_ca0106_remove(struct pci_dev *pci)
@@ -1705,6 +1763,59 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1705 pci_set_drvdata(pci, NULL); 1763 pci_set_drvdata(pci, NULL);
1706} 1764}
1707 1765
1766#ifdef CONFIG_PM
1767static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
1768{
1769 struct snd_card *card = pci_get_drvdata(pci);
1770 struct snd_ca0106 *chip = card->private_data;
1771 int i;
1772
1773 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1774 for (i = 0; i < 4; i++)
1775 snd_pcm_suspend_all(chip->pcm[i]);
1776 if (chip->details->ac97)
1777 snd_ac97_suspend(chip->ac97);
1778 snd_ca0106_mixer_suspend(chip);
1779
1780 ca0106_stop_chip(chip);
1781
1782 pci_disable_device(pci);
1783 pci_save_state(pci);
1784 pci_set_power_state(pci, pci_choose_state(pci, state));
1785 return 0;
1786}
1787
1788static int snd_ca0106_resume(struct pci_dev *pci)
1789{
1790 struct snd_card *card = pci_get_drvdata(pci);
1791 struct snd_ca0106 *chip = card->private_data;
1792 int i;
1793
1794 pci_set_power_state(pci, PCI_D0);
1795 pci_restore_state(pci);
1796
1797 if (pci_enable_device(pci) < 0) {
1798 snd_card_disconnect(card);
1799 return -EIO;
1800 }
1801
1802 pci_set_master(pci);
1803
1804 ca0106_init_chip(chip, 1);
1805
1806 if (chip->details->ac97)
1807 snd_ac97_resume(chip->ac97);
1808 snd_ca0106_mixer_resume(chip);
1809 if (chip->details->spi_dac) {
1810 for (i = 0; i < ARRAY_SIZE(chip->spi_dac_reg); i++)
1811 snd_ca0106_spi_write(chip, chip->spi_dac_reg[i]);
1812 }
1813
1814 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1815 return 0;
1816}
1817#endif
1818
1708// PCI IDs 1819// PCI IDs
1709static struct pci_device_id snd_ca0106_ids[] = { 1820static struct pci_device_id snd_ca0106_ids[] = {
1710 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ 1821 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
@@ -1718,6 +1829,10 @@ static struct pci_driver driver = {
1718 .id_table = snd_ca0106_ids, 1829 .id_table = snd_ca0106_ids,
1719 .probe = snd_ca0106_probe, 1830 .probe = snd_ca0106_probe,
1720 .remove = __devexit_p(snd_ca0106_remove), 1831 .remove = __devexit_p(snd_ca0106_remove),
1832#ifdef CONFIG_PM
1833 .suspend = snd_ca0106_suspend,
1834 .resume = snd_ca0106_resume,
1835#endif
1721}; 1836};
1722 1837
1723// initialization of the module 1838// initialization of the module
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 3025ed1b6e1e..ad2888705d2a 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -75,6 +75,84 @@
75 75
76#include "ca0106.h" 76#include "ca0106.h"
77 77
78static void ca0106_spdif_enable(struct snd_ca0106 *emu)
79{
80 unsigned int val;
81
82 if (emu->spdif_enable) {
83 /* Digital */
84 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
85 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
86 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
87 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
88 val = inl(emu->port + GPIO) & ~0x101;
89 outl(val, emu->port + GPIO);
90
91 } else {
92 /* Analog */
93 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
94 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
95 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
96 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
97 val = inl(emu->port + GPIO) | 0x101;
98 outl(val, emu->port + GPIO);
99 }
100}
101
102static void ca0106_set_capture_source(struct snd_ca0106 *emu)
103{
104 unsigned int val = emu->capture_source;
105 unsigned int source, mask;
106 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
107 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
108 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
109}
110
111static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
112 unsigned int val, int force)
113{
114 unsigned int ngain, ogain;
115 u32 source;
116
117 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
118 ngain = emu->i2c_capture_volume[val][0]; /* Left */
119 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
120 if (force || ngain != ogain)
121 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
122 ngain = emu->i2c_capture_volume[val][1]; /* Right */
123 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
124 if (force || ngain != ogain)
125 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
126 source = 1 << val;
127 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
128 emu->i2c_capture_source = val;
129}
130
131static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
132{
133 u32 tmp;
134
135 if (emu->capture_mic_line_in) {
136 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
137 tmp = inl(emu->port+GPIO) & ~0x400;
138 tmp = tmp | 0x400;
139 outl(tmp, emu->port+GPIO);
140 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
141 } else {
142 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
143 tmp = inl(emu->port+GPIO) & ~0x400;
144 outl(tmp, emu->port+GPIO);
145 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
146 }
147}
148
149static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
150{
151 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
152}
153
154/*
155 */
78static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); 156static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
79static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); 157static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
80 158
@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
95 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 173 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
96 unsigned int val; 174 unsigned int val;
97 int change = 0; 175 int change = 0;
98 u32 mask;
99 176
100 val = !!ucontrol->value.integer.value[0]; 177 val = !!ucontrol->value.integer.value[0];
101 change = (emu->spdif_enable != val); 178 change = (emu->spdif_enable != val);
102 if (change) { 179 if (change) {
103 emu->spdif_enable = val; 180 emu->spdif_enable = val;
104 if (val) { 181 ca0106_spdif_enable(emu);
105 /* Digital */
106 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
107 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
108 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
109 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
110 mask = inl(emu->port + GPIO) & ~0x101;
111 outl(mask, emu->port + GPIO);
112
113 } else {
114 /* Analog */
115 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
116 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
117 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
118 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
119 mask = inl(emu->port + GPIO) | 0x101;
120 outl(mask, emu->port + GPIO);
121 }
122 } 182 }
123 return change; 183 return change;
124} 184}
@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
154 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 214 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
155 unsigned int val; 215 unsigned int val;
156 int change = 0; 216 int change = 0;
157 u32 mask;
158 u32 source;
159 217
160 val = ucontrol->value.enumerated.item[0] ; 218 val = ucontrol->value.enumerated.item[0] ;
161 if (val >= 6) 219 if (val >= 6)
@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
163 change = (emu->capture_source != val); 221 change = (emu->capture_source != val);
164 if (change) { 222 if (change) {
165 emu->capture_source = val; 223 emu->capture_source = val;
166 source = (val << 28) | (val << 24) | (val << 20) | (val << 16); 224 ca0106_set_capture_source(emu);
167 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
168 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
169 } 225 }
170 return change; 226 return change;
171} 227}
@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
200{ 256{
201 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 257 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
202 unsigned int source_id; 258 unsigned int source_id;
203 unsigned int ngain, ogain;
204 int change = 0; 259 int change = 0;
205 u32 source;
206 /* If the capture source has changed, 260 /* If the capture source has changed,
207 * update the capture volume from the cached value 261 * update the capture volume from the cached value
208 * for the particular source. 262 * for the particular source.
@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
212 return -EINVAL; 266 return -EINVAL;
213 change = (emu->i2c_capture_source != source_id); 267 change = (emu->i2c_capture_source != source_id);
214 if (change) { 268 if (change) {
215 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ 269 ca0106_set_i2c_capture_source(emu, source_id, 0);
216 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
217 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
218 if (ngain != ogain)
219 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
220 ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
221 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
222 if (ngain != ogain)
223 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
224 source = 1 << source_id;
225 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
226 emu->i2c_capture_source = source_id;
227 } 270 }
228 return change; 271 return change;
229} 272}
@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
271 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 314 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
272 unsigned int val; 315 unsigned int val;
273 int change = 0; 316 int change = 0;
274 u32 tmp;
275 317
276 val = ucontrol->value.enumerated.item[0] ; 318 val = ucontrol->value.enumerated.item[0] ;
277 if (val > 1) 319 if (val > 1)
@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
279 change = (emu->capture_mic_line_in != val); 321 change = (emu->capture_mic_line_in != val);
280 if (change) { 322 if (change) {
281 emu->capture_mic_line_in = val; 323 emu->capture_mic_line_in = val;
282 if (val) { 324 ca0106_set_capture_mic_line_in(emu);
283 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
284 tmp = inl(emu->port+GPIO) & ~0x400;
285 tmp = tmp | 0x400;
286 outl(tmp, emu->port+GPIO);
287 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
288 } else {
289 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
290 tmp = inl(emu->port+GPIO) & ~0x400;
291 outl(tmp, emu->port+GPIO);
292 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
293 }
294 } 325 }
295 return change; 326 return change;
296} 327}
@@ -322,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
322 return 0; 353 return 0;
323} 354}
324 355
325static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol, 356static void decode_spdif_bits(unsigned char *status, unsigned int bits)
357{
358 status[0] = (bits >> 0) & 0xff;
359 status[1] = (bits >> 8) & 0xff;
360 status[2] = (bits >> 16) & 0xff;
361 status[3] = (bits >> 24) & 0xff;
362}
363
364static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol) 365 struct snd_ctl_elem_value *ucontrol)
327{ 366{
328 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 367 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
329 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 368 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330 369
331 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; 370 decode_spdif_bits(ucontrol->value.iec958.status,
332 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; 371 emu->spdif_bits[idx]);
333 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; 372 return 0;
334 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; 373}
374
375static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
378 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
379 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380
381 decode_spdif_bits(ucontrol->value.iec958.status,
382 emu->spdif_str_bits[idx]);
335 return 0; 383 return 0;
336} 384}
337 385
@@ -345,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
345 return 0; 393 return 0;
346} 394}
347 395
348static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol, 396static unsigned int encode_spdif_bits(unsigned char *status)
397{
398 return ((unsigned int)status[0] << 0) |
399 ((unsigned int)status[1] << 8) |
400 ((unsigned int)status[2] << 16) |
401 ((unsigned int)status[3] << 24);
402}
403
404static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol) 405 struct snd_ctl_elem_value *ucontrol)
350{ 406{
351 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 407 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
352 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 408 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
353 int change;
354 unsigned int val; 409 unsigned int val;
355 410
356 val = (ucontrol->value.iec958.status[0] << 0) | 411 val = encode_spdif_bits(ucontrol->value.iec958.status);
357 (ucontrol->value.iec958.status[1] << 8) | 412 if (val != emu->spdif_bits[idx]) {
358 (ucontrol->value.iec958.status[2] << 16) |
359 (ucontrol->value.iec958.status[3] << 24);
360 change = val != emu->spdif_bits[idx];
361 if (change) {
362 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
363 emu->spdif_bits[idx] = val; 413 emu->spdif_bits[idx] = val;
414 /* FIXME: this isn't safe, but needed to keep the compatibility
415 * with older alsa-lib config
416 */
417 emu->spdif_str_bits[idx] = val;
418 ca0106_set_spdif_bits(emu, idx);
419 return 1;
364 } 420 }
365 return change; 421 return 0;
422}
423
424static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol)
426{
427 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
428 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
429 unsigned int val;
430
431 val = encode_spdif_bits(ucontrol->value.iec958.status);
432 if (val != emu->spdif_str_bits[idx]) {
433 emu->spdif_str_bits[idx] = val;
434 ca0106_set_spdif_bits(emu, idx);
435 return 1;
436 }
437 return 0;
366} 438}
367 439
368static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol, 440static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
@@ -573,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
573 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 645 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
574 .count = 4, 646 .count = 4,
575 .info = snd_ca0106_spdif_info, 647 .info = snd_ca0106_spdif_info,
576 .get = snd_ca0106_spdif_get, 648 .get = snd_ca0106_spdif_get_default,
577 .put = snd_ca0106_spdif_put 649 .put = snd_ca0106_spdif_put_default
650 },
651 {
652 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
653 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
654 .count = 4,
655 .info = snd_ca0106_spdif_info,
656 .get = snd_ca0106_spdif_get_stream,
657 .put = snd_ca0106_spdif_put_stream
578 }, 658 },
579}; 659};
580 660
@@ -773,3 +853,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
773 return 0; 853 return 0;
774} 854}
775 855
856#ifdef CONFIG_PM
857struct ca0106_vol_tbl {
858 unsigned int channel_id;
859 unsigned int reg;
860};
861
862static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
863 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
864 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
865 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
866 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
867 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
868 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
869 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
870 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
871 { 1, CAPTURE_CONTROL },
872};
873
874void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
875{
876 int i;
877
878 /* save volumes */
879 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
880 chip->saved_vol[i] =
881 snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
882 saved_volumes[i].channel_id);
883}
884
885void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
886{
887 int i;
888
889 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
890 snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
891 saved_volumes[i].channel_id,
892 chip->saved_vol[i]);
893
894 ca0106_spdif_enable(chip);
895 ca0106_set_capture_source(chip);
896 ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
897 for (i = 0; i < 4; i++)
898 ca0106_set_spdif_bits(chip, i);
899 if (chip->details->i2c_adc)
900 ca0106_set_capture_mic_line_in(chip);
901}
902#endif /* CONFIG_PM */
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index ef9308f7c45b..192e7842e181 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1382,8 +1382,8 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
1382 chip->ba0_addr = pci_resource_start(pci, 0); 1382 chip->ba0_addr = pci_resource_start(pci, 0);
1383 chip->ba1_addr = pci_resource_start(pci, 1); 1383 chip->ba1_addr = pci_resource_start(pci, 1);
1384 1384
1385 chip->ba0 = ioremap_nocache(chip->ba0_addr, pci_resource_len(pci, 0)); 1385 chip->ba0 = pci_ioremap_bar(pci, 0);
1386 chip->ba1 = ioremap_nocache(chip->ba1_addr, pci_resource_len(pci, 1)); 1386 chip->ba1 = pci_ioremap_bar(pci, 1);
1387 if (!chip->ba0 || !chip->ba1) { 1387 if (!chip->ba0 || !chip->ba1) {
1388 snd_cs4281_free(chip); 1388 snd_cs4281_free(chip);
1389 return -ENOMEM; 1389 return -ENOMEM;
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index fb6dc3980257..8ab07aa63652 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3640,7 +3640,10 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3640{ 3640{
3641 struct snd_card *card = pci_get_drvdata(pci); 3641 struct snd_card *card = pci_get_drvdata(pci);
3642 struct snd_cs46xx *chip = card->private_data; 3642 struct snd_cs46xx *chip = card->private_data;
3643 int i, amp_saved; 3643 int amp_saved;
3644#ifdef CONFIG_SND_CS46XX_NEW_DSP
3645 int i;
3646#endif
3644 3647
3645 pci_set_power_state(pci, PCI_D0); 3648 pci_set_power_state(pci, PCI_D0);
3646 pci_restore_state(pci); 3649 pci_restore_state(pci);
diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
index 7ff8b68e997e..6dea5b5cc774 100644
--- a/sound/pci/cs5530.c
+++ b/sound/pci/cs5530.c
@@ -2,7 +2,7 @@
2 * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio 2 * cs5530.c - Initialisation code for Cyrix/NatSemi VSA1 softaudio
3 * 3 *
4 * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net> 4 * (C) Copyright 2007 Ash Willis <ashwillis@programmer.net>
5 * (C) Copyright 2003 Red Hat Inc <alan@redhat.com> 5 * (C) Copyright 2003 Red Hat Inc <alan@lxorguk.ukuu.org.uk>
6 * 6 *
7 * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did 7 * This driver was ported (shamelessly ripped ;) from oss/kahlua.c but I did
8 * mess with it a bit. The chip seems to have to have trouble with full duplex 8 * mess with it a bit. The chip seems to have to have trouble with full duplex
@@ -132,7 +132,7 @@ static int __devinit snd_cs5530_create(struct snd_card *card,
132 } 132 }
133 chip->pci_base = pci_resource_start(pci, 0); 133 chip->pci_base = pci_resource_start(pci, 0);
134 134
135 mem = ioremap_nocache(chip->pci_base, pci_resource_len(pci, 0)); 135 mem = pci_ioremap_bar(pci, 0);
136 if (mem == NULL) { 136 if (mem == NULL) {
137 kfree(chip); 137 kfree(chip);
138 pci_disable_device(pci); 138 pci_disable_device(pci);
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index bb3d57e6a3cb..fda7a94c992f 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,6 +4,9 @@
4 4
5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o 6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
7ifdef CONFIG_MGEODE_LX
8snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
9endif
7 10
8# Toplevel Module Dependency 11# Toplevel Module Dependency
9obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 1d8b16052535..826e6dec2e97 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -159,10 +159,14 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
159 return err; 159 return err;
160 160
161 memset(&ac97, 0, sizeof(ac97)); 161 memset(&ac97, 0, sizeof(ac97));
162 ac97.scaps = AC97_SCAP_AUDIO|AC97_SCAP_SKIP_MODEM; 162 ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM
163 | AC97_SCAP_POWER_SAVE;
163 ac97.private_data = cs5535au; 164 ac97.private_data = cs5535au;
164 ac97.pci = cs5535au->pci; 165 ac97.pci = cs5535au->pci;
165 166
167 /* set any OLPC-specific scaps */
168 olpc_prequirks(card, &ac97);
169
166 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) { 170 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
167 snd_printk(KERN_ERR "mixer failed\n"); 171 snd_printk(KERN_ERR "mixer failed\n");
168 return err; 172 return err;
@@ -170,6 +174,12 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
170 174
171 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk); 175 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
172 176
177 err = olpc_quirks(card, cs5535au->ac97);
178 if (err < 0) {
179 snd_printk(KERN_ERR "olpc quirks failed\n");
180 return err;
181 }
182
173 return 0; 183 return 0;
174} 184}
175 185
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 66bae7664193..7a298ac662e3 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -78,6 +78,7 @@ struct cs5535audio_dma {
78 unsigned int buf_addr, buf_bytes; 78 unsigned int buf_addr, buf_bytes;
79 unsigned int period_bytes, periods; 79 unsigned int period_bytes, periods;
80 u32 saved_prd; 80 u32 saved_prd;
81 int pcm_open_flag;
81}; 82};
82 83
83struct cs5535audio { 84struct cs5535audio {
@@ -93,8 +94,46 @@ struct cs5535audio {
93 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
94}; 95};
95 96
97#ifdef CONFIG_PM
96int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state); 98int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
97int snd_cs5535audio_resume(struct pci_dev *pci); 99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif
101
102#if defined(CONFIG_OLPC) && defined(CONFIG_MGEODE_LX)
103void __devinit olpc_prequirks(struct snd_card *card,
104 struct snd_ac97_template *ac97);
105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
106void olpc_analog_input(struct snd_ac97 *ac97, int on);
107void olpc_mic_bias(struct snd_ac97 *ac97, int on);
108
109static inline void olpc_capture_open(struct snd_ac97 *ac97)
110{
111 /* default to Analog Input off */
112 olpc_analog_input(ac97, 0);
113 /* enable MIC Bias for recording */
114 olpc_mic_bias(ac97, 1);
115}
116
117static inline void olpc_capture_close(struct snd_ac97 *ac97)
118{
119 /* disable Analog Input */
120 olpc_analog_input(ac97, 0);
121 /* disable the MIC Bias (so the recording LED turns off) */
122 olpc_mic_bias(ac97, 0);
123}
124#else
125static inline void olpc_prequirks(struct snd_card *card,
126 struct snd_ac97_template *ac97) { }
127static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
128{
129 return 0;
130}
131static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
132static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
133static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
134static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
135#endif
136
98int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 137int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
99 138
100#endif /* __SOUND_CS5535AUDIO_H */ 139#endif /* __SOUND_CS5535AUDIO_H */
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
new file mode 100644
index 000000000000..5c6814335cd7
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -0,0 +1,179 @@
1/*
2 * OLPC XO-1 additional sound features
3 *
4 * Copyright © 2006 Jaya Kumar <jayakumar.lkml@gmail.com>
5 * Copyright © 2007-2008 Andres Salomon <dilinger@debian.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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12#include <sound/core.h>
13#include <sound/info.h>
14#include <sound/control.h>
15#include <sound/ac97_codec.h>
16
17#include <asm/olpc.h>
18#include "cs5535audio.h"
19
20/*
21 * OLPC has an additional feature on top of the regular AD1888 codec features.
22 * It has an Analog Input mode that is switched into (after disabling the
23 * High Pass Filter) via GPIO. It is supported on B2 and later models.
24 */
25void olpc_analog_input(struct snd_ac97 *ac97, int on)
26{
27 int err;
28
29 if (!machine_is_olpc())
30 return;
31
32 /* update the High Pass Filter (via AC97_AD_TEST2) */
33 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
34 1 << AC97_AD_HPFD_SHIFT, on << AC97_AD_HPFD_SHIFT);
35 if (err < 0) {
36 snd_printk(KERN_ERR "setting High Pass Filter - %d\n", err);
37 return;
38 }
39
40 /* set Analog Input through GPIO */
41 if (on)
42 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
43 else
44 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
45}
46
47/*
48 * OLPC XO-1's V_REFOUT is a mic bias enable.
49 */
50void olpc_mic_bias(struct snd_ac97 *ac97, int on)
51{
52 int err;
53
54 if (!machine_is_olpc())
55 return;
56
57 on = on ? 0 : 1;
58 err = snd_ac97_update_bits(ac97, AC97_AD_MISC,
59 1 << AC97_AD_VREFD_SHIFT, on << AC97_AD_VREFD_SHIFT);
60 if (err < 0)
61 snd_printk(KERN_ERR "setting MIC Bias - %d\n", err);
62}
63
64static int olpc_dc_info(struct snd_kcontrol *kctl,
65 struct snd_ctl_elem_info *uinfo)
66{
67 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
68 uinfo->count = 1;
69 uinfo->value.integer.min = 0;
70 uinfo->value.integer.max = 1;
71 return 0;
72}
73
74static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
75{
76 v->value.integer.value[0] = geode_gpio_isset(OLPC_GPIO_MIC_AC,
77 GPIO_OUTPUT_VAL);
78 return 0;
79}
80
81static int olpc_dc_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
82{
83 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
84
85 olpc_analog_input(cs5535au->ac97, v->value.integer.value[0]);
86 return 1;
87}
88
89static int olpc_mic_info(struct snd_kcontrol *kctl,
90 struct snd_ctl_elem_info *uinfo)
91{
92 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
93 uinfo->count = 1;
94 uinfo->value.integer.min = 0;
95 uinfo->value.integer.max = 1;
96 return 0;
97}
98
99static int olpc_mic_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
100{
101 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
102 struct snd_ac97 *ac97 = cs5535au->ac97;
103 int i;
104
105 i = (snd_ac97_read(ac97, AC97_AD_MISC) >> AC97_AD_VREFD_SHIFT) & 0x1;
106 v->value.integer.value[0] = i ? 0 : 1;
107 return 0;
108}
109
110static int olpc_mic_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
111{
112 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
113
114 olpc_mic_bias(cs5535au->ac97, v->value.integer.value[0]);
115 return 1;
116}
117
118static struct snd_kcontrol_new olpc_cs5535audio_ctls[] __devinitdata = {
119{
120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
121 .name = "DC Mode Enable",
122 .info = olpc_dc_info,
123 .get = olpc_dc_get,
124 .put = olpc_dc_put,
125 .private_value = 0,
126},
127{
128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
129 .name = "MIC Bias Enable",
130 .info = olpc_mic_info,
131 .get = olpc_mic_get,
132 .put = olpc_mic_put,
133 .private_value = 0,
134},
135};
136
137void __devinit olpc_prequirks(struct snd_card *card,
138 struct snd_ac97_template *ac97)
139{
140 if (!machine_is_olpc())
141 return;
142
143 /* invert EAPD if on an OLPC B3 or higher */
144 if (olpc_board_at_least(olpc_board_pre(0xb3)))
145 ac97->scaps |= AC97_SCAP_INV_EAPD;
146}
147
148int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
149{
150 struct snd_ctl_elem_id elem;
151 int i, err;
152
153 if (!machine_is_olpc())
154 return 0;
155
156 /* drop the original AD1888 HPF control */
157 memset(&elem, 0, sizeof(elem));
158 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
159 strncpy(elem.name, "High Pass Filter Enable", sizeof(elem.name));
160 snd_ctl_remove_id(card, &elem);
161
162 /* drop the original V_REFOUT control */
163 memset(&elem, 0, sizeof(elem));
164 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
165 strncpy(elem.name, "V_REFOUT Enable", sizeof(elem.name));
166 snd_ctl_remove_id(card, &elem);
167
168 /* add the OLPC-specific controls */
169 for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
170 err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
171 ac97->private_data));
172 if (err < 0)
173 return err;
174 }
175
176 /* turn off the mic by default */
177 olpc_mic_bias(ac97, 0);
178 return 0;
179}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index cdcda87116c3..0f48a871f17b 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -260,6 +260,9 @@ static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream, 260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
261 params_periods(hw_params), 261 params_periods(hw_params),
262 params_period_bytes(hw_params)); 262 params_period_bytes(hw_params));
263 if (!err)
264 dma->pcm_open_flag = 1;
265
263 return err; 266 return err;
264} 267}
265 268
@@ -268,6 +271,15 @@ static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
268 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream); 271 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
269 struct cs5535audio_dma *dma = substream->runtime->private_data; 272 struct cs5535audio_dma *dma = substream->runtime->private_data;
270 273
274 if (dma->pcm_open_flag) {
275 if (substream == cs5535au->playback_substream)
276 snd_ac97_update_power(cs5535au->ac97,
277 AC97_PCM_FRONT_DAC_RATE, 0);
278 else
279 snd_ac97_update_power(cs5535au->ac97,
280 AC97_PCM_LR_ADC_RATE, 0);
281 dma->pcm_open_flag = 0;
282 }
271 cs5535audio_clear_dma_packets(cs5535au, dma, substream); 283 cs5535audio_clear_dma_packets(cs5535au, dma, substream);
272 return snd_pcm_lib_free_pages(substream); 284 return snd_pcm_lib_free_pages(substream);
273} 285}
@@ -351,11 +363,14 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
351 if ((err = snd_pcm_hw_constraint_integer(runtime, 363 if ((err = snd_pcm_hw_constraint_integer(runtime,
352 SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 364 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
353 return err; 365 return err;
366 olpc_capture_open(cs5535au->ac97);
354 return 0; 367 return 0;
355} 368}
356 369
357static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream) 370static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
358{ 371{
372 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
373 olpc_capture_close(cs5535au->ac97);
359 return 0; 374 return 0;
360} 375}
361 376
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 2f283ea6ad9a..7958006a1d66 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -69,7 +69,7 @@ MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
69 * EMU10K1 init / done 69 * EMU10K1 init / done
70 *************************************************************************/ 70 *************************************************************************/
71 71
72void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch) 72void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
73{ 73{
74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0); 74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
75 snd_emu10k1_ptr_write(emu, IP, ch, 0); 75 snd_emu10k1_ptr_write(emu, IP, ch, 0);
@@ -151,9 +151,9 @@ static unsigned int i2c_adc_init[][2] = {
151 { 0x12, 0x32 }, /* ALC Control 3 */ 151 { 0x12, 0x32 }, /* ALC Control 3 */
152 { 0x13, 0x00 }, /* Noise gate control */ 152 { 0x13, 0x00 }, /* Noise gate control */
153 { 0x14, 0xa6 }, /* Limiter control */ 153 { 0x14, 0xa6 }, /* Limiter control */
154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for Audigy 2 ZS Notebook */ 154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
155}; 155};
156 156
157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) 157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
158{ 158{
159 unsigned int silent_page; 159 unsigned int silent_page;
@@ -161,8 +161,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
161 u32 tmp; 161 u32 tmp;
162 162
163 /* disable audio and lock cache */ 163 /* disable audio and lock cache */
164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
165 emu->port + HCFG); 165 HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
166 166
167 /* reset recording buffers */ 167 /* reset recording buffers */
168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE); 168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
@@ -179,7 +179,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); 179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); 180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
181 181
182 if (emu->audigy){ 182 if (emu->audigy) {
183 /* set SPDIF bypass mode */ 183 /* set SPDIF bypass mode */
184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT); 184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
185 /* enable rear left + rear right AC97 slots */ 185 /* enable rear left + rear right AC97 slots */
@@ -197,12 +197,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
197 197
198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
199 /* Hacks for Alice3 to work independent of haP16V driver */ 199 /* Hacks for Alice3 to work independent of haP16V driver */
200 //Setup SRCMulti_I2S SamplingRate 200 /* Setup SRCMulti_I2S SamplingRate */
201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
202 tmp &= 0xfffff1ff; 202 tmp &= 0xfffff1ff;
203 tmp |= (0x2<<9); 203 tmp |= (0x2<<9);
204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); 204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
205 205
206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ 206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14); 207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
208 /* Setup SRCMulti Input Audio Enable */ 208 /* Setup SRCMulti Input Audio Enable */
@@ -217,7 +217,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ 217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
218 /* Hacks for Alice3 to work independent of haP16V driver */ 218 /* Hacks for Alice3 to work independent of haP16V driver */
219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); 219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
220 //Setup SRCMulti_I2S SamplingRate 220 /* Setup SRCMulti_I2S SamplingRate */
221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
222 tmp &= 0xfffff1ff; 222 tmp &= 0xfffff1ff;
223 tmp |= (0x2<<9); 223 tmp |= (0x2<<9);
@@ -270,13 +270,13 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
270 size = ARRAY_SIZE(i2c_adc_init); 270 size = ARRAY_SIZE(i2c_adc_init);
271 for (n = 0; n < size; n++) 271 for (n = 0; n < size; n++)
272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); 272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
273 for (n=0; n < 4; n++) { 273 for (n = 0; n < 4; n++) {
274 emu->i2c_capture_volume[n][0]= 0xcf; 274 emu->i2c_capture_volume[n][0] = 0xcf;
275 emu->i2c_capture_volume[n][1]= 0xcf; 275 emu->i2c_capture_volume[n][1] = 0xcf;
276 } 276 }
277 } 277 }
278 278
279 279
280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
@@ -313,7 +313,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
313 (emu->model == 0x21 && emu->revision < 6)) 313 (emu->model == 0x21 && emu->revision < 6))
314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG); 314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
315 else 315 else
316 // With on-chip joystick 316 /* With on-chip joystick */
317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); 317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
318 318
319 if (enable_ir) { /* enable IR for SB Live */ 319 if (enable_ir) { /* enable IR for SB Live */
@@ -335,9 +335,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG); 335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
336 udelay(100); 336 udelay(100);
337 outl(reg, emu->port + HCFG); 337 outl(reg, emu->port + HCFG);
338 } 338 }
339 } 339 }
340 340
341 if (emu->card_capabilities->emu_model) { 341 if (emu->card_capabilities->emu_model) {
342 ; /* Disable all access to A_IOCFG for the emu1010 */ 342 ; /* Disable all access to A_IOCFG for the emu1010 */
343 } else if (emu->card_capabilities->i2c_adc) { 343 } else if (emu->card_capabilities->i2c_adc) {
@@ -364,7 +364,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ 364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
365 } else if (emu->audigy) { 365 } else if (emu->audigy) {
366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); 366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
367 367
368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
369 /* Unmute Analog now. Set GPO6 to 1 for Apollo. 369 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
370 * This has to be done after init ALice3 I2SOut beyond 48KHz. 370 * This has to be done after init ALice3 I2SOut beyond 48KHz.
@@ -378,12 +378,12 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); 378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
379 } 379 }
380 } 380 }
381 381
382#if 0 382#if 0
383 { 383 {
384 unsigned int tmp; 384 unsigned int tmp;
385 /* FIXME: the following routine disables LiveDrive-II !! */ 385 /* FIXME: the following routine disables LiveDrive-II !! */
386 // TOSLink detection 386 /* TOSLink detection */
387 emu->tos_link = 0; 387 emu->tos_link = 0;
388 tmp = inl(emu->port + HCFG); 388 tmp = inl(emu->port + HCFG);
389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) { 389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
@@ -400,7 +400,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE); 400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
401} 401}
402 402
403int snd_emu10k1_done(struct snd_emu10k1 * emu) 403int snd_emu10k1_done(struct snd_emu10k1 *emu)
404{ 404{
405 int ch; 405 int ch;
406 406
@@ -495,7 +495,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
495 495
496#define EC_LAST_PROMFILE_ADDR 0x2f 496#define EC_LAST_PROMFILE_ADDR 0x2f
497 497
498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The 498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
499 * can be up to 30 characters in length 499 * can be up to 30 characters in length
500 * and is stored as a NULL-terminated 500 * and is stored as a NULL-terminated
501 * ASCII string. Any unused bytes must be 501 * ASCII string. Any unused bytes must be
@@ -503,8 +503,8 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */ 503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
504 504
505 505
506/* Most of this stuff is pretty self-evident. According to the hardware 506/* Most of this stuff is pretty self-evident. According to the hardware
507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC 507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
508 * offset problem. Weird. 508 * offset problem. Weird.
509 */ 509 */
510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \ 510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
@@ -523,7 +523,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
523 * register. 523 * register.
524 */ 524 */
525 525
526static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value) 526static void snd_emu10k1_ecard_write(struct snd_emu10k1 *emu, unsigned int value)
527{ 527{
528 unsigned short count; 528 unsigned short count;
529 unsigned int data; 529 unsigned int data;
@@ -561,7 +561,7 @@ static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value
561 * channel. 561 * channel.
562 */ 562 */
563 563
564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu, 564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 *emu,
565 unsigned short gain) 565 unsigned short gain)
566{ 566{
567 unsigned int bit; 567 unsigned int bit;
@@ -574,7 +574,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
574 574
575 for (bit = (1 << 15); bit; bit >>= 1) { 575 for (bit = (1 << 15); bit; bit >>= 1) {
576 unsigned int value; 576 unsigned int value;
577 577
578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA); 578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
579 579
580 if (gain & bit) 580 if (gain & bit)
@@ -589,7 +589,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl); 589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
590} 590}
591 591
592static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu) 592static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu)
593{ 593{
594 unsigned int hc_value; 594 unsigned int hc_value;
595 595
@@ -598,7 +598,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) | 598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL); 599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
600 600
601 /* Step 0: Set the codec type in the hardware control register 601 /* Step 0: Set the codec type in the hardware control register
602 * and enable audio output */ 602 * and enable audio output */
603 hc_value = inl(emu->port + HCFG); 603 hc_value = inl(emu->port + HCFG);
604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG); 604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
@@ -629,7 +629,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
629 return 0; 629 return 0;
630} 630}
631 631
632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) 632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
633{ 633{
634 unsigned long special_port; 634 unsigned long special_port;
635 unsigned int value; 635 unsigned int value;
@@ -656,7 +656,7 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
656 return 0; 656 return 0;
657} 657}
658 658
659static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename) 659static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
660{ 660{
661 int err; 661 int err;
662 int n, i; 662 int n, i;
@@ -666,11 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
666 unsigned long flags; 666 unsigned long flags;
667 const struct firmware *fw_entry; 667 const struct firmware *fw_entry;
668 668
669 if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { 669 err = request_firmware(&fw_entry, filename, &emu->pci->dev);
670 snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); 670 if (err != 0) {
671 snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
671 return err; 672 return err;
672 } 673 }
673 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); 674 snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
674 675
675 /* The FPGA is a Xilinx Spartan IIE XC2S50E */ 676 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
676 /* GPIO7 -> FPGA PGMN 677 /* GPIO7 -> FPGA PGMN
@@ -685,13 +686,13 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
685 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ 686 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
686 write_post = inl(emu->port + A_IOCFG); 687 write_post = inl(emu->port + A_IOCFG);
687 udelay(100); /* Allow FPGA memory to clean */ 688 udelay(100); /* Allow FPGA memory to clean */
688 for(n = 0; n < fw_entry->size; n++) { 689 for (n = 0; n < fw_entry->size; n++) {
689 value=fw_entry->data[n]; 690 value = fw_entry->data[n];
690 for(i = 0; i < 8; i++) { 691 for (i = 0; i < 8; i++) {
691 reg = 0x80; 692 reg = 0x80;
692 if (value & 0x1) 693 if (value & 0x1)
693 reg = reg | 0x20; 694 reg = reg | 0x20;
694 value = value >> 1; 695 value = value >> 1;
695 outl(reg, emu->port + A_IOCFG); 696 outl(reg, emu->port + A_IOCFG);
696 write_post = inl(emu->port + A_IOCFG); 697 write_post = inl(emu->port + A_IOCFG);
697 outl(reg | 0x40, emu->port + A_IOCFG); 698 outl(reg | 0x40, emu->port + A_IOCFG);
@@ -703,14 +704,14 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
703 write_post = inl(emu->port + A_IOCFG); 704 write_post = inl(emu->port + A_IOCFG);
704 spin_unlock_irqrestore(&emu->emu_lock, flags); 705 spin_unlock_irqrestore(&emu->emu_lock, flags);
705 706
706 release_firmware(fw_entry); 707 release_firmware(fw_entry);
707 return 0; 708 return 0;
708} 709}
709 710
710static int emu1010_firmware_thread(void *data) 711static int emu1010_firmware_thread(void *data)
711{ 712{
712 struct snd_emu10k1 * emu = data; 713 struct snd_emu10k1 *emu = data;
713 int tmp,tmp2; 714 int tmp, tmp2;
714 int reg; 715 int reg;
715 int err; 716 int err;
716 717
@@ -719,50 +720,50 @@ static int emu1010_firmware_thread(void *data)
719 msleep_interruptible(1000); 720 msleep_interruptible(1000);
720 if (kthread_should_stop()) 721 if (kthread_should_stop())
721 break; 722 break;
722 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ 723 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
723 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */ 724 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
724 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { 725 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
725 /* Audio Dock attached */ 726 /* Audio Dock attached */
726 /* Return to Audio Dock programming mode */ 727 /* Return to Audio Dock programming mode */
727 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); 728 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
728 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); 729 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
729 if (emu->card_capabilities->emu_model == 730 if (emu->card_capabilities->emu_model ==
730 EMU_MODEL_EMU1010) { 731 EMU_MODEL_EMU1010) {
731 if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { 732 err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
733 if (err != 0)
732 continue; 734 continue;
733 }
734 } else if (emu->card_capabilities->emu_model == 735 } else if (emu->card_capabilities->emu_model ==
735 EMU_MODEL_EMU1010B) { 736 EMU_MODEL_EMU1010B) {
736 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 737 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
738 if (err != 0)
737 continue; 739 continue;
738 }
739 } else if (emu->card_capabilities->emu_model == 740 } else if (emu->card_capabilities->emu_model ==
740 EMU_MODEL_EMU1616) { 741 EMU_MODEL_EMU1616) {
741 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 742 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
743 if (err != 0)
742 continue; 744 continue;
743 }
744 } 745 }
745 746
746 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); 747 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
747 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg ); 748 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
748 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); 749 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", reg);
749 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 750 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
750 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 751 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
751 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); 752 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", reg);
752 if ((reg & 0x1f) != 0x15) { 753 if ((reg & 0x1f) != 0x15) {
753 /* FPGA failed to be programmed */ 754 /* FPGA failed to be programmed */
754 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); 755 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", reg);
755 continue; 756 continue;
756 } 757 }
757 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); 758 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
758 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); 759 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
759 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); 760 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
760 snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); 761 snd_printk("Audio Dock ver:%d.%d\n", tmp, tmp2);
761 /* Sync clocking between 1010 and Dock */ 762 /* Sync clocking between 1010 and Dock */
762 /* Allow DLL to settle */ 763 /* Allow DLL to settle */
763 msleep(10); 764 msleep(10);
764 /* Unmute all. Default is muted after a firmware load */ 765 /* Unmute all. Default is muted after a firmware load */
765 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); 766 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
766 } 767 }
767 } 768 }
768 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n"); 769 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n");
@@ -800,10 +801,10 @@ static int emu1010_firmware_thread(void *data)
800 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops 801 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
801 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops 802 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
802 */ 803 */
803static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) 804static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
804{ 805{
805 unsigned int i; 806 unsigned int i;
806 int tmp,tmp2; 807 int tmp, tmp2;
807 int reg; 808 int reg;
808 int err; 809 int err;
809 const char *filename = NULL; 810 const char *filename = NULL;
@@ -818,7 +819,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
818 * Lock Tank Memory Cache, 819 * Lock Tank Memory Cache,
819 * Mute all codecs. 820 * Mute all codecs.
820 */ 821 */
821 outl(0x0005a004, emu->port + HCFG); 822 outl(0x0005a004, emu->port + HCFG);
822 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, 823 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
823 * Mute all codecs. 824 * Mute all codecs.
824 */ 825 */
@@ -829,25 +830,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
829 outl(0x0005a000, emu->port + HCFG); 830 outl(0x0005a000, emu->port + HCFG);
830 831
831 /* Disable 48Volt power to Audio Dock */ 832 /* Disable 48Volt power to Audio Dock */
832 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 833 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
833 834
834 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ 835 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
835 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 836 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
836 snd_printdd("reg1=0x%x\n",reg); 837 snd_printdd("reg1 = 0x%x\n", reg);
837 if ((reg & 0x3f) == 0x15) { 838 if ((reg & 0x3f) == 0x15) {
838 /* FPGA netlist already present so clear it */ 839 /* FPGA netlist already present so clear it */
839 /* Return to programming mode */ 840 /* Return to programming mode */
840 841
841 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 ); 842 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02);
842 } 843 }
843 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 844 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
844 snd_printdd("reg2=0x%x\n",reg); 845 snd_printdd("reg2 = 0x%x\n", reg);
845 if ((reg & 0x3f) == 0x15) { 846 if ((reg & 0x3f) == 0x15) {
846 /* FPGA failed to return to programming mode */ 847 /* FPGA failed to return to programming mode */
847 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); 848 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
848 return -ENODEV; 849 return -ENODEV;
849 } 850 }
850 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); 851 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);
851 switch (emu->card_capabilities->emu_model) { 852 switch (emu->card_capabilities->emu_model) {
852 case EMU_MODEL_EMU1010: 853 case EMU_MODEL_EMU1010:
853 filename = HANA_FILENAME; 854 filename = HANA_FILENAME;
@@ -876,25 +877,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
876 } 877 }
877 878
878 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 879 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
879 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 880 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
880 if ((reg & 0x3f) != 0x15) { 881 if ((reg & 0x3f) != 0x15) {
881 /* FPGA failed to be programmed */ 882 /* FPGA failed to be programmed */
882 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); 883 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n", reg);
883 return -ENODEV; 884 return -ENODEV;
884 } 885 }
885 886
886 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); 887 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
887 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp ); 888 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp);
888 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 ); 889 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2);
889 snd_printk("Hana ver:%d.%d\n",tmp ,tmp2); 890 snd_printk("emu1010: Hana version: %d.%d\n", tmp, tmp2);
890 /* Enable 48Volt power to Audio Dock */ 891 /* Enable 48Volt power to Audio Dock */
891 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON ); 892 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON);
892 893
893 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 894 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
894 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 895 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
895 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 896 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
896 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 897 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
897 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); 898 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp);
898 /* Optical -> ADAT I/O */ 899 /* Optical -> ADAT I/O */
899 /* 0 : SPDIF 900 /* 0 : SPDIF
900 * 1 : ADAT 901 * 1 : ADAT
@@ -904,41 +905,42 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
904 tmp = 0; 905 tmp = 0;
905 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | 906 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
906 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); 907 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
907 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp ); 908 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
908 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp ); 909 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
909 /* Set no attenuation on Audio Dock pads. */ 910 /* Set no attenuation on Audio Dock pads. */
910 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 ); 911 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
911 emu->emu1010.adc_pads = 0x00; 912 emu->emu1010.adc_pads = 0x00;
912 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 913 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
913 /* Unmute Audio dock DACs, Headphone source DAC-4. */ 914 /* Unmute Audio dock DACs, Headphone source DAC-4. */
914 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 916 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
916 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp ); 917 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp);
917 /* DAC PADs. */ 918 /* DAC PADs. */
918 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f ); 919 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
919 emu->emu1010.dac_pads = 0x0f; 920 emu->emu1010.dac_pads = 0x0f;
920 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 921 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
921 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 922 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
922 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 923 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
923 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ 924 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
924 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); 925 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
925 /* MIDI routing */ 926 /* MIDI routing */
926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); 927 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
927 /* Unknown. */ 928 /* Unknown. */
928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); 929 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
929 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */ 930 /* IRQ Enable: Alll on */
931 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
930 /* IRQ Enable: All off */ 932 /* IRQ Enable: All off */
931 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 ); 933 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
932 934
933 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 935 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
934 snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg); 936 snd_printk(KERN_INFO "emu1010: Card options3 = 0x%x\n", reg);
935 /* Default WCLK set to 48kHz. */ 937 /* Default WCLK set to 48kHz. */
936 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 ); 938 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
937 /* Word Clock source, Internal 48kHz x1 */ 939 /* Word Clock source, Internal 48kHz x1 */
938 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 940 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
939 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 941 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
940 /* Audio Dock LEDs. */ 942 /* Audio Dock LEDs. */
941 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 943 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
942 944
943#if 0 945#if 0
944 /* For 96kHz */ 946 /* For 96kHz */
@@ -992,7 +994,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
992 * Defaults only, users will set their own values anyways, let's 994 * Defaults only, users will set their own values anyways, let's
993 * just copy/paste. 995 * just copy/paste.
994 */ 996 */
995 997
996 snd_emu1010_fpga_link_dst_src_write(emu, 998 snd_emu1010_fpga_link_dst_src_write(emu,
997 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); 999 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
998 snd_emu1010_fpga_link_dst_src_write(emu, 1000 snd_emu1010_fpga_link_dst_src_write(emu,
@@ -1037,19 +1039,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1037 snd_emu1010_fpga_link_dst_src_write(emu, 1039 snd_emu1010_fpga_link_dst_src_write(emu,
1038 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); 1040 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
1039#endif 1041#endif
1040 for (i = 0;i < 0x20; i++ ) { 1042 for (i = 0; i < 0x20; i++) {
1041 /* AudioDock Elink <- Silence */ 1043 /* AudioDock Elink <- Silence */
1042 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE); 1044 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100 + i, EMU_SRC_SILENCE);
1043 } 1045 }
1044 for (i = 0;i < 4; i++) { 1046 for (i = 0; i < 4; i++) {
1045 /* Hana SPDIF Out <- Silence */ 1047 /* Hana SPDIF Out <- Silence */
1046 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE); 1048 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200 + i, EMU_SRC_SILENCE);
1047 } 1049 }
1048 for (i = 0;i < 7; i++) { 1050 for (i = 0; i < 7; i++) {
1049 /* Hamoa DAC <- Silence */ 1051 /* Hamoa DAC <- Silence */
1050 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE); 1052 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300 + i, EMU_SRC_SILENCE);
1051 } 1053 }
1052 for (i = 0;i < 7; i++) { 1054 for (i = 0; i < 7; i++) {
1053 /* Hana ADAT Out <- Silence */ 1055 /* Hana ADAT Out <- Silence */
1054 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); 1056 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
1055 } 1057 }
@@ -1065,30 +1067,30 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1065 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); 1067 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
1066 snd_emu1010_fpga_link_dst_src_write(emu, 1068 snd_emu1010_fpga_link_dst_src_write(emu,
1067 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); 1069 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
1068 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all 1070 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
1071
1072 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1069 1073
1070 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
1071
1072 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1074 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1073 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1075 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1074 * Mute all codecs. 1076 * Mute all codecs.
1075 */ 1077 */
1076 outl(0x0000a000, emu->port + HCFG); 1078 outl(0x0000a000, emu->port + HCFG);
1077 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1079 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1078 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1080 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1079 * Un-Mute all codecs. 1081 * Un-Mute all codecs.
1080 */ 1082 */
1081 outl(0x0000a001, emu->port + HCFG); 1083 outl(0x0000a001, emu->port + HCFG);
1082 1084
1083 /* Initial boot complete. Now patches */ 1085 /* Initial boot complete. Now patches */
1084 1086
1085 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); 1087 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1086 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1087 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1090 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1091 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1090 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 1092 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
1091 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ 1093 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
1092 1094
1093 /* Start Micro/Audio Dock firmware loader thread */ 1095 /* Start Micro/Audio Dock firmware loader thread */
1094 if (!emu->emu1010.firmware_thread) { 1096 if (!emu->emu1010.firmware_thread) {
@@ -1218,20 +1220,20 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1218 emu->emu1010.output_source[23] = 28; 1220 emu->emu1010.output_source[23] = 28;
1219 } 1221 }
1220 /* TEMP: Select SPDIF in/out */ 1222 /* TEMP: Select SPDIF in/out */
1221 //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ 1223 /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */
1222 1224
1223 /* TEMP: Select 48kHz SPDIF out */ 1225 /* TEMP: Select 48kHz SPDIF out */
1224 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ 1226 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
1225 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ 1227 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
1226 /* Word Clock source, Internal 48kHz x1 */ 1228 /* Word Clock source, Internal 48kHz x1 */
1227 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 1229 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
1228 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 1230 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
1229 emu->emu1010.internal_clock = 1; /* 48000 */ 1231 emu->emu1010.internal_clock = 1; /* 48000 */
1230 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ 1232 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */
1231 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ 1233 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
1232 //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ 1234 /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */
1233 //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */ 1235 /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */
1234 //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */ 1236 /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
1235 1237
1236 return 0; 1238 return 0;
1237} 1239}
@@ -1247,13 +1249,13 @@ static void free_pm_buffer(struct snd_emu10k1 *emu);
1247static int snd_emu10k1_free(struct snd_emu10k1 *emu) 1249static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1248{ 1250{
1249 if (emu->port) { /* avoid access to already used hardware */ 1251 if (emu->port) { /* avoid access to already used hardware */
1250 snd_emu10k1_fx8010_tram_setup(emu, 0); 1252 snd_emu10k1_fx8010_tram_setup(emu, 0);
1251 snd_emu10k1_done(emu); 1253 snd_emu10k1_done(emu);
1252 snd_emu10k1_free_efx(emu); 1254 snd_emu10k1_free_efx(emu);
1253 } 1255 }
1254 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { 1256 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
1255 /* Disable 48Volt power to Audio Dock */ 1257 /* Disable 48Volt power to Audio Dock */
1256 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 1258 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
1257 } 1259 }
1258 if (emu->emu1010.firmware_thread) 1260 if (emu->emu1010.firmware_thread)
1259 kthread_stop(emu->emu1010.firmware_thread); 1261 kthread_stop(emu->emu1010.firmware_thread);
@@ -1278,7 +1280,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1278#endif 1280#endif
1279 if (emu->port) 1281 if (emu->port)
1280 pci_release_regions(emu->pci); 1282 pci_release_regions(emu->pci);
1281 if (emu->card_capabilities->ca0151_chip) /* P16V */ 1283 if (emu->card_capabilities->ca0151_chip) /* P16V */
1282 snd_p16v_free(emu); 1284 snd_p16v_free(emu);
1283 pci_disable_device(emu->pci); 1285 pci_disable_device(emu->pci);
1284 kfree(emu); 1286 kfree(emu);
@@ -1292,21 +1294,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
1292} 1294}
1293 1295
1294static struct snd_emu_chip_details emu_chip_details[] = { 1296static struct snd_emu_chip_details emu_chip_details[] = {
1295 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
1296 /* Tested by James@superbug.co.uk 3rd July 2005 */
1297 /* DSP: CA0108-IAT
1298 * DAC: CS4382-KQ
1299 * ADC: Philips 1361T
1300 * AC97: STAC9750
1301 * CA0151: None
1302 */
1303 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1304 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
1305 .id = "Audigy2",
1306 .emu10k2_chip = 1,
1307 .ca0108_chip = 1,
1308 .spk71 = 1,
1309 .ac97_chip = 1} ,
1310 /* Audigy4 (Not PRO) SB0610 */ 1297 /* Audigy4 (Not PRO) SB0610 */
1311 /* Tested by James@superbug.co.uk 4th April 2006 */ 1298 /* Tested by James@superbug.co.uk 4th April 2006 */
1312 /* A_IOCFG bits 1299 /* A_IOCFG bits
@@ -1346,20 +1333,37 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1346 * CA0151: None 1333 * CA0151: None
1347 */ 1334 */
1348 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, 1335 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
1349 .driver = "Audigy2", .name = "Audigy 4 [SB0610]", 1336 .driver = "Audigy2", .name = "SB Audigy 4 [SB0610]",
1350 .id = "Audigy2", 1337 .id = "Audigy2",
1351 .emu10k2_chip = 1, 1338 .emu10k2_chip = 1,
1352 .ca0108_chip = 1, 1339 .ca0108_chip = 1,
1353 .spk71 = 1, 1340 .spk71 = 1,
1354 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1341 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1355 .ac97_chip = 1} , 1342 .ac97_chip = 1} ,
1343 /* Audigy 2 Value AC3 out does not work yet.
1344 * Need to find out how to turn off interpolators.
1345 */
1346 /* Tested by James@superbug.co.uk 3rd July 2005 */
1347 /* DSP: CA0108-IAT
1348 * DAC: CS4382-KQ
1349 * ADC: Philips 1361T
1350 * AC97: STAC9750
1351 * CA0151: None
1352 */
1353 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1354 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
1355 .id = "Audigy2",
1356 .emu10k2_chip = 1,
1357 .ca0108_chip = 1,
1358 .spk71 = 1,
1359 .ac97_chip = 1} ,
1356 /* Audigy 2 ZS Notebook Cardbus card.*/ 1360 /* Audigy 2 ZS Notebook Cardbus card.*/
1357 /* Tested by James@superbug.co.uk 6th November 2006 */ 1361 /* Tested by James@superbug.co.uk 6th November 2006 */
1358 /* Audio output 7.1/Headphones working. 1362 /* Audio output 7.1/Headphones working.
1359 * Digital output working. (AC3 not checked, only PCM) 1363 * Digital output working. (AC3 not checked, only PCM)
1360 * Audio Mic/Line inputs working. 1364 * Audio Mic/Line inputs working.
1361 * Digital input not tested. 1365 * Digital input not tested.
1362 */ 1366 */
1363 /* DSP: Tina2 1367 /* DSP: Tina2
1364 * DAC: Wolfson WM8768/WM8568 1368 * DAC: Wolfson WM8768/WM8568
1365 * ADC: Wolfson WM8775 1369 * ADC: Wolfson WM8775
@@ -1386,7 +1390,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1386 * 1390 *
1387 */ 1391 */
1388 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, 1392 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
1389 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 1393 .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
1390 .id = "Audigy2", 1394 .id = "Audigy2",
1391 .emu10k2_chip = 1, 1395 .emu10k2_chip = 1,
1392 .ca0108_chip = 1, 1396 .ca0108_chip = 1,
@@ -1396,7 +1400,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1396 .spk71 = 1} , 1400 .spk71 = 1} ,
1397 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1401 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1398 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, 1402 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
1399 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", 1403 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
1400 .id = "EMU1010", 1404 .id = "EMU1010",
1401 .emu10k2_chip = 1, 1405 .emu10k2_chip = 1,
1402 .ca0108_chip = 1, 1406 .ca0108_chip = 1,
@@ -1404,47 +1408,49 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1404 .spk71 = 1 , 1408 .spk71 = 1 ,
1405 .emu_model = EMU_MODEL_EMU1616}, 1409 .emu_model = EMU_MODEL_EMU1616},
1406 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1410 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1411 /* This is MAEM8960, 0202 is MAEM 8980 */
1407 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, 1412 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
1408 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", 1413 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
1409 .id = "EMU1010", 1414 .id = "EMU1010",
1410 .emu10k2_chip = 1, 1415 .emu10k2_chip = 1,
1411 .ca0108_chip = 1, 1416 .ca0108_chip = 1,
1412 .spk71 = 1, 1417 .spk71 = 1,
1413 .emu_model = EMU_MODEL_EMU1010B}, 1418 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
1414 /* Tested by James@superbug.co.uk 8th July 2005. */ 1419 /* Tested by James@superbug.co.uk 8th July 2005. */
1420 /* This is MAEM8810, 0202 is MAEM8820 */
1415 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, 1421 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
1416 .driver = "Audigy2", .name = "E-mu 1010 [4001]", 1422 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
1417 .id = "EMU1010", 1423 .id = "EMU1010",
1418 .emu10k2_chip = 1, 1424 .emu10k2_chip = 1,
1419 .ca0102_chip = 1, 1425 .ca0102_chip = 1,
1420 .spk71 = 1, 1426 .spk71 = 1,
1421 .emu_model = EMU_MODEL_EMU1010}, /* Emu 1010 */ 1427 .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */
1422 /* EMU0404b */ 1428 /* EMU0404b */
1423 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102, 1429 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
1424 .driver = "Audigy2", .name = "E-mu 0404b [4002]", 1430 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
1425 .id = "EMU0404", 1431 .id = "EMU0404",
1426 .emu10k2_chip = 1, 1432 .emu10k2_chip = 1,
1427 .ca0108_chip = 1, 1433 .ca0108_chip = 1,
1428 .spk71 = 1, 1434 .spk71 = 1,
1429 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1435 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
1430 /* Tested by James@superbug.co.uk 20-3-2007. */ 1436 /* Tested by James@superbug.co.uk 20-3-2007. */
1431 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102, 1437 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
1432 .driver = "Audigy2", .name = "E-mu 0404 [4002]", 1438 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
1433 .id = "EMU0404", 1439 .id = "EMU0404",
1434 .emu10k2_chip = 1, 1440 .emu10k2_chip = 1,
1435 .ca0102_chip = 1, 1441 .ca0102_chip = 1,
1436 .spk71 = 1, 1442 .spk71 = 1,
1437 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1443 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1438 /* Audigy4 (Not PRO) SB0610 */ 1444 /* Note that all E-mu cards require kernel 2.6 or newer. */
1439 {.vendor = 0x1102, .device = 0x0008, 1445 {.vendor = 0x1102, .device = 0x0008,
1440 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 1446 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
1441 .id = "Audigy2", 1447 .id = "Audigy2",
1442 .emu10k2_chip = 1, 1448 .emu10k2_chip = 1,
1443 .ca0108_chip = 1, 1449 .ca0108_chip = 1,
1444 .ac97_chip = 1} , 1450 .ac97_chip = 1} ,
1445 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1451 /* Tested by James@superbug.co.uk 3rd July 2005 */
1446 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, 1452 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
1447 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 1453 .driver = "Audigy2", .name = "SB Audigy 4 PRO [SB0380]",
1448 .id = "Audigy2", 1454 .id = "Audigy2",
1449 .emu10k2_chip = 1, 1455 .emu10k2_chip = 1,
1450 .ca0102_chip = 1, 1456 .ca0102_chip = 1,
@@ -1457,31 +1463,34 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1457 * Just like 0x20021102 1463 * Just like 0x20021102
1458 */ 1464 */
1459 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102, 1465 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
1460 .driver = "Audigy2", .name = "Audigy 2 [SB0350b]", 1466 .driver = "Audigy2", .name = "SB Audigy 2 [SB0350b]",
1461 .id = "Audigy2", 1467 .id = "Audigy2",
1462 .emu10k2_chip = 1, 1468 .emu10k2_chip = 1,
1463 .ca0102_chip = 1, 1469 .ca0102_chip = 1,
1464 .ca0151_chip = 1, 1470 .ca0151_chip = 1,
1465 .spk71 = 1, 1471 .spk71 = 1,
1466 .spdif_bug = 1, 1472 .spdif_bug = 1,
1473 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1467 .ac97_chip = 1} , 1474 .ac97_chip = 1} ,
1468 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, 1475 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
1469 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 1476 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]",
1470 .id = "Audigy2", 1477 .id = "Audigy2",
1471 .emu10k2_chip = 1, 1478 .emu10k2_chip = 1,
1472 .ca0102_chip = 1, 1479 .ca0102_chip = 1,
1473 .ca0151_chip = 1, 1480 .ca0151_chip = 1,
1474 .spk71 = 1, 1481 .spk71 = 1,
1475 .spdif_bug = 1, 1482 .spdif_bug = 1,
1483 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1476 .ac97_chip = 1} , 1484 .ac97_chip = 1} ,
1477 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, 1485 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
1478 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", 1486 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0360]",
1479 .id = "Audigy2", 1487 .id = "Audigy2",
1480 .emu10k2_chip = 1, 1488 .emu10k2_chip = 1,
1481 .ca0102_chip = 1, 1489 .ca0102_chip = 1,
1482 .ca0151_chip = 1, 1490 .ca0151_chip = 1,
1483 .spk71 = 1, 1491 .spk71 = 1,
1484 .spdif_bug = 1, 1492 .spdif_bug = 1,
1493 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1485 .ac97_chip = 1} , 1494 .ac97_chip = 1} ,
1486 /* Audigy 2 */ 1495 /* Audigy 2 */
1487 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1496 /* Tested by James@superbug.co.uk 3rd July 2005 */
@@ -1492,7 +1501,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1492 * CA0151: Yes 1501 * CA0151: Yes
1493 */ 1502 */
1494 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, 1503 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
1495 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 1504 .driver = "Audigy2", .name = "SB Audigy 2 [SB0240]",
1496 .id = "Audigy2", 1505 .id = "Audigy2",
1497 .emu10k2_chip = 1, 1506 .emu10k2_chip = 1,
1498 .ca0102_chip = 1, 1507 .ca0102_chip = 1,
@@ -1502,7 +1511,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1502 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1511 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1503 .ac97_chip = 1} , 1512 .ac97_chip = 1} ,
1504 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, 1513 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
1505 .driver = "Audigy2", .name = "Audigy 2 EX [1005]", 1514 .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
1506 .id = "Audigy2", 1515 .id = "Audigy2",
1507 .emu10k2_chip = 1, 1516 .emu10k2_chip = 1,
1508 .ca0102_chip = 1, 1517 .ca0102_chip = 1,
@@ -1512,7 +1521,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1512 /* Dell OEM/Creative Labs Audigy 2 ZS */ 1521 /* Dell OEM/Creative Labs Audigy 2 ZS */
1513 /* See ALSA bug#1365 */ 1522 /* See ALSA bug#1365 */
1514 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102, 1523 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102,
1515 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0353]", 1524 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0353]",
1516 .id = "Audigy2", 1525 .id = "Audigy2",
1517 .emu10k2_chip = 1, 1526 .emu10k2_chip = 1,
1518 .ca0102_chip = 1, 1527 .ca0102_chip = 1,
@@ -1521,7 +1530,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1521 .spdif_bug = 1, 1530 .spdif_bug = 1,
1522 .ac97_chip = 1} , 1531 .ac97_chip = 1} ,
1523 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, 1532 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
1524 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 1533 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
1525 .id = "Audigy2", 1534 .id = "Audigy2",
1526 .emu10k2_chip = 1, 1535 .emu10k2_chip = 1,
1527 .ca0102_chip = 1, 1536 .ca0102_chip = 1,
@@ -1532,7 +1541,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1532 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ 1541 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
1533 .ac97_chip = 1} , 1542 .ac97_chip = 1} ,
1534 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, 1543 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
1535 .driver = "Audigy2", .name = "Audigy 2 [Unknown]", 1544 .driver = "Audigy2", .name = "SB Audigy 2 [Unknown]",
1536 .id = "Audigy2", 1545 .id = "Audigy2",
1537 .emu10k2_chip = 1, 1546 .emu10k2_chip = 1,
1538 .ca0102_chip = 1, 1547 .ca0102_chip = 1,
@@ -1540,78 +1549,79 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1540 .spdif_bug = 1, 1549 .spdif_bug = 1,
1541 .ac97_chip = 1} , 1550 .ac97_chip = 1} ,
1542 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, 1551 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
1543 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1552 .driver = "Audigy", .name = "SB Audigy 1 [SB0092]",
1544 .id = "Audigy", 1553 .id = "Audigy",
1545 .emu10k2_chip = 1, 1554 .emu10k2_chip = 1,
1546 .ca0102_chip = 1, 1555 .ca0102_chip = 1,
1547 .ac97_chip = 1} , 1556 .ac97_chip = 1} ,
1548 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, 1557 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
1549 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", 1558 .driver = "Audigy", .name = "SB Audigy 1 ES [SB0160]",
1550 .id = "Audigy", 1559 .id = "Audigy",
1551 .emu10k2_chip = 1, 1560 .emu10k2_chip = 1,
1552 .ca0102_chip = 1, 1561 .ca0102_chip = 1,
1553 .spdif_bug = 1, 1562 .spdif_bug = 1,
1554 .ac97_chip = 1} , 1563 .ac97_chip = 1} ,
1555 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, 1564 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
1556 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1565 .driver = "Audigy", .name = "SB Audigy 1 [SB0090]",
1557 .id = "Audigy", 1566 .id = "Audigy",
1558 .emu10k2_chip = 1, 1567 .emu10k2_chip = 1,
1559 .ca0102_chip = 1, 1568 .ca0102_chip = 1,
1560 .ac97_chip = 1} , 1569 .ac97_chip = 1} ,
1561 {.vendor = 0x1102, .device = 0x0004, 1570 {.vendor = 0x1102, .device = 0x0004,
1562 .driver = "Audigy", .name = "Audigy 1 [Unknown]", 1571 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
1563 .id = "Audigy", 1572 .id = "Audigy",
1564 .emu10k2_chip = 1, 1573 .emu10k2_chip = 1,
1565 .ca0102_chip = 1, 1574 .ca0102_chip = 1,
1566 .ac97_chip = 1} , 1575 .ac97_chip = 1} ,
1567 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, 1576 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1568 .driver = "EMU10K1", .name = "SBLive! [SB0105]", 1577 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1569 .id = "Live", 1578 .id = "Live",
1570 .emu10k1_chip = 1, 1579 .emu10k1_chip = 1,
1571 .ac97_chip = 1, 1580 .ac97_chip = 1,
1572 .sblive51 = 1} , 1581 .sblive51 = 1} ,
1573 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, 1582 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806b1102,
1574 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", 1583 .driver = "EMU10K1", .name = "SB Live! [SB0105]",
1584 .id = "Live",
1585 .emu10k1_chip = 1,
1586 .ac97_chip = 1,
1587 .sblive51 = 1} ,
1588 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806a1102,
1589 .driver = "EMU10K1", .name = "SB Live! Value [SB0103]",
1575 .id = "Live", 1590 .id = "Live",
1576 .emu10k1_chip = 1, 1591 .emu10k1_chip = 1,
1577 .ac97_chip = 1, 1592 .ac97_chip = 1,
1578 .sblive51 = 1} , 1593 .sblive51 = 1} ,
1579 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, 1594 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
1580 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", 1595 .driver = "EMU10K1", .name = "SB Live! Value [SB0101]",
1581 .id = "Live", 1596 .id = "Live",
1582 .emu10k1_chip = 1, 1597 .emu10k1_chip = 1,
1583 .ac97_chip = 1, 1598 .ac97_chip = 1,
1584 .sblive51 = 1} , 1599 .sblive51 = 1} ,
1585 /* Tested by ALSA bug#1680 26th December 2005 */ 1600 /* Tested by ALSA bug#1680 26th December 2005 */
1586 /* note: It really has SB0220 written on the card. */ 1601 /* note: It really has SB0220 written on the card, */
1602 /* but it's SB0228 according to kx.inf */
1587 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102, 1603 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
1588 .driver = "EMU10K1", .name = "SB Live 5.1 Dell OEM [SB0220]", 1604 .driver = "EMU10K1", .name = "SB Live! 5.1 Dell OEM [SB0228]",
1589 .id = "Live", 1605 .id = "Live",
1590 .emu10k1_chip = 1, 1606 .emu10k1_chip = 1,
1591 .ac97_chip = 1, 1607 .ac97_chip = 1,
1592 .sblive51 = 1} , 1608 .sblive51 = 1} ,
1593 /* Tested by Thomas Zehetbauer 27th Aug 2005 */ 1609 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
1594 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, 1610 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
1595 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", 1611 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1596 .id = "Live",
1597 .emu10k1_chip = 1,
1598 .ac97_chip = 1,
1599 .sblive51 = 1} ,
1600 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1601 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
1602 .id = "Live", 1612 .id = "Live",
1603 .emu10k1_chip = 1, 1613 .emu10k1_chip = 1,
1604 .ac97_chip = 1, 1614 .ac97_chip = 1,
1605 .sblive51 = 1} , 1615 .sblive51 = 1} ,
1606 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, 1616 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
1607 .driver = "EMU10K1", .name = "SB Live 5.1", 1617 .driver = "EMU10K1", .name = "SB Live! 5.1",
1608 .id = "Live", 1618 .id = "Live",
1609 .emu10k1_chip = 1, 1619 .emu10k1_chip = 1,
1610 .ac97_chip = 1, 1620 .ac97_chip = 1,
1611 .sblive51 = 1} , 1621 .sblive51 = 1} ,
1612 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */ 1622 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
1613 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, 1623 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
1614 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]", 1624 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0060]",
1615 .id = "Live", 1625 .id = "Live",
1616 .emu10k1_chip = 1, 1626 .emu10k1_chip = 1,
1617 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum 1627 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
@@ -1619,78 +1629,78 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1619 */ 1629 */
1620 .sblive51 = 1} , 1630 .sblive51 = 1} ,
1621 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, 1631 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
1622 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 1632 .driver = "EMU10K1", .name = "SB Live! Value [CT4850]",
1623 .id = "Live", 1633 .id = "Live",
1624 .emu10k1_chip = 1, 1634 .emu10k1_chip = 1,
1625 .ac97_chip = 1, 1635 .ac97_chip = 1,
1626 .sblive51 = 1} , 1636 .sblive51 = 1} ,
1627 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, 1637 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
1628 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", 1638 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
1629 .id = "Live", 1639 .id = "Live",
1630 .emu10k1_chip = 1, 1640 .emu10k1_chip = 1,
1631 .ac97_chip = 1} , 1641 .ac97_chip = 1} ,
1632 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, 1642 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
1633 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", 1643 .driver = "EMU10K1", .name = "SB Live! Value [CT4871]",
1634 .id = "Live", 1644 .id = "Live",
1635 .emu10k1_chip = 1, 1645 .emu10k1_chip = 1,
1636 .ac97_chip = 1, 1646 .ac97_chip = 1,
1637 .sblive51 = 1} , 1647 .sblive51 = 1} ,
1638 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102, 1648 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
1639 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]", 1649 .driver = "EMU10K1", .name = "SB Live! Value [CT4831]",
1640 .id = "Live", 1650 .id = "Live",
1641 .emu10k1_chip = 1, 1651 .emu10k1_chip = 1,
1642 .ac97_chip = 1, 1652 .ac97_chip = 1,
1643 .sblive51 = 1} , 1653 .sblive51 = 1} ,
1644 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, 1654 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
1645 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", 1655 .driver = "EMU10K1", .name = "SB Live! Value [CT4870]",
1646 .id = "Live", 1656 .id = "Live",
1647 .emu10k1_chip = 1, 1657 .emu10k1_chip = 1,
1648 .ac97_chip = 1, 1658 .ac97_chip = 1,
1649 .sblive51 = 1} , 1659 .sblive51 = 1} ,
1650 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1660 /* Tested by James@superbug.co.uk 3rd July 2005 */
1651 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, 1661 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
1652 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", 1662 .driver = "EMU10K1", .name = "SB Live! Value [CT4832]",
1653 .id = "Live", 1663 .id = "Live",
1654 .emu10k1_chip = 1, 1664 .emu10k1_chip = 1,
1655 .ac97_chip = 1, 1665 .ac97_chip = 1,
1656 .sblive51 = 1} , 1666 .sblive51 = 1} ,
1657 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, 1667 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
1658 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", 1668 .driver = "EMU10K1", .name = "SB Live! Value [CT4830]",
1659 .id = "Live", 1669 .id = "Live",
1660 .emu10k1_chip = 1, 1670 .emu10k1_chip = 1,
1661 .ac97_chip = 1, 1671 .ac97_chip = 1,
1662 .sblive51 = 1} , 1672 .sblive51 = 1} ,
1663 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, 1673 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
1664 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", 1674 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
1665 .id = "Live", 1675 .id = "Live",
1666 .emu10k1_chip = 1, 1676 .emu10k1_chip = 1,
1667 .ac97_chip = 1, 1677 .ac97_chip = 1,
1668 .sblive51 = 1} , 1678 .sblive51 = 1} ,
1669 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, 1679 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
1670 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", 1680 .driver = "EMU10K1", .name = "SB Live! Value [CT4780]",
1671 .id = "Live", 1681 .id = "Live",
1672 .emu10k1_chip = 1, 1682 .emu10k1_chip = 1,
1673 .ac97_chip = 1, 1683 .ac97_chip = 1,
1674 .sblive51 = 1} , 1684 .sblive51 = 1} ,
1675 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, 1685 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1676 .driver = "EMU10K1", .name = "E-mu APS [4001]", 1686 .driver = "EMU10K1", .name = "E-mu APS [PC545]",
1677 .id = "APS", 1687 .id = "APS",
1678 .emu10k1_chip = 1, 1688 .emu10k1_chip = 1,
1679 .ecard = 1} , 1689 .ecard = 1} ,
1680 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, 1690 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1681 .driver = "EMU10K1", .name = "SBLive! [CT4620]", 1691 .driver = "EMU10K1", .name = "SB Live! [CT4620]",
1682 .id = "Live", 1692 .id = "Live",
1683 .emu10k1_chip = 1, 1693 .emu10k1_chip = 1,
1684 .ac97_chip = 1, 1694 .ac97_chip = 1,
1685 .sblive51 = 1} , 1695 .sblive51 = 1} ,
1686 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, 1696 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1687 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", 1697 .driver = "EMU10K1", .name = "SB Live! Value [CT4670]",
1688 .id = "Live", 1698 .id = "Live",
1689 .emu10k1_chip = 1, 1699 .emu10k1_chip = 1,
1690 .ac97_chip = 1, 1700 .ac97_chip = 1,
1691 .sblive51 = 1} , 1701 .sblive51 = 1} ,
1692 {.vendor = 0x1102, .device = 0x0002, 1702 {.vendor = 0x1102, .device = 0x0002,
1693 .driver = "EMU10K1", .name = "SB Live [Unknown]", 1703 .driver = "EMU10K1", .name = "SB Live! [Unknown]",
1694 .id = "Live", 1704 .id = "Live",
1695 .emu10k1_chip = 1, 1705 .emu10k1_chip = 1,
1696 .ac97_chip = 1, 1706 .ac97_chip = 1,
@@ -1699,13 +1709,13 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1699}; 1709};
1700 1710
1701int __devinit snd_emu10k1_create(struct snd_card *card, 1711int __devinit snd_emu10k1_create(struct snd_card *card,
1702 struct pci_dev * pci, 1712 struct pci_dev *pci,
1703 unsigned short extin_mask, 1713 unsigned short extin_mask,
1704 unsigned short extout_mask, 1714 unsigned short extout_mask,
1705 long max_cache_bytes, 1715 long max_cache_bytes,
1706 int enable_ir, 1716 int enable_ir,
1707 uint subsystem, 1717 uint subsystem,
1708 struct snd_emu10k1 ** remu) 1718 struct snd_emu10k1 **remu)
1709{ 1719{
1710 struct snd_emu10k1 *emu; 1720 struct snd_emu10k1 *emu;
1711 int idx, err; 1721 int idx, err;
@@ -1715,11 +1725,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1715 static struct snd_device_ops ops = { 1725 static struct snd_device_ops ops = {
1716 .dev_free = snd_emu10k1_dev_free, 1726 .dev_free = snd_emu10k1_dev_free,
1717 }; 1727 };
1718 1728
1719 *remu = NULL; 1729 *remu = NULL;
1720 1730
1721 /* enable PCI device */ 1731 /* enable PCI device */
1722 if ((err = pci_enable_device(pci)) < 0) 1732 err = pci_enable_device(pci);
1733 if (err < 0)
1723 return err; 1734 return err;
1724 1735
1725 emu = kzalloc(sizeof(*emu), GFP_KERNEL); 1736 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
@@ -1746,16 +1757,17 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1746 emu->revision = pci->revision; 1757 emu->revision = pci->revision;
1747 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); 1758 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1748 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); 1759 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
1749 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); 1760 snd_printdd("vendor = 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x\n", pci->vendor, pci->device, emu->serial, emu->model);
1750 1761
1751 for (c = emu_chip_details; c->vendor; c++) { 1762 for (c = emu_chip_details; c->vendor; c++) {
1752 if (c->vendor == pci->vendor && c->device == pci->device) { 1763 if (c->vendor == pci->vendor && c->device == pci->device) {
1753 if (subsystem) { 1764 if (subsystem) {
1754 if (c->subsystem && (c->subsystem == subsystem) ) { 1765 if (c->subsystem && (c->subsystem == subsystem))
1755 break; 1766 break;
1756 } else continue; 1767 else
1768 continue;
1757 } else { 1769 } else {
1758 if (c->subsystem && (c->subsystem != emu->serial) ) 1770 if (c->subsystem && (c->subsystem != emu->serial))
1759 continue; 1771 continue;
1760 if (c->revision && c->revision != emu->revision) 1772 if (c->revision && c->revision != emu->revision)
1761 continue; 1773 continue;
@@ -1771,14 +1783,18 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1771 } 1783 }
1772 emu->card_capabilities = c; 1784 emu->card_capabilities = c;
1773 if (c->subsystem && !subsystem) 1785 if (c->subsystem && !subsystem)
1774 snd_printdd("Sound card name=%s\n", c->name); 1786 snd_printdd("Sound card name = %s\n", c->name);
1775 else if (subsystem) 1787 else if (subsystem)
1776 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n", 1788 snd_printdd("Sound card name = %s, "
1777 c->name, pci->vendor, pci->device, emu->serial, c->subsystem); 1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
1778 else 1790 "Forced to subsytem = 0x%x\n", c->name,
1779 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n", 1791 pci->vendor, pci->device, emu->serial, c->subsystem);
1780 c->name, pci->vendor, pci->device, emu->serial); 1792 else
1781 1793 snd_printdd("Sound card name = %s, "
1794 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x.\n",
1795 c->name, pci->vendor, pci->device,
1796 emu->serial);
1797
1782 if (!*card->id && c->id) { 1798 if (!*card->id && c->id) {
1783 int i, n = 0; 1799 int i, n = 0;
1784 strlcpy(card->id, c->id, sizeof(card->id)); 1800 strlcpy(card->id, c->id, sizeof(card->id));
@@ -1812,7 +1828,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1812 else 1828 else
1813 emu->gpr_base = FXGPREGBASE; 1829 emu->gpr_base = FXGPREGBASE;
1814 1830
1815 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) { 1831 err = pci_request_regions(pci, "EMU10K1");
1832 if (err < 0) {
1816 kfree(emu); 1833 kfree(emu);
1817 pci_disable_device(pci); 1834 pci_disable_device(pci);
1818 return err; 1835 return err;
@@ -1859,21 +1876,25 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1859 emu->enable_ir = enable_ir; 1876 emu->enable_ir = enable_ir;
1860 1877
1861 if (emu->card_capabilities->ca_cardbus_chip) { 1878 if (emu->card_capabilities->ca_cardbus_chip) {
1862 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) 1879 err = snd_emu10k1_cardbus_init(emu);
1880 if (err < 0)
1863 goto error; 1881 goto error;
1864 } 1882 }
1865 if (emu->card_capabilities->ecard) { 1883 if (emu->card_capabilities->ecard) {
1866 if ((err = snd_emu10k1_ecard_init(emu)) < 0) 1884 err = snd_emu10k1_ecard_init(emu);
1885 if (err < 0)
1867 goto error; 1886 goto error;
1868 } else if (emu->card_capabilities->emu_model) { 1887 } else if (emu->card_capabilities->emu_model) {
1869 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { 1888 err = snd_emu10k1_emu1010_init(emu);
1870 snd_emu10k1_free(emu); 1889 if (err < 0) {
1871 return err; 1890 snd_emu10k1_free(emu);
1872 } 1891 return err;
1892 }
1873 } else { 1893 } else {
1874 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version 1894 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1875 does not support this, it shouldn't do any harm */ 1895 does not support this, it shouldn't do any harm */
1876 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 1896 snd_emu10k1_ptr_write(emu, AC97SLOT, 0,
1897 AC97SLOT_CNTR|AC97SLOT_LFE);
1877 } 1898 }
1878 1899
1879 /* initialize TRAM setup */ 1900 /* initialize TRAM setup */
@@ -1913,7 +1934,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1913 snd_emu10k1_synth_alloc(emu, 4096); 1934 snd_emu10k1_synth_alloc(emu, 4096);
1914 if (emu->reserved_page) 1935 if (emu->reserved_page)
1915 emu->reserved_page->map_locked = 1; 1936 emu->reserved_page->map_locked = 1;
1916 1937
1917 /* Clear silent pages and set up pointers */ 1938 /* Clear silent pages and set up pointers */
1918 memset(emu->silent_page.area, 0, PAGE_SIZE); 1939 memset(emu->silent_page.area, 0, PAGE_SIZE);
1919 silent_page = emu->silent_page.addr << 1; 1940 silent_page = emu->silent_page.addr << 1;
@@ -1926,19 +1947,23 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1926 emu->voices[idx].number = idx; 1947 emu->voices[idx].number = idx;
1927 } 1948 }
1928 1949
1929 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0) 1950 err = snd_emu10k1_init(emu, enable_ir, 0);
1951 if (err < 0)
1930 goto error; 1952 goto error;
1931#ifdef CONFIG_PM 1953#ifdef CONFIG_PM
1932 if ((err = alloc_pm_buffer(emu)) < 0) 1954 err = alloc_pm_buffer(emu);
1955 if (err < 0)
1933 goto error; 1956 goto error;
1934#endif 1957#endif
1935 1958
1936 /* Initialize the effect engine */ 1959 /* Initialize the effect engine */
1937 if ((err = snd_emu10k1_init_efx(emu)) < 0) 1960 err = snd_emu10k1_init_efx(emu);
1961 if (err < 0)
1938 goto error; 1962 goto error;
1939 snd_emu10k1_audio_enable(emu); 1963 snd_emu10k1_audio_enable(emu);
1940 1964
1941 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) 1965 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops);
1966 if (err < 0)
1942 goto error; 1967 goto error;
1943 1968
1944#ifdef CONFIG_PROC_FS 1969#ifdef CONFIG_PROC_FS
@@ -1978,7 +2003,7 @@ static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1978 if (emu->audigy) 2003 if (emu->audigy)
1979 size += ARRAY_SIZE(saved_regs_audigy); 2004 size += ARRAY_SIZE(saved_regs_audigy);
1980 emu->saved_ptr = vmalloc(4 * NUM_G * size); 2005 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1981 if (! emu->saved_ptr) 2006 if (!emu->saved_ptr)
1982 return -ENOMEM; 2007 return -ENOMEM;
1983 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) 2008 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1984 return -ENOMEM; 2009 return -ENOMEM;
@@ -2023,7 +2048,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
2023 if (emu->card_capabilities->ecard) 2048 if (emu->card_capabilities->ecard)
2024 snd_emu10k1_ecard_init(emu); 2049 snd_emu10k1_ecard_init(emu);
2025 else if (emu->card_capabilities->emu_model) 2050 else if (emu->card_capabilities->emu_model)
2026 snd_emu10k1_emu1010_init(emu); 2051 snd_emu10k1_emu1010_init(emu);
2027 else 2052 else
2028 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 2053 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
2029 snd_emu10k1_init(emu, emu->enable_ir, 1); 2054 snd_emu10k1_init(emu, emu->enable_ir, 1);
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index f34bbfb705f5..b0fb6c917c38 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1639,6 +1639,45 @@ static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
1639 .put = snd_emu10k1_shared_spdif_put 1639 .put = snd_emu10k1_shared_spdif_put
1640}; 1640};
1641 1641
1642/* workaround for too low volume on Audigy due to 16bit/24bit conversion */
1643
1644#define snd_audigy_capture_boost_info snd_ctl_boolean_mono_info
1645
1646static int snd_audigy_capture_boost_get(struct snd_kcontrol *kcontrol,
1647 struct snd_ctl_elem_value *ucontrol)
1648{
1649 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1650 unsigned int val;
1651
1652 /* FIXME: better to use a cached version */
1653 val = snd_ac97_read(emu->ac97, AC97_REC_GAIN);
1654 ucontrol->value.integer.value[0] = !!val;
1655 return 0;
1656}
1657
1658static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1660{
1661 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1662 unsigned int val;
1663
1664 if (ucontrol->value.integer.value[0])
1665 val = 0x0f0f;
1666 else
1667 val = 0;
1668 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
1669}
1670
1671static struct snd_kcontrol_new snd_audigy_capture_boost __devinitdata =
1672{
1673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1674 .name = "Analog Capture Boost",
1675 .info = snd_audigy_capture_boost_info,
1676 .get = snd_audigy_capture_boost_get,
1677 .put = snd_audigy_capture_boost_put
1678};
1679
1680
1642/* 1681/*
1643 */ 1682 */
1644static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97) 1683static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
@@ -2087,5 +2126,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
2087 } 2126 }
2088 } 2127 }
2089 2128
2129 if (emu->card_capabilities->ac97_chip && emu->audigy) {
2130 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_capture_boost,
2131 emu));
2132 if (err < 0)
2133 return err;
2134 }
2135
2090 return 0; 2136 return 0;
2091} 2137}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 20ee7599600b..e9c3794bbcb8 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1953,7 +1953,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 1954
1955 if (event & ESM_HWVOL_IRQ) 1955 if (event & ESM_HWVOL_IRQ)
1956 tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */ 1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
1957 1957
1958 /* else ack 'em all, i imagine */ 1958 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 1959 outb(0xFF, chip->io_port + 0x1A);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 717040a491b9..eb2a19b894a0 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -172,7 +172,6 @@ config SND_HDA_GENERIC
172 172
173config SND_HDA_POWER_SAVE 173config SND_HDA_POWER_SAVE
174 bool "Aggressive power-saving on HD-audio" 174 bool "Aggressive power-saving on HD-audio"
175 depends on EXPERIMENTAL
176 help 175 help
177 Say Y here to enable more aggressive power-saving mode on 176 Say Y here to enable more aggressive power-saving mode on
178 HD-audio driver. The power-saving timeout can be configured 177 HD-audio driver. The power-saving timeout can be configured
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index e00421c0d8ba..960fd7970384 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -135,7 +135,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
135 struct hda_beep *beep = codec->beep; 135 struct hda_beep *beep = codec->beep;
136 if (beep) { 136 if (beep) {
137 cancel_work_sync(&beep->beep_work); 137 cancel_work_sync(&beep->beep_work);
138 flush_scheduled_work();
139 138
140 input_unregister_device(beep->dev); 139 input_unregister_device(beep->dev);
141 kfree(beep); 140 kfree(beep);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 9c1af0101dde..b7bba7dc7cf1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -46,6 +46,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
46 { 0x1002, "ATI" }, 46 { 0x1002, "ATI" },
47 { 0x1057, "Motorola" }, 47 { 0x1057, "Motorola" },
48 { 0x1095, "Silicon Image" }, 48 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" },
49 { 0x10ec, "Realtek" }, 50 { 0x10ec, "Realtek" },
50 { 0x1106, "VIA" }, 51 { 0x1106, "VIA" },
51 { 0x111d, "IDT" }, 52 { 0x111d, "IDT" },
@@ -57,6 +58,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
57 { 0x1854, "LG" }, 58 { 0x1854, "LG" },
58 { 0x1aec, "Wolfson Microelectronics" }, 59 { 0x1aec, "Wolfson Microelectronics" },
59 { 0x434d, "C-Media" }, 60 { 0x434d, "C-Media" },
61 { 0x8086, "Intel" },
60 { 0x8384, "SigmaTel" }, 62 { 0x8384, "SigmaTel" },
61 {} /* terminator */ 63 {} /* terminator */
62}; 64};
@@ -371,7 +373,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
371 unsol->queue[wp] = res; 373 unsol->queue[wp] = res;
372 unsol->queue[wp + 1] = res_ex; 374 unsol->queue[wp + 1] = res_ex;
373 375
374 schedule_work(&unsol->work); 376 queue_work(bus->workq, &unsol->work);
375 377
376 return 0; 378 return 0;
377} 379}
@@ -435,15 +437,17 @@ static int snd_hda_bus_free(struct hda_bus *bus)
435 437
436 if (!bus) 438 if (!bus)
437 return 0; 439 return 0;
438 if (bus->unsol) { 440 if (bus->workq)
439 flush_scheduled_work(); 441 flush_workqueue(bus->workq);
442 if (bus->unsol)
440 kfree(bus->unsol); 443 kfree(bus->unsol);
441 }
442 list_for_each_entry_safe(codec, n, &bus->codec_list, list) { 444 list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
443 snd_hda_codec_free(codec); 445 snd_hda_codec_free(codec);
444 } 446 }
445 if (bus->ops.private_free) 447 if (bus->ops.private_free)
446 bus->ops.private_free(bus); 448 bus->ops.private_free(bus);
449 if (bus->workq)
450 destroy_workqueue(bus->workq);
447 kfree(bus); 451 kfree(bus);
448 return 0; 452 return 0;
449} 453}
@@ -483,6 +487,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
483{ 487{
484 struct hda_bus *bus; 488 struct hda_bus *bus;
485 int err; 489 int err;
490 char qname[8];
486 static struct snd_device_ops dev_ops = { 491 static struct snd_device_ops dev_ops = {
487 .dev_register = snd_hda_bus_dev_register, 492 .dev_register = snd_hda_bus_dev_register,
488 .dev_free = snd_hda_bus_dev_free, 493 .dev_free = snd_hda_bus_dev_free,
@@ -512,6 +517,14 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
512 mutex_init(&bus->cmd_mutex); 517 mutex_init(&bus->cmd_mutex);
513 INIT_LIST_HEAD(&bus->codec_list); 518 INIT_LIST_HEAD(&bus->codec_list);
514 519
520 snprintf(qname, sizeof(qname), "hda%d", card->number);
521 bus->workq = create_workqueue(qname);
522 if (!bus->workq) {
523 snd_printk(KERN_ERR "cannot create workqueue %s\n", qname);
524 kfree(bus);
525 return -ENOMEM;
526 }
527
515 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); 528 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
516 if (err < 0) { 529 if (err < 0) {
517 snd_hda_bus_free(bus); 530 snd_hda_bus_free(bus);
@@ -682,7 +695,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
682 return; 695 return;
683#ifdef CONFIG_SND_HDA_POWER_SAVE 696#ifdef CONFIG_SND_HDA_POWER_SAVE
684 cancel_delayed_work(&codec->power_work); 697 cancel_delayed_work(&codec->power_work);
685 flush_scheduled_work(); 698 flush_workqueue(codec->bus->workq);
686#endif 699#endif
687 list_del(&codec->list); 700 list_del(&codec->list);
688 snd_array_free(&codec->mixers); 701 snd_array_free(&codec->mixers);
@@ -707,7 +720,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
707 * Returns 0 if successful, or a negative error code. 720 * Returns 0 if successful, or a negative error code.
708 */ 721 */
709int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 722int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
710 struct hda_codec **codecp) 723 int do_init, struct hda_codec **codecp)
711{ 724{
712 struct hda_codec *codec; 725 struct hda_codec *codec;
713 char component[31]; 726 char component[31];
@@ -733,6 +746,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
733 codec->bus = bus; 746 codec->bus = bus;
734 codec->addr = codec_addr; 747 codec->addr = codec_addr;
735 mutex_init(&codec->spdif_mutex); 748 mutex_init(&codec->spdif_mutex);
749 mutex_init(&codec->control_mutex);
736 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 750 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
737 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 751 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
738 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32); 752 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
@@ -791,10 +805,12 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
791 if (bus->modelname) 805 if (bus->modelname)
792 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL); 806 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL);
793 807
794 err = snd_hda_codec_configure(codec); 808 if (do_init) {
795 if (err < 0) { 809 err = snd_hda_codec_configure(codec);
796 snd_hda_codec_free(codec); 810 if (err < 0) {
797 return err; 811 snd_hda_codec_free(codec);
812 return err;
813 }
798 } 814 }
799 snd_hda_codec_proc_new(codec); 815 snd_hda_codec_proc_new(codec);
800 816
@@ -1268,7 +1284,7 @@ void snd_hda_codec_reset(struct hda_codec *codec)
1268 1284
1269#ifdef CONFIG_SND_HDA_POWER_SAVE 1285#ifdef CONFIG_SND_HDA_POWER_SAVE
1270 cancel_delayed_work(&codec->power_work); 1286 cancel_delayed_work(&codec->power_work);
1271 flush_scheduled_work(); 1287 flush_workqueue(codec->bus->workq);
1272#endif 1288#endif
1273 snd_hda_ctls_clear(codec); 1289 snd_hda_ctls_clear(codec);
1274 /* relase PCMs */ 1290 /* relase PCMs */
@@ -1282,9 +1298,12 @@ void snd_hda_codec_reset(struct hda_codec *codec)
1282 } 1298 }
1283 if (codec->patch_ops.free) 1299 if (codec->patch_ops.free)
1284 codec->patch_ops.free(codec); 1300 codec->patch_ops.free(codec);
1301 codec->proc_widget_hook = NULL;
1285 codec->spec = NULL; 1302 codec->spec = NULL;
1286 free_hda_cache(&codec->amp_cache); 1303 free_hda_cache(&codec->amp_cache);
1287 free_hda_cache(&codec->cmd_cache); 1304 free_hda_cache(&codec->cmd_cache);
1305 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1306 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
1288 codec->num_pcms = 0; 1307 codec->num_pcms = 0;
1289 codec->pcm_info = NULL; 1308 codec->pcm_info = NULL;
1290 codec->preset = NULL; 1309 codec->preset = NULL;
@@ -1411,12 +1430,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1411 unsigned long pval; 1430 unsigned long pval;
1412 int err; 1431 int err;
1413 1432
1414 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1433 mutex_lock(&codec->control_mutex);
1415 pval = kcontrol->private_value; 1434 pval = kcontrol->private_value;
1416 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */ 1435 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
1417 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); 1436 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
1418 kcontrol->private_value = pval; 1437 kcontrol->private_value = pval;
1419 mutex_unlock(&codec->spdif_mutex); 1438 mutex_unlock(&codec->control_mutex);
1420 return err; 1439 return err;
1421} 1440}
1422EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get); 1441EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
@@ -1428,7 +1447,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1428 unsigned long pval; 1447 unsigned long pval;
1429 int i, indices, err = 0, change = 0; 1448 int i, indices, err = 0, change = 0;
1430 1449
1431 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1450 mutex_lock(&codec->control_mutex);
1432 pval = kcontrol->private_value; 1451 pval = kcontrol->private_value;
1433 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; 1452 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
1434 for (i = 0; i < indices; i++) { 1453 for (i = 0; i < indices; i++) {
@@ -1440,7 +1459,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1440 change |= err; 1459 change |= err;
1441 } 1460 }
1442 kcontrol->private_value = pval; 1461 kcontrol->private_value = pval;
1443 mutex_unlock(&codec->spdif_mutex); 1462 mutex_unlock(&codec->control_mutex);
1444 return err < 0 ? err : change; 1463 return err < 0 ? err : change;
1445} 1464}
1446EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put); 1465EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
@@ -1455,12 +1474,12 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1455 struct hda_bind_ctls *c; 1474 struct hda_bind_ctls *c;
1456 int err; 1475 int err;
1457 1476
1458 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1477 mutex_lock(&codec->control_mutex);
1459 c = (struct hda_bind_ctls *)kcontrol->private_value; 1478 c = (struct hda_bind_ctls *)kcontrol->private_value;
1460 kcontrol->private_value = *c->values; 1479 kcontrol->private_value = *c->values;
1461 err = c->ops->info(kcontrol, uinfo); 1480 err = c->ops->info(kcontrol, uinfo);
1462 kcontrol->private_value = (long)c; 1481 kcontrol->private_value = (long)c;
1463 mutex_unlock(&codec->spdif_mutex); 1482 mutex_unlock(&codec->control_mutex);
1464 return err; 1483 return err;
1465} 1484}
1466EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info); 1485EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
@@ -1472,12 +1491,12 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1472 struct hda_bind_ctls *c; 1491 struct hda_bind_ctls *c;
1473 int err; 1492 int err;
1474 1493
1475 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1494 mutex_lock(&codec->control_mutex);
1476 c = (struct hda_bind_ctls *)kcontrol->private_value; 1495 c = (struct hda_bind_ctls *)kcontrol->private_value;
1477 kcontrol->private_value = *c->values; 1496 kcontrol->private_value = *c->values;
1478 err = c->ops->get(kcontrol, ucontrol); 1497 err = c->ops->get(kcontrol, ucontrol);
1479 kcontrol->private_value = (long)c; 1498 kcontrol->private_value = (long)c;
1480 mutex_unlock(&codec->spdif_mutex); 1499 mutex_unlock(&codec->control_mutex);
1481 return err; 1500 return err;
1482} 1501}
1483EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get); 1502EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
@@ -1490,7 +1509,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1490 unsigned long *vals; 1509 unsigned long *vals;
1491 int err = 0, change = 0; 1510 int err = 0, change = 0;
1492 1511
1493 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1512 mutex_lock(&codec->control_mutex);
1494 c = (struct hda_bind_ctls *)kcontrol->private_value; 1513 c = (struct hda_bind_ctls *)kcontrol->private_value;
1495 for (vals = c->values; *vals; vals++) { 1514 for (vals = c->values; *vals; vals++) {
1496 kcontrol->private_value = *vals; 1515 kcontrol->private_value = *vals;
@@ -1500,7 +1519,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1500 change |= err; 1519 change |= err;
1501 } 1520 }
1502 kcontrol->private_value = (long)c; 1521 kcontrol->private_value = (long)c;
1503 mutex_unlock(&codec->spdif_mutex); 1522 mutex_unlock(&codec->control_mutex);
1504 return err < 0 ? err : change; 1523 return err < 0 ? err : change;
1505} 1524}
1506EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put); 1525EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
@@ -1512,12 +1531,12 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1512 struct hda_bind_ctls *c; 1531 struct hda_bind_ctls *c;
1513 int err; 1532 int err;
1514 1533
1515 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1534 mutex_lock(&codec->control_mutex);
1516 c = (struct hda_bind_ctls *)kcontrol->private_value; 1535 c = (struct hda_bind_ctls *)kcontrol->private_value;
1517 kcontrol->private_value = *c->values; 1536 kcontrol->private_value = *c->values;
1518 err = c->ops->tlv(kcontrol, op_flag, size, tlv); 1537 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
1519 kcontrol->private_value = (long)c; 1538 kcontrol->private_value = (long)c;
1520 mutex_unlock(&codec->spdif_mutex); 1539 mutex_unlock(&codec->control_mutex);
1521 return err; 1540 return err;
1522} 1541}
1523EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv); 1542EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
@@ -2857,7 +2876,7 @@ void snd_hda_power_down(struct hda_codec *codec)
2857 return; 2876 return;
2858 if (power_save(codec)) { 2877 if (power_save(codec)) {
2859 codec->power_transition = 1; /* avoid reentrance */ 2878 codec->power_transition = 1; /* avoid reentrance */
2860 schedule_delayed_work(&codec->power_work, 2879 queue_delayed_work(codec->bus->workq, &codec->power_work,
2861 msecs_to_jiffies(power_save(codec) * 1000)); 2880 msecs_to_jiffies(power_save(codec) * 1000));
2862 } 2881 }
2863} 2882}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 6612d0f20bc6..5810ef588402 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -614,8 +614,7 @@ struct hda_bus {
614 614
615 /* unsolicited event queue */ 615 /* unsolicited event queue */
616 struct hda_bus_unsolicited *unsol; 616 struct hda_bus_unsolicited *unsol;
617 617 struct workqueue_struct *workq; /* common workqueue for codecs */
618 struct snd_info_entry *proc;
619 618
620 /* assigned PCMs */ 619 /* assigned PCMs */
621 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES); 620 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
@@ -773,6 +772,7 @@ struct hda_codec {
773 struct hda_cache_rec cmd_cache; /* cache for other commands */ 772 struct hda_cache_rec cmd_cache; /* cache for other commands */
774 773
775 struct mutex spdif_mutex; 774 struct mutex spdif_mutex;
775 struct mutex control_mutex;
776 unsigned int spdif_status; /* IEC958 status bits */ 776 unsigned int spdif_status; /* IEC958 status bits */
777 unsigned short spdif_ctls; /* SPDIF control bits */ 777 unsigned short spdif_ctls; /* SPDIF control bits */
778 unsigned int spdif_in_enable; /* SPDIF input enable? */ 778 unsigned int spdif_in_enable; /* SPDIF input enable? */
@@ -795,6 +795,10 @@ struct hda_codec {
795 int power_count; /* current (global) power refcount */ 795 int power_count; /* current (global) power refcount */
796 struct delayed_work power_work; /* delayed task for powerdown */ 796 struct delayed_work power_work; /* delayed task for powerdown */
797#endif 797#endif
798
799 /* codec-specific additional proc output */
800 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
801 struct hda_codec *codec, hda_nid_t nid);
798}; 802};
799 803
800/* direction */ 804/* direction */
@@ -809,7 +813,7 @@ enum {
809int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 813int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
810 struct hda_bus **busp); 814 struct hda_bus **busp);
811int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 815int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
812 struct hda_codec **codecp); 816 int do_init, struct hda_codec **codecp);
813 817
814/* 818/*
815 * low level functions 819 * low level functions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f17ccd513350..11e791b965f6 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS];
58static int position_fix[SNDRV_CARDS]; 58static int position_fix[SNDRV_CARDS];
59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS];
61static int single_cmd; 62static int single_cmd;
62static int enable_msi; 63static int enable_msi;
63 64
@@ -76,6 +77,8 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
76MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 77MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
77module_param_array(probe_mask, int, NULL, 0444); 78module_param_array(probe_mask, int, NULL, 0444);
78MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 79MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
80module_param_array(probe_only, bool, NULL, 0444);
81MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
79module_param(single_cmd, bool, 0444); 82module_param(single_cmd, bool, 0444);
80MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 83MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
81 "(for debugging only)."); 84 "(for debugging only).");
@@ -993,10 +996,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
993 spin_unlock(&chip->reg_lock); 996 spin_unlock(&chip->reg_lock);
994 snd_pcm_period_elapsed(azx_dev->substream); 997 snd_pcm_period_elapsed(azx_dev->substream);
995 spin_lock(&chip->reg_lock); 998 spin_lock(&chip->reg_lock);
996 } else { 999 } else if (chip->bus && chip->bus->workq) {
997 /* bogus IRQ, process it later */ 1000 /* bogus IRQ, process it later */
998 azx_dev->irq_pending = 1; 1001 azx_dev->irq_pending = 1;
999 schedule_work(&chip->irq_pending_work); 1002 queue_work(chip->bus->workq,
1003 &chip->irq_pending_work);
1000 } 1004 }
1001 } 1005 }
1002 } 1006 }
@@ -1224,7 +1228,8 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1224}; 1228};
1225 1229
1226static int __devinit azx_codec_create(struct azx *chip, const char *model, 1230static int __devinit azx_codec_create(struct azx *chip, const char *model,
1227 unsigned int codec_probe_mask) 1231 unsigned int codec_probe_mask,
1232 int no_init)
1228{ 1233{
1229 struct hda_bus_template bus_temp; 1234 struct hda_bus_template bus_temp;
1230 int c, codecs, err; 1235 int c, codecs, err;
@@ -1233,12 +1238,12 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1233 memset(&bus_temp, 0, sizeof(bus_temp)); 1238 memset(&bus_temp, 0, sizeof(bus_temp));
1234 bus_temp.private_data = chip; 1239 bus_temp.private_data = chip;
1235 bus_temp.modelname = model; 1240 bus_temp.modelname = model;
1236 bus_temp.power_save = &power_save;
1237 bus_temp.pci = chip->pci; 1241 bus_temp.pci = chip->pci;
1238 bus_temp.ops.command = azx_send_cmd; 1242 bus_temp.ops.command = azx_send_cmd;
1239 bus_temp.ops.get_response = azx_get_response; 1243 bus_temp.ops.get_response = azx_get_response;
1240 bus_temp.ops.attach_pcm = azx_attach_pcm_stream; 1244 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1241#ifdef CONFIG_SND_HDA_POWER_SAVE 1245#ifdef CONFIG_SND_HDA_POWER_SAVE
1246 bus_temp.power_save = &power_save;
1242 bus_temp.ops.pm_notify = azx_power_notify; 1247 bus_temp.ops.pm_notify = azx_power_notify;
1243#endif 1248#endif
1244 1249
@@ -1282,7 +1287,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1282 for (c = 0; c < max_slots; c++) { 1287 for (c = 0; c < max_slots; c++) {
1283 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { 1288 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1284 struct hda_codec *codec; 1289 struct hda_codec *codec;
1285 err = snd_hda_codec_new(chip->bus, c, &codec); 1290 err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
1286 if (err < 0) 1291 if (err < 0)
1287 continue; 1292 continue;
1288 codecs++; 1293 codecs++;
@@ -1737,7 +1742,6 @@ static void azx_clear_irq_pending(struct azx *chip)
1737 for (i = 0; i < chip->num_streams; i++) 1742 for (i = 0; i < chip->num_streams; i++)
1738 chip->azx_dev[i].irq_pending = 0; 1743 chip->azx_dev[i].irq_pending = 0;
1739 spin_unlock_irq(&chip->reg_lock); 1744 spin_unlock_irq(&chip->reg_lock);
1740 flush_scheduled_work();
1741} 1745}
1742 1746
1743static struct snd_pcm_ops azx_pcm_ops = { 1747static struct snd_pcm_ops azx_pcm_ops = {
@@ -1900,6 +1904,12 @@ static void azx_power_notify(struct hda_bus *bus)
1900 else if (chip->running && power_save_controller) 1904 else if (chip->running && power_save_controller)
1901 azx_stop_chip(chip); 1905 azx_stop_chip(chip);
1902} 1906}
1907#endif /* CONFIG_SND_HDA_POWER_SAVE */
1908
1909#ifdef CONFIG_PM
1910/*
1911 * power management
1912 */
1903 1913
1904static int snd_hda_codecs_inuse(struct hda_bus *bus) 1914static int snd_hda_codecs_inuse(struct hda_bus *bus)
1905{ 1915{
@@ -1911,14 +1921,7 @@ static int snd_hda_codecs_inuse(struct hda_bus *bus)
1911 } 1921 }
1912 return 0; 1922 return 0;
1913} 1923}
1914#else /* !CONFIG_SND_HDA_POWER_SAVE */
1915#define snd_hda_codecs_inuse(bus) 1
1916#endif /* CONFIG_SND_HDA_POWER_SAVE */
1917 1924
1918#ifdef CONFIG_PM
1919/*
1920 * power management
1921 */
1922static int azx_suspend(struct pci_dev *pci, pm_message_t state) 1925static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1923{ 1926{
1924 struct snd_card *card = pci_get_drvdata(pci); 1927 struct snd_card *card = pci_get_drvdata(pci);
@@ -1944,13 +1947,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1944 return 0; 1947 return 0;
1945} 1948}
1946 1949
1950static int azx_resume_early(struct pci_dev *pci)
1951{
1952 return pci_restore_state(pci);
1953}
1954
1947static int azx_resume(struct pci_dev *pci) 1955static int azx_resume(struct pci_dev *pci)
1948{ 1956{
1949 struct snd_card *card = pci_get_drvdata(pci); 1957 struct snd_card *card = pci_get_drvdata(pci);
1950 struct azx *chip = card->private_data; 1958 struct azx *chip = card->private_data;
1951 1959
1952 pci_set_power_state(pci, PCI_D0);
1953 pci_restore_state(pci);
1954 if (pci_enable_device(pci) < 0) { 1960 if (pci_enable_device(pci) < 0) {
1955 printk(KERN_ERR "hda-intel: pci_enable_device failed, " 1961 printk(KERN_ERR "hda-intel: pci_enable_device failed, "
1956 "disabling device\n"); 1962 "disabling device\n");
@@ -2183,7 +2189,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2183 } 2189 }
2184 2190
2185 chip->addr = pci_resource_start(pci, 0); 2191 chip->addr = pci_resource_start(pci, 0);
2186 chip->remap_addr = ioremap_nocache(chip->addr, pci_resource_len(pci,0)); 2192 chip->remap_addr = pci_ioremap_bar(pci, 0);
2187 if (chip->remap_addr == NULL) { 2193 if (chip->remap_addr == NULL) {
2188 snd_printk(KERN_ERR SFX "ioremap error\n"); 2194 snd_printk(KERN_ERR SFX "ioremap error\n");
2189 err = -ENXIO; 2195 err = -ENXIO;
@@ -2341,7 +2347,8 @@ static int __devinit azx_probe(struct pci_dev *pci,
2341 card->private_data = chip; 2347 card->private_data = chip;
2342 2348
2343 /* create codec instances */ 2349 /* create codec instances */
2344 err = azx_codec_create(chip, model[dev], probe_mask[dev]); 2350 err = azx_codec_create(chip, model[dev], probe_mask[dev],
2351 probe_only[dev]);
2345 if (err < 0) 2352 if (err < 0)
2346 goto out_free; 2353 goto out_free;
2347 2354
@@ -2461,6 +2468,7 @@ static struct pci_driver driver = {
2461 .remove = __devexit_p(azx_remove), 2468 .remove = __devexit_p(azx_remove),
2462#ifdef CONFIG_PM 2469#ifdef CONFIG_PM
2463 .suspend = azx_suspend, 2470 .suspend = azx_suspend,
2471 .resume_early = azx_resume_early,
2464 .resume = azx_resume, 2472 .resume = azx_resume,
2465#endif 2473#endif
2466}; 2474};
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 9a8498456e6c..7ca66d654148 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -414,17 +414,6 @@ static void print_conn_list(struct snd_info_buffer *buffer,
414 } 414 }
415} 415}
416 416
417static void print_realtek_coef(struct snd_info_buffer *buffer,
418 struct hda_codec *codec, hda_nid_t nid)
419{
420 int coeff = snd_hda_codec_read(codec, nid, 0,
421 AC_VERB_GET_PROC_COEF, 0);
422 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
423 coeff = snd_hda_codec_read(codec, nid, 0,
424 AC_VERB_GET_COEF_INDEX, 0);
425 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
426}
427
428static void print_gpio(struct snd_info_buffer *buffer, 417static void print_gpio(struct snd_info_buffer *buffer,
429 struct hda_codec *codec, hda_nid_t nid) 418 struct hda_codec *codec, hda_nid_t nid)
430{ 419{
@@ -504,6 +493,8 @@ static void print_codec_info(struct snd_info_entry *entry,
504 } 493 }
505 494
506 print_gpio(buffer, codec, codec->afg); 495 print_gpio(buffer, codec, codec->afg);
496 if (codec->proc_widget_hook)
497 codec->proc_widget_hook(buffer, codec, codec->afg);
507 498
508 for (i = 0; i < nodes; i++, nid++) { 499 for (i = 0; i < nodes; i++, nid++) {
509 unsigned int wid_caps = 500 unsigned int wid_caps =
@@ -606,9 +597,8 @@ static void print_codec_info(struct snd_info_entry *entry,
606 if (wid_caps & AC_WCAP_PROC_WID) 597 if (wid_caps & AC_WCAP_PROC_WID)
607 print_proc_caps(buffer, codec, nid); 598 print_proc_caps(buffer, codec, nid);
608 599
609 /* NID 0x20 == Realtek Define Registers */ 600 if (codec->proc_widget_hook)
610 if (codec->vendor_id == 0x10ec && nid == 0x20) 601 codec->proc_widget_hook(buffer, codec, nid);
611 print_realtek_coef(buffer, codec, nid);
612 } 602 }
613 snd_hda_power_down(codec); 603 snd_hda_power_down(codec);
614} 604}
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index c1918a1a6df9..2e7371ec2e23 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3900,7 +3900,9 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
3900 3900
3901static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 3901static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
3902 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 3902 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
3903 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
3903 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 3904 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
3905 SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
3904 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), 3906 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
3905 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), 3907 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
3906 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 3908 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
@@ -4261,13 +4263,13 @@ static int patch_ad1882(struct hda_codec *codec)
4261 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); 4263 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
4262 spec->adc_nids = ad1882_adc_nids; 4264 spec->adc_nids = ad1882_adc_nids;
4263 spec->capsrc_nids = ad1882_capsrc_nids; 4265 spec->capsrc_nids = ad1882_capsrc_nids;
4264 if (codec->vendor_id == 0x11d1882) 4266 if (codec->vendor_id == 0x11d41882)
4265 spec->input_mux = &ad1882_capture_source; 4267 spec->input_mux = &ad1882_capture_source;
4266 else 4268 else
4267 spec->input_mux = &ad1882a_capture_source; 4269 spec->input_mux = &ad1882a_capture_source;
4268 spec->num_mixers = 2; 4270 spec->num_mixers = 2;
4269 spec->mixers[0] = ad1882_base_mixers; 4271 spec->mixers[0] = ad1882_base_mixers;
4270 if (codec->vendor_id == 0x11d1882) 4272 if (codec->vendor_id == 0x11d41882)
4271 spec->mixers[1] = ad1882_loopback_mixers; 4273 spec->mixers[1] = ad1882_loopback_mixers;
4272 else 4274 else
4273 spec->mixers[1] = ad1882a_loopback_mixers; 4275 spec->mixers[1] = ad1882a_loopback_mixers;
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 5887b827bb32..233e4778bba9 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -187,10 +187,10 @@ static int patch_atihdmi(struct hda_codec *codec)
187 * patch entries 187 * patch entries
188 */ 188 */
189static struct hda_codec_preset snd_hda_preset_atihdmi[] = { 189static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
190 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 190 { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
191 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 191 { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
192 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, 192 { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
193 { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, 193 { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
194 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi }, 194 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
195 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, 195 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
196 {} /* terminator */ 196 {} /* terminator */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b20e1cede00b..75de40aaab0a 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -25,6 +25,8 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/jack.h>
29
28#include "hda_codec.h" 30#include "hda_codec.h"
29#include "hda_local.h" 31#include "hda_local.h"
30 32
@@ -37,8 +39,21 @@
37#define CONEXANT_HP_EVENT 0x37 39#define CONEXANT_HP_EVENT 0x37
38#define CONEXANT_MIC_EVENT 0x38 40#define CONEXANT_MIC_EVENT 0x38
39 41
42/* Conexant 5051 specific */
43
44#define CXT5051_SPDIF_OUT 0x1C
45#define CXT5051_PORTB_EVENT 0x38
46#define CXT5051_PORTC_EVENT 0x39
40 47
41 48
49struct conexant_jack {
50
51 hda_nid_t nid;
52 int type;
53 struct snd_jack *jack;
54
55};
56
42struct conexant_spec { 57struct conexant_spec {
43 58
44 struct snd_kcontrol_new *mixers[5]; 59 struct snd_kcontrol_new *mixers[5];
@@ -83,6 +98,9 @@ struct conexant_spec {
83 98
84 unsigned int spdif_route; 99 unsigned int spdif_route;
85 100
101 /* jack detection */
102 struct snd_array jacks;
103
86 /* dynamic controls, init_verbs and input_mux */ 104 /* dynamic controls, init_verbs and input_mux */
87 struct auto_pin_cfg autocfg; 105 struct auto_pin_cfg autocfg;
88 struct hda_input_mux private_imux; 106 struct hda_input_mux private_imux;
@@ -329,6 +347,86 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
329 &spec->cur_mux[adc_idx]); 347 &spec->cur_mux[adc_idx]);
330} 348}
331 349
350static int conexant_add_jack(struct hda_codec *codec,
351 hda_nid_t nid, int type)
352{
353 struct conexant_spec *spec;
354 struct conexant_jack *jack;
355 const char *name;
356
357 spec = codec->spec;
358 snd_array_init(&spec->jacks, sizeof(*jack), 32);
359 jack = snd_array_new(&spec->jacks);
360 name = (type == SND_JACK_HEADPHONE) ? "Headphone" : "Mic" ;
361
362 if (!jack)
363 return -ENOMEM;
364
365 jack->nid = nid;
366 jack->type = type;
367
368 return snd_jack_new(codec->bus->card, name, type, &jack->jack);
369}
370
371static void conexant_report_jack(struct hda_codec *codec, hda_nid_t nid)
372{
373 struct conexant_spec *spec = codec->spec;
374 struct conexant_jack *jacks = spec->jacks.list;
375
376 if (jacks) {
377 int i;
378 for (i = 0; i < spec->jacks.used; i++) {
379 if (jacks->nid == nid) {
380 unsigned int present;
381 present = snd_hda_codec_read(codec, nid, 0,
382 AC_VERB_GET_PIN_SENSE, 0) &
383 AC_PINSENSE_PRESENCE;
384
385 present = (present) ? jacks->type : 0 ;
386
387 snd_jack_report(jacks->jack,
388 present);
389 }
390 jacks++;
391 }
392 }
393}
394
395static int conexant_init_jacks(struct hda_codec *codec)
396{
397#ifdef CONFIG_SND_JACK
398 struct conexant_spec *spec = codec->spec;
399 int i;
400
401 for (i = 0; i < spec->num_init_verbs; i++) {
402 const struct hda_verb *hv;
403
404 hv = spec->init_verbs[i];
405 while (hv->nid) {
406 int err = 0;
407 switch (hv->param ^ AC_USRSP_EN) {
408 case CONEXANT_HP_EVENT:
409 err = conexant_add_jack(codec, hv->nid,
410 SND_JACK_HEADPHONE);
411 conexant_report_jack(codec, hv->nid);
412 break;
413 case CXT5051_PORTC_EVENT:
414 case CONEXANT_MIC_EVENT:
415 err = conexant_add_jack(codec, hv->nid,
416 SND_JACK_MICROPHONE);
417 conexant_report_jack(codec, hv->nid);
418 break;
419 }
420 if (err < 0)
421 return err;
422 ++hv;
423 }
424 }
425#endif
426 return 0;
427
428}
429
332static int conexant_init(struct hda_codec *codec) 430static int conexant_init(struct hda_codec *codec)
333{ 431{
334 struct conexant_spec *spec = codec->spec; 432 struct conexant_spec *spec = codec->spec;
@@ -341,6 +439,16 @@ static int conexant_init(struct hda_codec *codec)
341 439
342static void conexant_free(struct hda_codec *codec) 440static void conexant_free(struct hda_codec *codec)
343{ 441{
442#ifdef CONFIG_SND_JACK
443 struct conexant_spec *spec = codec->spec;
444 if (spec->jacks.list) {
445 struct conexant_jack *jacks = spec->jacks.list;
446 int i;
447 for (i = 0; i < spec->jacks.used; i++)
448 snd_device_free(codec->bus->card, &jacks[i].jack);
449 snd_array_free(&spec->jacks);
450 }
451#endif
344 kfree(codec->spec); 452 kfree(codec->spec);
345} 453}
346 454
@@ -1526,9 +1634,6 @@ static int patch_cxt5047(struct hda_codec *codec)
1526/* Conexant 5051 specific */ 1634/* Conexant 5051 specific */
1527static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; 1635static hda_nid_t cxt5051_dac_nids[1] = { 0x10 };
1528static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; 1636static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 };
1529#define CXT5051_SPDIF_OUT 0x1C
1530#define CXT5051_PORTB_EVENT 0x38
1531#define CXT5051_PORTC_EVENT 0x39
1532 1637
1533static struct hda_channel_mode cxt5051_modes[1] = { 1638static struct hda_channel_mode cxt5051_modes[1] = {
1534 { 2, NULL }, 1639 { 2, NULL },
@@ -1608,6 +1713,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec)
1608static void cxt5051_hp_unsol_event(struct hda_codec *codec, 1713static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1609 unsigned int res) 1714 unsigned int res)
1610{ 1715{
1716 int nid = (res & AC_UNSOL_RES_SUBTAG) >> 20;
1611 switch (res >> 26) { 1717 switch (res >> 26) {
1612 case CONEXANT_HP_EVENT: 1718 case CONEXANT_HP_EVENT:
1613 cxt5051_hp_automute(codec); 1719 cxt5051_hp_automute(codec);
@@ -1619,6 +1725,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1619 cxt5051_portc_automic(codec); 1725 cxt5051_portc_automic(codec);
1620 break; 1726 break;
1621 } 1727 }
1728 conexant_report_jack(codec, nid);
1622} 1729}
1623 1730
1624static struct snd_kcontrol_new cxt5051_mixers[] = { 1731static struct snd_kcontrol_new cxt5051_mixers[] = {
@@ -1693,6 +1800,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1693static int cxt5051_init(struct hda_codec *codec) 1800static int cxt5051_init(struct hda_codec *codec)
1694{ 1801{
1695 conexant_init(codec); 1802 conexant_init(codec);
1803 conexant_init_jacks(codec);
1696 if (codec->patch_ops.unsol_event) { 1804 if (codec->patch_ops.unsol_event) {
1697 cxt5051_hp_automute(codec); 1805 cxt5051_hp_automute(codec);
1698 cxt5051_portb_automic(codec); 1806 cxt5051_portb_automic(codec);
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 290da562f29b..3564f4e4b74c 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -675,10 +675,10 @@ static int patch_intel_hdmi(struct hda_codec *codec)
675} 675}
676 676
677static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 677static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
678 { .id = 0x808629fb, .name = "INTEL G45 DEVCL", .patch = patch_intel_hdmi }, 678 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
679 { .id = 0x80862801, .name = "INTEL G45 DEVBLC", .patch = patch_intel_hdmi }, 679 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
680 { .id = 0x80862802, .name = "INTEL G45 DEVCTG", .patch = patch_intel_hdmi }, 680 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
681 { .id = 0x80862803, .name = "INTEL G45 DEVELK", .patch = patch_intel_hdmi }, 681 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
682 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 682 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
683 {} /* terminator */ 683 {} /* terminator */
684}; 684};
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index e23de5594b6e..d57d8132a06e 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -159,13 +159,19 @@ static int patch_nvhdmi(struct hda_codec *codec)
159 * patch entries 159 * patch entries
160 */ 160 */
161static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 161static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
162 { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, 162 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
163 { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, 163 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
164 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi },
165 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi },
166 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi },
164 {} /* terminator */ 167 {} /* terminator */
165}; 168};
166 169
167MODULE_ALIAS("snd-hda-codec-id:10de0002"); 170MODULE_ALIAS("snd-hda-codec-id:10de0002");
171MODULE_ALIAS("snd-hda-codec-id:10de0006");
168MODULE_ALIAS("snd-hda-codec-id:10de0007"); 172MODULE_ALIAS("snd-hda-codec-id:10de0007");
173MODULE_ALIAS("snd-hda-codec-id:10de0067");
174MODULE_ALIAS("snd-hda-codec-id:10de8001");
169 175
170MODULE_LICENSE("GPL"); 176MODULE_LICENSE("GPL");
171MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); 177MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index ba640d36d648..ea4c88fe05c4 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -765,6 +765,27 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
765 spec->init_verbs[spec->num_init_verbs++] = verb; 765 spec->init_verbs[spec->num_init_verbs++] = verb;
766} 766}
767 767
768#ifdef CONFIG_PROC_FS
769/*
770 * hook for proc
771 */
772static void print_realtek_coef(struct snd_info_buffer *buffer,
773 struct hda_codec *codec, hda_nid_t nid)
774{
775 int coeff;
776
777 if (nid != 0x20)
778 return;
779 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
780 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
781 coeff = snd_hda_codec_read(codec, nid, 0,
782 AC_VERB_GET_COEF_INDEX, 0);
783 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
784}
785#else
786#define print_realtek_coef NULL
787#endif
788
768/* 789/*
769 * set up from the preset table 790 * set up from the preset table
770 */ 791 */
@@ -1481,11 +1502,11 @@ static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1481 struct alc_spec *spec = codec->spec; 1502 struct alc_spec *spec = codec->spec;
1482 int err; 1503 int err;
1483 1504
1484 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1505 mutex_lock(&codec->control_mutex);
1485 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1506 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1486 HDA_INPUT); 1507 HDA_INPUT);
1487 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo); 1508 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1488 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1509 mutex_unlock(&codec->control_mutex);
1489 return err; 1510 return err;
1490} 1511}
1491 1512
@@ -1496,11 +1517,11 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1496 struct alc_spec *spec = codec->spec; 1517 struct alc_spec *spec = codec->spec;
1497 int err; 1518 int err;
1498 1519
1499 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1520 mutex_lock(&codec->control_mutex);
1500 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0, 1521 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1501 HDA_INPUT); 1522 HDA_INPUT);
1502 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv); 1523 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1503 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1524 mutex_unlock(&codec->control_mutex);
1504 return err; 1525 return err;
1505} 1526}
1506 1527
@@ -1516,11 +1537,11 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1516 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 1537 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1517 int err; 1538 int err;
1518 1539
1519 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1540 mutex_lock(&codec->control_mutex);
1520 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], 1541 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1521 3, 0, HDA_INPUT); 1542 3, 0, HDA_INPUT);
1522 err = func(kcontrol, ucontrol); 1543 err = func(kcontrol, ucontrol);
1523 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */ 1544 mutex_unlock(&codec->control_mutex);
1524 return err; 1545 return err;
1525} 1546}
1526 1547
@@ -4343,6 +4364,7 @@ static int patch_alc880(struct hda_codec *codec)
4343 if (!spec->loopback.amplist) 4364 if (!spec->loopback.amplist)
4344 spec->loopback.amplist = alc880_loopbacks; 4365 spec->loopback.amplist = alc880_loopbacks;
4345#endif 4366#endif
4367 codec->proc_widget_hook = print_realtek_coef;
4346 4368
4347 return 0; 4369 return 0;
4348} 4370}
@@ -5868,6 +5890,7 @@ static int patch_alc260(struct hda_codec *codec)
5868 if (!spec->loopback.amplist) 5890 if (!spec->loopback.amplist)
5869 spec->loopback.amplist = alc260_loopbacks; 5891 spec->loopback.amplist = alc260_loopbacks;
5870#endif 5892#endif
5893 codec->proc_widget_hook = print_realtek_coef;
5871 5894
5872 return 0; 5895 return 0;
5873} 5896}
@@ -7073,6 +7096,7 @@ static int patch_alc882(struct hda_codec *codec)
7073 if (!spec->loopback.amplist) 7096 if (!spec->loopback.amplist)
7074 spec->loopback.amplist = alc882_loopbacks; 7097 spec->loopback.amplist = alc882_loopbacks;
7075#endif 7098#endif
7099 codec->proc_widget_hook = print_realtek_coef;
7076 7100
7077 return 0; 7101 return 0;
7078} 7102}
@@ -8437,12 +8461,17 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8437 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8461 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8438 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", 8462 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8439 ALC888_ACER_ASPIRE_4930G), 8463 ALC888_ACER_ASPIRE_4930G),
8464 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
8465 ALC888_ACER_ASPIRE_4930G),
8466 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
8467 ALC888_ACER_ASPIRE_4930G),
8440 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ 8468 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8441 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8469 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8442 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8470 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
8443 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8471 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
8444 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8472 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
8445 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8473 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8474 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
8446 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8475 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8447 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8476 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8448 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 8477 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
@@ -8497,6 +8526,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8497 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8526 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8498 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8527 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
8499 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8528 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
8529 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
8500 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8530 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
8501 {} 8531 {}
8502}; 8532};
@@ -9041,6 +9071,7 @@ static int patch_alc883(struct hda_codec *codec)
9041 if (!spec->loopback.amplist) 9071 if (!spec->loopback.amplist)
9042 spec->loopback.amplist = alc883_loopbacks; 9072 spec->loopback.amplist = alc883_loopbacks;
9043#endif 9073#endif
9074 codec->proc_widget_hook = print_realtek_coef;
9044 9075
9045 return 0; 9076 return 0;
9046} 9077}
@@ -10533,6 +10564,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
10533 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10564 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10534 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10565 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10535 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 10566 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10567 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10568 ALC262_SONY_ASSAMD),
10536 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10569 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10537 ALC262_TOSHIBA_RX1), 10570 ALC262_TOSHIBA_RX1),
10538 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 10571 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -10847,6 +10880,7 @@ static int patch_alc262(struct hda_codec *codec)
10847 if (!spec->loopback.amplist) 10880 if (!spec->loopback.amplist)
10848 spec->loopback.amplist = alc262_loopbacks; 10881 spec->loopback.amplist = alc262_loopbacks;
10849#endif 10882#endif
10883 codec->proc_widget_hook = print_realtek_coef;
10850 10884
10851 return 0; 10885 return 0;
10852} 10886}
@@ -11660,6 +11694,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
11660 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", 11694 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
11661 ALC268_ACER_ASPIRE_ONE), 11695 ALC268_ACER_ASPIRE_ONE),
11662 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 11696 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
11697 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
11663 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), 11698 SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
11664 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 11699 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
11665 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), 11700 SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
@@ -11912,6 +11947,8 @@ static int patch_alc268(struct hda_codec *codec)
11912 if (board_config == ALC268_AUTO) 11947 if (board_config == ALC268_AUTO)
11913 spec->init_hook = alc268_auto_init; 11948 spec->init_hook = alc268_auto_init;
11914 11949
11950 codec->proc_widget_hook = print_realtek_coef;
11951
11915 return 0; 11952 return 0;
11916} 11953}
11917 11954
@@ -12713,6 +12750,7 @@ static int patch_alc269(struct hda_codec *codec)
12713 if (!spec->loopback.amplist) 12750 if (!spec->loopback.amplist)
12714 spec->loopback.amplist = alc269_loopbacks; 12751 spec->loopback.amplist = alc269_loopbacks;
12715#endif 12752#endif
12753 codec->proc_widget_hook = print_realtek_coef;
12716 12754
12717 return 0; 12755 return 0;
12718} 12756}
@@ -13801,6 +13839,7 @@ static int patch_alc861(struct hda_codec *codec)
13801 if (!spec->loopback.amplist) 13839 if (!spec->loopback.amplist)
13802 spec->loopback.amplist = alc861_loopbacks; 13840 spec->loopback.amplist = alc861_loopbacks;
13803#endif 13841#endif
13842 codec->proc_widget_hook = print_realtek_coef;
13804 13843
13805 return 0; 13844 return 0;
13806} 13845}
@@ -14762,6 +14801,7 @@ static int patch_alc861vd(struct hda_codec *codec)
14762 if (!spec->loopback.amplist) 14801 if (!spec->loopback.amplist)
14763 spec->loopback.amplist = alc861vd_loopbacks; 14802 spec->loopback.amplist = alc861vd_loopbacks;
14764#endif 14803#endif
14804 codec->proc_widget_hook = print_realtek_coef;
14765 14805
14766 return 0; 14806 return 0;
14767} 14807}
@@ -16571,6 +16611,7 @@ static int patch_alc662(struct hda_codec *codec)
16571 if (!spec->loopback.amplist) 16611 if (!spec->loopback.amplist)
16572 spec->loopback.amplist = alc662_loopbacks; 16612 spec->loopback.amplist = alc662_loopbacks;
16573#endif 16613#endif
16614 codec->proc_widget_hook = print_realtek_coef;
16574 16615
16575 return 0; 16616 return 0;
16576} 16617}
@@ -16604,9 +16645,9 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
16604 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 16645 .patch = patch_alc882 }, /* should be patch_alc883() in future */
16605 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 16646 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
16606 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 16647 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 },
16607 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16608 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 16648 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
16609 .patch = patch_alc883 }, 16649 .patch = patch_alc883 },
16650 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
16610 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 16651 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16611 {} /* terminator */ 16652 {} /* terminator */
16612}; 16653};
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index c05d4643afd5..0e6fc56fa378 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -70,6 +70,7 @@ enum {
70}; 70};
71 71
72enum { 72enum {
73 STAC_92HD73XX_NO_JD, /* no jack-detection */
73 STAC_92HD73XX_REF, 74 STAC_92HD73XX_REF,
74 STAC_DELL_M6_AMIC, 75 STAC_DELL_M6_AMIC,
75 STAC_DELL_M6_DMIC, 76 STAC_DELL_M6_DMIC,
@@ -132,6 +133,7 @@ enum {
132}; 133};
133 134
134enum { 135enum {
136 STAC_D965_REF_NO_JD, /* no jack-detection */
135 STAC_D965_REF, 137 STAC_D965_REF,
136 STAC_D965_3ST, 138 STAC_D965_3ST,
137 STAC_D965_5ST, 139 STAC_D965_5ST,
@@ -160,8 +162,6 @@ struct sigmatel_spec {
160 int board_config; 162 int board_config;
161 unsigned int eapd_switch: 1; 163 unsigned int eapd_switch: 1;
162 unsigned int surr_switch: 1; 164 unsigned int surr_switch: 1;
163 unsigned int line_switch: 1;
164 unsigned int mic_switch: 1;
165 unsigned int alt_switch: 1; 165 unsigned int alt_switch: 1;
166 unsigned int hp_detect: 1; 166 unsigned int hp_detect: 1;
167 unsigned int spdif_mute: 1; 167 unsigned int spdif_mute: 1;
@@ -198,6 +198,8 @@ struct sigmatel_spec {
198 unsigned int cur_mmux; 198 unsigned int cur_mmux;
199 struct hda_multi_out multiout; 199 struct hda_multi_out multiout;
200 hda_nid_t dac_nids[5]; 200 hda_nid_t dac_nids[5];
201 hda_nid_t hp_dacs[5];
202 hda_nid_t speaker_dacs[5];
201 203
202 /* capture */ 204 /* capture */
203 hda_nid_t *adc_nids; 205 hda_nid_t *adc_nids;
@@ -241,7 +243,9 @@ struct sigmatel_spec {
241 /* i/o switches */ 243 /* i/o switches */
242 unsigned int io_switch[2]; 244 unsigned int io_switch[2];
243 unsigned int clfe_swap; 245 unsigned int clfe_swap;
244 unsigned int hp_switch; /* NID of HP as line-out */ 246 hda_nid_t line_switch; /* shared line-in for input and output */
247 hda_nid_t mic_switch; /* shared mic-in for input and output */
248 hda_nid_t hp_switch; /* NID of HP as line-out */
245 unsigned int aloopback; 249 unsigned int aloopback;
246 250
247 struct hda_pcm pcm_rec[2]; /* PCM information */ 251 struct hda_pcm pcm_rec[2]; /* PCM information */
@@ -292,9 +296,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
292}; 296};
293 297
294#define STAC92HD73_DAC_COUNT 5 298#define STAC92HD73_DAC_COUNT 5
295static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
296 0x15, 0x16, 0x17, 0x18, 0x19,
297};
298 299
299static hda_nid_t stac92hd73xx_mux_nids[4] = { 300static hda_nid_t stac92hd73xx_mux_nids[4] = {
300 0x28, 0x29, 0x2a, 0x2b, 301 0x28, 0x29, 0x2a, 0x2b,
@@ -313,11 +314,7 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
313 0x11, 0x12, 0 314 0x11, 0x12, 0
314}; 315};
315 316
316#define STAC92HD81_DAC_COUNT 2
317#define STAC92HD83_DAC_COUNT 3 317#define STAC92HD83_DAC_COUNT 3
318static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
319 0x13, 0x14, 0x22,
320};
321 318
322static hda_nid_t stac92hd83xxx_dmux_nids[2] = { 319static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
323 0x17, 0x18, 320 0x17, 0x18,
@@ -359,10 +356,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = {
359 0x24, 0x25, 356 0x24, 0x25,
360}; 357};
361 358
362static hda_nid_t stac92hd71bxx_dac_nids[1] = {
363 0x10, /*0x11, */
364};
365
366#define STAC92HD71BXX_NUM_DMICS 2 359#define STAC92HD71BXX_NUM_DMICS 2
367static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 360static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
368 0x18, 0x19, 0 361 0x18, 0x19, 0
@@ -594,12 +587,12 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
594 else 587 else
595 nid = codec->slave_dig_outs[smux_idx - 1]; 588 nid = codec->slave_dig_outs[smux_idx - 1];
596 if (spec->cur_smux[smux_idx] == smux->num_items - 1) 589 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
597 val = AMP_OUT_MUTE; 590 val = HDA_AMP_MUTE;
598 else 591 else
599 val = AMP_OUT_UNMUTE; 592 val = 0;
600 /* un/mute SPDIF out */ 593 /* un/mute SPDIF out */
601 snd_hda_codec_write_cache(codec, nid, 0, 594 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
602 AC_VERB_SET_AMP_GAIN_MUTE, val); 595 HDA_AMP_MUTE, val);
603 } 596 }
604 return 0; 597 return 0;
605} 598}
@@ -764,10 +757,6 @@ static struct hda_verb stac9200_eapd_init[] = {
764static struct hda_verb stac92hd73xx_6ch_core_init[] = { 757static struct hda_verb stac92hd73xx_6ch_core_init[] = {
765 /* set master volume and direct control */ 758 /* set master volume and direct control */
766 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 759 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
767 /* setup audio connections */
768 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
769 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
770 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
771 /* setup adcs to point to mixer */ 760 /* setup adcs to point to mixer */
772 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 761 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
773 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 762 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -786,10 +775,6 @@ static struct hda_verb dell_eq_core_init[] = {
786 /* set master volume to max value without distortion 775 /* set master volume to max value without distortion
787 * and direct control */ 776 * and direct control */
788 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 777 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
789 /* setup audio connections */
790 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
791 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
792 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
793 /* setup adcs to point to mixer */ 778 /* setup adcs to point to mixer */
794 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 779 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
795 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 780 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -803,10 +788,6 @@ static struct hda_verb dell_eq_core_init[] = {
803 788
804static struct hda_verb dell_m6_core_init[] = { 789static struct hda_verb dell_m6_core_init[] = {
805 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 790 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
806 /* setup audio connections */
807 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
808 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
809 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
810 /* setup adcs to point to mixer */ 791 /* setup adcs to point to mixer */
811 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 792 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
812 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 793 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -821,13 +802,6 @@ static struct hda_verb dell_m6_core_init[] = {
821static struct hda_verb stac92hd73xx_8ch_core_init[] = { 802static struct hda_verb stac92hd73xx_8ch_core_init[] = {
822 /* set master volume and direct control */ 803 /* set master volume and direct control */
823 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 804 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
824 /* setup audio connections */
825 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
826 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
827 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
828 /* connect hp ports to dac3 */
829 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
830 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
831 /* setup adcs to point to mixer */ 805 /* setup adcs to point to mixer */
832 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 806 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
833 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 807 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -845,15 +819,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = {
845static struct hda_verb stac92hd73xx_10ch_core_init[] = { 819static struct hda_verb stac92hd73xx_10ch_core_init[] = {
846 /* set master volume and direct control */ 820 /* set master volume and direct control */
847 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 821 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
848 /* setup audio connections */
849 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
850 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
851 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
852 /* dac3 is connected to import3 mux */ 822 /* dac3 is connected to import3 mux */
853 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, 823 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
854 /* connect hp ports to dac4 */
855 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
856 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
857 /* setup adcs to point to mixer */ 824 /* setup adcs to point to mixer */
858 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 825 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
859 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 826 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -879,17 +846,17 @@ static struct hda_verb stac92hd83xxx_core_init[] = {
879 846
880 /* power state controls amps */ 847 /* power state controls amps */
881 { 0x01, AC_VERB_SET_EAPD, 1 << 2}, 848 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
849 {}
882}; 850};
883 851
884static struct hda_verb stac92hd71bxx_core_init[] = { 852static struct hda_verb stac92hd71bxx_core_init[] = {
885 /* set master volume and direct control */ 853 /* set master volume and direct control */
886 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 854 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
887 /* connect headphone jack to dac1 */
888 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
889 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 855 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
890 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 856 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
891 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 857 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
892 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 858 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
859 {}
893}; 860};
894 861
895#define HD_DISABLE_PORTF 2 862#define HD_DISABLE_PORTF 2
@@ -904,8 +871,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = {
904 871
905 /* set master volume and direct control */ 872 /* set master volume and direct control */
906 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 873 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
907 /* connect headphone jack to dac1 */
908 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
909 /* unmute right and left channels for nodes 0x0a, 0xd */ 874 /* unmute right and left channels for nodes 0x0a, 0xd */
910 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 875 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
911 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 876 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1105,21 +1070,21 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1105 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), 1070 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1106 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), 1071 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1107 1072
1108 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), 1073 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
1109 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), 1074 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
1110 1075
1111 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), 1076 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
1112 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), 1077 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
1113 1078
1114 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), 1079 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
1115 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), 1080 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
1116 1081
1117 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), 1082 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
1118 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), 1083 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
1119 1084
1120 /* 1085 /*
1121 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), 1086 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
1122 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), 1087 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
1123 */ 1088 */
1124 { } /* end */ 1089 { } /* end */
1125}; 1090};
@@ -1296,7 +1261,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1296 spec->spdif_mute = 1; 1261 spec->spdif_mute = 1;
1297 } 1262 }
1298 stac_smux_mixer.count = spec->num_smuxes; 1263 stac_smux_mixer.count = spec->num_smuxes;
1299 err = snd_ctl_add(codec->bus->card, 1264 err = snd_hda_ctl_add(codec,
1300 snd_ctl_new1(&stac_smux_mixer, codec)); 1265 snd_ctl_new1(&stac_smux_mixer, codec));
1301 if (err < 0) 1266 if (err < 0)
1302 return err; 1267 return err;
@@ -1720,6 +1685,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1720}; 1685};
1721 1686
1722static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1687static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1688 [STAC_92HD73XX_NO_JD] = "no-jd",
1723 [STAC_92HD73XX_REF] = "ref", 1689 [STAC_92HD73XX_REF] = "ref",
1724 [STAC_DELL_M6_AMIC] = "dell-m6-amic", 1690 [STAC_DELL_M6_AMIC] = "dell-m6-amic",
1725 [STAC_DELL_M6_DMIC] = "dell-m6-dmic", 1691 [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
@@ -1749,6 +1715,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1749 "unknown Dell", STAC_DELL_M6_DMIC), 1715 "unknown Dell", STAC_DELL_M6_DMIC),
1750 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, 1716 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1751 "Dell Studio 1537", STAC_DELL_M6_DMIC), 1717 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1718 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1719 "Dell Studio 17", STAC_DELL_M6_DMIC),
1752 {} /* terminator */ 1720 {} /* terminator */
1753}; 1721};
1754 1722
@@ -1770,7 +1738,8 @@ static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1770static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { 1738static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1771 /* SigmaTel reference board */ 1739 /* SigmaTel reference board */
1772 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1740 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1773 "DFI LanParty", STAC_92HD71BXX_REF), 1741 "DFI LanParty", STAC_92HD83XXX_REF),
1742 {} /* terminator */
1774}; 1743};
1775 1744
1776static unsigned int ref92hd71bxx_pin_configs[11] = { 1745static unsigned int ref92hd71bxx_pin_configs[11] = {
@@ -1821,6 +1790,10 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1821 "HP dv5", STAC_HP_M4), 1790 "HP dv5", STAC_HP_M4),
1822 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, 1791 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
1823 "HP dv7", STAC_HP_M4), 1792 "HP dv7", STAC_HP_M4),
1793 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
1794 "HP dv7", STAC_HP_M4),
1795 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603,
1796 "HP dv5", STAC_HP_M4),
1824 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1797 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1825 "unknown HP", STAC_HP_M4), 1798 "unknown HP", STAC_HP_M4),
1826 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1799 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2136,6 +2109,7 @@ static unsigned int dell_3st_pin_configs[14] = {
2136}; 2109};
2137 2110
2138static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { 2111static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2112 [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
2139 [STAC_D965_REF] = ref927x_pin_configs, 2113 [STAC_D965_REF] = ref927x_pin_configs,
2140 [STAC_D965_3ST] = d965_3st_pin_configs, 2114 [STAC_D965_3ST] = d965_3st_pin_configs,
2141 [STAC_D965_5ST] = d965_5st_pin_configs, 2115 [STAC_D965_5ST] = d965_5st_pin_configs,
@@ -2144,6 +2118,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2144}; 2118};
2145 2119
2146static const char *stac927x_models[STAC_927X_MODELS] = { 2120static const char *stac927x_models[STAC_927X_MODELS] = {
2121 [STAC_D965_REF_NO_JD] = "ref-no-jd",
2147 [STAC_D965_REF] = "ref", 2122 [STAC_D965_REF] = "ref",
2148 [STAC_D965_3ST] = "3stack", 2123 [STAC_D965_3ST] = "3stack",
2149 [STAC_D965_5ST] = "5stack", 2124 [STAC_D965_5ST] = "5stack",
@@ -2468,7 +2443,7 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2468 2443
2469 if (spec->powerdown_adcs) { 2444 if (spec->powerdown_adcs) {
2470 msleep(40); 2445 msleep(40);
2471 snd_hda_codec_write_cache(codec, nid, 0, 2446 snd_hda_codec_write(codec, nid, 0,
2472 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 2447 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2473 } 2448 }
2474 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 2449 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -2484,7 +2459,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2484 2459
2485 snd_hda_codec_cleanup_stream(codec, nid); 2460 snd_hda_codec_cleanup_stream(codec, nid);
2486 if (spec->powerdown_adcs) 2461 if (spec->powerdown_adcs)
2487 snd_hda_codec_write_cache(codec, nid, 0, 2462 snd_hda_codec_write(codec, nid, 0,
2488 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 2463 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2489 return 0; 2464 return 0;
2490} 2465}
@@ -2796,70 +2771,53 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2796 return stac92xx_add_control_idx(spec, type, 0, name, val); 2771 return stac92xx_add_control_idx(spec, type, 0, name, val);
2797} 2772}
2798 2773
2799/* flag inputs as additional dynamic lineouts */ 2774/* check whether the line-input can be used as line-out */
2800static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) 2775static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2801{ 2776{
2802 struct sigmatel_spec *spec = codec->spec; 2777 struct sigmatel_spec *spec = codec->spec;
2803 unsigned int wcaps, wtype; 2778 struct auto_pin_cfg *cfg = &spec->autocfg;
2804 int i, num_dacs = 0; 2779 hda_nid_t nid;
2805 2780 unsigned int pincap;
2806 /* use the wcaps cache to count all DACs available for line-outs */
2807 for (i = 0; i < codec->num_nodes; i++) {
2808 wcaps = codec->wcaps[i];
2809 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2810 2781
2811 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) 2782 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2812 num_dacs++; 2783 return 0;
2813 } 2784 nid = cfg->input_pins[AUTO_PIN_LINE];
2785 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2786 if (pincap & AC_PINCAP_OUT)
2787 return nid;
2788 return 0;
2789}
2814 2790
2815 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); 2791/* check whether the mic-input can be used as line-out */
2816 2792static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
2817 switch (cfg->line_outs) { 2793{
2818 case 3: 2794 struct sigmatel_spec *spec = codec->spec;
2819 /* add line-in as side */ 2795 struct auto_pin_cfg *cfg = &spec->autocfg;
2820 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { 2796 unsigned int def_conf, pincap;
2821 cfg->line_out_pins[cfg->line_outs] = 2797 unsigned int mic_pin;
2822 cfg->input_pins[AUTO_PIN_LINE]; 2798
2823 spec->line_switch = 1; 2799 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2824 cfg->line_outs++; 2800 return 0;
2825 } 2801 mic_pin = AUTO_PIN_MIC;
2826 break; 2802 for (;;) {
2827 case 2: 2803 hda_nid_t nid = cfg->input_pins[mic_pin];
2828 /* add line-in as clfe and mic as side */ 2804 def_conf = snd_hda_codec_read(codec, nid, 0,
2829 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { 2805 AC_VERB_GET_CONFIG_DEFAULT, 0);
2830 cfg->line_out_pins[cfg->line_outs] = 2806 /* some laptops have an internal analog microphone
2831 cfg->input_pins[AUTO_PIN_LINE]; 2807 * which can't be used as a output */
2832 spec->line_switch = 1; 2808 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2833 cfg->line_outs++; 2809 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2834 } 2810 if (pincap & AC_PINCAP_OUT)
2835 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { 2811 return nid;
2836 cfg->line_out_pins[cfg->line_outs] =
2837 cfg->input_pins[AUTO_PIN_MIC];
2838 spec->mic_switch = 1;
2839 cfg->line_outs++;
2840 }
2841 break;
2842 case 1:
2843 /* add line-in as surr and mic as clfe */
2844 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2845 cfg->line_out_pins[cfg->line_outs] =
2846 cfg->input_pins[AUTO_PIN_LINE];
2847 spec->line_switch = 1;
2848 cfg->line_outs++;
2849 }
2850 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2851 cfg->line_out_pins[cfg->line_outs] =
2852 cfg->input_pins[AUTO_PIN_MIC];
2853 spec->mic_switch = 1;
2854 cfg->line_outs++;
2855 } 2812 }
2856 break; 2813 if (mic_pin == AUTO_PIN_MIC)
2814 mic_pin = AUTO_PIN_FRONT_MIC;
2815 else
2816 break;
2857 } 2817 }
2858
2859 return 0; 2818 return 0;
2860} 2819}
2861 2820
2862
2863static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 2821static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2864{ 2822{
2865 int i; 2823 int i;
@@ -2872,6 +2830,52 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2872 return 0; 2830 return 0;
2873} 2831}
2874 2832
2833static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2834{
2835 int i;
2836 if (is_in_dac_nids(spec, nid))
2837 return 1;
2838 for (i = 0; i < spec->autocfg.hp_outs; i++)
2839 if (spec->hp_dacs[i] == nid)
2840 return 1;
2841 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2842 if (spec->speaker_dacs[i] == nid)
2843 return 1;
2844 return 0;
2845}
2846
2847static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2848{
2849 struct sigmatel_spec *spec = codec->spec;
2850 int j, conn_len;
2851 hda_nid_t conn[HDA_MAX_CONNECTIONS];
2852 unsigned int wcaps, wtype;
2853
2854 conn_len = snd_hda_get_connections(codec, nid, conn,
2855 HDA_MAX_CONNECTIONS);
2856 for (j = 0; j < conn_len; j++) {
2857 wcaps = snd_hda_param_read(codec, conn[j],
2858 AC_PAR_AUDIO_WIDGET_CAP);
2859 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2860 /* we check only analog outputs */
2861 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
2862 continue;
2863 /* if this route has a free DAC, assign it */
2864 if (!check_all_dac_nids(spec, conn[j])) {
2865 if (conn_len > 1) {
2866 /* select this DAC in the pin's input mux */
2867 snd_hda_codec_write_cache(codec, nid, 0,
2868 AC_VERB_SET_CONNECT_SEL, j);
2869 }
2870 return conn[j];
2871 }
2872 }
2873 return 0;
2874}
2875
2876static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2877static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2878
2875/* 2879/*
2876 * Fill in the dac_nids table from the parsed pin configuration 2880 * Fill in the dac_nids table from the parsed pin configuration
2877 * This function only works when every pin in line_out_pins[] 2881 * This function only works when every pin in line_out_pins[]
@@ -2879,31 +2883,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2879 * codecs are not connected directly to a DAC, such as the 9200 2883 * codecs are not connected directly to a DAC, such as the 9200
2880 * and 9202/925x. For those, dac_nids[] must be hard-coded. 2884 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2881 */ 2885 */
2882static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, 2886static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
2883 struct auto_pin_cfg *cfg)
2884{ 2887{
2885 struct sigmatel_spec *spec = codec->spec; 2888 struct sigmatel_spec *spec = codec->spec;
2886 int i, j, conn_len = 0; 2889 struct auto_pin_cfg *cfg = &spec->autocfg;
2887 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; 2890 int i;
2888 unsigned int wcaps, wtype; 2891 hda_nid_t nid, dac;
2889 2892
2890 for (i = 0; i < cfg->line_outs; i++) { 2893 for (i = 0; i < cfg->line_outs; i++) {
2891 nid = cfg->line_out_pins[i]; 2894 nid = cfg->line_out_pins[i];
2892 conn_len = snd_hda_get_connections(codec, nid, conn, 2895 dac = get_unassigned_dac(codec, nid);
2893 HDA_MAX_CONNECTIONS); 2896 if (!dac) {
2894 for (j = 0; j < conn_len; j++) {
2895 wcaps = snd_hda_param_read(codec, conn[j],
2896 AC_PAR_AUDIO_WIDGET_CAP);
2897 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2898 if (wtype != AC_WID_AUD_OUT ||
2899 (wcaps & AC_WCAP_DIGITAL))
2900 continue;
2901 /* conn[j] is a DAC routed to this line-out */
2902 if (!is_in_dac_nids(spec, conn[j]))
2903 break;
2904 }
2905
2906 if (j == conn_len) {
2907 if (spec->multiout.num_dacs > 0) { 2897 if (spec->multiout.num_dacs > 0) {
2908 /* we have already working output pins, 2898 /* we have already working output pins,
2909 * so let's drop the broken ones again 2899 * so let's drop the broken ones again
@@ -2917,24 +2907,64 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2917 __func__, nid); 2907 __func__, nid);
2918 return -ENODEV; 2908 return -ENODEV;
2919 } 2909 }
2910 add_spec_dacs(spec, dac);
2911 }
2920 2912
2921 spec->multiout.dac_nids[i] = conn[j]; 2913 /* add line-in as output */
2922 spec->multiout.num_dacs++; 2914 nid = check_line_out_switch(codec);
2923 if (conn_len > 1) { 2915 if (nid) {
2924 /* select this DAC in the pin's input mux */ 2916 dac = get_unassigned_dac(codec, nid);
2925 snd_hda_codec_write_cache(codec, nid, 0, 2917 if (dac) {
2926 AC_VERB_SET_CONNECT_SEL, j); 2918 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
2919 nid, cfg->line_outs);
2920 cfg->line_out_pins[cfg->line_outs] = nid;
2921 cfg->line_outs++;
2922 spec->line_switch = nid;
2923 add_spec_dacs(spec, dac);
2924 }
2925 }
2926 /* add mic as output */
2927 nid = check_mic_out_switch(codec);
2928 if (nid) {
2929 dac = get_unassigned_dac(codec, nid);
2930 if (dac) {
2931 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
2932 nid, cfg->line_outs);
2933 cfg->line_out_pins[cfg->line_outs] = nid;
2934 cfg->line_outs++;
2935 spec->mic_switch = nid;
2936 add_spec_dacs(spec, dac);
2937 }
2938 }
2927 2939
2940 for (i = 0; i < cfg->hp_outs; i++) {
2941 nid = cfg->hp_pins[i];
2942 dac = get_unassigned_dac(codec, nid);
2943 if (dac) {
2944 if (!spec->multiout.hp_nid)
2945 spec->multiout.hp_nid = dac;
2946 else
2947 add_spec_extra_dacs(spec, dac);
2928 } 2948 }
2949 spec->hp_dacs[i] = dac;
2929 } 2950 }
2930 2951
2931 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2952 for (i = 0; i < cfg->speaker_outs; i++) {
2953 nid = cfg->speaker_pins[i];
2954 dac = get_unassigned_dac(codec, nid);
2955 if (dac)
2956 add_spec_extra_dacs(spec, dac);
2957 spec->speaker_dacs[i] = dac;
2958 }
2959
2960 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2932 spec->multiout.num_dacs, 2961 spec->multiout.num_dacs,
2933 spec->multiout.dac_nids[0], 2962 spec->multiout.dac_nids[0],
2934 spec->multiout.dac_nids[1], 2963 spec->multiout.dac_nids[1],
2935 spec->multiout.dac_nids[2], 2964 spec->multiout.dac_nids[2],
2936 spec->multiout.dac_nids[3], 2965 spec->multiout.dac_nids[3],
2937 spec->multiout.dac_nids[4]); 2966 spec->multiout.dac_nids[4]);
2967
2938 return 0; 2968 return 0;
2939} 2969}
2940 2970
@@ -2959,9 +2989,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_
2959 2989
2960static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) 2990static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2961{ 2991{
2962 if (!spec->multiout.hp_nid) 2992 if (spec->multiout.num_dacs > 4) {
2963 spec->multiout.hp_nid = nid;
2964 else if (spec->multiout.num_dacs > 4) {
2965 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); 2993 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2966 return 1; 2994 return 1;
2967 } else { 2995 } else {
@@ -2971,35 +2999,47 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2971 return 0; 2999 return 0;
2972} 3000}
2973 3001
2974static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 3002static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2975{ 3003{
2976 if (is_in_dac_nids(spec, nid)) 3004 int i;
2977 return 1; 3005 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
3006 if (!spec->multiout.extra_out_nid[i]) {
3007 spec->multiout.extra_out_nid[i] = nid;
3008 return 0;
3009 }
3010 }
3011 printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
3012 return 1;
3013}
3014
3015static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid)
3016{
3017 int i;
3018
3019 if (spec->autocfg.line_outs != 1)
3020 return 0;
2978 if (spec->multiout.hp_nid == nid) 3021 if (spec->multiout.hp_nid == nid)
2979 return 1; 3022 return 0;
2980 return 0; 3023 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
3024 if (spec->multiout.extra_out_nid[i] == nid)
3025 return 0;
3026 return 1;
2981} 3027}
2982 3028
2983/* add playback controls from the parsed DAC table */ 3029/* add playback controls from the parsed DAC table */
2984static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, 3030static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2985 const struct auto_pin_cfg *cfg) 3031 const struct auto_pin_cfg *cfg)
2986{ 3032{
3033 struct sigmatel_spec *spec = codec->spec;
2987 static const char *chname[4] = { 3034 static const char *chname[4] = {
2988 "Front", "Surround", NULL /*CLFE*/, "Side" 3035 "Front", "Surround", NULL /*CLFE*/, "Side"
2989 }; 3036 };
2990 hda_nid_t nid = 0; 3037 hda_nid_t nid = 0;
2991 int i, err; 3038 int i, err;
3039 unsigned int wid_caps;
2992 3040
2993 struct sigmatel_spec *spec = codec->spec; 3041 for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) {
2994 unsigned int wid_caps, pincap;
2995
2996
2997 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
2998 if (!spec->multiout.dac_nids[i])
2999 continue;
3000
3001 nid = spec->multiout.dac_nids[i]; 3042 nid = spec->multiout.dac_nids[i];
3002
3003 if (i == 2) { 3043 if (i == 2) {
3004 /* Center/LFE */ 3044 /* Center/LFE */
3005 err = create_controls(spec, "Center", nid, 1); 3045 err = create_controls(spec, "Center", nid, 1);
@@ -3021,16 +3061,24 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3021 } 3061 }
3022 3062
3023 } else { 3063 } else {
3024 err = create_controls(spec, chname[i], nid, 3); 3064 const char *name = chname[i];
3065 /* if it's a single DAC, assign a better name */
3066 if (!i && is_unique_dac(spec, nid)) {
3067 switch (cfg->line_out_type) {
3068 case AUTO_PIN_HP_OUT:
3069 name = "Headphone";
3070 break;
3071 case AUTO_PIN_SPEAKER_OUT:
3072 name = "Speaker";
3073 break;
3074 }
3075 }
3076 err = create_controls(spec, name, nid, 3);
3025 if (err < 0) 3077 if (err < 0)
3026 return err; 3078 return err;
3027 } 3079 }
3028 } 3080 }
3029 3081
3030 if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
3031 cfg->hp_outs && !spec->multiout.hp_nid)
3032 spec->multiout.hp_nid = nid;
3033
3034 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { 3082 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
3035 err = stac92xx_add_control(spec, 3083 err = stac92xx_add_control(spec,
3036 STAC_CTL_WIDGET_HP_SWITCH, 3084 STAC_CTL_WIDGET_HP_SWITCH,
@@ -3041,45 +3089,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3041 } 3089 }
3042 3090
3043 if (spec->line_switch) { 3091 if (spec->line_switch) {
3044 nid = cfg->input_pins[AUTO_PIN_LINE]; 3092 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
3045 pincap = snd_hda_param_read(codec, nid, 3093 "Line In as Output Switch",
3046 AC_PAR_PIN_CAP); 3094 spec->line_switch << 8);
3047 if (pincap & AC_PINCAP_OUT) { 3095 if (err < 0)
3048 err = stac92xx_add_control(spec, 3096 return err;
3049 STAC_CTL_WIDGET_IO_SWITCH,
3050 "Line In as Output Switch", nid << 8);
3051 if (err < 0)
3052 return err;
3053 }
3054 } 3097 }
3055 3098
3056 if (spec->mic_switch) { 3099 if (spec->mic_switch) {
3057 unsigned int def_conf; 3100 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
3058 unsigned int mic_pin = AUTO_PIN_MIC; 3101 "Mic as Output Switch",
3059again: 3102 (spec->mic_switch << 8) | 1);
3060 nid = cfg->input_pins[mic_pin]; 3103 if (err < 0)
3061 def_conf = snd_hda_codec_read(codec, nid, 0, 3104 return err;
3062 AC_VERB_GET_CONFIG_DEFAULT, 0);
3063 /* some laptops have an internal analog microphone
3064 * which can't be used as a output */
3065 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
3066 pincap = snd_hda_param_read(codec, nid,
3067 AC_PAR_PIN_CAP);
3068 if (pincap & AC_PINCAP_OUT) {
3069 err = stac92xx_add_control(spec,
3070 STAC_CTL_WIDGET_IO_SWITCH,
3071 "Mic as Output Switch", (nid << 8) | 1);
3072 nid = snd_hda_codec_read(codec, nid, 0,
3073 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
3074 if (!check_in_dac_nids(spec, nid))
3075 add_spec_dacs(spec, nid);
3076 if (err < 0)
3077 return err;
3078 }
3079 } else if (mic_pin == AUTO_PIN_MIC) {
3080 mic_pin = AUTO_PIN_FRONT_MIC;
3081 goto again;
3082 }
3083 } 3105 }
3084 3106
3085 return 0; 3107 return 0;
@@ -3091,55 +3113,39 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
3091{ 3113{
3092 struct sigmatel_spec *spec = codec->spec; 3114 struct sigmatel_spec *spec = codec->spec;
3093 hda_nid_t nid; 3115 hda_nid_t nid;
3094 int i, old_num_dacs, err; 3116 int i, err, nums;
3095 3117
3096 old_num_dacs = spec->multiout.num_dacs; 3118 nums = 0;
3097 for (i = 0; i < cfg->hp_outs; i++) { 3119 for (i = 0; i < cfg->hp_outs; i++) {
3120 static const char *pfxs[] = {
3121 "Headphone", "Headphone2", "Headphone3",
3122 };
3098 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); 3123 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
3099 if (wid_caps & AC_WCAP_UNSOL_CAP) 3124 if (wid_caps & AC_WCAP_UNSOL_CAP)
3100 spec->hp_detect = 1; 3125 spec->hp_detect = 1;
3101 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, 3126 if (nums >= ARRAY_SIZE(pfxs))
3102 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
3103 if (check_in_dac_nids(spec, nid))
3104 nid = 0;
3105 if (! nid)
3106 continue;
3107 add_spec_dacs(spec, nid);
3108 }
3109 for (i = 0; i < cfg->speaker_outs; i++) {
3110 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
3111 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
3112 if (check_in_dac_nids(spec, nid))
3113 nid = 0;
3114 if (! nid)
3115 continue; 3127 continue;
3116 add_spec_dacs(spec, nid); 3128 nid = spec->hp_dacs[i];
3117 } 3129 if (!nid)
3118 for (i = 0; i < cfg->line_outs; i++) {
3119 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
3120 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
3121 if (check_in_dac_nids(spec, nid))
3122 nid = 0;
3123 if (! nid)
3124 continue; 3130 continue;
3125 add_spec_dacs(spec, nid); 3131 err = create_controls(spec, pfxs[nums++], nid, 3);
3132 if (err < 0)
3133 return err;
3126 } 3134 }
3127 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { 3135 nums = 0;
3136 for (i = 0; i < cfg->speaker_outs; i++) {
3128 static const char *pfxs[] = { 3137 static const char *pfxs[] = {
3129 "Speaker", "External Speaker", "Speaker2", 3138 "Speaker", "External Speaker", "Speaker2",
3130 }; 3139 };
3131 err = create_controls(spec, pfxs[i - old_num_dacs], 3140 if (nums >= ARRAY_SIZE(pfxs))
3132 spec->multiout.dac_nids[i], 3); 3141 continue;
3133 if (err < 0) 3142 nid = spec->speaker_dacs[i];
3134 return err; 3143 if (!nid)
3135 } 3144 continue;
3136 if (spec->multiout.hp_nid) { 3145 err = create_controls(spec, pfxs[nums++], nid, 3);
3137 err = create_controls(spec, "Headphone",
3138 spec->multiout.hp_nid, 3);
3139 if (err < 0) 3146 if (err < 0)
3140 return err; 3147 return err;
3141 } 3148 }
3142
3143 return 0; 3149 return 0;
3144} 3150}
3145 3151
@@ -3477,7 +3483,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3477{ 3483{
3478 struct sigmatel_spec *spec = codec->spec; 3484 struct sigmatel_spec *spec = codec->spec;
3479 int err; 3485 int err;
3480 int hp_speaker_swap = 0;
3481 3486
3482 if ((err = snd_hda_parse_pin_def_config(codec, 3487 if ((err = snd_hda_parse_pin_def_config(codec,
3483 &spec->autocfg, 3488 &spec->autocfg,
@@ -3495,13 +3500,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3495 * speaker_outs so that the following routines can handle 3500 * speaker_outs so that the following routines can handle
3496 * HP pins as primary outputs. 3501 * HP pins as primary outputs.
3497 */ 3502 */
3503 snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
3498 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, 3504 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
3499 sizeof(spec->autocfg.line_out_pins)); 3505 sizeof(spec->autocfg.line_out_pins));
3500 spec->autocfg.speaker_outs = spec->autocfg.line_outs; 3506 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
3501 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, 3507 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
3502 sizeof(spec->autocfg.hp_pins)); 3508 sizeof(spec->autocfg.hp_pins));
3503 spec->autocfg.line_outs = spec->autocfg.hp_outs; 3509 spec->autocfg.line_outs = spec->autocfg.hp_outs;
3504 hp_speaker_swap = 1; 3510 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
3511 spec->autocfg.hp_outs = 0;
3505 } 3512 }
3506 if (spec->autocfg.mono_out_pin) { 3513 if (spec->autocfg.mono_out_pin) {
3507 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & 3514 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
@@ -3553,11 +3560,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3553 AC_PINCTL_OUT_EN); 3560 AC_PINCTL_OUT_EN);
3554 } 3561 }
3555 3562
3556 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 3563 if (!spec->multiout.num_dacs) {
3557 return err; 3564 err = stac92xx_auto_fill_dac_nids(codec);
3558 if (spec->multiout.num_dacs == 0) 3565 if (err < 0)
3559 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3560 return err; 3566 return err;
3567 }
3561 3568
3562 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); 3569 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
3563 3570
@@ -3595,19 +3602,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3595 } 3602 }
3596#endif 3603#endif
3597 3604
3598 if (hp_speaker_swap == 1) {
3599 /* Restore the hp_outs and line_outs */
3600 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
3601 sizeof(spec->autocfg.line_out_pins));
3602 spec->autocfg.hp_outs = spec->autocfg.line_outs;
3603 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
3604 sizeof(spec->autocfg.speaker_pins));
3605 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
3606 memset(spec->autocfg.speaker_pins, 0,
3607 sizeof(spec->autocfg.speaker_pins));
3608 spec->autocfg.speaker_outs = 0;
3609 }
3610
3611 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); 3605 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
3612 3606
3613 if (err < 0) 3607 if (err < 0)
@@ -3656,7 +3650,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3656 spec->mixers[spec->num_mixers++] = spec->kctls.list; 3650 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3657 3651
3658 spec->input_mux = &spec->private_imux; 3652 spec->input_mux = &spec->private_imux;
3659 spec->dinput_mux = &spec->private_dimux; 3653 if (!spec->dinput_mux)
3654 spec->dinput_mux = &spec->private_dimux;
3660 spec->sinput_mux = &spec->private_smux; 3655 spec->sinput_mux = &spec->private_smux;
3661 spec->mono_mux = &spec->private_mono_mux; 3656 spec->mono_mux = &spec->private_mono_mux;
3662 spec->amp_mux = &spec->private_amp_mux; 3657 spec->amp_mux = &spec->private_amp_mux;
@@ -3919,9 +3914,8 @@ static void stac92xx_power_down(struct hda_codec *codec)
3919 /* power down inactive DACs */ 3914 /* power down inactive DACs */
3920 hda_nid_t *dac; 3915 hda_nid_t *dac;
3921 for (dac = spec->dac_list; *dac; dac++) 3916 for (dac = spec->dac_list; *dac; dac++)
3922 if (!is_in_dac_nids(spec, *dac) && 3917 if (!check_all_dac_nids(spec, *dac))
3923 spec->multiout.hp_nid != *dac) 3918 snd_hda_codec_write(codec, *dac, 0,
3924 snd_hda_codec_write_cache(codec, *dac, 0,
3925 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3919 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3926} 3920}
3927 3921
@@ -3940,7 +3934,7 @@ static int stac92xx_init(struct hda_codec *codec)
3940 /* power down adcs initially */ 3934 /* power down adcs initially */
3941 if (spec->powerdown_adcs) 3935 if (spec->powerdown_adcs)
3942 for (i = 0; i < spec->num_adcs; i++) 3936 for (i = 0; i < spec->num_adcs; i++)
3943 snd_hda_codec_write_cache(codec, 3937 snd_hda_codec_write(codec,
3944 spec->adc_nids[i], 0, 3938 spec->adc_nids[i], 0,
3945 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3939 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3946 3940
@@ -3971,24 +3965,36 @@ static int stac92xx_init(struct hda_codec *codec)
3971 } else { 3965 } else {
3972 stac92xx_auto_init_multi_out(codec); 3966 stac92xx_auto_init_multi_out(codec);
3973 stac92xx_auto_init_hp_out(codec); 3967 stac92xx_auto_init_hp_out(codec);
3968 for (i = 0; i < cfg->hp_outs; i++)
3969 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
3974 } 3970 }
3975 for (i = 0; i < AUTO_PIN_LAST; i++) { 3971 for (i = 0; i < AUTO_PIN_LAST; i++) {
3976 hda_nid_t nid = cfg->input_pins[i]; 3972 hda_nid_t nid = cfg->input_pins[i];
3977 if (nid) { 3973 if (nid) {
3978 unsigned int pinctl; 3974 unsigned int pinctl, conf;
3979 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 3975 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
3980 /* for mic pins, force to initialize */ 3976 /* for mic pins, force to initialize */
3981 pinctl = stac92xx_get_vref(codec, nid); 3977 pinctl = stac92xx_get_vref(codec, nid);
3978 pinctl |= AC_PINCTL_IN_EN;
3979 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3982 } else { 3980 } else {
3983 pinctl = snd_hda_codec_read(codec, nid, 0, 3981 pinctl = snd_hda_codec_read(codec, nid, 0,
3984 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3982 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3985 /* if PINCTL already set then skip */ 3983 /* if PINCTL already set then skip */
3986 if (pinctl & AC_PINCTL_IN_EN) 3984 if (!(pinctl & AC_PINCTL_IN_EN)) {
3987 continue; 3985 pinctl |= AC_PINCTL_IN_EN;
3986 stac92xx_auto_set_pinctl(codec, nid,
3987 pinctl);
3988 }
3989 }
3990 conf = snd_hda_codec_read(codec, nid, 0,
3991 AC_VERB_GET_CONFIG_DEFAULT, 0);
3992 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
3993 enable_pin_detect(codec, nid,
3994 STAC_INSERT_EVENT);
3995 stac_issue_unsol_event(codec, nid,
3996 STAC_INSERT_EVENT);
3988 } 3997 }
3989 pinctl |= AC_PINCTL_IN_EN;
3990 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3991 enable_pin_detect(codec, nid, STAC_INSERT_EVENT);
3992 } 3998 }
3993 } 3999 }
3994 for (i = 0; i < spec->num_dmics; i++) 4000 for (i = 0; i < spec->num_dmics; i++)
@@ -4004,7 +4010,13 @@ static int stac92xx_init(struct hda_codec *codec)
4004 hda_nid_t nid = spec->pwr_nids[i]; 4010 hda_nid_t nid = spec->pwr_nids[i];
4005 int pinctl, def_conf; 4011 int pinctl, def_conf;
4006 4012
4007 if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) 4013 /* power on when no jack detection is available */
4014 if (!spec->hp_detect) {
4015 stac_toggle_power_map(codec, nid, 1);
4016 continue;
4017 }
4018
4019 if (is_nid_hp_pin(cfg, nid))
4008 continue; /* already has an unsol event */ 4020 continue; /* already has an unsol event */
4009 4021
4010 pinctl = snd_hda_codec_read(codec, nid, 0, 4022 pinctl = snd_hda_codec_read(codec, nid, 0,
@@ -4013,8 +4025,10 @@ static int stac92xx_init(struct hda_codec *codec)
4013 * any attempts on powering down a input port cause the 4025 * any attempts on powering down a input port cause the
4014 * referenced VREF to act quirky. 4026 * referenced VREF to act quirky.
4015 */ 4027 */
4016 if (pinctl & AC_PINCTL_IN_EN) 4028 if (pinctl & AC_PINCTL_IN_EN) {
4029 stac_toggle_power_map(codec, nid, 1);
4017 continue; 4030 continue;
4031 }
4018 def_conf = snd_hda_codec_read(codec, nid, 0, 4032 def_conf = snd_hda_codec_read(codec, nid, 0,
4019 AC_VERB_GET_CONFIG_DEFAULT, 0); 4033 AC_VERB_GET_CONFIG_DEFAULT, 0);
4020 def_conf = get_defcfg_connect(def_conf); 4034 def_conf = get_defcfg_connect(def_conf);
@@ -4025,8 +4039,10 @@ static int stac92xx_init(struct hda_codec *codec)
4025 stac_toggle_power_map(codec, nid, 1); 4039 stac_toggle_power_map(codec, nid, 1);
4026 continue; 4040 continue;
4027 } 4041 }
4028 enable_pin_detect(codec, nid, STAC_PWR_EVENT); 4042 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) {
4029 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT); 4043 enable_pin_detect(codec, nid, STAC_PWR_EVENT);
4044 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
4045 }
4030 } 4046 }
4031 if (spec->dac_list) 4047 if (spec->dac_list)
4032 stac92xx_power_down(codec); 4048 stac92xx_power_down(codec);
@@ -4089,11 +4105,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
4089 * "xxx as Output" mixer switch 4105 * "xxx as Output" mixer switch
4090 */ 4106 */
4091 struct sigmatel_spec *spec = codec->spec; 4107 struct sigmatel_spec *spec = codec->spec;
4092 struct auto_pin_cfg *cfg = &spec->autocfg; 4108 if (nid == spec->line_switch || nid == spec->mic_switch)
4093 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
4094 spec->line_switch) ||
4095 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
4096 spec->mic_switch))
4097 return; 4109 return;
4098 } 4110 }
4099 4111
@@ -4117,20 +4129,13 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
4117 pin_ctl & ~flag); 4129 pin_ctl & ~flag);
4118} 4130}
4119 4131
4120static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) 4132static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
4121{ 4133{
4122 if (!nid) 4134 if (!nid)
4123 return 0; 4135 return 0;
4124 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) 4136 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
4125 & (1 << 31)) { 4137 & (1 << 31))
4126 unsigned int pinctl; 4138 return 1;
4127 pinctl = snd_hda_codec_read(codec, nid, 0,
4128 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4129 if (pinctl & AC_PINCTL_IN_EN)
4130 return 0; /* mic- or line-input */
4131 else
4132 return 1; /* HP-output */
4133 }
4134 return 0; 4139 return 0;
4135} 4140}
4136 4141
@@ -4142,11 +4147,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
4142 struct auto_pin_cfg *cfg = &spec->autocfg; 4147 struct auto_pin_cfg *cfg = &spec->autocfg;
4143 4148
4144 /* ignore sensing of shared line and mic jacks */ 4149 /* ignore sensing of shared line and mic jacks */
4145 if (spec->line_switch && 4150 if (cfg->hp_pins[i] == spec->line_switch)
4146 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
4147 return 1; 4151 return 1;
4148 if (spec->mic_switch && 4152 if (cfg->hp_pins[i] == spec->mic_switch)
4149 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
4150 return 1; 4153 return 1;
4151 /* ignore if the pin is set as line-out */ 4154 /* ignore if the pin is set as line-out */
4152 if (cfg->hp_pins[i] == spec->hp_switch) 4155 if (cfg->hp_pins[i] == spec->hp_switch)
@@ -4170,7 +4173,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4170 break; 4173 break;
4171 if (no_hp_sensing(spec, i)) 4174 if (no_hp_sensing(spec, i))
4172 continue; 4175 continue;
4173 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); 4176 presence = get_pin_presence(codec, cfg->hp_pins[i]);
4177 if (presence) {
4178 unsigned int pinctl;
4179 pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
4180 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4181 if (pinctl & AC_PINCTL_IN_EN)
4182 presence = 0; /* mic- or line-input */
4183 }
4174 } 4184 }
4175 4185
4176 if (presence) { 4186 if (presence) {
@@ -4247,7 +4257,7 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4247 4257
4248static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) 4258static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4249{ 4259{
4250 stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); 4260 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4251} 4261}
4252 4262
4253static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) 4263static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
@@ -4269,7 +4279,7 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4269 type = (pin_ctl & AC_PINCTL_HP_EN) 4279 type = (pin_ctl & AC_PINCTL_HP_EN)
4270 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT; 4280 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4271 snd_jack_report(jacks->jack, 4281 snd_jack_report(jacks->jack,
4272 get_hp_pin_presence(codec, nid) 4282 get_pin_presence(codec, nid)
4273 ? type : 0); 4283 ? type : 0);
4274 } 4284 }
4275 jacks++; 4285 jacks++;
@@ -4317,6 +4327,52 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4317 } 4327 }
4318} 4328}
4319 4329
4330#ifdef CONFIG_PROC_FS
4331static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4332 struct hda_codec *codec, hda_nid_t nid)
4333{
4334 if (nid == codec->afg)
4335 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4336 snd_hda_codec_read(codec, nid, 0, 0x0fec, 0x0));
4337}
4338
4339static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4340 struct hda_codec *codec,
4341 unsigned int verb)
4342{
4343 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4344 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
4345}
4346
4347/* stac92hd71bxx, stac92hd73xx */
4348static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4349 struct hda_codec *codec, hda_nid_t nid)
4350{
4351 stac92hd_proc_hook(buffer, codec, nid);
4352 if (nid == codec->afg)
4353 analog_loop_proc_hook(buffer, codec, 0xfa0);
4354}
4355
4356static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4357 struct hda_codec *codec, hda_nid_t nid)
4358{
4359 if (nid == codec->afg)
4360 analog_loop_proc_hook(buffer, codec, 0xfe0);
4361}
4362
4363static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4364 struct hda_codec *codec, hda_nid_t nid)
4365{
4366 if (nid == codec->afg)
4367 analog_loop_proc_hook(buffer, codec, 0xfeb);
4368}
4369#else
4370#define stac92hd_proc_hook NULL
4371#define stac92hd7x_proc_hook NULL
4372#define stac9205_proc_hook NULL
4373#define stac927x_proc_hook NULL
4374#endif
4375
4320#ifdef SND_HDA_NEEDS_RESUME 4376#ifdef SND_HDA_NEEDS_RESUME
4321static int stac92xx_resume(struct hda_codec *codec) 4377static int stac92xx_resume(struct hda_codec *codec)
4322{ 4378{
@@ -4515,6 +4571,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4515 struct sigmatel_spec *spec; 4571 struct sigmatel_spec *spec;
4516 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; 4572 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
4517 int err = 0; 4573 int err = 0;
4574 int num_dacs;
4518 4575
4519 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4576 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4520 if (spec == NULL) 4577 if (spec == NULL)
@@ -4541,16 +4598,15 @@ again:
4541 return err; 4598 return err;
4542 } 4599 }
4543 4600
4544 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, 4601 num_dacs = snd_hda_get_connections(codec, 0x0a,
4545 conn, STAC92HD73_DAC_COUNT + 2) - 1; 4602 conn, STAC92HD73_DAC_COUNT + 2) - 1;
4546 4603
4547 if (spec->multiout.num_dacs < 0) { 4604 if (num_dacs < 3 || num_dacs > 5) {
4548 printk(KERN_WARNING "hda_codec: Could not determine " 4605 printk(KERN_WARNING "hda_codec: Could not determine "
4549 "number of channels defaulting to DAC count\n"); 4606 "number of channels defaulting to DAC count\n");
4550 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; 4607 num_dacs = STAC92HD73_DAC_COUNT;
4551 } 4608 }
4552 4609 switch (num_dacs) {
4553 switch (spec->multiout.num_dacs) {
4554 case 0x3: /* 6 Channel */ 4610 case 0x3: /* 6 Channel */
4555 spec->mixer = stac92hd73xx_6ch_mixer; 4611 spec->mixer = stac92hd73xx_6ch_mixer;
4556 spec->init = stac92hd73xx_6ch_core_init; 4612 spec->init = stac92hd73xx_6ch_core_init;
@@ -4562,9 +4618,9 @@ again:
4562 case 0x5: /* 10 Channel */ 4618 case 0x5: /* 10 Channel */
4563 spec->mixer = stac92hd73xx_10ch_mixer; 4619 spec->mixer = stac92hd73xx_10ch_mixer;
4564 spec->init = stac92hd73xx_10ch_core_init; 4620 spec->init = stac92hd73xx_10ch_core_init;
4565 }; 4621 }
4622 spec->multiout.dac_nids = spec->dac_nids;
4566 4623
4567 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
4568 spec->aloopback_mask = 0x01; 4624 spec->aloopback_mask = 0x01;
4569 spec->aloopback_shift = 8; 4625 spec->aloopback_shift = 8;
4570 4626
@@ -4596,7 +4652,7 @@ again:
4596 spec->eapd_switch = 0; 4652 spec->eapd_switch = 0;
4597 spec->num_amps = 1; 4653 spec->num_amps = 1;
4598 4654
4599 if (!spec->init) 4655 if (spec->board_config != STAC_DELL_EQ)
4600 spec->init = dell_m6_core_init; 4656 spec->init = dell_m6_core_init;
4601 switch (spec->board_config) { 4657 switch (spec->board_config) {
4602 case STAC_DELL_M6_AMIC: /* Analog Mics */ 4658 case STAC_DELL_M6_AMIC: /* Analog Mics */
@@ -4649,8 +4705,13 @@ again:
4649 return err; 4705 return err;
4650 } 4706 }
4651 4707
4708 if (spec->board_config == STAC_92HD73XX_NO_JD)
4709 spec->hp_detect = 0;
4710
4652 codec->patch_ops = stac92xx_patch_ops; 4711 codec->patch_ops = stac92xx_patch_ops;
4653 4712
4713 codec->proc_widget_hook = stac92hd7x_proc_hook;
4714
4654 return 0; 4715 return 0;
4655} 4716}
4656 4717
@@ -4682,17 +4743,15 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
4682 spec->pwr_nids = stac92hd83xxx_pwr_nids; 4743 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4683 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 4744 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
4684 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 4745 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4685 spec->multiout.dac_nids = stac92hd83xxx_dac_nids; 4746 spec->multiout.dac_nids = spec->dac_nids;
4686 4747
4687 spec->init = stac92hd83xxx_core_init; 4748 spec->init = stac92hd83xxx_core_init;
4688 switch (codec->vendor_id) { 4749 switch (codec->vendor_id) {
4689 case 0x111d7605: 4750 case 0x111d7605:
4690 spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
4691 break; 4751 break;
4692 default: 4752 default:
4693 spec->num_pwrs--; 4753 spec->num_pwrs--;
4694 spec->init++; /* switch to config #2 */ 4754 spec->init++; /* switch to config #2 */
4695 spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
4696 } 4755 }
4697 4756
4698 spec->mixer = stac92hd83xxx_mixer; 4757 spec->mixer = stac92hd83xxx_mixer;
@@ -4737,51 +4796,11 @@ again:
4737 4796
4738 codec->patch_ops = stac92xx_patch_ops; 4797 codec->patch_ops = stac92xx_patch_ops;
4739 4798
4740 return 0; 4799 codec->proc_widget_hook = stac92hd_proc_hook;
4741}
4742 4800
4743#ifdef SND_HDA_NEEDS_RESUME 4801 return 0;
4744static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
4745{
4746 struct sigmatel_spec *spec = codec->spec;
4747 int i;
4748 snd_hda_codec_write_cache(codec, codec->afg, 0,
4749 AC_VERB_SET_POWER_STATE, pwr);
4750
4751 msleep(1);
4752 for (i = 0; i < spec->num_adcs; i++) {
4753 snd_hda_codec_write_cache(codec,
4754 spec->adc_nids[i], 0,
4755 AC_VERB_SET_POWER_STATE, pwr);
4756 }
4757};
4758
4759static int stac92hd71xx_resume(struct hda_codec *codec)
4760{
4761 stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
4762 return stac92xx_resume(codec);
4763} 4802}
4764 4803
4765static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4766{
4767 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
4768 return stac92xx_suspend(codec, state);
4769};
4770
4771#endif
4772
4773static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4774 .build_controls = stac92xx_build_controls,
4775 .build_pcms = stac92xx_build_pcms,
4776 .init = stac92xx_init,
4777 .free = stac92xx_free,
4778 .unsol_event = stac92xx_unsol_event,
4779#ifdef SND_HDA_NEEDS_RESUME
4780 .suspend = stac92hd71xx_suspend,
4781 .resume = stac92hd71xx_resume,
4782#endif
4783};
4784
4785static struct hda_input_mux stac92hd71bxx_dmux = { 4804static struct hda_input_mux stac92hd71bxx_dmux = {
4786 .num_items = 4, 4805 .num_items = 4,
4787 .items = { 4806 .items = {
@@ -4858,12 +4877,8 @@ again:
4858 break; 4877 break;
4859 } 4878 }
4860 if ((codec->revision_id & 0xf) == 0 || 4879 if ((codec->revision_id & 0xf) == 0 ||
4861 (codec->revision_id & 0xf) == 1) { 4880 (codec->revision_id & 0xf) == 1)
4862#ifdef SND_HDA_NEEDS_RESUME
4863 codec->patch_ops = stac92hd71bxx_patch_ops;
4864#endif
4865 spec->stream_delay = 40; /* 40 milliseconds */ 4881 spec->stream_delay = 40; /* 40 milliseconds */
4866 }
4867 4882
4868 /* no output amps */ 4883 /* no output amps */
4869 spec->num_pwrs = 0; 4884 spec->num_pwrs = 0;
@@ -4875,12 +4890,8 @@ again:
4875 stac_change_pin_config(codec, 0xf, 0x40f000f0); 4890 stac_change_pin_config(codec, 0xf, 0x40f000f0);
4876 break; 4891 break;
4877 case 0x111d7603: /* 6 Port with Analog Mixer */ 4892 case 0x111d7603: /* 6 Port with Analog Mixer */
4878 if ((codec->revision_id & 0xf) == 1) { 4893 if ((codec->revision_id & 0xf) == 1)
4879#ifdef SND_HDA_NEEDS_RESUME
4880 codec->patch_ops = stac92hd71bxx_patch_ops;
4881#endif
4882 spec->stream_delay = 40; /* 40 milliseconds */ 4894 spec->stream_delay = 40; /* 40 milliseconds */
4883 }
4884 4895
4885 /* no output amps */ 4896 /* no output amps */
4886 spec->num_pwrs = 0; 4897 spec->num_pwrs = 0;
@@ -4931,9 +4942,7 @@ again:
4931 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 4942 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4932 }; 4943 };
4933 4944
4934 spec->multiout.num_dacs = 1; 4945 spec->multiout.dac_nids = spec->dac_nids;
4935 spec->multiout.hp_nid = 0x11;
4936 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4937 if (spec->dinput_mux) 4946 if (spec->dinput_mux)
4938 spec->private_dimux.num_items += 4947 spec->private_dimux.num_items +=
4939 spec->num_dmics - 4948 spec->num_dmics -
@@ -4955,6 +4964,8 @@ again:
4955 return err; 4964 return err;
4956 } 4965 }
4957 4966
4967 codec->proc_widget_hook = stac92hd7x_proc_hook;
4968
4958 return 0; 4969 return 0;
4959}; 4970};
4960 4971
@@ -5175,6 +5186,8 @@ static int patch_stac927x(struct hda_codec *codec)
5175 5186
5176 codec->patch_ops = stac92xx_patch_ops; 5187 codec->patch_ops = stac92xx_patch_ops;
5177 5188
5189 codec->proc_widget_hook = stac927x_proc_hook;
5190
5178 /* 5191 /*
5179 * !!FIXME!! 5192 * !!FIXME!!
5180 * The STAC927x seem to require fairly long delays for certain 5193 * The STAC927x seem to require fairly long delays for certain
@@ -5187,6 +5200,10 @@ static int patch_stac927x(struct hda_codec *codec)
5187 */ 5200 */
5188 codec->bus->needs_damn_long_delay = 1; 5201 codec->bus->needs_damn_long_delay = 1;
5189 5202
5203 /* no jack detecion for ref-no-jd model */
5204 if (spec->board_config == STAC_D965_REF_NO_JD)
5205 spec->hp_detect = 0;
5206
5190 return 0; 5207 return 0;
5191} 5208}
5192 5209
@@ -5290,6 +5307,8 @@ static int patch_stac9205(struct hda_codec *codec)
5290 5307
5291 codec->patch_ops = stac92xx_patch_ops; 5308 codec->patch_ops = stac92xx_patch_ops;
5292 5309
5310 codec->proc_widget_hook = stac9205_proc_hook;
5311
5293 return 0; 5312 return 0;
5294} 5313}
5295 5314
@@ -5410,7 +5429,7 @@ static int stac9872_vaio_init(struct hda_codec *codec)
5410 5429
5411static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) 5430static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
5412{ 5431{
5413 if (get_hp_pin_presence(codec, 0x0a)) { 5432 if (get_pin_presence(codec, 0x0a)) {
5414 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); 5433 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
5415 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); 5434 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
5416 } else { 5435 } else {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 6e4d01d1d502..c761394cbe84 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -3249,73 +3249,73 @@ static int patch_vt1702(struct hda_codec *codec)
3249 * patch entries 3249 * patch entries
3250 */ 3250 */
3251static struct hda_codec_preset snd_hda_preset_via[] = { 3251static struct hda_codec_preset snd_hda_preset_via[] = {
3252 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 3252 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3253 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 3253 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3254 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 3254 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3255 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 3255 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3256 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", 3256 { .id = 0x1106e710, .name = "VT1709 10-Ch",
3257 .patch = patch_vt1709_10ch}, 3257 .patch = patch_vt1709_10ch},
3258 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", 3258 { .id = 0x1106e711, .name = "VT1709 10-Ch",
3259 .patch = patch_vt1709_10ch}, 3259 .patch = patch_vt1709_10ch},
3260 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", 3260 { .id = 0x1106e712, .name = "VT1709 10-Ch",
3261 .patch = patch_vt1709_10ch}, 3261 .patch = patch_vt1709_10ch},
3262 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", 3262 { .id = 0x1106e713, .name = "VT1709 10-Ch",
3263 .patch = patch_vt1709_10ch}, 3263 .patch = patch_vt1709_10ch},
3264 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", 3264 { .id = 0x1106e714, .name = "VT1709 6-Ch",
3265 .patch = patch_vt1709_6ch}, 3265 .patch = patch_vt1709_6ch},
3266 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", 3266 { .id = 0x1106e715, .name = "VT1709 6-Ch",
3267 .patch = patch_vt1709_6ch}, 3267 .patch = patch_vt1709_6ch},
3268 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", 3268 { .id = 0x1106e716, .name = "VT1709 6-Ch",
3269 .patch = patch_vt1709_6ch}, 3269 .patch = patch_vt1709_6ch},
3270 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", 3270 { .id = 0x1106e717, .name = "VT1709 6-Ch",
3271 .patch = patch_vt1709_6ch}, 3271 .patch = patch_vt1709_6ch},
3272 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch", 3272 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3273 .patch = patch_vt1708B_8ch}, 3273 .patch = patch_vt1708B_8ch},
3274 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch", 3274 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3275 .patch = patch_vt1708B_8ch}, 3275 .patch = patch_vt1708B_8ch},
3276 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch", 3276 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3277 .patch = patch_vt1708B_8ch}, 3277 .patch = patch_vt1708B_8ch},
3278 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch", 3278 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3279 .patch = patch_vt1708B_8ch}, 3279 .patch = patch_vt1708B_8ch},
3280 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch", 3280 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3281 .patch = patch_vt1708B_4ch}, 3281 .patch = patch_vt1708B_4ch},
3282 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch", 3282 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3283 .patch = patch_vt1708B_4ch}, 3283 .patch = patch_vt1708B_4ch},
3284 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch", 3284 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3285 .patch = patch_vt1708B_4ch}, 3285 .patch = patch_vt1708B_4ch},
3286 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 3286 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3287 .patch = patch_vt1708B_4ch}, 3287 .patch = patch_vt1708B_4ch},
3288 { .id = 0x11060397, .name = "VIA VT1708S", 3288 { .id = 0x11060397, .name = "VT1708S",
3289 .patch = patch_vt1708S}, 3289 .patch = patch_vt1708S},
3290 { .id = 0x11061397, .name = "VIA VT1708S", 3290 { .id = 0x11061397, .name = "VT1708S",
3291 .patch = patch_vt1708S}, 3291 .patch = patch_vt1708S},
3292 { .id = 0x11062397, .name = "VIA VT1708S", 3292 { .id = 0x11062397, .name = "VT1708S",
3293 .patch = patch_vt1708S}, 3293 .patch = patch_vt1708S},
3294 { .id = 0x11063397, .name = "VIA VT1708S", 3294 { .id = 0x11063397, .name = "VT1708S",
3295 .patch = patch_vt1708S}, 3295 .patch = patch_vt1708S},
3296 { .id = 0x11064397, .name = "VIA VT1708S", 3296 { .id = 0x11064397, .name = "VT1708S",
3297 .patch = patch_vt1708S}, 3297 .patch = patch_vt1708S},
3298 { .id = 0x11065397, .name = "VIA VT1708S", 3298 { .id = 0x11065397, .name = "VT1708S",
3299 .patch = patch_vt1708S}, 3299 .patch = patch_vt1708S},
3300 { .id = 0x11066397, .name = "VIA VT1708S", 3300 { .id = 0x11066397, .name = "VT1708S",
3301 .patch = patch_vt1708S}, 3301 .patch = patch_vt1708S},
3302 { .id = 0x11067397, .name = "VIA VT1708S", 3302 { .id = 0x11067397, .name = "VT1708S",
3303 .patch = patch_vt1708S}, 3303 .patch = patch_vt1708S},
3304 { .id = 0x11060398, .name = "VIA VT1702", 3304 { .id = 0x11060398, .name = "VT1702",
3305 .patch = patch_vt1702}, 3305 .patch = patch_vt1702},
3306 { .id = 0x11061398, .name = "VIA VT1702", 3306 { .id = 0x11061398, .name = "VT1702",
3307 .patch = patch_vt1702}, 3307 .patch = patch_vt1702},
3308 { .id = 0x11062398, .name = "VIA VT1702", 3308 { .id = 0x11062398, .name = "VT1702",
3309 .patch = patch_vt1702}, 3309 .patch = patch_vt1702},
3310 { .id = 0x11063398, .name = "VIA VT1702", 3310 { .id = 0x11063398, .name = "VT1702",
3311 .patch = patch_vt1702}, 3311 .patch = patch_vt1702},
3312 { .id = 0x11064398, .name = "VIA VT1702", 3312 { .id = 0x11064398, .name = "VT1702",
3313 .patch = patch_vt1702}, 3313 .patch = patch_vt1702},
3314 { .id = 0x11065398, .name = "VIA VT1702", 3314 { .id = 0x11065398, .name = "VT1702",
3315 .patch = patch_vt1702}, 3315 .patch = patch_vt1702},
3316 { .id = 0x11066398, .name = "VIA VT1702", 3316 { .id = 0x11066398, .name = "VT1702",
3317 .patch = patch_vt1702}, 3317 .patch = patch_vt1702},
3318 { .id = 0x11067398, .name = "VIA VT1702", 3318 { .id = 0x11067398, .name = "VT1702",
3319 .patch = patch_vt1702}, 3319 .patch = patch_vt1702},
3320 {} /* terminator */ 3320 {} /* terminator */
3321}; 3321};
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 5b442383fcda..58d7cda03de5 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -2688,12 +2688,13 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2688 return err; 2688 return err;
2689 } 2689 }
2690 2690
2691 if (ice_has_con_ac97(ice)) 2691 if (ice_has_con_ac97(ice)) {
2692 err = snd_ice1712_pcm(ice, pcm_dev++, NULL); 2692 err = snd_ice1712_pcm(ice, pcm_dev++, NULL);
2693 if (err < 0) { 2693 if (err < 0) {
2694 snd_card_free(card); 2694 snd_card_free(card);
2695 return err; 2695 return err;
2696 } 2696 }
2697 }
2697 2698
2698 err = snd_ice1712_ac97_mixer(ice); 2699 err = snd_ice1712_ac97_mixer(ice);
2699 if (err < 0) { 2700 if (err < 0) {
@@ -2715,12 +2716,13 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2715 } 2716 }
2716 } 2717 }
2717 2718
2718 if (ice_has_con_ac97(ice)) 2719 if (ice_has_con_ac97(ice)) {
2719 err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); 2720 err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL);
2720 if (err < 0) { 2721 if (err < 0) {
2721 snd_card_free(card); 2722 snd_card_free(card);
2722 return err; 2723 return err;
2723 } 2724 }
2725 }
2724 2726
2725 if (!c->no_mpu401) { 2727 if (!c->no_mpu401) {
2726 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, 2728 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712,
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 1b3f11702713..bb8d8c766b9d 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
382 unsigned char status_mask = 382 unsigned char status_mask =
383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; 383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
384 int handled = 0; 384 int handled = 0;
385#ifdef CONFIG_SND_DEBUG
386 int timeout = 0; 385 int timeout = 0;
387#endif
388 386
389 while (1) { 387 while (1) {
390 status = inb(ICEREG1724(ice, IRQSTAT)); 388 status = inb(ICEREG1724(ice, IRQSTAT));
391 status &= status_mask; 389 status &= status_mask;
392 if (status == 0) 390 if (status == 0)
393 break; 391 break;
394#ifdef CONFIG_SND_DEBUG
395 if (++timeout > 10) { 392 if (++timeout > 10) {
396 printk(KERN_ERR 393 status = inb(ICEREG1724(ice, IRQSTAT));
397 "ice1724: Too long irq loop, status = 0x%x\n", 394 printk(KERN_ERR "ice1724: Too long irq loop, "
398 status); 395 "status = 0x%x\n", status);
396 if (status & VT1724_IRQ_MPU_TX) {
397 printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
398 outb(inb(ICEREG1724(ice, IRQMASK)) |
399 VT1724_IRQ_MPU_TX,
400 ICEREG1724(ice, IRQMASK));
401 }
399 break; 402 break;
400 } 403 }
401#endif
402 handled = 1; 404 handled = 1;
403 if (status & VT1724_IRQ_MPU_TX) { 405 if (status & VT1724_IRQ_MPU_TX) {
404 spin_lock(&ice->reg_lock); 406 spin_lock(&ice->reg_lock);
@@ -1237,7 +1239,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device)
1237 if (ice->force_pdma4 || ice->force_rdma1) 1239 if (ice->force_pdma4 || ice->force_rdma1)
1238 name = "ICE1724 Secondary"; 1240 name = "ICE1724 Secondary";
1239 else 1241 else
1240 name = "IEC1724 IEC958"; 1242 name = "ICE1724 IEC958";
1241 err = snd_pcm_new(ice->card, name, device, play, capt, &pcm); 1243 err = snd_pcm_new(ice->card, name, device, play, capt, &pcm);
1242 if (err < 0) 1244 if (err < 0)
1243 return err; 1245 return err;
@@ -2351,7 +2353,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2351{ 2353{
2352 struct snd_ice1712 *ice; 2354 struct snd_ice1712 *ice;
2353 int err; 2355 int err;
2354 unsigned char mask;
2355 static struct snd_device_ops ops = { 2356 static struct snd_device_ops ops = {
2356 .dev_free = snd_vt1724_dev_free, 2357 .dev_free = snd_vt1724_dev_free,
2357 }; 2358 };
@@ -2412,9 +2413,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2412 return -EIO; 2413 return -EIO;
2413 } 2414 }
2414 2415
2415 /* unmask used interrupts */ 2416 /* MPU_RX and TX irq masks are cleared later dynamically */
2416 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; 2417 outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
2417 outb(mask, ICEREG1724(ice, IRQMASK)); 2418
2418 /* don't handle FIFO overrun/underruns (just yet), 2419 /* don't handle FIFO overrun/underruns (just yet),
2419 * since they cause machine lockups 2420 * since they cause machine lockups
2420 */ 2421 */
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index c88d1eace1c4..19d3391e229f 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2702,6 +2702,7 @@ static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = {
2702 SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000), 2702 SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000),
2703 SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100), 2703 SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100),
2704 SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000), 2704 SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000),
2705 SND_PCI_QUIRK(0x1028, 0x01ad, "AD1981B", 48000),
2705 SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000), 2706 SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000),
2706 { } /* terminator */ 2707 { } /* terminator */
2707}; 2708};
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 9ff3f9e34404..59bbaf8f3e5b 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1670,7 +1670,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1670 return IRQ_NONE; 1670 return IRQ_NONE;
1671 1671
1672 if (status & HV_INT_PENDING) 1672 if (status & HV_INT_PENDING)
1673 tasklet_hi_schedule(&chip->hwvol_tq); 1673 tasklet_schedule(&chip->hwvol_tq);
1674 1674
1675 /* 1675 /*
1676 * ack an assp int if its running 1676 * ack an assp int if its running
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index 2d0dce649a64..f23a73577c22 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1010,7 +1010,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1010 .dev_free = snd_mixart_chip_dev_free, 1010 .dev_free = snd_mixart_chip_dev_free,
1011 }; 1011 };
1012 1012
1013 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1013 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1014 if (! chip) { 1014 if (! chip) {
1015 snd_printk(KERN_ERR "cannot allocate chip\n"); 1015 snd_printk(KERN_ERR "cannot allocate chip\n");
1016 return -ENOMEM; 1016 return -ENOMEM;
@@ -1025,6 +1025,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1025 return err; 1025 return err;
1026 } 1026 }
1027 1027
1028 mgr->chip[idx] = chip;
1028 snd_card_set_dev(card, &mgr->pci->dev); 1029 snd_card_set_dev(card, &mgr->pci->dev);
1029 1030
1030 return 0; 1031 return 0;
@@ -1314,8 +1315,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
1314 } 1315 }
1315 for (i = 0; i < 2; i++) { 1316 for (i = 0; i < 2; i++) {
1316 mgr->mem[i].phys = pci_resource_start(pci, i); 1317 mgr->mem[i].phys = pci_resource_start(pci, i);
1317 mgr->mem[i].virt = ioremap_nocache(mgr->mem[i].phys, 1318 mgr->mem[i].virt = pci_ioremap_bar(pci, i);
1318 pci_resource_len(pci, i));
1319 if (!mgr->mem[i].virt) { 1319 if (!mgr->mem[i].virt) {
1320 printk(KERN_ERR "unable to remap resource 0x%lx\n", 1320 printk(KERN_ERR "unable to remap resource 0x%lx\n",
1321 mgr->mem[i].phys); 1321 mgr->mem[i].phys);
@@ -1378,6 +1378,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
1378 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1378 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1379 1379
1380 if ((err = snd_mixart_create(mgr, card, i)) < 0) { 1380 if ((err = snd_mixart_create(mgr, card, i)) < 0) {
1381 snd_card_free(card);
1381 snd_mixart_free(mgr); 1382 snd_mixart_free(mgr);
1382 return err; 1383 return err;
1383 } 1384 }
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index b9a06c279397..d3350f383966 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -550,7 +550,7 @@ irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg; 550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
551 mgr->msg_fifo_writeptr++; 551 mgr->msg_fifo_writeptr++;
552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE; 552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
553 tasklet_hi_schedule(&mgr->msg_taskq); 553 tasklet_schedule(&mgr->msg_taskq);
554 } 554 }
555 spin_unlock(&mgr->msg_lock); 555 spin_unlock(&mgr->msg_lock);
556 break; 556 break;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index b60f6212745a..de999c6d6dd3 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -61,6 +61,7 @@ MODULE_PARM_DESC(enable, "enable card");
61enum { 61enum {
62 MODEL_CMEDIA_REF, /* C-Media's reference design */ 62 MODEL_CMEDIA_REF, /* C-Media's reference design */
63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
64 MODEL_HALO, /* HT-Omega Claro halo */
64}; 65};
65 66
66static struct pci_device_id oxygen_ids[] __devinitdata = { 67static struct pci_device_id oxygen_ids[] __devinitdata = {
@@ -74,6 +75,7 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
74 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 75 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
75 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 76 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
76 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO },
77 { } 79 { }
78}; 80};
79MODULE_DEVICE_TABLE(pci, oxygen_ids); 81MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -301,6 +303,8 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data)
301 PLAYBACK_1_TO_SPDIF | 303 PLAYBACK_1_TO_SPDIF |
302 CAPTURE_0_FROM_I2S_2 | 304 CAPTURE_0_FROM_I2S_2 |
303 CAPTURE_1_FROM_SPDIF; 305 CAPTURE_1_FROM_SPDIF;
306 }
307 if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) {
304 chip->model.misc_flags = OXYGEN_MISC_MIDI; 308 chip->model.misc_flags = OXYGEN_MISC_MIDI;
305 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 309 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
306 } 310 }
diff --git a/sound/pci/pcxhr/Makefile b/sound/pci/pcxhr/Makefile
index 10473c05918d..b06128e918ca 100644
--- a/sound/pci/pcxhr/Makefile
+++ b/sound/pci/pcxhr/Makefile
@@ -1,2 +1,2 @@
1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o 1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o 2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 0e06c6c9fcc0..27cf2c28d113 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -40,18 +40,20 @@
40#include "pcxhr_mixer.h" 40#include "pcxhr_mixer.h"
41#include "pcxhr_hwdep.h" 41#include "pcxhr_hwdep.h"
42#include "pcxhr_core.h" 42#include "pcxhr_core.h"
43#include "pcxhr_mix22.h"
43 44
44#define DRIVER_NAME "pcxhr" 45#define DRIVER_NAME "pcxhr"
45 46
46MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>"); 47MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>, "
48 "Marc Titinger <titinger@digigram.com>");
47MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING); 49MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
48MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
49MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}"); 51MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}");
50 52
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 54static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
54static int mono[SNDRV_CARDS]; /* capture in mono only */ 56static int mono[SNDRV_CARDS]; /* capture mono only */
55 57
56module_param_array(index, int, NULL, 0444); 58module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard"); 59MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
@@ -67,18 +69,58 @@ enum {
67 PCI_ID_PCX882HR, 69 PCI_ID_PCX882HR,
68 PCI_ID_VX881HR, 70 PCI_ID_VX881HR,
69 PCI_ID_PCX881HR, 71 PCI_ID_PCX881HR,
72 PCI_ID_VX882E,
73 PCI_ID_PCX882E,
74 PCI_ID_VX881E,
75 PCI_ID_PCX881E,
76 PCI_ID_VX1222HR,
70 PCI_ID_PCX1222HR, 77 PCI_ID_PCX1222HR,
78 PCI_ID_VX1221HR,
71 PCI_ID_PCX1221HR, 79 PCI_ID_PCX1221HR,
80 PCI_ID_VX1222E,
81 PCI_ID_PCX1222E,
82 PCI_ID_VX1221E,
83 PCI_ID_PCX1221E,
84 PCI_ID_VX222HR,
85 PCI_ID_VX222E,
86 PCI_ID_PCX22HR,
87 PCI_ID_PCX22E,
88 PCI_ID_VX222HRMIC,
89 PCI_ID_VX222E_MIC,
90 PCI_ID_PCX924HR,
91 PCI_ID_PCX924E,
92 PCI_ID_PCX924HRMIC,
93 PCI_ID_PCX924E_MIC,
72 PCI_ID_LAST 94 PCI_ID_LAST
73}; 95};
74 96
75static struct pci_device_id pcxhr_ids[] = { 97static struct pci_device_id pcxhr_ids[] = {
76 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */ 98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
77 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */ 99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
78 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */ 100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
79 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, }, /* PCX881HR */ 101 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },
80 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, }, /* PCX1222HR */ 102 { 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },
81 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, }, /* PCX1221HR */ 103 { 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },
104 { 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },
105 { 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },
106 { 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },
107 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },
108 { 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },
109 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },
110 { 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },
111 { 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },
112 { 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },
113 { 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },
114 { 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },
115 { 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },
116 { 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },
117 { 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },
118 { 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },
119 { 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },
120 { 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },
121 { 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
122 { 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
123 { 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
82 { 0, } 124 { 0, }
83}; 125};
84 126
@@ -88,27 +130,55 @@ struct board_parameters {
88 char* board_name; 130 char* board_name;
89 short playback_chips; 131 short playback_chips;
90 short capture_chips; 132 short capture_chips;
133 short fw_file_set;
91 short firmware_num; 134 short firmware_num;
92}; 135};
93static struct board_parameters pcxhr_board_params[] = { 136static struct board_parameters pcxhr_board_params[] = {
94[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 41, }, 137[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 0, 41 },
95[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 41, }, 138[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 0, 41 },
96[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 41, }, 139[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 0, 41 },
97[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 41, }, 140[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 0, 41 },
98[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 42, }, 141[PCI_ID_VX882E] = { "VX882e", 4, 4, 1, 41 },
99[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 42, }, 142[PCI_ID_PCX882E] = { "PCX882e", 4, 4, 1, 41 },
143[PCI_ID_VX881E] = { "VX881e", 4, 4, 1, 41 },
144[PCI_ID_PCX881E] = { "PCX881e", 4, 4, 1, 41 },
145[PCI_ID_VX1222HR] = { "VX1222HR", 6, 1, 2, 42 },
146[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 2, 42 },
147[PCI_ID_VX1221HR] = { "VX1221HR", 6, 1, 2, 42 },
148[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 2, 42 },
149[PCI_ID_VX1222E] = { "VX1222e", 6, 1, 3, 42 },
150[PCI_ID_PCX1222E] = { "PCX1222e", 6, 1, 3, 42 },
151[PCI_ID_VX1221E] = { "VX1221e", 6, 1, 3, 42 },
152[PCI_ID_PCX1221E] = { "PCX1221e", 6, 1, 3, 42 },
153[PCI_ID_VX222HR] = { "VX222HR", 1, 1, 4, 44 },
154[PCI_ID_VX222E] = { "VX222e", 1, 1, 4, 44 },
155[PCI_ID_PCX22HR] = { "PCX22HR", 1, 0, 4, 44 },
156[PCI_ID_PCX22E] = { "PCX22e", 1, 0, 4, 44 },
157[PCI_ID_VX222HRMIC] = { "VX222HR-Mic", 1, 1, 5, 44 },
158[PCI_ID_VX222E_MIC] = { "VX222e-Mic", 1, 1, 5, 44 },
159[PCI_ID_PCX924HR] = { "PCX924HR", 1, 1, 5, 44 },
160[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
161[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
162[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
100}; 163};
101 164
165/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
166/* VX222HR, VX222e, PCX22HR and PCX22e */
167#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)
168/* some boards do not support 192kHz on digital AES input plugs */
169#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \
170 (x->fw_file_set == 0) || \
171 (x->fw_file_set == 2))
102 172
103static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg, 173static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
104 unsigned int* realfreq) 174 unsigned int* realfreq)
105{ 175{
106 unsigned int reg; 176 unsigned int reg;
107 177
108 if (freq < 6900 || freq > 110250) 178 if (freq < 6900 || freq > 110000)
109 return -EINVAL; 179 return -EINVAL;
110 reg = (28224000 * 10) / freq; 180 reg = (28224000 * 2) / freq;
111 reg = (reg + 5) / 10; 181 reg = (reg - 1) / 2;
112 if (reg < 0x200) 182 if (reg < 0x200)
113 *pllreg = reg + 0x800; 183 *pllreg = reg + 0x800;
114 else if (reg < 0x400) 184 else if (reg < 0x400)
@@ -121,7 +191,7 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
121 reg &= ~3; 191 reg &= ~3;
122 } 192 }
123 if (realfreq) 193 if (realfreq)
124 *realfreq = ((28224000 * 10) / reg + 5) / 10; 194 *realfreq = (28224000 / (reg + 1));
125 return 0; 195 return 0;
126} 196}
127 197
@@ -151,11 +221,6 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
151#define PCXHR_FREQ_AES_3 0x03 221#define PCXHR_FREQ_AES_3 0x03
152#define PCXHR_FREQ_AES_4 0x0d 222#define PCXHR_FREQ_AES_4 0x0d
153 223
154#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
155
156#define PCXHR_IRQ_TIMER_FREQ 92000
157#define PCXHR_IRQ_TIMER_PERIOD 48
158
159static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate, 224static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
160 unsigned int *reg, unsigned int *freq) 225 unsigned int *reg, unsigned int *freq)
161{ 226{
@@ -196,19 +261,32 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
196 err = pcxhr_send_msg(mgr, &rmh); 261 err = pcxhr_send_msg(mgr, &rmh);
197 if (err < 0) { 262 if (err < 0) {
198 snd_printk(KERN_ERR 263 snd_printk(KERN_ERR
199 "error CMD_ACCESS_IO_WRITE for PLL register : %x!\n", 264 "error CMD_ACCESS_IO_WRITE "
200 err ); 265 "for PLL register : %x!\n", err);
201 return err; 266 return err;
202 } 267 }
203 } 268 }
204 break; 269 break;
205 case PCXHR_CLOCK_TYPE_WORD_CLOCK : val = PCXHR_FREQ_WORD_CLOCK; break; 270 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
206 case PCXHR_CLOCK_TYPE_AES_SYNC : val = PCXHR_FREQ_SYNC_AES; break; 271 val = PCXHR_FREQ_WORD_CLOCK;
207 case PCXHR_CLOCK_TYPE_AES_1 : val = PCXHR_FREQ_AES_1; break; 272 break;
208 case PCXHR_CLOCK_TYPE_AES_2 : val = PCXHR_FREQ_AES_2; break; 273 case PCXHR_CLOCK_TYPE_AES_SYNC:
209 case PCXHR_CLOCK_TYPE_AES_3 : val = PCXHR_FREQ_AES_3; break; 274 val = PCXHR_FREQ_SYNC_AES;
210 case PCXHR_CLOCK_TYPE_AES_4 : val = PCXHR_FREQ_AES_4; break; 275 break;
211 default : return -EINVAL; 276 case PCXHR_CLOCK_TYPE_AES_1:
277 val = PCXHR_FREQ_AES_1;
278 break;
279 case PCXHR_CLOCK_TYPE_AES_2:
280 val = PCXHR_FREQ_AES_2;
281 break;
282 case PCXHR_CLOCK_TYPE_AES_3:
283 val = PCXHR_FREQ_AES_3;
284 break;
285 case PCXHR_CLOCK_TYPE_AES_4:
286 val = PCXHR_FREQ_AES_4;
287 break;
288 default:
289 return -EINVAL;
212 } 290 }
213 *reg = val; 291 *reg = val;
214 *freq = realfreq; 292 *freq = realfreq;
@@ -216,14 +294,13 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
216} 294}
217 295
218 296
219int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate) 297static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,
298 unsigned int rate,
299 int *changed)
220{ 300{
221 unsigned int val, realfreq, speed; 301 unsigned int val, realfreq, speed;
222 struct pcxhr_rmh rmh; 302 struct pcxhr_rmh rmh;
223 int err, changed; 303 int err;
224
225 if (rate == 0)
226 return 0; /* nothing to do */
227 304
228 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq); 305 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
229 if (err) 306 if (err)
@@ -237,13 +314,17 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
237 else 314 else
238 speed = 2; /* quad speed */ 315 speed = 2; /* quad speed */
239 if (mgr->codec_speed != speed) { 316 if (mgr->codec_speed != speed) {
240 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */ 317 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */
241 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 318 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
319 if (DSP_EXT_CMD_SET(mgr)) {
320 rmh.cmd[1] = 1;
321 rmh.cmd_len = 2;
322 }
242 err = pcxhr_send_msg(mgr, &rmh); 323 err = pcxhr_send_msg(mgr, &rmh);
243 if (err) 324 if (err)
244 return err; 325 return err;
245 326
246 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */ 327 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */
247 rmh.cmd[0] |= IO_NUM_SPEED_RATIO; 328 rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
248 rmh.cmd[1] = speed; 329 rmh.cmd[1] = speed;
249 rmh.cmd_len = 2; 330 rmh.cmd_len = 2;
@@ -253,25 +334,57 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
253 } 334 }
254 /* set the new frequency */ 335 /* set the new frequency */
255 snd_printdd("clock register : set %x\n", val); 336 snd_printdd("clock register : set %x\n", val);
256 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK, val, &changed); 337 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,
338 val, changed);
257 if (err) 339 if (err)
258 return err; 340 return err;
341
259 mgr->sample_rate_real = realfreq; 342 mgr->sample_rate_real = realfreq;
260 mgr->cur_clock_type = mgr->use_clock_type; 343 mgr->cur_clock_type = mgr->use_clock_type;
261 344
262 /* unmute after codec speed modes */ 345 /* unmute after codec speed modes */
263 if (mgr->codec_speed != speed) { 346 if (mgr->codec_speed != speed) {
264 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */ 347 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */
265 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 348 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
349 if (DSP_EXT_CMD_SET(mgr)) {
350 rmh.cmd[1] = 1;
351 rmh.cmd_len = 2;
352 }
266 err = pcxhr_send_msg(mgr, &rmh); 353 err = pcxhr_send_msg(mgr, &rmh);
267 if (err) 354 if (err)
268 return err; 355 return err;
269 mgr->codec_speed = speed; /* save new codec speed */ 356 mgr->codec_speed = speed; /* save new codec speed */
270 } 357 }
271 358
359 snd_printdd("pcxhr_sub_set_clock to %dHz (realfreq=%d)\n",
360 rate, realfreq);
361 return 0;
362}
363
364#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
365
366#define PCXHR_IRQ_TIMER_FREQ 92000
367#define PCXHR_IRQ_TIMER_PERIOD 48
368
369int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
370{
371 struct pcxhr_rmh rmh;
372 int err, changed;
373
374 if (rate == 0)
375 return 0; /* nothing to do */
376
377 if (mgr->is_hr_stereo)
378 err = hr222_sub_set_clock(mgr, rate, &changed);
379 else
380 err = pcxhr_sub_set_clock(mgr, rate, &changed);
381
382 if (err)
383 return err;
384
272 if (changed) { 385 if (changed) {
273 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK); 386 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
274 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */ 387 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */
275 if (rate < PCXHR_IRQ_TIMER_FREQ) 388 if (rate < PCXHR_IRQ_TIMER_FREQ)
276 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD; 389 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
277 else 390 else
@@ -282,26 +395,39 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
282 if (err) 395 if (err)
283 return err; 396 return err;
284 } 397 }
285 snd_printdd("pcxhr_set_clock to %dHz (realfreq=%d)\n", rate, realfreq);
286 return 0; 398 return 0;
287} 399}
288 400
289 401
290int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, 402static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,
291 int *sample_rate) 403 enum pcxhr_clock_type clock_type,
404 int *sample_rate)
292{ 405{
293 struct pcxhr_rmh rmh; 406 struct pcxhr_rmh rmh;
294 unsigned char reg; 407 unsigned char reg;
295 int err, rate; 408 int err, rate;
296 409
297 switch (clock_type) { 410 switch (clock_type) {
298 case PCXHR_CLOCK_TYPE_WORD_CLOCK : reg = REG_STATUS_WORD_CLOCK; break; 411 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
299 case PCXHR_CLOCK_TYPE_AES_SYNC : reg = REG_STATUS_AES_SYNC; break; 412 reg = REG_STATUS_WORD_CLOCK;
300 case PCXHR_CLOCK_TYPE_AES_1 : reg = REG_STATUS_AES_1; break; 413 break;
301 case PCXHR_CLOCK_TYPE_AES_2 : reg = REG_STATUS_AES_2; break; 414 case PCXHR_CLOCK_TYPE_AES_SYNC:
302 case PCXHR_CLOCK_TYPE_AES_3 : reg = REG_STATUS_AES_3; break; 415 reg = REG_STATUS_AES_SYNC;
303 case PCXHR_CLOCK_TYPE_AES_4 : reg = REG_STATUS_AES_4; break; 416 break;
304 default : return -EINVAL; 417 case PCXHR_CLOCK_TYPE_AES_1:
418 reg = REG_STATUS_AES_1;
419 break;
420 case PCXHR_CLOCK_TYPE_AES_2:
421 reg = REG_STATUS_AES_2;
422 break;
423 case PCXHR_CLOCK_TYPE_AES_3:
424 reg = REG_STATUS_AES_3;
425 break;
426 case PCXHR_CLOCK_TYPE_AES_4:
427 reg = REG_STATUS_AES_4;
428 break;
429 default:
430 return -EINVAL;
305 } 431 }
306 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 432 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
307 rmh.cmd_len = 2; 433 rmh.cmd_len = 2;
@@ -311,7 +437,7 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
311 err = pcxhr_send_msg(mgr, &rmh); 437 err = pcxhr_send_msg(mgr, &rmh);
312 if (err) 438 if (err)
313 return err; 439 return err;
314 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */ 440 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */
315 mgr->last_reg_stat = reg; 441 mgr->last_reg_stat = reg;
316 } 442 }
317 rmh.cmd[1] = REG_STATUS_CURRENT; 443 rmh.cmd[1] = REG_STATUS_CURRENT;
@@ -336,6 +462,18 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
336} 462}
337 463
338 464
465int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
466 enum pcxhr_clock_type clock_type,
467 int *sample_rate)
468{
469 if (mgr->is_hr_stereo)
470 return hr222_get_external_clock(mgr, clock_type,
471 sample_rate);
472 else
473 return pcxhr_sub_get_external_clock(mgr, clock_type,
474 sample_rate);
475}
476
339/* 477/*
340 * start or stop playback/capture substream 478 * start or stop playback/capture substream
341 */ 479 */
@@ -350,7 +488,8 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
350 start = 1; 488 start = 1;
351 else { 489 else {
352 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { 490 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
353 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state CANNOT be stopped\n"); 491 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state "
492 "CANNOT be stopped\n");
354 return -EINVAL; 493 return -EINVAL;
355 } 494 }
356 start = 0; 495 start = 0;
@@ -359,11 +498,12 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
359 return -EINVAL; 498 return -EINVAL;
360 499
361 stream->timer_abs_periods = 0; 500 stream->timer_abs_periods = 0;
362 stream->timer_period_frag = 0; /* reset theoretical stream pos */ 501 stream->timer_period_frag = 0; /* reset theoretical stream pos */
363 stream->timer_buf_periods = 0; 502 stream->timer_buf_periods = 0;
364 stream->timer_is_synced = 0; 503 stream->timer_is_synced = 0;
365 504
366 stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number; 505 stream_mask =
506 stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
367 507
368 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM); 508 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
369 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 509 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
@@ -373,8 +513,10 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
373 513
374 err = pcxhr_send_msg(chip->mgr, &rmh); 514 err = pcxhr_send_msg(chip->mgr, &rmh);
375 if (err) 515 if (err)
376 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n", err); 516 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n",
377 stream->status = start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED; 517 err);
518 stream->status =
519 start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
378 return err; 520 return err;
379} 521}
380 522
@@ -399,13 +541,15 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
399 header = HEADER_FMT_BASE_LIN; 541 header = HEADER_FMT_BASE_LIN;
400 break; 542 break;
401 case SNDRV_PCM_FORMAT_S16_LE: 543 case SNDRV_PCM_FORMAT_S16_LE:
402 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS | HEADER_FMT_INTEL; 544 header = HEADER_FMT_BASE_LIN |
545 HEADER_FMT_16BITS | HEADER_FMT_INTEL;
403 break; 546 break;
404 case SNDRV_PCM_FORMAT_S16_BE: 547 case SNDRV_PCM_FORMAT_S16_BE:
405 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS; 548 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
406 break; 549 break;
407 case SNDRV_PCM_FORMAT_S24_3LE: 550 case SNDRV_PCM_FORMAT_S24_3LE:
408 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS | HEADER_FMT_INTEL; 551 header = HEADER_FMT_BASE_LIN |
552 HEADER_FMT_24BITS | HEADER_FMT_INTEL;
409 break; 553 break;
410 case SNDRV_PCM_FORMAT_S24_3BE: 554 case SNDRV_PCM_FORMAT_S24_3BE:
411 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS; 555 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
@@ -414,7 +558,8 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
414 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; 558 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
415 break; 559 break;
416 default: 560 default:
417 snd_printk(KERN_ERR "error pcxhr_set_format() : unknown format\n"); 561 snd_printk(KERN_ERR
562 "error pcxhr_set_format() : unknown format\n");
418 return -EINVAL; 563 return -EINVAL;
419 } 564 }
420 chip = snd_pcm_substream_chip(stream->substream); 565 chip = snd_pcm_substream_chip(stream->substream);
@@ -432,14 +577,31 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
432 is_capture = stream->pipe->is_capture; 577 is_capture = stream->pipe->is_capture;
433 stream_num = is_capture ? 0 : stream->substream->number; 578 stream_num = is_capture ? 0 : stream->substream->number;
434 579
435 pcxhr_init_rmh(&rmh, is_capture ? CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT); 580 pcxhr_init_rmh(&rmh, is_capture ?
436 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 581 CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
437 if (is_capture) 582 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
438 rmh.cmd[0] |= 1<<12; 583 stream_num, 0);
584 if (is_capture) {
585 /* bug with old dsp versions: */
586 /* bit 12 also sets the format of the playback stream */
587 if (DSP_EXT_CMD_SET(chip->mgr))
588 rmh.cmd[0] |= 1<<10;
589 else
590 rmh.cmd[0] |= 1<<12;
591 }
439 rmh.cmd[1] = 0; 592 rmh.cmd[1] = 0;
440 rmh.cmd[2] = header >> 8; 593 rmh.cmd_len = 2;
441 rmh.cmd[3] = (header & 0xff) << 16; 594 if (DSP_EXT_CMD_SET(chip->mgr)) {
442 rmh.cmd_len = 4; 595 /* add channels and set bit 19 if channels>2 */
596 rmh.cmd[1] = stream->channels;
597 if (!is_capture) {
598 /* playback : add channel mask to command */
599 rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;
600 rmh.cmd_len = 3;
601 }
602 }
603 rmh.cmd[rmh.cmd_len++] = header >> 8;
604 rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;
443 err = pcxhr_send_msg(chip->mgr, &rmh); 605 err = pcxhr_send_msg(chip->mgr, &rmh);
444 if (err) 606 if (err)
445 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err); 607 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err);
@@ -456,30 +618,38 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
456 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); 618 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
457 stream_num = is_capture ? 0 : subs->number; 619 stream_num = is_capture ? 0 : subs->number;
458 620
459 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", 621 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : "
622 "addr(%p) bytes(%zx) subs(%d)\n",
460 is_capture ? 'c' : 'p', 623 is_capture ? 'c' : 'p',
461 chip->chip_idx, (void *)(long)subs->runtime->dma_addr, 624 chip->chip_idx, (void *)(long)subs->runtime->dma_addr,
462 subs->runtime->dma_bytes, subs->number); 625 subs->runtime->dma_bytes, subs->number);
463 626
464 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); 627 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
465 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 628 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
629 stream_num, 0);
466 630
467 /* max buffer size is 2 MByte */ 631 /* max buffer size is 2 MByte */
468 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000); 632 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
469 rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */ 633 /* size in bits */
470 rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */ 634 rmh.cmd[1] = subs->runtime->dma_bytes * 8;
471 rmh.cmd[2] |= 1<<19; /* this is a circular buffer */ 635 /* most significant byte */
472 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD; /* least 3 significant bytes */ 636 rmh.cmd[2] = subs->runtime->dma_addr >> 24;
637 /* this is a circular buffer */
638 rmh.cmd[2] |= 1<<19;
639 /* least 3 significant bytes */
640 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;
473 rmh.cmd_len = 4; 641 rmh.cmd_len = 4;
474 err = pcxhr_send_msg(chip->mgr, &rmh); 642 err = pcxhr_send_msg(chip->mgr, &rmh);
475 if (err) 643 if (err)
476 snd_printk(KERN_ERR "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err); 644 snd_printk(KERN_ERR
645 "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
477 return err; 646 return err;
478} 647}
479 648
480 649
481#if 0 650#if 0
482static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, snd_pcm_uframes_t *sample_count) 651static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,
652 snd_pcm_uframes_t *sample_count)
483{ 653{
484 struct pcxhr_rmh rmh; 654 struct pcxhr_rmh rmh;
485 int err; 655 int err;
@@ -533,8 +703,8 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
533 for (j = 0; j < chip->nb_streams_play; j++) { 703 for (j = 0; j < chip->nb_streams_play; j++) {
534 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) { 704 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
535 playback_mask |= (1 << pipe->first_audio); 705 playback_mask |= (1 << pipe->first_audio);
536 break; /* add only once, as all playback streams of 706 break; /* add only once, as all playback
537 * one chip use the same pipe 707 * streams of one chip use the same pipe
538 */ 708 */
539 } 709 }
540 } 710 }
@@ -545,19 +715,21 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
545 return; 715 return;
546 } 716 }
547 717
548 snd_printdd("pcxhr_trigger_tasklet : playback_mask=%x capture_mask=%x\n", 718 snd_printdd("pcxhr_trigger_tasklet : "
719 "playback_mask=%x capture_mask=%x\n",
549 playback_mask, capture_mask); 720 playback_mask, capture_mask);
550 721
551 /* synchronous stop of all the pipes concerned */ 722 /* synchronous stop of all the pipes concerned */
552 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); 723 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
553 if (err) { 724 if (err) {
554 mutex_unlock(&mgr->setup_mutex); 725 mutex_unlock(&mgr->setup_mutex);
555 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", 726 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
727 "error stop pipes (P%x C%x)\n",
556 playback_mask, capture_mask); 728 playback_mask, capture_mask);
557 return; 729 return;
558 } 730 }
559 731
560 /* unfortunately the dsp lost format and buffer info with the stop pipe */ 732 /* the dsp lost format and buffer info with the stop pipe */
561 for (i = 0; i < mgr->num_cards; i++) { 733 for (i = 0; i < mgr->num_cards; i++) {
562 struct pcxhr_stream *stream; 734 struct pcxhr_stream *stream;
563 chip = mgr->chip[i]; 735 chip = mgr->chip[i];
@@ -596,12 +768,15 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
596 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 768 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
597 if (err) { 769 if (err) {
598 mutex_unlock(&mgr->setup_mutex); 770 mutex_unlock(&mgr->setup_mutex);
599 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", 771 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
772 "error start pipes (P%x C%x)\n",
600 playback_mask, capture_mask); 773 playback_mask, capture_mask);
601 return; 774 return;
602 } 775 }
603 776
604 /* put the streams into the running state now (increment pointer by interrupt) */ 777 /* put the streams into the running state now
778 * (increment pointer by interrupt)
779 */
605 spin_lock_irqsave(&mgr->lock, flags); 780 spin_lock_irqsave(&mgr->lock, flags);
606 for ( i =0; i < mgr->num_cards; i++) { 781 for ( i =0; i < mgr->num_cards; i++) {
607 struct pcxhr_stream *stream; 782 struct pcxhr_stream *stream;
@@ -615,7 +790,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
615 stream = &chip->playback_stream[j]; 790 stream = &chip->playback_stream[j];
616 if (stream->status == PCXHR_STREAM_STATUS_STARTED) { 791 if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
617 /* playback will already have advanced ! */ 792 /* playback will already have advanced ! */
618 stream->timer_period_frag += PCXHR_GRANULARITY; 793 stream->timer_period_frag += mgr->granularity;
619 stream->status = PCXHR_STREAM_STATUS_RUNNING; 794 stream->status = PCXHR_STREAM_STATUS_RUNNING;
620 } 795 }
621 } 796 }
@@ -653,7 +828,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
653 PCXHR_STREAM_STATUS_SCHEDULE_RUN; 828 PCXHR_STREAM_STATUS_SCHEDULE_RUN;
654 snd_pcm_trigger_done(s, subs); 829 snd_pcm_trigger_done(s, subs);
655 } 830 }
656 tasklet_hi_schedule(&chip->mgr->trigger_taskq); 831 tasklet_schedule(&chip->mgr->trigger_taskq);
657 } else { 832 } else {
658 stream = subs->runtime->private_data; 833 stream = subs->runtime->private_data;
659 snd_printdd("Only one Substream %c %d\n", 834 snd_printdd("Only one Substream %c %d\n",
@@ -697,12 +872,14 @@ static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
697 872
698 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT); 873 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
699 if (start) { 874 if (start) {
700 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; /* last dsp time invalid */ 875 /* last dsp time invalid */
701 rmh.cmd[0] |= PCXHR_GRANULARITY; 876 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
877 rmh.cmd[0] |= mgr->granularity;
702 } 878 }
703 err = pcxhr_send_msg(mgr, &rmh); 879 err = pcxhr_send_msg(mgr, &rmh);
704 if (err < 0) 880 if (err < 0)
705 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n", err); 881 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n",
882 err);
706 return err; 883 return err;
707} 884}
708 885
@@ -713,38 +890,16 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs)
713{ 890{
714 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); 891 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
715 struct pcxhr_mgr *mgr = chip->mgr; 892 struct pcxhr_mgr *mgr = chip->mgr;
716 /*
717 struct pcxhr_stream *stream = (pcxhr_stream_t*)subs->runtime->private_data;
718 */
719 int err = 0; 893 int err = 0;
720 894
721 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n", 895 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n",
722 subs->runtime->period_size, subs->runtime->periods, 896 subs->runtime->period_size, subs->runtime->periods,
723 subs->runtime->buffer_size); 897 subs->runtime->buffer_size);
724 898
725 /*
726 if(subs->runtime->period_size <= PCXHR_GRANULARITY) {
727 snd_printk(KERN_ERR "pcxhr_prepare : error period_size too small (%x)\n",
728 (unsigned int)subs->runtime->period_size);
729 return -EINVAL;
730 }
731 */
732
733 mutex_lock(&mgr->setup_mutex); 899 mutex_lock(&mgr->setup_mutex);
734 900
735 do { 901 do {
736 /* if the stream was stopped before, format and buffer were reset */
737 /*
738 if(stream->status == PCXHR_STREAM_STATUS_STOPPED) {
739 err = pcxhr_set_format(stream);
740 if(err) break;
741 err = pcxhr_update_r_buffer(stream);
742 if(err) break;
743 }
744 */
745
746 /* only the first stream can choose the sample rate */ 902 /* only the first stream can choose the sample rate */
747 /* the further opened streams will be limited to its frequency (see open) */
748 /* set the clock only once (first stream) */ 903 /* set the clock only once (first stream) */
749 if (mgr->sample_rate != subs->runtime->rate) { 904 if (mgr->sample_rate != subs->runtime->rate) {
750 err = pcxhr_set_clock(mgr, subs->runtime->rate); 905 err = pcxhr_set_clock(mgr, subs->runtime->rate);
@@ -787,22 +942,9 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs,
787 stream->channels = channels; 942 stream->channels = channels;
788 stream->format = format; 943 stream->format = format;
789 944
790 /* set the format to the board */
791 /*
792 err = pcxhr_set_format(stream);
793 if(err) {
794 mutex_unlock(&mgr->setup_mutex);
795 return err;
796 }
797 */
798 /* allocate buffer */ 945 /* allocate buffer */
799 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw)); 946 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
800 947
801 /*
802 if (err > 0) {
803 err = pcxhr_update_r_buffer(stream);
804 }
805 */
806 mutex_unlock(&mgr->setup_mutex); 948 mutex_unlock(&mgr->setup_mutex);
807 949
808 return err; 950 return err;
@@ -820,14 +962,18 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs)
820 */ 962 */
821static struct snd_pcm_hardware pcxhr_caps = 963static struct snd_pcm_hardware pcxhr_caps =
822{ 964{
823 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 965 .info = (SNDRV_PCM_INFO_MMAP |
824 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 966 SNDRV_PCM_INFO_INTERLEAVED |
825 0 /*SNDRV_PCM_INFO_PAUSE*/), 967 SNDRV_PCM_INFO_MMAP_VALID |
826 .formats = ( SNDRV_PCM_FMTBIT_U8 | 968 SNDRV_PCM_INFO_SYNC_START),
827 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 969 .formats = (SNDRV_PCM_FMTBIT_U8 |
828 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 970 SNDRV_PCM_FMTBIT_S16_LE |
829 SNDRV_PCM_FMTBIT_FLOAT_LE ), 971 SNDRV_PCM_FMTBIT_S16_BE |
830 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, 972 SNDRV_PCM_FMTBIT_S24_3LE |
973 SNDRV_PCM_FMTBIT_S24_3BE |
974 SNDRV_PCM_FMTBIT_FLOAT_LE),
975 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
976 SNDRV_PCM_RATE_8000_192000),
831 .rate_min = 8000, 977 .rate_min = 8000,
832 .rate_max = 192000, 978 .rate_max = 192000,
833 .channels_min = 1, 979 .channels_min = 1,
@@ -847,6 +993,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
847 struct pcxhr_mgr *mgr = chip->mgr; 993 struct pcxhr_mgr *mgr = chip->mgr;
848 struct snd_pcm_runtime *runtime = subs->runtime; 994 struct snd_pcm_runtime *runtime = subs->runtime;
849 struct pcxhr_stream *stream; 995 struct pcxhr_stream *stream;
996 int err;
850 997
851 mutex_lock(&mgr->setup_mutex); 998 mutex_lock(&mgr->setup_mutex);
852 999
@@ -874,6 +1021,18 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
874 return -EBUSY; 1021 return -EBUSY;
875 } 1022 }
876 1023
1024 /* float format support is in some cases buggy on stereo cards */
1025 if (mgr->is_hr_stereo)
1026 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;
1027
1028 /* buffer-size should better be multiple of period-size */
1029 err = snd_pcm_hw_constraint_integer(runtime,
1030 SNDRV_PCM_HW_PARAM_PERIODS);
1031 if (err < 0) {
1032 mutex_unlock(&mgr->setup_mutex);
1033 return err;
1034 }
1035
877 /* if a sample rate is already used or fixed by external clock, 1036 /* if a sample rate is already used or fixed by external clock,
878 * the stream cannot change 1037 * the stream cannot change
879 */ 1038 */
@@ -889,7 +1048,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
889 mutex_unlock(&mgr->setup_mutex); 1048 mutex_unlock(&mgr->setup_mutex);
890 return -EBUSY; 1049 return -EBUSY;
891 } 1050 }
892 runtime->hw.rate_min = runtime->hw.rate_max = external_rate; 1051 runtime->hw.rate_min = external_rate;
1052 runtime->hw.rate_max = external_rate;
893 } 1053 }
894 } 1054 }
895 1055
@@ -899,9 +1059,11 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
899 1059
900 runtime->private_data = stream; 1060 runtime->private_data = stream;
901 1061
902 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4); 1062 /* better get a divisor of granularity values (96 or 192) */
903 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4); 1063 snd_pcm_hw_constraint_step(runtime, 0,
904 1064 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
1065 snd_pcm_hw_constraint_step(runtime, 0,
1066 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
905 snd_pcm_set_sync(subs); 1067 snd_pcm_set_sync(subs);
906 1068
907 mgr->ref_count_rate++; 1069 mgr->ref_count_rate++;
@@ -919,11 +1081,12 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
919 1081
920 mutex_lock(&mgr->setup_mutex); 1082 mutex_lock(&mgr->setup_mutex);
921 1083
922 snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); 1084 snd_printdd("pcxhr_close chip%d subs%d\n",
1085 chip->chip_idx, subs->number);
923 1086
924 /* sample rate released */ 1087 /* sample rate released */
925 if (--mgr->ref_count_rate == 0) { 1088 if (--mgr->ref_count_rate == 0) {
926 mgr->sample_rate = 0; /* the sample rate is no more locked */ 1089 mgr->sample_rate = 0; /* the sample rate is no more locked */
927 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */ 1090 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */
928 } 1091 }
929 1092
@@ -1016,7 +1179,8 @@ static int pcxhr_chip_dev_free(struct snd_device *device)
1016 1179
1017/* 1180/*
1018 */ 1181 */
1019static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card, int idx) 1182static int __devinit pcxhr_create(struct pcxhr_mgr *mgr,
1183 struct snd_card *card, int idx)
1020{ 1184{
1021 int err; 1185 int err;
1022 struct snd_pcxhr *chip; 1186 struct snd_pcxhr *chip;
@@ -1024,7 +1188,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1024 .dev_free = pcxhr_chip_dev_free, 1188 .dev_free = pcxhr_chip_dev_free,
1025 }; 1189 };
1026 1190
1027 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1191 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1028 if (! chip) { 1192 if (! chip) {
1029 snd_printk(KERN_ERR "cannot allocate chip\n"); 1193 snd_printk(KERN_ERR "cannot allocate chip\n");
1030 return -ENOMEM; 1194 return -ENOMEM;
@@ -1040,7 +1204,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1040 1204
1041 if (idx < mgr->capture_chips) { 1205 if (idx < mgr->capture_chips) {
1042 if (mgr->mono_capture) 1206 if (mgr->mono_capture)
1043 chip->nb_streams_capt = 2; /* 2 mono streams (left+right) */ 1207 chip->nb_streams_capt = 2; /* 2 mono streams */
1044 else 1208 else
1045 chip->nb_streams_capt = 1; /* or 1 stereo stream */ 1209 chip->nb_streams_capt = 1; /* or 1 stereo stream */
1046 } 1210 }
@@ -1050,13 +1214,15 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1050 return err; 1214 return err;
1051 } 1215 }
1052 1216
1217 mgr->chip[idx] = chip;
1053 snd_card_set_dev(card, &mgr->pci->dev); 1218 snd_card_set_dev(card, &mgr->pci->dev);
1054 1219
1055 return 0; 1220 return 0;
1056} 1221}
1057 1222
1058/* proc interface */ 1223/* proc interface */
1059static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1224static void pcxhr_proc_info(struct snd_info_entry *entry,
1225 struct snd_info_buffer *buffer)
1060{ 1226{
1061 struct snd_pcxhr *chip = entry->private_data; 1227 struct snd_pcxhr *chip = entry->private_data;
1062 struct pcxhr_mgr *mgr = chip->mgr; 1228 struct pcxhr_mgr *mgr = chip->mgr;
@@ -1069,8 +1235,10 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1069 short ver_maj = (mgr->dsp_version >> 16) & 0xff; 1235 short ver_maj = (mgr->dsp_version >> 16) & 0xff;
1070 short ver_min = (mgr->dsp_version >> 8) & 0xff; 1236 short ver_min = (mgr->dsp_version >> 8) & 0xff;
1071 short ver_build = mgr->dsp_version & 0xff; 1237 short ver_build = mgr->dsp_version & 0xff;
1072 snd_iprintf(buffer, "module version %s\n", PCXHR_DRIVER_VERSION_STRING); 1238 snd_iprintf(buffer, "module version %s\n",
1073 snd_iprintf(buffer, "dsp version %d.%d.%d\n", ver_maj, ver_min, ver_build); 1239 PCXHR_DRIVER_VERSION_STRING);
1240 snd_iprintf(buffer, "dsp version %d.%d.%d\n",
1241 ver_maj, ver_min, ver_build);
1074 if (mgr->board_has_analog) 1242 if (mgr->board_has_analog)
1075 snd_iprintf(buffer, "analog io available\n"); 1243 snd_iprintf(buffer, "analog io available\n");
1076 else 1244 else
@@ -1084,18 +1252,22 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1084 if (ref > 0) { 1252 if (ref > 0) {
1085 if (mgr->sample_rate_real != 0 && 1253 if (mgr->sample_rate_real != 0 &&
1086 mgr->sample_rate_real != 48000) { 1254 mgr->sample_rate_real != 48000) {
1087 ref = (ref * 48000) / mgr->sample_rate_real; 1255 ref = (ref * 48000) /
1088 if (mgr->sample_rate_real >= PCXHR_IRQ_TIMER_FREQ) 1256 mgr->sample_rate_real;
1257 if (mgr->sample_rate_real >=
1258 PCXHR_IRQ_TIMER_FREQ)
1089 ref *= 2; 1259 ref *= 2;
1090 } 1260 }
1091 cur = 100 - (100 * cur) / ref; 1261 cur = 100 - (100 * cur) / ref;
1092 snd_iprintf(buffer, "cpu load %d%%\n", cur); 1262 snd_iprintf(buffer, "cpu load %d%%\n", cur);
1093 snd_iprintf(buffer, "buffer pool %d/%d kWords\n", 1263 snd_iprintf(buffer, "buffer pool %d/%d\n",
1094 rmh.stat[2], rmh.stat[3]); 1264 rmh.stat[2], rmh.stat[3]);
1095 } 1265 }
1096 } 1266 }
1097 snd_iprintf(buffer, "dma granularity : %d\n", PCXHR_GRANULARITY); 1267 snd_iprintf(buffer, "dma granularity : %d\n",
1098 snd_iprintf(buffer, "dsp time errors : %d\n", mgr->dsp_time_err); 1268 mgr->granularity);
1269 snd_iprintf(buffer, "dsp time errors : %d\n",
1270 mgr->dsp_time_err);
1099 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n", 1271 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
1100 mgr->async_err_pipe_xrun); 1272 mgr->async_err_pipe_xrun);
1101 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n", 1273 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
@@ -1110,33 +1282,52 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1110 rmh.cmd_idx = CMD_LAST_INDEX; 1282 rmh.cmd_idx = CMD_LAST_INDEX;
1111 if( ! pcxhr_send_msg(mgr, &rmh) ) { 1283 if( ! pcxhr_send_msg(mgr, &rmh) ) {
1112 int i; 1284 int i;
1285 if (rmh.stat_len > 8)
1286 rmh.stat_len = 8;
1113 for (i = 0; i < rmh.stat_len; i++) 1287 for (i = 0; i < rmh.stat_len; i++)
1114 snd_iprintf(buffer, "debug[%02d] = %06x\n", i, rmh.stat[i]); 1288 snd_iprintf(buffer, "debug[%02d] = %06x\n",
1289 i, rmh.stat[i]);
1115 } 1290 }
1116 } else 1291 } else
1117 snd_iprintf(buffer, "no firmware loaded\n"); 1292 snd_iprintf(buffer, "no firmware loaded\n");
1118 snd_iprintf(buffer, "\n"); 1293 snd_iprintf(buffer, "\n");
1119} 1294}
1120static void pcxhr_proc_sync(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1295static void pcxhr_proc_sync(struct snd_info_entry *entry,
1296 struct snd_info_buffer *buffer)
1121{ 1297{
1122 struct snd_pcxhr *chip = entry->private_data; 1298 struct snd_pcxhr *chip = entry->private_data;
1123 struct pcxhr_mgr *mgr = chip->mgr; 1299 struct pcxhr_mgr *mgr = chip->mgr;
1124 static char *texts[7] = { 1300 static const char *textsHR22[3] = {
1125 "Internal", "Word", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 1301 "Internal", "AES Sync", "AES 1"
1302 };
1303 static const char *textsPCXHR[7] = {
1304 "Internal", "Word", "AES Sync",
1305 "AES 1", "AES 2", "AES 3", "AES 4"
1126 }; 1306 };
1307 const char **texts;
1308 int max_clock;
1309 if (mgr->is_hr_stereo) {
1310 texts = textsHR22;
1311 max_clock = HR22_CLOCK_TYPE_MAX;
1312 } else {
1313 texts = textsPCXHR;
1314 max_clock = PCXHR_CLOCK_TYPE_MAX;
1315 }
1127 1316
1128 snd_iprintf(buffer, "\n%s\n", mgr->longname); 1317 snd_iprintf(buffer, "\n%s\n", mgr->longname);
1129 snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]); 1318 snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
1130 snd_iprintf(buffer, "Current Sample Rate\t= %d\n", mgr->sample_rate_real); 1319 texts[mgr->cur_clock_type]);
1131 1320 snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
1321 mgr->sample_rate_real);
1132 /* commands available when embedded DSP is running */ 1322 /* commands available when embedded DSP is running */
1133 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 1323 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1134 int i, err, sample_rate; 1324 int i, err, sample_rate;
1135 for (i = PCXHR_CLOCK_TYPE_WORD_CLOCK; i< (3 + mgr->capture_chips); i++) { 1325 for (i = 1; i <= max_clock; i++) {
1136 err = pcxhr_get_external_clock(mgr, i, &sample_rate); 1326 err = pcxhr_get_external_clock(mgr, i, &sample_rate);
1137 if (err) 1327 if (err)
1138 break; 1328 break;
1139 snd_iprintf(buffer, "%s Clock\t\t= %d\n", texts[i], sample_rate); 1329 snd_iprintf(buffer, "%s Clock\t\t= %d\n",
1330 texts[i], sample_rate);
1140 } 1331 }
1141 } else 1332 } else
1142 snd_iprintf(buffer, "no firmware loaded\n"); 1333 snd_iprintf(buffer, "no firmware loaded\n");
@@ -1194,7 +1385,8 @@ static int pcxhr_free(struct pcxhr_mgr *mgr)
1194/* 1385/*
1195 * probe function - creates the card manager 1386 * probe function - creates the card manager
1196 */ 1387 */
1197static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 1388static int __devinit pcxhr_probe(struct pci_dev *pci,
1389 const struct pci_device_id *pci_id)
1198{ 1390{
1199 static int dev; 1391 static int dev;
1200 struct pcxhr_mgr *mgr; 1392 struct pcxhr_mgr *mgr;
@@ -1217,7 +1409,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1217 1409
1218 /* check if we can restrict PCI DMA transfers to 32 bits */ 1410 /* check if we can restrict PCI DMA transfers to 32 bits */
1219 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { 1411 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1220 snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); 1412 snd_printk(KERN_ERR "architecture does not support "
1413 "32bit PCI busmaster DMA\n");
1221 pci_disable_device(pci); 1414 pci_disable_device(pci);
1222 return -ENXIO; 1415 return -ENXIO;
1223 } 1416 }
@@ -1229,13 +1422,30 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1229 return -ENOMEM; 1422 return -ENOMEM;
1230 } 1423 }
1231 1424
1232 if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) 1425 if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) {
1426 kfree(mgr);
1427 pci_disable_device(pci);
1233 return -ENODEV; 1428 return -ENODEV;
1234 card_name = pcxhr_board_params[pci_id->driver_data].board_name; 1429 }
1235 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; 1430 card_name =
1236 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; 1431 pcxhr_board_params[pci_id->driver_data].board_name;
1237 mgr->firmware_num = pcxhr_board_params[pci_id->driver_data].firmware_num; 1432 mgr->playback_chips =
1433 pcxhr_board_params[pci_id->driver_data].playback_chips;
1434 mgr->capture_chips =
1435 pcxhr_board_params[pci_id->driver_data].capture_chips;
1436 mgr->fw_file_set =
1437 pcxhr_board_params[pci_id->driver_data].fw_file_set;
1438 mgr->firmware_num =
1439 pcxhr_board_params[pci_id->driver_data].firmware_num;
1238 mgr->mono_capture = mono[dev]; 1440 mgr->mono_capture = mono[dev];
1441 mgr->is_hr_stereo = (mgr->playback_chips == 1);
1442 mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);
1443 mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);
1444
1445 if (mgr->is_hr_stereo)
1446 mgr->granularity = PCXHR_GRANULARITY_HR22;
1447 else
1448 mgr->granularity = PCXHR_GRANULARITY;
1239 1449
1240 /* resource assignment */ 1450 /* resource assignment */
1241 if ((err = pci_request_regions(pci, card_name)) < 0) { 1451 if ((err = pci_request_regions(pci, card_name)) < 0) {
@@ -1258,7 +1468,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1258 mgr->irq = pci->irq; 1468 mgr->irq = pci->irq;
1259 1469
1260 sprintf(mgr->shortname, "Digigram %s", card_name); 1470 sprintf(mgr->shortname, "Digigram %s", card_name);
1261 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", mgr->shortname, 1471 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i",
1472 mgr->shortname,
1262 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); 1473 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
1263 1474
1264 /* ISR spinlock */ 1475 /* ISR spinlock */
@@ -1269,10 +1480,14 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1269 mutex_init(&mgr->setup_mutex); 1480 mutex_init(&mgr->setup_mutex);
1270 1481
1271 /* init taslket */ 1482 /* init taslket */
1272 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); 1483 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet,
1273 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet, (unsigned long) mgr); 1484 (unsigned long) mgr);
1485 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet,
1486 (unsigned long) mgr);
1487
1274 mgr->prmh = kmalloc(sizeof(*mgr->prmh) + 1488 mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
1275 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS - PCXHR_SIZE_MAX_STATUS), 1489 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
1490 PCXHR_SIZE_MAX_STATUS),
1276 GFP_KERNEL); 1491 GFP_KERNEL);
1277 if (! mgr->prmh) { 1492 if (! mgr->prmh) {
1278 pcxhr_free(mgr); 1493 pcxhr_free(mgr);
@@ -1293,7 +1508,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1293 else 1508 else
1294 idx = index[dev] + i; 1509 idx = index[dev] + i;
1295 1510
1296 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : card_name, i); 1511 snprintf(tmpid, sizeof(tmpid), "%s-%d",
1512 id[dev] ? id[dev] : card_name, i);
1297 card = snd_card_new(idx, tmpid, THIS_MODULE, 0); 1513 card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
1298 1514
1299 if (! card) { 1515 if (! card) {
@@ -1307,6 +1523,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1307 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1523 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1308 1524
1309 if ((err = pcxhr_create(mgr, card, i)) < 0) { 1525 if ((err = pcxhr_create(mgr, card, i)) < 0) {
1526 snd_card_free(card);
1310 pcxhr_free(mgr); 1527 pcxhr_free(mgr);
1311 return err; 1528 return err;
1312 } 1529 }
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index 652064787a55..84131a916c92 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -27,15 +27,18 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29 29
30#define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ 30#define PCXHR_DRIVER_VERSION 0x000905 /* 0.9.5 */
31#define PCXHR_DRIVER_VERSION_STRING "0.8.4" /* 0.8.4 */ 31#define PCXHR_DRIVER_VERSION_STRING "0.9.5" /* 0.9.5 */
32 32
33 33
34#define PCXHR_MAX_CARDS 6 34#define PCXHR_MAX_CARDS 6
35#define PCXHR_PLAYBACK_STREAMS 4 35#define PCXHR_PLAYBACK_STREAMS 4
36 36
37#define PCXHR_GRANULARITY 96 /* transfer granularity (should be min 96 and multiple of 48) */ 37#define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */
38#define PCXHR_GRANULARITY_MIN 96 /* transfer granularity of pipes and the dsp time (MBOX4) */ 38/* transfer granularity of pipes and the dsp time (MBOX4) */
39#define PCXHR_GRANULARITY_MIN 96
40/* TODO : granularity could be 64 or 128 */
41#define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */
39 42
40struct snd_pcxhr; 43struct snd_pcxhr;
41struct pcxhr_mgr; 44struct pcxhr_mgr;
@@ -51,6 +54,11 @@ enum pcxhr_clock_type {
51 PCXHR_CLOCK_TYPE_AES_2, 54 PCXHR_CLOCK_TYPE_AES_2,
52 PCXHR_CLOCK_TYPE_AES_3, 55 PCXHR_CLOCK_TYPE_AES_3,
53 PCXHR_CLOCK_TYPE_AES_4, 56 PCXHR_CLOCK_TYPE_AES_4,
57 PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
58 HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
59 HR22_CLOCK_TYPE_AES_SYNC,
60 HR22_CLOCK_TYPE_AES_1,
61 HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
54}; 62};
55 63
56struct pcxhr_mgr { 64struct pcxhr_mgr {
@@ -61,6 +69,8 @@ struct pcxhr_mgr {
61 69
62 int irq; 70 int irq;
63 71
72 int granularity;
73
64 /* card access with 1 mem bar and 2 io bar's */ 74 /* card access with 1 mem bar and 2 io bar's */
65 unsigned long port[3]; 75 unsigned long port[3];
66 76
@@ -83,11 +93,16 @@ struct pcxhr_mgr {
83 /* hardware interface */ 93 /* hardware interface */
84 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ 94 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
85 unsigned int dsp_version; /* read from embedded once firmware is loaded */ 95 unsigned int dsp_version; /* read from embedded once firmware is loaded */
86 int board_has_analog; /* if 0 the board is digital only */ 96 int playback_chips;
87 int mono_capture; /* if 1 the board does mono capture */ 97 int capture_chips;
88 int playback_chips; /* 4 or 6 */ 98 int fw_file_set;
89 int capture_chips; /* 4 or 1 */ 99 int firmware_num;
90 int firmware_num; /* 41 or 42 */ 100 int is_hr_stereo:1;
101 int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */
102 int board_has_analog:1; /* if 0 the board is digital only */
103 int board_has_mic:1; /* if 1 the board has microphone input */
104 int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
105 int mono_capture:1; /* if 1 the board does mono capture */
91 106
92 struct snd_dma_buffer hostport; 107 struct snd_dma_buffer hostport;
93 108
@@ -106,6 +121,9 @@ struct pcxhr_mgr {
106 int async_err_stream_xrun; 121 int async_err_stream_xrun;
107 int async_err_pipe_xrun; 122 int async_err_pipe_xrun;
108 int async_err_other_last; 123 int async_err_other_last;
124
125 unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */
126 unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */
109}; 127};
110 128
111 129
@@ -155,24 +173,30 @@ struct snd_pcxhr {
155 173
156 struct snd_pcm *pcm; /* PCM */ 174 struct snd_pcm *pcm; /* PCM */
157 175
158 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ 176 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */
159 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo pipe or 2 mono pipes */ 177 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */
160 178
161 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; 179 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS];
162 struct pcxhr_stream capture_stream[2]; /* 1 stereo stream or 2 mono streams */ 180 struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */
163 int nb_streams_play; 181 int nb_streams_play;
164 int nb_streams_capt; 182 int nb_streams_capt;
165 183
166 int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */ 184 int analog_playback_active[2]; /* Mixer : Master Playback !mute */
167 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ 185 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
168 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ 186 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
169 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [streams][stereo]*/ 187 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2];
170 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [streams][stereo]*/ 188 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2];
171 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume [stereo] */ 189 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */
172 int monitoring_active[2]; /* Mixer : Monitoring Active */ 190 int monitoring_active[2]; /* Mixer : Monitoring Active */
173 int monitoring_volume[2]; /* Mixer : Monitoring Volume */ 191 int monitoring_volume[2]; /* Mixer : Monitoring Volume */
174 int audio_capture_source; /* Mixer : Audio Capture Source */ 192 int audio_capture_source; /* Mixer : Audio Capture Source */
175 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ 193 int mic_volume; /* used by cards with MIC only */
194 int mic_boost; /* used by cards with MIC only */
195 int mic_active; /* used by cards with MIC only */
196 int analog_capture_active; /* used by cards with MIC only */
197 int phantom_power; /* used by cards with MIC only */
198
199 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */
176}; 200};
177 201
178struct pcxhr_hostport 202struct pcxhr_hostport
@@ -184,6 +208,8 @@ struct pcxhr_hostport
184/* exported */ 208/* exported */
185int pcxhr_create_pcm(struct snd_pcxhr *chip); 209int pcxhr_create_pcm(struct snd_pcxhr *chip);
186int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); 210int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate);
187int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, int *sample_rate); 211int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
212 enum pcxhr_clock_type clock_type,
213 int *sample_rate);
188 214
189#endif /* __SOUND_PCXHR_H */ 215#endif /* __SOUND_PCXHR_H */
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 7143259cfe34..833e7180ad2d 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -132,13 +132,15 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
132 *read = PCXHR_INPB(mgr, reg); 132 *read = PCXHR_INPB(mgr, reg);
133 if ((*read & mask) == bit) { 133 if ((*read & mask) == bit) {
134 if (i > 100) 134 if (i > 100)
135 snd_printdd("ATTENTION! check_reg(%x) loopcount=%d\n", 135 snd_printdd("ATTENTION! check_reg(%x) "
136 "loopcount=%d\n",
136 reg, i); 137 reg, i);
137 return 0; 138 return 0;
138 } 139 }
139 i++; 140 i++;
140 } while (time_after_eq(end_time, jiffies)); 141 } while (time_after_eq(end_time, jiffies));
141 snd_printk(KERN_ERR "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=0x%x\n", 142 snd_printk(KERN_ERR
143 "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=%x\n",
142 reg, mask, *read); 144 reg, mask, *read);
143 return -EIO; 145 return -EIO;
144} 146}
@@ -159,18 +161,22 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
159#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \ 161#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \
160 PCXHR_MASK_IT_MANAGE_HF5) 162 PCXHR_MASK_IT_MANAGE_HF5)
161#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \ 163#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \
162 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 164 PCXHR_MASK_IT_MANAGE_HF5 | \
165 PCXHR_MASK_IT_WAIT)
163#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \ 166#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \
164 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT_EXTRA) 167 PCXHR_MASK_IT_MANAGE_HF5 | \
168 PCXHR_MASK_IT_WAIT_EXTRA)
165#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \ 169#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \
166 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 170 PCXHR_MASK_IT_MANAGE_HF5 | \
171 PCXHR_MASK_IT_WAIT)
167#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1) 172#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
168#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1) 173#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
169#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1) 174#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
170#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1) 175#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
171#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1) 176#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
172 177
173static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atomic) 178static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr,
179 unsigned int itdsp, int atomic)
174{ 180{
175 int err; 181 int err;
176 unsigned char reg; 182 unsigned char reg;
@@ -178,17 +184,21 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
178 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 184 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
179 /* clear hf5 bit */ 185 /* clear hf5 bit */
180 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0, 186 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
181 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5); 187 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) &
188 ~PCXHR_MBOX0_HF5);
182 } 189 }
183 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) { 190 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
184 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 191 reg = (PCXHR_ICR_HI08_RREQ |
192 PCXHR_ICR_HI08_TREQ |
193 PCXHR_ICR_HI08_HDRQ);
185 if (itdsp & PCXHR_MASK_IT_HF0) 194 if (itdsp & PCXHR_MASK_IT_HF0)
186 reg |= PCXHR_ICR_HI08_HF0; 195 reg |= PCXHR_ICR_HI08_HF0;
187 if (itdsp & PCXHR_MASK_IT_HF1) 196 if (itdsp & PCXHR_MASK_IT_HF1)
188 reg |= PCXHR_ICR_HI08_HF1; 197 reg |= PCXHR_ICR_HI08_HF1;
189 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 198 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
190 } 199 }
191 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) | PCXHR_CVR_HI08_HC); 200 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) |
201 PCXHR_CVR_HI08_HC);
192 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg); 202 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
193 if (itdsp & PCXHR_MASK_IT_WAIT) { 203 if (itdsp & PCXHR_MASK_IT_WAIT) {
194 if (atomic) 204 if (atomic)
@@ -211,10 +221,14 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
211 } 221 }
212 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 222 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
213 /* wait for hf5 bit */ 223 /* wait for hf5 bit */
214 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5, 224 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0,
215 PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &reg); 225 PCXHR_MBOX0_HF5,
226 PCXHR_MBOX0_HF5,
227 PCXHR_TIMEOUT_DSP,
228 &reg);
216 if (err) { 229 if (err) {
217 snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT HF5\n"); 230 snd_printk(KERN_ERR
231 "pcxhr_send_it_dsp : TIMEOUT HF5\n");
218 return err; 232 return err;
219 } 233 }
220 } 234 }
@@ -263,7 +277,8 @@ void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
263/* 277/*
264 * load the xilinx image 278 * load the xilinx image
265 */ 279 */
266int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second) 280int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr,
281 const struct firmware *xilinx, int second)
267{ 282{
268 unsigned int i; 283 unsigned int i;
269 unsigned int chipsc; 284 unsigned int chipsc;
@@ -274,7 +289,9 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
274 /* test first xilinx */ 289 /* test first xilinx */
275 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); 290 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
276 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */ 291 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
277 /* this bit will always be 1; no possibility to test presence of first xilinx */ 292 /* this bit will always be 1;
293 * no possibility to test presence of first xilinx
294 */
278 if(second) { 295 if(second) {
279 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) { 296 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
280 snd_printk(KERN_ERR "error loading first xilinx\n"); 297 snd_printk(KERN_ERR "error loading first xilinx\n");
@@ -290,7 +307,8 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
290 data = *image; 307 data = *image;
291 mask = 0x80; 308 mask = 0x80;
292 while (mask) { 309 while (mask) {
293 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN); 310 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK |
311 PCXHR_CHIPSC_DATA_IN);
294 if (data & mask) 312 if (data & mask)
295 chipsc |= PCXHR_CHIPSC_DATA_IN; 313 chipsc |= PCXHR_CHIPSC_DATA_IN;
296 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc); 314 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
@@ -330,15 +348,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
330 data = dsp->data + i; 348 data = dsp->data + i;
331 if (i == 0) { 349 if (i == 0) {
332 /* test data header consistency */ 350 /* test data header consistency */
333 len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]); 351 len = (unsigned int)((data[0]<<16) +
334 if (len && dsp->size != (len + 2) * 3) 352 (data[1]<<8) +
353 data[2]);
354 if (len && (dsp->size != (len + 2) * 3))
335 return -EINVAL; 355 return -EINVAL;
336 } 356 }
337 /* wait DSP ready for new transfer */ 357 /* wait DSP ready for new transfer */
338 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 358 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
339 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &dummy); 359 PCXHR_ISR_HI08_TRDY,
360 PCXHR_ISR_HI08_TRDY,
361 PCXHR_TIMEOUT_DSP, &dummy);
340 if (err) { 362 if (err) {
341 snd_printk(KERN_ERR "dsp loading error at position %d\n", i); 363 snd_printk(KERN_ERR
364 "dsp loading error at position %d\n", i);
342 return err; 365 return err;
343 } 366 }
344 /* send host data */ 367 /* send host data */
@@ -357,7 +380,8 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
357/* 380/*
358 * load the eeprom image 381 * load the eeprom image
359 */ 382 */
360int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom) 383int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr,
384 const struct firmware *eeprom)
361{ 385{
362 int err; 386 int err;
363 unsigned char reg; 387 unsigned char reg;
@@ -365,7 +389,9 @@ int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eepro
365 /* init value of the ICR register */ 389 /* init value of the ICR register */
366 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 390 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
367 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) { 391 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
368 /* no need to load the eeprom binary, but init the HI08 interface */ 392 /* no need to load the eeprom binary,
393 * but init the HI08 interface
394 */
369 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT); 395 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
370 msleep(PCXHR_WAIT_DEFAULT); 396 msleep(PCXHR_WAIT_DEFAULT);
371 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 397 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
@@ -429,8 +455,10 @@ int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
429 if (err) 455 if (err)
430 return err; 456 return err;
431 /* wait for chk bit */ 457 /* wait for chk bit */
432 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK, 458 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
433 PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &dummy); 459 PCXHR_ISR_HI08_CHK,
460 PCXHR_ISR_HI08_CHK,
461 PCXHR_TIMEOUT_DSP, &dummy);
434} 462}
435 463
436 464
@@ -443,8 +471,8 @@ struct pcxhr_cmd_info {
443/* RMH status type */ 471/* RMH status type */
444enum { 472enum {
445 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */ 473 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */
446 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte (used with st_length = 1) */ 474 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
447 RMH_SSIZE_MASK = 2, /* status size given in bitmask (used with st_length = 1) */ 475 RMH_SSIZE_MASK = 2, /* status size given in bitmask */
448}; 476};
449 477
450/* 478/*
@@ -474,7 +502,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
474[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED }, 502[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED },
475[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED }, 503[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED },
476[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, 504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
477[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, /* stat_len = nb_streams * 2 */ 505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
478[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
479}; 507};
480 508
@@ -524,10 +552,13 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
524 552
525 for (i = 0; i < rmh->stat_len; i++) { 553 for (i = 0; i < rmh->stat_len; i++) {
526 /* wait for receiver full */ 554 /* wait for receiver full */
527 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 555 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
528 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 556 PCXHR_ISR_HI08_RXDF,
557 PCXHR_ISR_HI08_RXDF,
558 PCXHR_TIMEOUT_DSP, &reg);
529 if (err) { 559 if (err) {
530 snd_printk(KERN_ERR "ERROR RMH stat: ISR:RXDF=1 (ISR = %x; i=%d )\n", 560 snd_printk(KERN_ERR "ERROR RMH stat: "
561 "ISR:RXDF=1 (ISR = %x; i=%d )\n",
531 reg, i); 562 reg, i);
532 return err; 563 return err;
533 } 564 }
@@ -537,10 +568,10 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
537 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 568 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
538 569
539 /* need to update rmh->stat_len on the fly ?? */ 570 /* need to update rmh->stat_len on the fly ?? */
540 if (i==0) { 571 if (!i) {
541 if (rmh->dsp_stat != RMH_SSIZE_FIXED) { 572 if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
542 if (rmh->dsp_stat == RMH_SSIZE_ARG) { 573 if (rmh->dsp_stat == RMH_SSIZE_ARG) {
543 rmh->stat_len = (u16)(data & 0x0000ff) + 1; 574 rmh->stat_len = (data & 0x0000ff) + 1;
544 data &= 0xffff00; 575 data &= 0xffff00;
545 } else { 576 } else {
546 /* rmh->dsp_stat == RMH_SSIZE_MASK */ 577 /* rmh->dsp_stat == RMH_SSIZE_MASK */
@@ -562,7 +593,8 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
562 rmh->stat[i] = data; 593 rmh->stat[i] = data;
563 } 594 }
564 if (rmh->stat_len > max_stat_len) { 595 if (rmh->stat_len > max_stat_len) {
565 snd_printdd("PCXHR : rmh->stat_len=%x too big\n", rmh->stat_len); 596 snd_printdd("PCXHR : rmh->stat_len=%x too big\n",
597 rmh->stat_len);
566 rmh->stat_len = max_stat_len; 598 rmh->stat_len = max_stat_len;
567 } 599 }
568 return 0; 600 return 0;
@@ -605,7 +637,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
605 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */ 637 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
606#ifdef CONFIG_SND_DEBUG_VERBOSE 638#ifdef CONFIG_SND_DEBUG_VERBOSE
607 if (rmh->cmd_idx < CMD_LAST_INDEX) 639 if (rmh->cmd_idx < CMD_LAST_INDEX)
608 snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]); 640 snd_printdd("MSG cmd[0]=%x (%s)\n",
641 data, cmd_names[rmh->cmd_idx]);
609#endif 642#endif
610 643
611 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 644 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
@@ -619,8 +652,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
619 if (rmh->cmd_len > 1) { 652 if (rmh->cmd_len > 1) {
620 /* send length */ 653 /* send length */
621 data = rmh->cmd_len - 1; 654 data = rmh->cmd_len - 1;
622 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 655 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
623 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg); 656 PCXHR_ISR_HI08_TRDY,
657 PCXHR_ISR_HI08_TRDY,
658 PCXHR_TIMEOUT_DSP, &reg);
624 if (err) 659 if (err)
625 return err; 660 return err;
626 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF); 661 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
@@ -653,8 +688,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
653 /* test status ISR */ 688 /* test status ISR */
654 if (reg & PCXHR_ISR_HI08_ERR) { 689 if (reg & PCXHR_ISR_HI08_ERR) {
655 /* ERROR, wait for receiver full */ 690 /* ERROR, wait for receiver full */
656 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 691 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
657 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 692 PCXHR_ISR_HI08_RXDF,
693 PCXHR_ISR_HI08_RXDF,
694 PCXHR_TIMEOUT_DSP, &reg);
658 if (err) { 695 if (err) {
659 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg); 696 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
660 return err; 697 return err;
@@ -663,7 +700,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
663 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16; 700 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
664 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8; 701 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
665 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 702 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
666 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n", rmh->cmd_idx, data); 703 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n",
704 rmh->cmd_idx, data);
667 err = -EINVAL; 705 err = -EINVAL;
668 } else { 706 } else {
669 /* read the response data */ 707 /* read the response data */
@@ -732,8 +770,9 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
732static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr) 770static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
733{ 771{
734 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2); 772 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
735 /* least segnificant 12 bits are the pipe states for the playback audios */ 773 /* least segnificant 12 bits are the pipe states
736 /* next 12 bits are the pipe states for the capture audios 774 * for the playback audios
775 * next 12 bits are the pipe states for the capture audios
737 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET) 776 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
738 */ 777 */
739 start_mask &= 0xffffff; 778 start_mask &= 0xffffff;
@@ -744,7 +783,8 @@ static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
744#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12 783#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12
745#define MAX_WAIT_FOR_DSP 20 784#define MAX_WAIT_FOR_DSP 20
746 785
747static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *retry) 786static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr,
787 int audio_mask, int *retry)
748{ 788{
749 struct pcxhr_rmh rmh; 789 struct pcxhr_rmh rmh;
750 int err; 790 int err;
@@ -760,17 +800,20 @@ static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *
760 } else { 800 } else {
761 /* can start capture pipe */ 801 /* can start capture pipe */
762 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 802 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
763 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 803 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
764 0, 0); 804 0, 0);
765 } 805 }
766 err = pcxhr_send_msg(mgr, &rmh); 806 err = pcxhr_send_msg(mgr, &rmh);
767 if (err) { 807 if (err) {
768 snd_printk(KERN_ERR 808 snd_printk(KERN_ERR
769 "error pipe start (CMD_CAN_START_PIPE) err=%x!\n", 809 "error pipe start "
810 "(CMD_CAN_START_PIPE) err=%x!\n",
770 err); 811 err);
771 return err; 812 return err;
772 } 813 }
773 /* if the pipe couldn't be prepaired for start, retry it later */ 814 /* if the pipe couldn't be prepaired for start,
815 * retry it later
816 */
774 if (rmh.stat[0] == 0) 817 if (rmh.stat[0] == 0)
775 *retry |= (1<<audio); 818 *retry |= (1<<audio);
776 } 819 }
@@ -795,14 +838,14 @@ static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
795 } else { 838 } else {
796 /* stop capture pipe */ 839 /* stop capture pipe */
797 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 840 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
798 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 841 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
799 0, 0); 842 0, 0);
800 } 843 }
801 err = pcxhr_send_msg(mgr, &rmh); 844 err = pcxhr_send_msg(mgr, &rmh);
802 if (err) { 845 if (err) {
803 snd_printk(KERN_ERR 846 snd_printk(KERN_ERR
804 "error pipe stop (CMD_STOP_PIPE) err=%x!\n", 847 "error pipe stop "
805 err); 848 "(CMD_STOP_PIPE) err=%x!\n", err);
806 return err; 849 return err;
807 } 850 }
808 } 851 }
@@ -822,15 +865,16 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
822 if (audio_mask & 1) { 865 if (audio_mask & 1) {
823 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE); 866 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
824 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) 867 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
825 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0, 1 << audio); 868 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0,
869 1 << audio);
826 else 870 else
827 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0, 871 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
828 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 872 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
829 err = pcxhr_send_msg(mgr, &rmh); 873 err = pcxhr_send_msg(mgr, &rmh);
830 if (err) { 874 if (err) {
831 snd_printk(KERN_ERR 875 snd_printk(KERN_ERR
832 "error pipe start (CMD_CONF_PIPE) err=%x!\n", 876 "error pipe start "
833 err); 877 "(CMD_CONF_PIPE) err=%x!\n", err);
834 return err; 878 return err;
835 } 879 }
836 } 880 }
@@ -841,7 +885,9 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
841 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA); 885 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
842 err = pcxhr_send_msg(mgr, &rmh); 886 err = pcxhr_send_msg(mgr, &rmh);
843 if (err) { 887 if (err) {
844 snd_printk(KERN_ERR "error pipe start (CMD_SEND_IRQA) err=%x!\n", err ); 888 snd_printk(KERN_ERR
889 "error pipe start (CMD_SEND_IRQA) err=%x!\n",
890 err);
845 return err; 891 return err;
846 } 892 }
847 return 0; 893 return 0;
@@ -849,7 +895,8 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
849 895
850 896
851 897
852int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start) 898int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask,
899 int capture_mask, int start)
853{ 900{
854 int state, i, err; 901 int state, i, err;
855 int audio_mask; 902 int audio_mask;
@@ -858,21 +905,23 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
858 struct timeval my_tv1, my_tv2; 905 struct timeval my_tv1, my_tv2;
859 do_gettimeofday(&my_tv1); 906 do_gettimeofday(&my_tv1);
860#endif 907#endif
861 audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 908 audio_mask = (playback_mask |
909 (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
862 /* current pipe state (playback + record) */ 910 /* current pipe state (playback + record) */
863 state = pcxhr_pipes_running(mgr); 911 state = pcxhr_pipes_running(mgr);
864 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n", 912 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
865 start ? "START" : "STOP", audio_mask, state); 913 start ? "START" : "STOP", audio_mask, state);
866 if (start) { 914 if (start) {
867 audio_mask &= ~state; /* start only pipes that are not yet started */ 915 /* start only pipes that are not yet started */
916 audio_mask &= ~state;
868 state = audio_mask; 917 state = audio_mask;
869 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) { 918 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
870 err = pcxhr_prepair_pipe_start(mgr, state, &state); 919 err = pcxhr_prepair_pipe_start(mgr, state, &state);
871 if (err) 920 if (err)
872 return err; 921 return err;
873 if (state == 0) 922 if (state == 0)
874 break; /* success, all pipes prepaired for start */ 923 break; /* success, all pipes prepaired */
875 mdelay(1); /* otherwise wait 1 millisecond and retry */ 924 mdelay(1); /* wait 1 millisecond and retry */
876 } 925 }
877 } else { 926 } else {
878 audio_mask &= state; /* stop only pipes that are started */ 927 audio_mask &= state; /* stop only pipes that are started */
@@ -891,7 +940,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
891 if ((state & audio_mask) == (start ? audio_mask : 0)) 940 if ((state & audio_mask) == (start ? audio_mask : 0))
892 break; 941 break;
893 if (++i >= MAX_WAIT_FOR_DSP * 100) { 942 if (++i >= MAX_WAIT_FOR_DSP * 100) {
894 snd_printk(KERN_ERR "error pipe start/stop (ED_NO_RESPONSE_AT_IRQA)\n"); 943 snd_printk(KERN_ERR "error pipe start/stop\n");
895 return -EBUSY; 944 return -EBUSY;
896 } 945 }
897 udelay(10); /* wait 10 microseconds */ 946 udelay(10); /* wait 10 microseconds */
@@ -918,7 +967,8 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
918 967
919 spin_lock_irqsave(&mgr->msg_lock, flags); 968 spin_lock_irqsave(&mgr->msg_lock, flags);
920 if ((mgr->io_num_reg_cont & mask) == value) { 969 if ((mgr->io_num_reg_cont & mask) == value) {
921 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n", mask, value); 970 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n",
971 mask, value);
922 if (changed) 972 if (changed)
923 *changed = 0; 973 *changed = 0;
924 spin_unlock_irqrestore(&mgr->msg_lock, flags); 974 spin_unlock_irqrestore(&mgr->msg_lock, flags);
@@ -971,7 +1021,8 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
971 err = ((err >> 12) & 0xfff); 1021 err = ((err >> 12) & 0xfff);
972 if (!err) 1022 if (!err)
973 return 0; 1023 return 0;
974 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n", err_src_name[err_src], 1024 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n",
1025 err_src_name[err_src],
975 is_capture ? "Record" : "Play", pipe, err); 1026 is_capture ? "Record" : "Play", pipe, err);
976 if (err == 0xe01) 1027 if (err == 0xe01)
977 mgr->async_err_stream_xrun++; 1028 mgr->async_err_stream_xrun++;
@@ -996,6 +1047,13 @@ void pcxhr_msg_tasklet(unsigned long arg)
996 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n"); 1047 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n");
997 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) 1048 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
998 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n"); 1049 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n");
1050 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
1051 /* clear events FREQ_CHANGE and TIME_CODE */
1052 pcxhr_init_rmh(prmh, CMD_TEST_IT);
1053 err = pcxhr_send_msg(mgr, prmh);
1054 snd_printdd("CMD_TEST_IT : err=%x, stat=%x\n",
1055 err, prmh->stat[0]);
1056 }
999 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { 1057 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
1000 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n"); 1058 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n");
1001 1059
@@ -1005,18 +1063,22 @@ void pcxhr_msg_tasklet(unsigned long arg)
1005 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS; 1063 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
1006 err = pcxhr_send_msg(mgr, prmh); 1064 err = pcxhr_send_msg(mgr, prmh);
1007 if (err) 1065 if (err)
1008 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n", err); 1066 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n",
1067 err);
1009 i = 1; 1068 i = 1;
1010 while (i < prmh->stat_len) { 1069 while (i < prmh->stat_len) {
1011 int nb_audio = (prmh->stat[i] >> FIELD_SIZE) & MASK_FIRST_FIELD; 1070 int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) &
1012 int nb_stream = (prmh->stat[i] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD; 1071 MASK_FIRST_FIELD);
1072 int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) &
1073 MASK_FIRST_FIELD);
1013 int pipe = prmh->stat[i] & MASK_FIRST_FIELD; 1074 int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
1014 int is_capture = prmh->stat[i] & 0x400000; 1075 int is_capture = prmh->stat[i] & 0x400000;
1015 u32 err2; 1076 u32 err2;
1016 1077
1017 if (prmh->stat[i] & 0x800000) { /* if BIT_END */ 1078 if (prmh->stat[i] & 0x800000) { /* if BIT_END */
1018 snd_printdd("TASKLET : End%sPipe %d\n", 1079 snd_printdd("TASKLET : End%sPipe %d\n",
1019 is_capture ? "Record" : "Play", pipe); 1080 is_capture ? "Record" : "Play",
1081 pipe);
1020 } 1082 }
1021 i++; 1083 i++;
1022 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1]; 1084 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
@@ -1062,7 +1124,7 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1062 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT); 1124 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
1063 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 1125 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
1064 stream->pipe->first_audio, 0, stream_mask); 1126 stream->pipe->first_audio, 0, stream_mask);
1065 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */ 1127 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
1066 1128
1067 err = pcxhr_send_msg(mgr, &rmh); 1129 err = pcxhr_send_msg(mgr, &rmh);
1068 if (err) 1130 if (err)
@@ -1072,18 +1134,21 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1072 hw_sample_count += (u_int64_t)rmh.stat[1]; 1134 hw_sample_count += (u_int64_t)rmh.stat[1];
1073 1135
1074 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", 1136 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
1075 stream->pipe->is_capture ? 'C':'P', stream->substream->number, 1137 stream->pipe->is_capture ? 'C' : 'P',
1138 stream->substream->number,
1076 (long unsigned int)hw_sample_count, 1139 (long unsigned int)hw_sample_count,
1077 (long unsigned int)(stream->timer_abs_periods + 1140 (long unsigned int)(stream->timer_abs_periods +
1078 stream->timer_period_frag + PCXHR_GRANULARITY)); 1141 stream->timer_period_frag +
1079 1142 mgr->granularity));
1080 return hw_sample_count; 1143 return hw_sample_count;
1081} 1144}
1082 1145
1083static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr, 1146static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1084 struct pcxhr_stream *stream, int samples_to_add) 1147 struct pcxhr_stream *stream,
1148 int samples_to_add)
1085{ 1149{
1086 if (stream->substream && (stream->status == PCXHR_STREAM_STATUS_RUNNING)) { 1150 if (stream->substream &&
1151 (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
1087 u_int64_t new_sample_count; 1152 u_int64_t new_sample_count;
1088 int elapsed = 0; 1153 int elapsed = 0;
1089 int hardware_read = 0; 1154 int hardware_read = 0;
@@ -1092,20 +1157,22 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1092 if (samples_to_add < 0) { 1157 if (samples_to_add < 0) {
1093 stream->timer_is_synced = 0; 1158 stream->timer_is_synced = 0;
1094 /* add default if no hardware_read possible */ 1159 /* add default if no hardware_read possible */
1095 samples_to_add = PCXHR_GRANULARITY; 1160 samples_to_add = mgr->granularity;
1096 } 1161 }
1097 1162
1098 if (!stream->timer_is_synced) { 1163 if (!stream->timer_is_synced) {
1099 if (stream->timer_abs_periods != 0 || 1164 if ((stream->timer_abs_periods != 0) ||
1100 stream->timer_period_frag + PCXHR_GRANULARITY >= 1165 ((stream->timer_period_frag + samples_to_add) >=
1101 runtime->period_size) { 1166 runtime->period_size)) {
1102 new_sample_count = pcxhr_stream_read_position(mgr, stream); 1167 new_sample_count =
1168 pcxhr_stream_read_position(mgr, stream);
1103 hardware_read = 1; 1169 hardware_read = 1;
1104 if (new_sample_count >= PCXHR_GRANULARITY_MIN) { 1170 if (new_sample_count >= mgr->granularity) {
1105 /* sub security offset because of jitter and 1171 /* sub security offset because of
1106 * finer granularity of dsp time (MBOX4) 1172 * jitter and finer granularity of
1173 * dsp time (MBOX4)
1107 */ 1174 */
1108 new_sample_count -= PCXHR_GRANULARITY_MIN; 1175 new_sample_count -= mgr->granularity;
1109 stream->timer_is_synced = 1; 1176 stream->timer_is_synced = 1;
1110 } 1177 }
1111 } 1178 }
@@ -1128,12 +1195,15 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1128 stream->timer_buf_periods = 0; 1195 stream->timer_buf_periods = 0;
1129 stream->timer_abs_periods = new_elapse_pos; 1196 stream->timer_abs_periods = new_elapse_pos;
1130 } 1197 }
1131 if (new_sample_count >= stream->timer_abs_periods) 1198 if (new_sample_count >= stream->timer_abs_periods) {
1132 stream->timer_period_frag = (u_int32_t)(new_sample_count - 1199 stream->timer_period_frag =
1133 stream->timer_abs_periods); 1200 (u_int32_t)(new_sample_count -
1134 else 1201 stream->timer_abs_periods);
1135 snd_printk(KERN_ERR "ERROR new_sample_count too small ??? %lx\n", 1202 } else {
1203 snd_printk(KERN_ERR
1204 "ERROR new_sample_count too small ??? %ld\n",
1136 (long unsigned int)new_sample_count); 1205 (long unsigned int)new_sample_count);
1206 }
1137 1207
1138 if (elapsed) { 1208 if (elapsed) {
1139 spin_unlock(&mgr->lock); 1209 spin_unlock(&mgr->lock);
@@ -1143,7 +1213,6 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1143 } 1213 }
1144} 1214}
1145 1215
1146
1147irqreturn_t pcxhr_interrupt(int irq, void *dev_id) 1216irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1148{ 1217{
1149 struct pcxhr_mgr *mgr = dev_id; 1218 struct pcxhr_mgr *mgr = dev_id;
@@ -1156,7 +1225,8 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1156 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS); 1225 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
1157 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) { 1226 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
1158 spin_unlock(&mgr->lock); 1227 spin_unlock(&mgr->lock);
1159 return IRQ_NONE; /* this device did not cause the interrupt */ 1228 /* this device did not cause the interrupt */
1229 return IRQ_NONE;
1160 } 1230 }
1161 1231
1162 /* clear interrupt */ 1232 /* clear interrupt */
@@ -1167,10 +1237,12 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1167 if (reg & PCXHR_IRQ_TIMER) { 1237 if (reg & PCXHR_IRQ_TIMER) {
1168 int timer_toggle = reg & PCXHR_IRQ_TIMER; 1238 int timer_toggle = reg & PCXHR_IRQ_TIMER;
1169 /* is a 24 bit counter */ 1239 /* is a 24 bit counter */
1170 int dsp_time_new = PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK; 1240 int dsp_time_new =
1241 PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
1171 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last; 1242 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
1172 1243
1173 if (dsp_time_diff < 0 && mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID) { 1244 if ((dsp_time_diff < 0) &&
1245 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
1174 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " 1246 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
1175 "resynchronize all streams\n", 1247 "resynchronize all streams\n",
1176 mgr->dsp_time_last, dsp_time_new); 1248 mgr->dsp_time_last, dsp_time_new);
@@ -1178,42 +1250,51 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1178 } 1250 }
1179#ifdef CONFIG_SND_DEBUG_VERBOSE 1251#ifdef CONFIG_SND_DEBUG_VERBOSE
1180 if (dsp_time_diff == 0) 1252 if (dsp_time_diff == 0)
1181 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new); 1253 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
1182 else if (dsp_time_diff >= (2*PCXHR_GRANULARITY)) 1254 dsp_time_new);
1255 else if (dsp_time_diff >= (2*mgr->granularity))
1183 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n", 1256 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
1184 mgr->dsp_time_last, dsp_time_new - mgr->dsp_time_last); 1257 mgr->dsp_time_last,
1258 dsp_time_new - mgr->dsp_time_last);
1259 else if (dsp_time_diff % mgr->granularity)
1260 snd_printdd("ERROR DSP TIME increased by %d\n",
1261 dsp_time_diff);
1185#endif 1262#endif
1186 mgr->dsp_time_last = dsp_time_new; 1263 mgr->dsp_time_last = dsp_time_new;
1187 1264
1188 if (timer_toggle == mgr->timer_toggle) 1265 if (timer_toggle == mgr->timer_toggle) {
1189 snd_printdd("ERROR TIMER TOGGLE\n"); 1266 snd_printdd("ERROR TIMER TOGGLE\n");
1267 mgr->dsp_time_err++;
1268 }
1190 mgr->timer_toggle = timer_toggle; 1269 mgr->timer_toggle = timer_toggle;
1191 1270
1192 reg &= ~PCXHR_IRQ_TIMER; 1271 reg &= ~PCXHR_IRQ_TIMER;
1193 for (i = 0; i < mgr->num_cards; i++) { 1272 for (i = 0; i < mgr->num_cards; i++) {
1194 chip = mgr->chip[i]; 1273 chip = mgr->chip[i];
1195 for (j = 0; j < chip->nb_streams_capt; j++) 1274 for (j = 0; j < chip->nb_streams_capt; j++)
1196 pcxhr_update_timer_pos(mgr, &chip->capture_stream[j], 1275 pcxhr_update_timer_pos(mgr,
1197 dsp_time_diff); 1276 &chip->capture_stream[j],
1277 dsp_time_diff);
1198 } 1278 }
1199 for (i = 0; i < mgr->num_cards; i++) { 1279 for (i = 0; i < mgr->num_cards; i++) {
1200 chip = mgr->chip[i]; 1280 chip = mgr->chip[i];
1201 for (j = 0; j < chip->nb_streams_play; j++) 1281 for (j = 0; j < chip->nb_streams_play; j++)
1202 pcxhr_update_timer_pos(mgr, &chip->playback_stream[j], 1282 pcxhr_update_timer_pos(mgr,
1203 dsp_time_diff); 1283 &chip->playback_stream[j],
1284 dsp_time_diff);
1204 } 1285 }
1205 } 1286 }
1206 /* other irq's handled in the tasklet */ 1287 /* other irq's handled in the tasklet */
1207 if (reg & PCXHR_IRQ_MASK) { 1288 if (reg & PCXHR_IRQ_MASK) {
1208 1289 if (reg & PCXHR_IRQ_ASYNC) {
1209 /* as we didn't request any notifications, some kind of xrun error 1290 /* as we didn't request any async notifications,
1210 * will probably occured 1291 * some kind of xrun error will probably occured
1211 */ 1292 */
1212 /* better resynchronize all streams next interrupt : */ 1293 /* better resynchronize all streams next interrupt : */
1213 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; 1294 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
1214 1295 }
1215 mgr->src_it_dsp = reg; 1296 mgr->src_it_dsp = reg;
1216 tasklet_hi_schedule(&mgr->msg_taskq); 1297 tasklet_schedule(&mgr->msg_taskq);
1217 } 1298 }
1218#ifdef CONFIG_SND_DEBUG_VERBOSE 1299#ifdef CONFIG_SND_DEBUG_VERBOSE
1219 if (reg & PCXHR_FATAL_DSP_ERR) 1300 if (reg & PCXHR_FATAL_DSP_ERR)
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
index d9a4ab609875..bbbd66d13a64 100644
--- a/sound/pci/pcxhr/pcxhr_core.h
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -65,7 +65,7 @@ enum {
65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */ 65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */
66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */ 66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */
67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */ 67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */
68 CMD_RES_PIPE, /* cmd_len = 2 stat_len = 0 */ 68 CMD_RES_PIPE, /* cmd_len >=2 stat_len = 0 */
69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */ 69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */
70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */ 70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */
71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */ 71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */
@@ -96,6 +96,8 @@ void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd);
96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1, 96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1,
97 unsigned int param2, unsigned int param3); 97 unsigned int param2, unsigned int param3);
98 98
99#define DSP_EXT_CMD_SET(x) (x->dsp_version > 0x012800)
100
99/* 101/*
100 send the rmh 102 send the rmh
101 */ 103 */
@@ -110,6 +112,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
110#define IO_NUM_REG_STATUS 5 112#define IO_NUM_REG_STATUS 5
111#define IO_NUM_REG_CUER 10 113#define IO_NUM_REG_CUER 10
112#define IO_NUM_UER_CHIP_REG 11 114#define IO_NUM_UER_CHIP_REG 11
115#define IO_NUM_REG_CONFIG_SRC 12
113#define IO_NUM_REG_OUT_ANA_LEVEL 20 116#define IO_NUM_REG_OUT_ANA_LEVEL 20
114#define IO_NUM_REG_IN_ANA_LEVEL 21 117#define IO_NUM_REG_IN_ANA_LEVEL 21
115 118
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 96640d9c227d..592743a298b0 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -31,6 +31,7 @@
31#include "pcxhr_mixer.h" 31#include "pcxhr_mixer.h"
32#include "pcxhr_hwdep.h" 32#include "pcxhr_hwdep.h"
33#include "pcxhr_core.h" 33#include "pcxhr_core.h"
34#include "pcxhr_mix22.h"
34 35
35 36
36#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 37#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
@@ -40,10 +41,10 @@
40#endif 41#endif
41 42
42 43
44static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
43/* 45/*
44 * get basic information and init pcxhr card 46 * get basic information and init pcxhr card
45 */ 47 */
46
47static int pcxhr_init_board(struct pcxhr_mgr *mgr) 48static int pcxhr_init_board(struct pcxhr_mgr *mgr)
48{ 49{
49 int err; 50 int err;
@@ -68,7 +69,7 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
68 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) 69 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
69 return -EINVAL; 70 return -EINVAL;
70 /* test 8 or 2 phys in */ 71 /* test 8 or 2 phys in */
71 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) != 72 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
72 mgr->capture_chips * 2) 73 mgr->capture_chips * 2)
73 return -EINVAL; 74 return -EINVAL;
74 /* test max nb substream per board */ 75 /* test max nb substream per board */
@@ -77,20 +78,34 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
77 /* test max nb substream per pipe */ 78 /* test max nb substream per pipe */
78 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) 79 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
79 return -EINVAL; 80 return -EINVAL;
81 snd_printdd("supported formats : playback=%x capture=%x\n",
82 rmh.stat[2], rmh.stat[3]);
80 83
81 pcxhr_init_rmh(&rmh, CMD_VERSION); 84 pcxhr_init_rmh(&rmh, CMD_VERSION);
82 /* firmware num for DSP */ 85 /* firmware num for DSP */
83 rmh.cmd[0] |= mgr->firmware_num; 86 rmh.cmd[0] |= mgr->firmware_num;
84 /* transfer granularity in samples (should be multiple of 48) */ 87 /* transfer granularity in samples (should be multiple of 48) */
85 rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY; 88 rmh.cmd[1] = (1<<23) + mgr->granularity;
86 rmh.cmd_len = 2; 89 rmh.cmd_len = 2;
87 err = pcxhr_send_msg(mgr, &rmh); 90 err = pcxhr_send_msg(mgr, &rmh);
88 if (err) 91 if (err)
89 return err; 92 return err;
90 snd_printdd("PCXHR DSP version is %d.%d.%d\n", 93 snd_printdd("PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff,
91 (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff); 94 (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
92 mgr->dsp_version = rmh.stat[0]; 95 mgr->dsp_version = rmh.stat[0];
93 96
97 if (mgr->is_hr_stereo)
98 err = hr222_sub_init(mgr);
99 else
100 err = pcxhr_sub_init(mgr);
101 return err;
102}
103
104static int pcxhr_sub_init(struct pcxhr_mgr *mgr)
105{
106 int err;
107 struct pcxhr_rmh rmh;
108
94 /* get options */ 109 /* get options */
95 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 110 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
96 rmh.cmd[0] |= IO_NUM_REG_STATUS; 111 rmh.cmd[0] |= IO_NUM_REG_STATUS;
@@ -100,20 +115,22 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
100 if (err) 115 if (err)
101 return err; 116 return err;
102 117
103 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD) 118 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) ==
104 mgr->board_has_analog = 1; /* analog addon board available */ 119 REG_STATUS_OPT_ANALOG_BOARD)
105 else 120 mgr->board_has_analog = 1; /* analog addon board found */
106 /* analog addon board not available -> no support for instance */
107 return -EINVAL;
108 121
109 /* unmute inputs */ 122 /* unmute inputs */
110 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 123 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
111 REG_CONT_UNMUTE_INPUTS, NULL); 124 REG_CONT_UNMUTE_INPUTS, NULL);
112 if (err) 125 if (err)
113 return err; 126 return err;
114 /* unmute outputs */ 127 /* unmute outputs (a write to IO_NUM_REG_MUTE_OUT mutes!) */
115 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */ 128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
116 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 if (DSP_EXT_CMD_SET(mgr)) {
131 rmh.cmd[1] = 1; /* unmute digital plugs */
132 rmh.cmd_len = 2;
133 }
117 err = pcxhr_send_msg(mgr, &rmh); 134 err = pcxhr_send_msg(mgr, &rmh);
118 return err; 135 return err;
119} 136}
@@ -124,19 +141,25 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
124 141
125 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 142 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
126 /* mute outputs */ 143 /* mute outputs */
144 if (!mgr->is_hr_stereo) {
127 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */ 145 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 146 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 147 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 pcxhr_send_msg(mgr, &rmh); 148 pcxhr_send_msg(mgr, &rmh);
131 /* mute inputs */ 149 /* mute inputs */
132 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL); 150 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
151 0, NULL);
152 }
153 /* stereo cards mute with reset of dsp */
133 } 154 }
134 /* reset pcxhr dsp */ 155 /* reset pcxhr dsp */
135 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX)) 156 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
136 pcxhr_reset_dsp(mgr); 157 pcxhr_reset_dsp(mgr);
137 /* reset second xilinx */ 158 /* reset second xilinx */
138 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) 159 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) {
139 pcxhr_reset_xilinx_com(mgr); 160 pcxhr_reset_xilinx_com(mgr);
161 mgr->dsp_loaded = 1;
162 }
140 return; 163 return;
141} 164}
142 165
@@ -144,8 +167,9 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
144/* 167/*
145 * allocate a playback/capture pipe (pcmp0/pcmc0) 168 * allocate a playback/capture pipe (pcmp0/pcmc0)
146 */ 169 */
147static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe, 170static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr,
148 int is_capture, int pin) 171 struct pcxhr_pipe *pipe,
172 int is_capture, int pin)
149{ 173{
150 int stream_count, audio_count; 174 int stream_count, audio_count;
151 int err; 175 int err;
@@ -161,15 +185,23 @@ static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pi
161 stream_count = PCXHR_PLAYBACK_STREAMS; 185 stream_count = PCXHR_PLAYBACK_STREAMS;
162 audio_count = 2; /* always stereo */ 186 audio_count = 2; /* always stereo */
163 } 187 }
164 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p'); 188 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n",
189 pin, is_capture ? 'c' : 'p');
165 pipe->is_capture = is_capture; 190 pipe->is_capture = is_capture;
166 pipe->first_audio = pin; 191 pipe->first_audio = pin;
167 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */ 192 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
168 pcxhr_init_rmh(&rmh, CMD_RES_PIPE); 193 pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
169 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); 194 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin,
195 audio_count, stream_count);
196 rmh.cmd[1] |= 0x020000; /* add P_PCM_ONLY_MASK */
197 if (DSP_EXT_CMD_SET(mgr)) {
198 /* add channel mask to command */
199 rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03;
200 }
170 err = pcxhr_send_msg(mgr, &rmh); 201 err = pcxhr_send_msg(mgr, &rmh);
171 if (err < 0) { 202 if (err < 0) {
172 snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err ); 203 snd_printk(KERN_ERR "error pipe allocation "
204 "(CMD_RES_PIPE) err=%x!\n", err);
173 return err; 205 return err;
174 } 206 }
175 pipe->status = PCXHR_PIPE_DEFINED; 207 pipe->status = PCXHR_PIPE_DEFINED;
@@ -199,10 +231,12 @@ static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
199 snd_printk(KERN_ERR "error stopping pipe!\n"); 231 snd_printk(KERN_ERR "error stopping pipe!\n");
200 /* release the pipe */ 232 /* release the pipe */
201 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE); 233 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
202 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0); 234 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio,
235 0, 0);
203 err = pcxhr_send_msg(mgr, &rmh); 236 err = pcxhr_send_msg(mgr, &rmh);
204 if (err < 0) 237 if (err < 0)
205 snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err); 238 snd_printk(KERN_ERR "error pipe release "
239 "(CMD_FREE_PIPE) err(%x)\n", err);
206 pipe->status = PCXHR_PIPE_UNDEFINED; 240 pipe->status = PCXHR_PIPE_UNDEFINED;
207 return err; 241 return err;
208} 242}
@@ -248,15 +282,16 @@ static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
248 for (i = 0; i < mgr->num_cards; i++) { 282 for (i = 0; i < mgr->num_cards; i++) {
249 chip = mgr->chip[i]; 283 chip = mgr->chip[i];
250 if (chip->nb_streams_play) 284 if (chip->nb_streams_play)
251 playback_mask |= (1 << chip->playback_pipe.first_audio); 285 playback_mask |= 1 << chip->playback_pipe.first_audio;
252 for (j = 0; j < chip->nb_streams_capt; j++) 286 for (j = 0; j < chip->nb_streams_capt; j++)
253 capture_mask |= (1 << chip->capture_pipe[j].first_audio); 287 capture_mask |= 1 << chip->capture_pipe[j].first_audio;
254 } 288 }
255 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 289 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
256} 290}
257 291
258 292
259static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmware *dsp) 293static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
294 const struct firmware *dsp)
260{ 295{
261 int err, card_index; 296 int err, card_index;
262 297
@@ -330,22 +365,33 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmwar
330 365
331int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) 366int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
332{ 367{
333 static char *fw_files[5] = { 368 static char *fw_files[][5] = {
334 "xi_1_882.dat", 369 [0] = { "xlxint.dat", "xlxc882hr.dat",
335 "xc_1_882.dat", 370 "dspe882.e56", "dspb882hr.b56", "dspd882.d56" },
336 "e321_512.e56", 371 [1] = { "xlxint.dat", "xlxc882e.dat",
337 "b321_512.b56", 372 "dspe882.e56", "dspb882e.b56", "dspd882.d56" },
338 "d321_512.d56" 373 [2] = { "xlxint.dat", "xlxc1222hr.dat",
374 "dspe882.e56", "dspb1222hr.b56", "dspd1222.d56" },
375 [3] = { "xlxint.dat", "xlxc1222e.dat",
376 "dspe882.e56", "dspb1222e.b56", "dspd1222.d56" },
377 [4] = { NULL, "xlxc222.dat",
378 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
379 [5] = { NULL, "xlxc924.dat",
380 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
339 }; 381 };
340 char path[32]; 382 char path[32];
341 383
342 const struct firmware *fw_entry; 384 const struct firmware *fw_entry;
343 int i, err; 385 int i, err;
386 int fw_set = mgr->fw_file_set;
344 387
345 for (i = 0; i < ARRAY_SIZE(fw_files); i++) { 388 for (i = 0; i < 5; i++) {
346 sprintf(path, "pcxhr/%s", fw_files[i]); 389 if (!fw_files[fw_set][i])
390 continue;
391 sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
347 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { 392 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
348 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", path); 393 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n",
394 path);
349 return -ENOENT; 395 return -ENOENT;
350 } 396 }
351 /* fake hwdep dsp record */ 397 /* fake hwdep dsp record */
@@ -358,11 +404,26 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
358 return 0; 404 return 0;
359} 405}
360 406
361MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); 407MODULE_FIRMWARE("pcxhr/xlxint.dat");
362MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); 408MODULE_FIRMWARE("pcxhr/xlxc882hr.dat");
363MODULE_FIRMWARE("pcxhr/e321_512.e56"); 409MODULE_FIRMWARE("pcxhr/xlxc882e.dat");
364MODULE_FIRMWARE("pcxhr/b321_512.b56"); 410MODULE_FIRMWARE("pcxhr/dspe882.e56");
365MODULE_FIRMWARE("pcxhr/d321_512.d56"); 411MODULE_FIRMWARE("pcxhr/dspb882hr.b56");
412MODULE_FIRMWARE("pcxhr/dspb882e.b56");
413MODULE_FIRMWARE("pcxhr/dspd882.d56");
414
415MODULE_FIRMWARE("pcxhr/xlxc1222hr.dat");
416MODULE_FIRMWARE("pcxhr/xlxc1222e.dat");
417MODULE_FIRMWARE("pcxhr/dspb1222hr.b56");
418MODULE_FIRMWARE("pcxhr/dspb1222e.b56");
419MODULE_FIRMWARE("pcxhr/dspd1222.d56");
420
421MODULE_FIRMWARE("pcxhr/xlxc222.dat");
422MODULE_FIRMWARE("pcxhr/xlxc924.dat");
423MODULE_FIRMWARE("pcxhr/dspe924.e56");
424MODULE_FIRMWARE("pcxhr/dspb924.b56");
425MODULE_FIRMWARE("pcxhr/dspd222.d56");
426
366 427
367#else /* old style firmware loading */ 428#else /* old style firmware loading */
368 429
@@ -373,7 +434,8 @@ MODULE_FIRMWARE("pcxhr/d321_512.d56");
373static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw, 434static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
374 struct snd_hwdep_dsp_status *info) 435 struct snd_hwdep_dsp_status *info)
375{ 436{
376 strcpy(info->id, "pcxhr"); 437 struct pcxhr_mgr *mgr = hw->private_data;
438 sprintf(info->id, "pcxhr%d", mgr->fw_file_set);
377 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX; 439 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
378 440
379 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) 441 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
@@ -393,8 +455,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
393 fw.size = dsp->length; 455 fw.size = dsp->length;
394 fw.data = vmalloc(fw.size); 456 fw.data = vmalloc(fw.size);
395 if (! fw.data) { 457 if (! fw.data) {
396 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n", 458 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image "
397 (unsigned long)fw.size); 459 "(%lu bytes)\n", (unsigned long)fw.size);
398 return -ENOMEM; 460 return -ENOMEM;
399 } 461 }
400 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { 462 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
@@ -424,8 +486,11 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
424 int err; 486 int err;
425 struct snd_hwdep *hw; 487 struct snd_hwdep *hw;
426 488
427 /* only create hwdep interface for first cardX (see "index" module parameter)*/ 489 /* only create hwdep interface for first cardX
428 if ((err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw)) < 0) 490 * (see "index" module parameter)
491 */
492 err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw);
493 if (err < 0)
429 return err; 494 return err;
430 495
431 hw->iface = SNDRV_HWDEP_IFACE_PCXHR; 496 hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
@@ -435,10 +500,13 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
435 hw->ops.dsp_status = pcxhr_hwdep_dsp_status; 500 hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
436 hw->ops.dsp_load = pcxhr_hwdep_dsp_load; 501 hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
437 hw->exclusive = 1; 502 hw->exclusive = 1;
503 /* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */
504 hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0;
438 mgr->dsp_loaded = 0; 505 mgr->dsp_loaded = 0;
439 sprintf(hw->name, PCXHR_HWDEP_ID); 506 sprintf(hw->name, PCXHR_HWDEP_ID);
440 507
441 if ((err = snd_card_register(mgr->chip[0]->card)) < 0) 508 err = snd_card_register(mgr->chip[0]->card);
509 if (err < 0)
442 return err; 510 return err;
443 return 0; 511 return 0;
444} 512}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
new file mode 100644
index 000000000000..ff019126b672
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -0,0 +1,820 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * mixer interface for stereo cards
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/delay.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/tlv.h>
28#include <sound/asoundef.h>
29#include "pcxhr.h"
30#include "pcxhr_core.h"
31#include "pcxhr_mix22.h"
32
33
34/* registers used on the DSP and Xilinx (port 2) : HR stereo cards only */
35#define PCXHR_DSP_RESET 0x20
36#define PCXHR_XLX_CFG 0x24
37#define PCXHR_XLX_RUER 0x28
38#define PCXHR_XLX_DATA 0x2C
39#define PCXHR_XLX_STATUS 0x30
40#define PCXHR_XLX_LOFREQ 0x34
41#define PCXHR_XLX_HIFREQ 0x38
42#define PCXHR_XLX_CSUER 0x3C
43#define PCXHR_XLX_SELMIC 0x40
44
45#define PCXHR_DSP 2
46
47/* byte access only ! */
48#define PCXHR_INPB(mgr, x) inb((mgr)->port[PCXHR_DSP] + (x))
49#define PCXHR_OUTPB(mgr, x, data) outb((data), (mgr)->port[PCXHR_DSP] + (x))
50
51
52/* values for PCHR_DSP_RESET register */
53#define PCXHR_DSP_RESET_DSP 0x01
54#define PCXHR_DSP_RESET_MUTE 0x02
55#define PCXHR_DSP_RESET_CODEC 0x08
56
57/* values for PCHR_XLX_CFG register */
58#define PCXHR_CFG_SYNCDSP_MASK 0x80
59#define PCXHR_CFG_DEPENDENCY_MASK 0x60
60#define PCXHR_CFG_INDEPENDANT_SEL 0x00
61#define PCXHR_CFG_MASTER_SEL 0x40
62#define PCXHR_CFG_SLAVE_SEL 0x20
63#define PCXHR_CFG_DATA_UER1_SEL_MASK 0x10 /* 0 (UER0), 1(UER1) */
64#define PCXHR_CFG_DATAIN_SEL_MASK 0x08 /* 0 (ana), 1 (UER) */
65#define PCXHR_CFG_SRC_MASK 0x04 /* 0 (Bypass), 1 (SRC Actif) */
66#define PCXHR_CFG_CLOCK_UER1_SEL_MASK 0x02 /* 0 (UER0), 1(UER1) */
67#define PCXHR_CFG_CLOCKIN_SEL_MASK 0x01 /* 0 (internal), 1 (AES/EBU) */
68
69/* values for PCHR_XLX_DATA register */
70#define PCXHR_DATA_CODEC 0x80
71#define AKM_POWER_CONTROL_CMD 0xA007
72#define AKM_RESET_ON_CMD 0xA100
73#define AKM_RESET_OFF_CMD 0xA103
74#define AKM_CLOCK_INF_55K_CMD 0xA240
75#define AKM_CLOCK_SUP_55K_CMD 0xA24D
76#define AKM_MUTE_CMD 0xA38D
77#define AKM_UNMUTE_CMD 0xA30D
78#define AKM_LEFT_LEVEL_CMD 0xA600
79#define AKM_RIGHT_LEVEL_CMD 0xA700
80
81/* values for PCHR_XLX_STATUS register - READ */
82#define PCXHR_STAT_SRC_LOCK 0x01
83#define PCXHR_STAT_LEVEL_IN 0x02
84#define PCXHR_STAT_MIC_CAPS 0x10
85/* values for PCHR_XLX_STATUS register - WRITE */
86#define PCXHR_STAT_FREQ_SYNC_MASK 0x01
87#define PCXHR_STAT_FREQ_UER1_MASK 0x02
88#define PCXHR_STAT_FREQ_SAVE_MASK 0x80
89
90/* values for PCHR_XLX_CSUER register */
91#define PCXHR_SUER1_BIT_U_READ_MASK 0x80
92#define PCXHR_SUER1_BIT_C_READ_MASK 0x40
93#define PCXHR_SUER1_DATA_PRESENT_MASK 0x20
94#define PCXHR_SUER1_CLOCK_PRESENT_MASK 0x10
95#define PCXHR_SUER_BIT_U_READ_MASK 0x08
96#define PCXHR_SUER_BIT_C_READ_MASK 0x04
97#define PCXHR_SUER_DATA_PRESENT_MASK 0x02
98#define PCXHR_SUER_CLOCK_PRESENT_MASK 0x01
99
100#define PCXHR_SUER_BIT_U_WRITE_MASK 0x02
101#define PCXHR_SUER_BIT_C_WRITE_MASK 0x01
102
103/* values for PCXHR_XLX_SELMIC register - WRITE */
104#define PCXHR_SELMIC_PREAMPLI_OFFSET 2
105#define PCXHR_SELMIC_PREAMPLI_MASK 0x0C
106#define PCXHR_SELMIC_PHANTOM_ALIM 0x80
107
108
109static const unsigned char g_hr222_p_level[] = {
110 0x00, /* [000] -49.5 dB: AKM[000] = -1.#INF dB (mute) */
111 0x01, /* [001] -49.0 dB: AKM[001] = -48.131 dB (diff=0.86920 dB) */
112 0x01, /* [002] -48.5 dB: AKM[001] = -48.131 dB (diff=0.36920 dB) */
113 0x01, /* [003] -48.0 dB: AKM[001] = -48.131 dB (diff=0.13080 dB) */
114 0x01, /* [004] -47.5 dB: AKM[001] = -48.131 dB (diff=0.63080 dB) */
115 0x01, /* [005] -46.5 dB: AKM[001] = -48.131 dB (diff=1.63080 dB) */
116 0x01, /* [006] -47.0 dB: AKM[001] = -48.131 dB (diff=1.13080 dB) */
117 0x01, /* [007] -46.0 dB: AKM[001] = -48.131 dB (diff=2.13080 dB) */
118 0x01, /* [008] -45.5 dB: AKM[001] = -48.131 dB (diff=2.63080 dB) */
119 0x02, /* [009] -45.0 dB: AKM[002] = -42.110 dB (diff=2.88980 dB) */
120 0x02, /* [010] -44.5 dB: AKM[002] = -42.110 dB (diff=2.38980 dB) */
121 0x02, /* [011] -44.0 dB: AKM[002] = -42.110 dB (diff=1.88980 dB) */
122 0x02, /* [012] -43.5 dB: AKM[002] = -42.110 dB (diff=1.38980 dB) */
123 0x02, /* [013] -43.0 dB: AKM[002] = -42.110 dB (diff=0.88980 dB) */
124 0x02, /* [014] -42.5 dB: AKM[002] = -42.110 dB (diff=0.38980 dB) */
125 0x02, /* [015] -42.0 dB: AKM[002] = -42.110 dB (diff=0.11020 dB) */
126 0x02, /* [016] -41.5 dB: AKM[002] = -42.110 dB (diff=0.61020 dB) */
127 0x02, /* [017] -41.0 dB: AKM[002] = -42.110 dB (diff=1.11020 dB) */
128 0x02, /* [018] -40.5 dB: AKM[002] = -42.110 dB (diff=1.61020 dB) */
129 0x03, /* [019] -40.0 dB: AKM[003] = -38.588 dB (diff=1.41162 dB) */
130 0x03, /* [020] -39.5 dB: AKM[003] = -38.588 dB (diff=0.91162 dB) */
131 0x03, /* [021] -39.0 dB: AKM[003] = -38.588 dB (diff=0.41162 dB) */
132 0x03, /* [022] -38.5 dB: AKM[003] = -38.588 dB (diff=0.08838 dB) */
133 0x03, /* [023] -38.0 dB: AKM[003] = -38.588 dB (diff=0.58838 dB) */
134 0x03, /* [024] -37.5 dB: AKM[003] = -38.588 dB (diff=1.08838 dB) */
135 0x04, /* [025] -37.0 dB: AKM[004] = -36.090 dB (diff=0.91040 dB) */
136 0x04, /* [026] -36.5 dB: AKM[004] = -36.090 dB (diff=0.41040 dB) */
137 0x04, /* [027] -36.0 dB: AKM[004] = -36.090 dB (diff=0.08960 dB) */
138 0x04, /* [028] -35.5 dB: AKM[004] = -36.090 dB (diff=0.58960 dB) */
139 0x05, /* [029] -35.0 dB: AKM[005] = -34.151 dB (diff=0.84860 dB) */
140 0x05, /* [030] -34.5 dB: AKM[005] = -34.151 dB (diff=0.34860 dB) */
141 0x05, /* [031] -34.0 dB: AKM[005] = -34.151 dB (diff=0.15140 dB) */
142 0x05, /* [032] -33.5 dB: AKM[005] = -34.151 dB (diff=0.65140 dB) */
143 0x06, /* [033] -33.0 dB: AKM[006] = -32.568 dB (diff=0.43222 dB) */
144 0x06, /* [034] -32.5 dB: AKM[006] = -32.568 dB (diff=0.06778 dB) */
145 0x06, /* [035] -32.0 dB: AKM[006] = -32.568 dB (diff=0.56778 dB) */
146 0x07, /* [036] -31.5 dB: AKM[007] = -31.229 dB (diff=0.27116 dB) */
147 0x07, /* [037] -31.0 dB: AKM[007] = -31.229 dB (diff=0.22884 dB) */
148 0x08, /* [038] -30.5 dB: AKM[008] = -30.069 dB (diff=0.43100 dB) */
149 0x08, /* [039] -30.0 dB: AKM[008] = -30.069 dB (diff=0.06900 dB) */
150 0x09, /* [040] -29.5 dB: AKM[009] = -29.046 dB (diff=0.45405 dB) */
151 0x09, /* [041] -29.0 dB: AKM[009] = -29.046 dB (diff=0.04595 dB) */
152 0x0a, /* [042] -28.5 dB: AKM[010] = -28.131 dB (diff=0.36920 dB) */
153 0x0a, /* [043] -28.0 dB: AKM[010] = -28.131 dB (diff=0.13080 dB) */
154 0x0b, /* [044] -27.5 dB: AKM[011] = -27.303 dB (diff=0.19705 dB) */
155 0x0b, /* [045] -27.0 dB: AKM[011] = -27.303 dB (diff=0.30295 dB) */
156 0x0c, /* [046] -26.5 dB: AKM[012] = -26.547 dB (diff=0.04718 dB) */
157 0x0d, /* [047] -26.0 dB: AKM[013] = -25.852 dB (diff=0.14806 dB) */
158 0x0e, /* [048] -25.5 dB: AKM[014] = -25.208 dB (diff=0.29176 dB) */
159 0x0e, /* [049] -25.0 dB: AKM[014] = -25.208 dB (diff=0.20824 dB) */
160 0x0f, /* [050] -24.5 dB: AKM[015] = -24.609 dB (diff=0.10898 dB) */
161 0x10, /* [051] -24.0 dB: AKM[016] = -24.048 dB (diff=0.04840 dB) */
162 0x11, /* [052] -23.5 dB: AKM[017] = -23.522 dB (diff=0.02183 dB) */
163 0x12, /* [053] -23.0 dB: AKM[018] = -23.025 dB (diff=0.02535 dB) */
164 0x13, /* [054] -22.5 dB: AKM[019] = -22.556 dB (diff=0.05573 dB) */
165 0x14, /* [055] -22.0 dB: AKM[020] = -22.110 dB (diff=0.11020 dB) */
166 0x15, /* [056] -21.5 dB: AKM[021] = -21.686 dB (diff=0.18642 dB) */
167 0x17, /* [057] -21.0 dB: AKM[023] = -20.896 dB (diff=0.10375 dB) */
168 0x18, /* [058] -20.5 dB: AKM[024] = -20.527 dB (diff=0.02658 dB) */
169 0x1a, /* [059] -20.0 dB: AKM[026] = -19.831 dB (diff=0.16866 dB) */
170 0x1b, /* [060] -19.5 dB: AKM[027] = -19.504 dB (diff=0.00353 dB) */
171 0x1d, /* [061] -19.0 dB: AKM[029] = -18.883 dB (diff=0.11716 dB) */
172 0x1e, /* [062] -18.5 dB: AKM[030] = -18.588 dB (diff=0.08838 dB) */
173 0x20, /* [063] -18.0 dB: AKM[032] = -18.028 dB (diff=0.02780 dB) */
174 0x22, /* [064] -17.5 dB: AKM[034] = -17.501 dB (diff=0.00123 dB) */
175 0x24, /* [065] -17.0 dB: AKM[036] = -17.005 dB (diff=0.00475 dB) */
176 0x26, /* [066] -16.5 dB: AKM[038] = -16.535 dB (diff=0.03513 dB) */
177 0x28, /* [067] -16.0 dB: AKM[040] = -16.090 dB (diff=0.08960 dB) */
178 0x2b, /* [068] -15.5 dB: AKM[043] = -15.461 dB (diff=0.03857 dB) */
179 0x2d, /* [069] -15.0 dB: AKM[045] = -15.067 dB (diff=0.06655 dB) */
180 0x30, /* [070] -14.5 dB: AKM[048] = -14.506 dB (diff=0.00598 dB) */
181 0x33, /* [071] -14.0 dB: AKM[051] = -13.979 dB (diff=0.02060 dB) */
182 0x36, /* [072] -13.5 dB: AKM[054] = -13.483 dB (diff=0.01707 dB) */
183 0x39, /* [073] -13.0 dB: AKM[057] = -13.013 dB (diff=0.01331 dB) */
184 0x3c, /* [074] -12.5 dB: AKM[060] = -12.568 dB (diff=0.06778 dB) */
185 0x40, /* [075] -12.0 dB: AKM[064] = -12.007 dB (diff=0.00720 dB) */
186 0x44, /* [076] -11.5 dB: AKM[068] = -11.481 dB (diff=0.01937 dB) */
187 0x48, /* [077] -11.0 dB: AKM[072] = -10.984 dB (diff=0.01585 dB) */
188 0x4c, /* [078] -10.5 dB: AKM[076] = -10.515 dB (diff=0.01453 dB) */
189 0x51, /* [079] -10.0 dB: AKM[081] = -9.961 dB (diff=0.03890 dB) */
190 0x55, /* [080] -9.5 dB: AKM[085] = -9.542 dB (diff=0.04243 dB) */
191 0x5a, /* [081] -9.0 dB: AKM[090] = -9.046 dB (diff=0.04595 dB) */
192 0x60, /* [082] -8.5 dB: AKM[096] = -8.485 dB (diff=0.01462 dB) */
193 0x66, /* [083] -8.0 dB: AKM[102] = -7.959 dB (diff=0.04120 dB) */
194 0x6c, /* [084] -7.5 dB: AKM[108] = -7.462 dB (diff=0.03767 dB) */
195 0x72, /* [085] -7.0 dB: AKM[114] = -6.993 dB (diff=0.00729 dB) */
196 0x79, /* [086] -6.5 dB: AKM[121] = -6.475 dB (diff=0.02490 dB) */
197 0x80, /* [087] -6.0 dB: AKM[128] = -5.987 dB (diff=0.01340 dB) */
198 0x87, /* [088] -5.5 dB: AKM[135] = -5.524 dB (diff=0.02413 dB) */
199 0x8f, /* [089] -5.0 dB: AKM[143] = -5.024 dB (diff=0.02408 dB) */
200 0x98, /* [090] -4.5 dB: AKM[152] = -4.494 dB (diff=0.00607 dB) */
201 0xa1, /* [091] -4.0 dB: AKM[161] = -3.994 dB (diff=0.00571 dB) */
202 0xaa, /* [092] -3.5 dB: AKM[170] = -3.522 dB (diff=0.02183 dB) */
203 0xb5, /* [093] -3.0 dB: AKM[181] = -2.977 dB (diff=0.02277 dB) */
204 0xbf, /* [094] -2.5 dB: AKM[191] = -2.510 dB (diff=0.01014 dB) */
205 0xcb, /* [095] -2.0 dB: AKM[203] = -1.981 dB (diff=0.01912 dB) */
206 0xd7, /* [096] -1.5 dB: AKM[215] = -1.482 dB (diff=0.01797 dB) */
207 0xe3, /* [097] -1.0 dB: AKM[227] = -1.010 dB (diff=0.01029 dB) */
208 0xf1, /* [098] -0.5 dB: AKM[241] = -0.490 dB (diff=0.00954 dB) */
209 0xff, /* [099] +0.0 dB: AKM[255] = +0.000 dB (diff=0.00000 dB) */
210};
211
212
213static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data)
214{
215 unsigned short mask = 0x8000;
216 /* activate access to codec registers */
217 PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ);
218
219 while (mask) {
220 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
221 data & mask ? PCXHR_DATA_CODEC : 0);
222 mask >>= 1;
223 }
224 /* termiate access to codec registers */
225 PCXHR_INPB(mgr, PCXHR_XLX_RUER);
226}
227
228
229static int hr222_set_hw_playback_level(struct pcxhr_mgr *mgr,
230 int idx, int level)
231{
232 unsigned short cmd;
233 if (idx > 1 ||
234 level < 0 ||
235 level >= ARRAY_SIZE(g_hr222_p_level))
236 return -EINVAL;
237
238 if (idx == 0)
239 cmd = AKM_LEFT_LEVEL_CMD;
240 else
241 cmd = AKM_RIGHT_LEVEL_CMD;
242
243 /* conversion from PmBoardCodedLevel to AKM nonlinear programming */
244 cmd += g_hr222_p_level[level];
245
246 hr222_config_akm(mgr, cmd);
247 return 0;
248}
249
250
251static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr,
252 int level_l, int level_r, int level_mic)
253{
254 /* program all input levels at the same time */
255 unsigned int data;
256 int i;
257
258 if (!mgr->capture_chips)
259 return -EINVAL; /* no PCX22 */
260
261 data = ((level_mic & 0xff) << 24); /* micro is mono, but apply */
262 data |= ((level_mic & 0xff) << 16); /* level on both channels */
263 data |= ((level_r & 0xff) << 8); /* line input right channel */
264 data |= (level_l & 0xff); /* line input left channel */
265
266 PCXHR_INPB(mgr, PCXHR_XLX_DATA); /* activate input codec */
267 /* send 32 bits (4 x 8 bits) */
268 for (i = 0; i < 32; i++, data <<= 1) {
269 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
270 (data & 0x80000000) ? PCXHR_DATA_CODEC : 0);
271 }
272 PCXHR_INPB(mgr, PCXHR_XLX_RUER); /* close input level codec */
273 return 0;
274}
275
276static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level);
277
278int hr222_sub_init(struct pcxhr_mgr *mgr)
279{
280 unsigned char reg;
281
282 mgr->board_has_analog = 1; /* analog always available */
283 mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK;
284
285 reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS);
286 if (reg & PCXHR_STAT_MIC_CAPS)
287 mgr->board_has_mic = 1; /* microphone available */
288 snd_printdd("MIC input available = %d\n", mgr->board_has_mic);
289
290 /* reset codec */
291 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
292 PCXHR_DSP_RESET_DSP);
293 msleep(5);
294 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
295 PCXHR_DSP_RESET_DSP |
296 PCXHR_DSP_RESET_MUTE |
297 PCXHR_DSP_RESET_CODEC);
298 msleep(5);
299
300 /* config AKM */
301 hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD);
302 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
303 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
304 hr222_config_akm(mgr, AKM_RESET_OFF_CMD);
305
306 /* init micro boost */
307 hr222_micro_boost(mgr, 0);
308
309 return 0;
310}
311
312
313/* calc PLL register */
314/* TODO : there is a very similar fct in pcxhr.c */
315static int hr222_pll_freq_register(unsigned int freq,
316 unsigned int *pllreg,
317 unsigned int *realfreq)
318{
319 unsigned int reg;
320
321 if (freq < 6900 || freq > 219000)
322 return -EINVAL;
323 reg = (28224000 * 2) / freq;
324 reg = (reg - 1) / 2;
325 if (reg < 0x100)
326 *pllreg = reg + 0xC00;
327 else if (reg < 0x200)
328 *pllreg = reg + 0x800;
329 else if (reg < 0x400)
330 *pllreg = reg & 0x1ff;
331 else if (reg < 0x800) {
332 *pllreg = ((reg >> 1) & 0x1ff) + 0x200;
333 reg &= ~1;
334 } else {
335 *pllreg = ((reg >> 2) & 0x1ff) + 0x400;
336 reg &= ~3;
337 }
338 if (realfreq)
339 *realfreq = (28224000 / (reg + 1));
340 return 0;
341}
342
343int hr222_sub_set_clock(struct pcxhr_mgr *mgr,
344 unsigned int rate,
345 int *changed)
346{
347 unsigned int speed, pllreg = 0;
348 int err;
349 unsigned realfreq = rate;
350
351 switch (mgr->use_clock_type) {
352 case HR22_CLOCK_TYPE_INTERNAL:
353 err = hr222_pll_freq_register(rate, &pllreg, &realfreq);
354 if (err)
355 return err;
356
357 mgr->xlx_cfg &= ~(PCXHR_CFG_CLOCKIN_SEL_MASK |
358 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
359 break;
360 case HR22_CLOCK_TYPE_AES_SYNC:
361 mgr->xlx_cfg |= PCXHR_CFG_CLOCKIN_SEL_MASK;
362 mgr->xlx_cfg &= ~PCXHR_CFG_CLOCK_UER1_SEL_MASK;
363 break;
364 case HR22_CLOCK_TYPE_AES_1:
365 if (!mgr->board_has_aes1)
366 return -EINVAL;
367
368 mgr->xlx_cfg |= (PCXHR_CFG_CLOCKIN_SEL_MASK |
369 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
370 break;
371 default:
372 return -EINVAL;
373 }
374 hr222_config_akm(mgr, AKM_MUTE_CMD);
375
376 if (mgr->use_clock_type == HR22_CLOCK_TYPE_INTERNAL) {
377 PCXHR_OUTPB(mgr, PCXHR_XLX_HIFREQ, pllreg >> 8);
378 PCXHR_OUTPB(mgr, PCXHR_XLX_LOFREQ, pllreg & 0xff);
379 }
380
381 /* set clock source */
382 PCXHR_OUTPB(mgr, PCXHR_XLX_CFG, mgr->xlx_cfg);
383
384 /* codec speed modes */
385 speed = rate < 55000 ? 0 : 1;
386 if (mgr->codec_speed != speed) {
387 mgr->codec_speed = speed;
388 if (speed == 0)
389 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
390 else
391 hr222_config_akm(mgr, AKM_CLOCK_SUP_55K_CMD);
392 }
393
394 mgr->sample_rate_real = realfreq;
395 mgr->cur_clock_type = mgr->use_clock_type;
396
397 if (changed)
398 *changed = 1;
399
400 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
401
402 snd_printdd("set_clock to %dHz (realfreq=%d pllreg=%x)\n",
403 rate, realfreq, pllreg);
404 return 0;
405}
406
407int hr222_get_external_clock(struct pcxhr_mgr *mgr,
408 enum pcxhr_clock_type clock_type,
409 int *sample_rate)
410{
411 int rate, calc_rate = 0;
412 unsigned int ticks;
413 unsigned char mask, reg;
414
415 if (clock_type == HR22_CLOCK_TYPE_AES_SYNC) {
416
417 mask = (PCXHR_SUER_CLOCK_PRESENT_MASK |
418 PCXHR_SUER_DATA_PRESENT_MASK);
419 reg = PCXHR_STAT_FREQ_SYNC_MASK;
420
421 } else if (clock_type == HR22_CLOCK_TYPE_AES_1 && mgr->board_has_aes1) {
422
423 mask = (PCXHR_SUER1_CLOCK_PRESENT_MASK |
424 PCXHR_SUER1_DATA_PRESENT_MASK);
425 reg = PCXHR_STAT_FREQ_UER1_MASK;
426
427 } else {
428 snd_printdd("get_external_clock : type %d not supported\n",
429 clock_type);
430 return -EINVAL; /* other clocks not supported */
431 }
432
433 if ((PCXHR_INPB(mgr, PCXHR_XLX_CSUER) & mask) != mask) {
434 snd_printdd("get_external_clock(%d) = 0 Hz\n", clock_type);
435 *sample_rate = 0;
436 return 0; /* no external clock locked */
437 }
438
439 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* calculate freq */
440
441 /* save the measured clock frequency */
442 reg |= PCXHR_STAT_FREQ_SAVE_MASK;
443
444 if (mgr->last_reg_stat != reg) {
445 udelay(500); /* wait min 2 cycles of lowest freq (8000) */
446 mgr->last_reg_stat = reg;
447 }
448
449 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* save */
450
451 /* get the frequency */
452 ticks = (unsigned int)PCXHR_INPB(mgr, PCXHR_XLX_CFG);
453 ticks = (ticks & 0x03) << 8;
454 ticks |= (unsigned int)PCXHR_INPB(mgr, PCXHR_DSP_RESET);
455
456 if (ticks != 0)
457 calc_rate = 28224000 / ticks;
458 /* rounding */
459 if (calc_rate > 184200)
460 rate = 192000;
461 else if (calc_rate > 152200)
462 rate = 176400;
463 else if (calc_rate > 112000)
464 rate = 128000;
465 else if (calc_rate > 92100)
466 rate = 96000;
467 else if (calc_rate > 76100)
468 rate = 88200;
469 else if (calc_rate > 56000)
470 rate = 64000;
471 else if (calc_rate > 46050)
472 rate = 48000;
473 else if (calc_rate > 38050)
474 rate = 44100;
475 else if (calc_rate > 28000)
476 rate = 32000;
477 else if (calc_rate > 23025)
478 rate = 24000;
479 else if (calc_rate > 19025)
480 rate = 22050;
481 else if (calc_rate > 14000)
482 rate = 16000;
483 else if (calc_rate > 11512)
484 rate = 12000;
485 else if (calc_rate > 9512)
486 rate = 11025;
487 else if (calc_rate > 7000)
488 rate = 8000;
489 else
490 rate = 0;
491
492 snd_printdd("External clock is at %d Hz (measured %d Hz)\n",
493 rate, calc_rate);
494 *sample_rate = rate;
495 return 0;
496}
497
498
499int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
500 int is_capture, int channel)
501{
502 snd_printdd("hr222_update_analog_audio_level(%s chan=%d)\n",
503 is_capture ? "capture" : "playback", channel);
504 if (is_capture) {
505 int level_l, level_r, level_mic;
506 /* we have to update all levels */
507 if (chip->analog_capture_active) {
508 level_l = chip->analog_capture_volume[0];
509 level_r = chip->analog_capture_volume[1];
510 } else {
511 level_l = HR222_LINE_CAPTURE_LEVEL_MIN;
512 level_r = HR222_LINE_CAPTURE_LEVEL_MIN;
513 }
514 if (chip->mic_active)
515 level_mic = chip->mic_volume;
516 else
517 level_mic = HR222_MICRO_CAPTURE_LEVEL_MIN;
518 return hr222_set_hw_capture_level(chip->mgr,
519 level_l, level_r, level_mic);
520 } else {
521 int vol;
522 if (chip->analog_playback_active[channel])
523 vol = chip->analog_playback_volume[channel];
524 else
525 vol = HR222_LINE_PLAYBACK_LEVEL_MIN;
526 return hr222_set_hw_playback_level(chip->mgr, channel, vol);
527 }
528}
529
530
531/*texts[5] = {"Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"}*/
532#define SOURCE_LINE 0
533#define SOURCE_DIGITAL 1
534#define SOURCE_DIGISRC 2
535#define SOURCE_MIC 3
536#define SOURCE_LINEMIC 4
537
538int hr222_set_audio_source(struct snd_pcxhr *chip)
539{
540 int digital = 0;
541 /* default analog source */
542 chip->mgr->xlx_cfg &= ~(PCXHR_CFG_SRC_MASK |
543 PCXHR_CFG_DATAIN_SEL_MASK |
544 PCXHR_CFG_DATA_UER1_SEL_MASK);
545
546 if (chip->audio_capture_source == SOURCE_DIGISRC) {
547 chip->mgr->xlx_cfg |= PCXHR_CFG_SRC_MASK;
548 digital = 1;
549 } else {
550 if (chip->audio_capture_source == SOURCE_DIGITAL)
551 digital = 1;
552 }
553 if (digital) {
554 chip->mgr->xlx_cfg |= PCXHR_CFG_DATAIN_SEL_MASK;
555 if (chip->mgr->board_has_aes1) {
556 /* get data from the AES1 plug */
557 chip->mgr->xlx_cfg |= PCXHR_CFG_DATA_UER1_SEL_MASK;
558 }
559 /* chip->mic_active = 0; */
560 /* chip->analog_capture_active = 0; */
561 } else {
562 int update_lvl = 0;
563 chip->analog_capture_active = 0;
564 chip->mic_active = 0;
565 if (chip->audio_capture_source == SOURCE_LINE ||
566 chip->audio_capture_source == SOURCE_LINEMIC) {
567 if (chip->analog_capture_active == 0)
568 update_lvl = 1;
569 chip->analog_capture_active = 1;
570 }
571 if (chip->audio_capture_source == SOURCE_MIC ||
572 chip->audio_capture_source == SOURCE_LINEMIC) {
573 if (chip->mic_active == 0)
574 update_lvl = 1;
575 chip->mic_active = 1;
576 }
577 if (update_lvl) {
578 /* capture: update all 3 mutes/unmutes with one call */
579 hr222_update_analog_audio_level(chip, 1, 0);
580 }
581 }
582 /* set the source infos (max 3 bits modified) */
583 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CFG, chip->mgr->xlx_cfg);
584 return 0;
585}
586
587
588int hr222_iec958_capture_byte(struct snd_pcxhr *chip,
589 int aes_idx, unsigned char *aes_bits)
590{
591 unsigned char idx = (unsigned char)(aes_idx * 8);
592 unsigned char temp = 0;
593 unsigned char mask = chip->mgr->board_has_aes1 ?
594 PCXHR_SUER1_BIT_C_READ_MASK : PCXHR_SUER_BIT_C_READ_MASK;
595 int i;
596 for (i = 0; i < 8; i++) {
597 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx++); /* idx < 192 */
598 temp <<= 1;
599 if (PCXHR_INPB(chip->mgr, PCXHR_XLX_CSUER) & mask)
600 temp |= 1;
601 }
602 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
603 chip->chip_idx, aes_idx, temp);
604 *aes_bits = temp;
605 return 0;
606}
607
608
609int hr222_iec958_update_byte(struct snd_pcxhr *chip,
610 int aes_idx, unsigned char aes_bits)
611{
612 int i;
613 unsigned char new_bits = aes_bits;
614 unsigned char old_bits = chip->aes_bits[aes_idx];
615 unsigned char idx = (unsigned char)(aes_idx * 8);
616 for (i = 0; i < 8; i++) {
617 if ((old_bits & 0x01) != (new_bits & 0x01)) {
618 /* idx < 192 */
619 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx);
620 /* write C and U bit */
621 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CSUER, new_bits&0x01 ?
622 PCXHR_SUER_BIT_C_WRITE_MASK : 0);
623 }
624 idx++;
625 old_bits >>= 1;
626 new_bits >>= 1;
627 }
628 chip->aes_bits[aes_idx] = aes_bits;
629 return 0;
630}
631
632static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level)
633{
634 unsigned char boost_mask;
635 boost_mask = (unsigned char) (level << PCXHR_SELMIC_PREAMPLI_OFFSET);
636 if (boost_mask & (~PCXHR_SELMIC_PREAMPLI_MASK))
637 return; /* only values form 0 to 3 accepted */
638
639 mgr->xlx_selmic &= ~PCXHR_SELMIC_PREAMPLI_MASK;
640 mgr->xlx_selmic |= boost_mask;
641
642 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
643
644 snd_printdd("hr222_micro_boost : set %x\n", boost_mask);
645}
646
647static void hr222_phantom_power(struct pcxhr_mgr *mgr, int power)
648{
649 if (power)
650 mgr->xlx_selmic |= PCXHR_SELMIC_PHANTOM_ALIM;
651 else
652 mgr->xlx_selmic &= ~PCXHR_SELMIC_PHANTOM_ALIM;
653
654 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
655
656 snd_printdd("hr222_phantom_power : set %d\n", power);
657}
658
659
660/* mic level */
661static const DECLARE_TLV_DB_SCALE(db_scale_mic_hr222, -9850, 50, 650);
662
663static int hr222_mic_vol_info(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_info *uinfo)
665{
666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
667 uinfo->count = 1;
668 uinfo->value.integer.min = HR222_MICRO_CAPTURE_LEVEL_MIN; /* -98 dB */
669 /* gains from 9 dB to 31.5 dB not recommended; use micboost instead */
670 uinfo->value.integer.max = HR222_MICRO_CAPTURE_LEVEL_MAX; /* +7 dB */
671 return 0;
672}
673
674static int hr222_mic_vol_get(struct snd_kcontrol *kcontrol,
675 struct snd_ctl_elem_value *ucontrol)
676{
677 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
678 mutex_lock(&chip->mgr->mixer_mutex);
679 ucontrol->value.integer.value[0] = chip->mic_volume;
680 mutex_unlock(&chip->mgr->mixer_mutex);
681 return 0;
682}
683
684static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
686{
687 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
688 int changed = 0;
689 mutex_lock(&chip->mgr->mixer_mutex);
690 if (chip->mic_volume != ucontrol->value.integer.value[0]) {
691 changed = 1;
692 chip->mic_volume = ucontrol->value.integer.value[0];
693 hr222_update_analog_audio_level(chip, 1, 0);
694 }
695 mutex_unlock(&chip->mgr->mixer_mutex);
696 return changed;
697}
698
699static struct snd_kcontrol_new hr222_control_mic_level = {
700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
701 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
702 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
703 .name = "Mic Capture Volume",
704 .info = hr222_mic_vol_info,
705 .get = hr222_mic_vol_get,
706 .put = hr222_mic_vol_put,
707 .tlv = { .p = db_scale_mic_hr222 },
708};
709
710
711/* mic boost level */
712static const DECLARE_TLV_DB_SCALE(db_scale_micboost_hr222, 0, 1800, 5400);
713
714static int hr222_mic_boost_info(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_info *uinfo)
716{
717 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
718 uinfo->count = 1;
719 uinfo->value.integer.min = 0; /* 0 dB */
720 uinfo->value.integer.max = 3; /* 54 dB */
721 return 0;
722}
723
724static int hr222_mic_boost_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726{
727 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
728 mutex_lock(&chip->mgr->mixer_mutex);
729 ucontrol->value.integer.value[0] = chip->mic_boost;
730 mutex_unlock(&chip->mgr->mixer_mutex);
731 return 0;
732}
733
734static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_value *ucontrol)
736{
737 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
738 int changed = 0;
739 mutex_lock(&chip->mgr->mixer_mutex);
740 if (chip->mic_boost != ucontrol->value.integer.value[0]) {
741 changed = 1;
742 chip->mic_boost = ucontrol->value.integer.value[0];
743 hr222_micro_boost(chip->mgr, chip->mic_boost);
744 }
745 mutex_unlock(&chip->mgr->mixer_mutex);
746 return changed;
747}
748
749static struct snd_kcontrol_new hr222_control_mic_boost = {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
752 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
753 .name = "MicBoost Capture Volume",
754 .info = hr222_mic_boost_info,
755 .get = hr222_mic_boost_get,
756 .put = hr222_mic_boost_put,
757 .tlv = { .p = db_scale_micboost_hr222 },
758};
759
760
761/******************* Phantom power switch *******************/
762#define hr222_phantom_power_info snd_ctl_boolean_mono_info
763
764static int hr222_phantom_power_get(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
766{
767 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
768 mutex_lock(&chip->mgr->mixer_mutex);
769 ucontrol->value.integer.value[0] = chip->phantom_power;
770 mutex_unlock(&chip->mgr->mixer_mutex);
771 return 0;
772}
773
774static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *ucontrol)
776{
777 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
778 int power, changed = 0;
779
780 mutex_lock(&chip->mgr->mixer_mutex);
781 power = !!ucontrol->value.integer.value[0];
782 if (chip->phantom_power != power) {
783 hr222_phantom_power(chip->mgr, power);
784 chip->phantom_power = power;
785 changed = 1;
786 }
787 mutex_unlock(&chip->mgr->mixer_mutex);
788 return changed;
789}
790
791static struct snd_kcontrol_new hr222_phantom_power_switch = {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "Phantom Power Switch",
794 .info = hr222_phantom_power_info,
795 .get = hr222_phantom_power_get,
796 .put = hr222_phantom_power_put,
797};
798
799
800int hr222_add_mic_controls(struct snd_pcxhr *chip)
801{
802 int err;
803 if (!chip->mgr->board_has_mic)
804 return 0;
805
806 /* controls */
807 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_level,
808 chip));
809 if (err < 0)
810 return err;
811
812 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_boost,
813 chip));
814 if (err < 0)
815 return err;
816
817 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_phantom_power_switch,
818 chip));
819 return err;
820}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h
new file mode 100644
index 000000000000..6b318b2f0100
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.h
@@ -0,0 +1,56 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * low level interface with interrupt ans message handling
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_PCXHR_MIX22_H
24#define __SOUND_PCXHR_MIX22_H
25
26struct pcxhr_mgr;
27
28int hr222_sub_init(struct pcxhr_mgr *mgr);
29int hr222_sub_set_clock(struct pcxhr_mgr *mgr, unsigned int rate,
30 int *changed);
31int hr222_get_external_clock(struct pcxhr_mgr *mgr,
32 enum pcxhr_clock_type clock_type,
33 int *sample_rate);
34
35#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
36#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
37#define HR222_LINE_PLAYBACK_LEVEL_MAX 99 /* +24.0 dB */
38
39#define HR222_LINE_CAPTURE_LEVEL_MIN 0 /* -111.5 dB */
40#define HR222_LINE_CAPTURE_ZERO_LEVEL 223 /* 0.0 dB */
41#define HR222_LINE_CAPTURE_LEVEL_MAX 255 /* +16 dB */
42#define HR222_MICRO_CAPTURE_LEVEL_MIN 0 /* -98.5 dB */
43#define HR222_MICRO_CAPTURE_LEVEL_MAX 210 /* +6.5 dB */
44
45int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
46 int is_capture,
47 int channel);
48int hr222_set_audio_source(struct snd_pcxhr *chip);
49int hr222_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx,
50 unsigned char *aes_bits);
51int hr222_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx,
52 unsigned char aes_bits);
53
54int hr222_add_mic_controls(struct snd_pcxhr *chip);
55
56#endif /* __SOUND_PCXHR_MIX22_H */
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index aabc7bc5321e..2436e374586f 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -33,20 +33,24 @@
33#include <sound/tlv.h> 33#include <sound/tlv.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include "pcxhr_mixer.h" 35#include "pcxhr_mixer.h"
36#include "pcxhr_mix22.h"
36 37
38#define PCXHR_LINE_CAPTURE_LEVEL_MIN 0 /* -112.0 dB */
39#define PCXHR_LINE_CAPTURE_LEVEL_MAX 255 /* +15.5 dB */
40#define PCXHR_LINE_CAPTURE_ZERO_LEVEL 224 /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
37 41
38#define PCXHR_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB */ 42#define PCXHR_LINE_PLAYBACK_LEVEL_MIN 0 /* -104.0 dB */
39#define PCXHR_ANALOG_CAPTURE_LEVEL_MAX 255 /* +31.5 dB */ 43#define PCXHR_LINE_PLAYBACK_LEVEL_MAX 128 /* +24.0 dB */
40#define PCXHR_ANALOG_CAPTURE_ZERO_LEVEL 224 /* +16.0 dB ( +31.5 dB - fix level +15.5 dB ) */ 44#define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104 /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
41 45
42#define PCXHR_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -128.0 dB */ 46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
43#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
44#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
45
46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150);
47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400); 47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
48 48
49static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) 49static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
50static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
51
52static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
53 int is_capture, int channel)
50{ 54{
51 int err, vol; 55 int err, vol;
52 struct pcxhr_rmh rmh; 56 struct pcxhr_rmh rmh;
@@ -60,15 +64,17 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
60 if (chip->analog_playback_active[channel]) 64 if (chip->analog_playback_active[channel])
61 vol = chip->analog_playback_volume[channel]; 65 vol = chip->analog_playback_volume[channel];
62 else 66 else
63 vol = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; 67 vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
64 rmh.cmd[2] = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX - vol; /* playback analog levels are inversed */ 68 /* playback analog levels are inversed */
69 rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
65 } 70 }
66 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */ 71 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
67 rmh.cmd_len = 3; 72 rmh.cmd_len = 3;
68 err = pcxhr_send_msg(chip->mgr, &rmh); 73 err = pcxhr_send_msg(chip->mgr, &rmh);
69 if (err < 0) { 74 if (err < 0) {
70 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d) " 75 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d)"
71 "is_capture(%d) err(%x)\n", chip->chip_idx, is_capture, err); 76 " is_capture(%d) err(%x)\n",
77 chip->chip_idx, is_capture, err);
72 return -EINVAL; 78 return -EINVAL;
73 } 79 }
74 return 0; 80 return 0;
@@ -80,14 +86,34 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
80static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol, 86static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
81 struct snd_ctl_elem_info *uinfo) 87 struct snd_ctl_elem_info *uinfo)
82{ 88{
89 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
90
83 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 91 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
84 uinfo->count = 2; 92 uinfo->count = 2;
85 if (kcontrol->private_value == 0) { /* playback */ 93 if (kcontrol->private_value == 0) { /* playback */
86 uinfo->value.integer.min = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; /* -128 dB */ 94 if (chip->mgr->is_hr_stereo) {
87 uinfo->value.integer.max = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */ 95 uinfo->value.integer.min =
96 HR222_LINE_PLAYBACK_LEVEL_MIN; /* -25 dB */
97 uinfo->value.integer.max =
98 HR222_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
99 } else {
100 uinfo->value.integer.min =
101 PCXHR_LINE_PLAYBACK_LEVEL_MIN; /*-104 dB */
102 uinfo->value.integer.max =
103 PCXHR_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
104 }
88 } else { /* capture */ 105 } else { /* capture */
89 uinfo->value.integer.min = PCXHR_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */ 106 if (chip->mgr->is_hr_stereo) {
90 uinfo->value.integer.max = PCXHR_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */ 107 uinfo->value.integer.min =
108 HR222_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
109 uinfo->value.integer.max =
110 HR222_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
111 } else {
112 uinfo->value.integer.min =
113 PCXHR_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
114 uinfo->value.integer.max =
115 PCXHR_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
116 }
91 } 117 }
92 return 0; 118 return 0;
93} 119}
@@ -98,11 +124,11 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
98 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 124 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
99 mutex_lock(&chip->mgr->mixer_mutex); 125 mutex_lock(&chip->mgr->mixer_mutex);
100 if (kcontrol->private_value == 0) { /* playback */ 126 if (kcontrol->private_value == 0) { /* playback */
101 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; 127 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
102 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; 128 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
103 } else { /* capture */ 129 } else { /* capture */
104 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; 130 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
105 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; 131 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
106 } 132 }
107 mutex_unlock(&chip->mgr->mixer_mutex); 133 mutex_unlock(&chip->mgr->mixer_mutex);
108 return 0; 134 return 0;
@@ -123,18 +149,35 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
123 &chip->analog_capture_volume[i] : 149 &chip->analog_capture_volume[i] :
124 &chip->analog_playback_volume[i]; 150 &chip->analog_playback_volume[i];
125 if (is_capture) { 151 if (is_capture) {
126 if (new_volume < PCXHR_ANALOG_CAPTURE_LEVEL_MIN || 152 if (chip->mgr->is_hr_stereo) {
127 new_volume > PCXHR_ANALOG_CAPTURE_LEVEL_MAX) 153 if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
128 continue; 154 new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
155 continue;
156 } else {
157 if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
158 new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
159 continue;
160 }
129 } else { 161 } else {
130 if (new_volume < PCXHR_ANALOG_PLAYBACK_LEVEL_MIN || 162 if (chip->mgr->is_hr_stereo) {
131 new_volume > PCXHR_ANALOG_PLAYBACK_LEVEL_MAX) 163 if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
132 continue; 164 new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
165 continue;
166 } else {
167 if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
168 new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
169 continue;
170 }
133 } 171 }
134 if (*stored_volume != new_volume) { 172 if (*stored_volume != new_volume) {
135 *stored_volume = new_volume; 173 *stored_volume = new_volume;
136 changed = 1; 174 changed = 1;
137 pcxhr_update_analog_audio_level(chip, is_capture, i); 175 if (chip->mgr->is_hr_stereo)
176 hr222_update_analog_audio_level(chip,
177 is_capture, i);
178 else
179 pcxhr_update_analog_audio_level(chip,
180 is_capture, i);
138 } 181 }
139 } 182 }
140 mutex_unlock(&chip->mgr->mixer_mutex); 183 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -153,6 +196,7 @@ static struct snd_kcontrol_new pcxhr_control_analog_level = {
153}; 196};
154 197
155/* shared */ 198/* shared */
199
156#define pcxhr_sw_info snd_ctl_boolean_stereo_info 200#define pcxhr_sw_info snd_ctl_boolean_stereo_info
157 201
158static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, 202static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
@@ -180,7 +224,10 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
180 !!ucontrol->value.integer.value[i]; 224 !!ucontrol->value.integer.value[i];
181 changed = 1; 225 changed = 1;
182 /* update playback levels */ 226 /* update playback levels */
183 pcxhr_update_analog_audio_level(chip, 0, i); 227 if (chip->mgr->is_hr_stereo)
228 hr222_update_analog_audio_level(chip, 0, i);
229 else
230 pcxhr_update_analog_audio_level(chip, 0, i);
184 } 231 }
185 } 232 }
186 mutex_unlock(&chip->mgr->mixer_mutex); 233 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -251,7 +298,8 @@ static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
251#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004 298#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004
252#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008 299#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008
253 300
254static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel) 301static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
302 int capture, int channel)
255{ 303{
256 int err; 304 int err;
257 struct pcxhr_rmh rmh; 305 struct pcxhr_rmh rmh;
@@ -264,18 +312,20 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
264 312
265 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST); 313 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
266 /* add channel mask */ 314 /* add channel mask */
267 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0, 1 << (channel + pipe->first_audio)); 315 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
268 /* TODO : if mask (3 << pipe->first_audio) is used, left and right channel 316 1 << (channel + pipe->first_audio));
269 * will be programmed to the same params 317 /* TODO : if mask (3 << pipe->first_audio) is used, left and right
270 */ 318 * channel will be programmed to the same params */
271 if (capture) { 319 if (capture) {
272 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL; 320 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
273 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled (capture pipe level) */ 321 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
322 * (capture pipe level) */
274 rmh.cmd[2] = chip->digital_capture_volume[channel]; 323 rmh.cmd[2] = chip->digital_capture_volume[channel];
275 } else { 324 } else {
276 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL | VALID_AUDIO_IO_MUTE_MONITOR_1; 325 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL |
277 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL not yet 326 VALID_AUDIO_IO_MUTE_MONITOR_1;
278 * handled (playback pipe level) 327 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
328 * not yet handled (playback pipe level)
279 */ 329 */
280 rmh.cmd[2] = chip->monitoring_volume[channel] << 10; 330 rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
281 if (chip->monitoring_active[channel] == 0) 331 if (chip->monitoring_active[channel] == 0)
@@ -284,8 +334,8 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
284 rmh.cmd_len = 3; 334 rmh.cmd_len = 3;
285 335
286 err = pcxhr_send_msg(chip->mgr, &rmh); 336 err = pcxhr_send_msg(chip->mgr, &rmh);
287 if(err<0) { 337 if (err < 0) {
288 snd_printk(KERN_DEBUG "error update_audio_level card(%d) err(%x)\n", 338 snd_printk(KERN_DEBUG "error update_audio_level(%d) err=%x\n",
289 chip->chip_idx, err); 339 chip->chip_idx, err);
290 return -EINVAL; 340 return -EINVAL;
291 } 341 }
@@ -309,15 +359,15 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol) 359 struct snd_ctl_elem_value *ucontrol)
310{ 360{
311 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 361 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
312 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 362 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
313 int *stored_volume; 363 int *stored_volume;
314 int is_capture = kcontrol->private_value; 364 int is_capture = kcontrol->private_value;
315 365
316 mutex_lock(&chip->mgr->mixer_mutex); 366 mutex_lock(&chip->mgr->mixer_mutex);
317 if (is_capture) 367 if (is_capture) /* digital capture */
318 stored_volume = chip->digital_capture_volume; /* digital capture */ 368 stored_volume = chip->digital_capture_volume;
319 else 369 else /* digital playback */
320 stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ 370 stored_volume = chip->digital_playback_volume[idx];
321 ucontrol->value.integer.value[0] = stored_volume[0]; 371 ucontrol->value.integer.value[0] = stored_volume[0];
322 ucontrol->value.integer.value[1] = stored_volume[1]; 372 ucontrol->value.integer.value[1] = stored_volume[1];
323 mutex_unlock(&chip->mgr->mixer_mutex); 373 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -328,7 +378,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol) 378 struct snd_ctl_elem_value *ucontrol)
329{ 379{
330 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 380 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
331 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 381 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
332 int changed = 0; 382 int changed = 0;
333 int is_capture = kcontrol->private_value; 383 int is_capture = kcontrol->private_value;
334 int *stored_volume; 384 int *stored_volume;
@@ -384,7 +434,8 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
384 return 0; 434 return 0;
385} 435}
386 436
387static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 437static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
388{ 439{
389 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 440 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
390 int changed = 0; 441 int changed = 0;
@@ -444,8 +495,8 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
444 if (chip->monitoring_volume[i] != 495 if (chip->monitoring_volume[i] !=
445 ucontrol->value.integer.value[i]) { 496 ucontrol->value.integer.value[i]) {
446 chip->monitoring_volume[i] = 497 chip->monitoring_volume[i] =
447 !!ucontrol->value.integer.value[i]; 498 ucontrol->value.integer.value[i];
448 if(chip->monitoring_active[i]) 499 if (chip->monitoring_active[i])
449 /* update monitoring volume and mute */ 500 /* update monitoring volume and mute */
450 /* do only when monitoring is unmuted */ 501 /* do only when monitoring is unmuted */
451 pcxhr_update_audio_pipe_level(chip, 0, i); 502 pcxhr_update_audio_pipe_level(chip, 0, i);
@@ -460,7 +511,7 @@ static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
461 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 512 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
462 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 513 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
463 .name = "Monitoring Volume", 514 .name = "Monitoring Playback Volume",
464 .info = pcxhr_digital_vol_info, /* shared */ 515 .info = pcxhr_digital_vol_info, /* shared */
465 .get = pcxhr_monitor_vol_get, 516 .get = pcxhr_monitor_vol_get,
466 .put = pcxhr_monitor_vol_put, 517 .put = pcxhr_monitor_vol_put,
@@ -511,7 +562,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
511 562
512static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 563static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .name = "Monitoring Switch", 565 .name = "Monitoring Playback Switch",
515 .info = pcxhr_sw_info, /* shared */ 566 .info = pcxhr_sw_info, /* shared */
516 .get = pcxhr_monitor_sw_get, 567 .get = pcxhr_monitor_sw_get,
517 .put = pcxhr_monitor_sw_put 568 .put = pcxhr_monitor_sw_put
@@ -533,7 +584,7 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
533 struct pcxhr_rmh rmh; 584 struct pcxhr_rmh rmh;
534 unsigned int mask, reg; 585 unsigned int mask, reg;
535 unsigned int codec; 586 unsigned int codec;
536 int err, use_src, changed; 587 int err, changed;
537 588
538 switch (chip->chip_idx) { 589 switch (chip->chip_idx) {
539 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break; 590 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
@@ -542,13 +593,10 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
542 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break; 593 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
543 default: return -EINVAL; 594 default: return -EINVAL;
544 } 595 }
545 reg = 0; /* audio source from analog plug */
546 use_src = 0; /* do not activate codec SRC */
547
548 if (chip->audio_capture_source != 0) { 596 if (chip->audio_capture_source != 0) {
549 reg = mask; /* audio source from digital plug */ 597 reg = mask; /* audio source from digital plug */
550 if (chip->audio_capture_source == 2) 598 } else {
551 use_src = 1; 599 reg = 0; /* audio source from analog plug */
552 } 600 }
553 /* set the input source */ 601 /* set the input source */
554 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed); 602 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
@@ -560,29 +608,61 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
560 if (err) 608 if (err)
561 return err; 609 return err;
562 } 610 }
563 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set codec SRC on off */ 611 if (chip->mgr->board_aes_in_192k) {
564 rmh.cmd_len = 3; 612 int i;
565 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 613 unsigned int src_config = 0xC0;
566 rmh.cmd[1] = codec; 614 /* update all src configs with one call */
567 rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54); 615 for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
568 err = pcxhr_send_msg(chip->mgr, &rmh); 616 if (chip->mgr->chip[i]->audio_capture_source == 2)
569 if(err) 617 src_config |= (1 << (3 - i));
570 return err; 618 }
571 rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49); 619 /* set codec SRC on off */
572 err = pcxhr_send_msg(chip->mgr, &rmh); 620 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
621 rmh.cmd_len = 2;
622 rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
623 rmh.cmd[1] = src_config;
624 err = pcxhr_send_msg(chip->mgr, &rmh);
625 } else {
626 int use_src = 0;
627 if (chip->audio_capture_source == 2)
628 use_src = 1;
629 /* set codec SRC on off */
630 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
631 rmh.cmd_len = 3;
632 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
633 rmh.cmd[1] = codec;
634 rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
635 (use_src ? 0x41 : 0x54));
636 err = pcxhr_send_msg(chip->mgr, &rmh);
637 if (err)
638 return err;
639 rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
640 (use_src ? 0x41 : 0x49));
641 err = pcxhr_send_msg(chip->mgr, &rmh);
642 }
573 return err; 643 return err;
574} 644}
575 645
576static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, 646static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_info *uinfo) 647 struct snd_ctl_elem_info *uinfo)
578{ 648{
579 static char *texts[3] = {"Analog", "Digital", "Digi+SRC"}; 649 static const char *texts[5] = {
650 "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
651 };
652 int i;
653 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
580 654
655 i = 2; /* no SRC, no Mic available */
656 if (chip->mgr->board_has_aes1) {
657 i = 3; /* SRC available */
658 if (chip->mgr->board_has_mic)
659 i = 5; /* Mic and MicroMix available */
660 }
581 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 661 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
582 uinfo->count = 1; 662 uinfo->count = 1;
583 uinfo->value.enumerated.items = 3; 663 uinfo->value.enumerated.items = i;
584 if (uinfo->value.enumerated.item > 2) 664 if (uinfo->value.enumerated.item > (i-1))
585 uinfo->value.enumerated.item = 2; 665 uinfo->value.enumerated.item = i-1;
586 strcpy(uinfo->value.enumerated.name, 666 strcpy(uinfo->value.enumerated.name,
587 texts[uinfo->value.enumerated.item]); 667 texts[uinfo->value.enumerated.item]);
588 return 0; 668 return 0;
@@ -601,13 +681,21 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
601{ 681{
602 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 682 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
603 int ret = 0; 683 int ret = 0;
604 684 int i = 2; /* no SRC, no Mic available */
605 if (ucontrol->value.enumerated.item[0] >= 3) 685 if (chip->mgr->board_has_aes1) {
686 i = 3; /* SRC available */
687 if (chip->mgr->board_has_mic)
688 i = 5; /* Mic and MicroMix available */
689 }
690 if (ucontrol->value.enumerated.item[0] >= i)
606 return -EINVAL; 691 return -EINVAL;
607 mutex_lock(&chip->mgr->mixer_mutex); 692 mutex_lock(&chip->mgr->mixer_mutex);
608 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { 693 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
609 chip->audio_capture_source = ucontrol->value.enumerated.item[0]; 694 chip->audio_capture_source = ucontrol->value.enumerated.item[0];
610 pcxhr_set_audio_source(chip); 695 if (chip->mgr->is_hr_stereo)
696 hr222_set_audio_source(chip);
697 else
698 pcxhr_set_audio_source(chip);
611 ret = 1; 699 ret = 1;
612 } 700 }
613 mutex_unlock(&chip->mgr->mixer_mutex); 701 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -626,25 +714,46 @@ static struct snd_kcontrol_new pcxhr_control_audio_src = {
626/* 714/*
627 * clock type selection 715 * clock type selection
628 * enum pcxhr_clock_type { 716 * enum pcxhr_clock_type {
629 * PCXHR_CLOCK_TYPE_INTERNAL = 0, 717 * PCXHR_CLOCK_TYPE_INTERNAL = 0,
630 * PCXHR_CLOCK_TYPE_WORD_CLOCK, 718 * PCXHR_CLOCK_TYPE_WORD_CLOCK,
631 * PCXHR_CLOCK_TYPE_AES_SYNC, 719 * PCXHR_CLOCK_TYPE_AES_SYNC,
632 * PCXHR_CLOCK_TYPE_AES_1, 720 * PCXHR_CLOCK_TYPE_AES_1,
633 * PCXHR_CLOCK_TYPE_AES_2, 721 * PCXHR_CLOCK_TYPE_AES_2,
634 * PCXHR_CLOCK_TYPE_AES_3, 722 * PCXHR_CLOCK_TYPE_AES_3,
635 * PCXHR_CLOCK_TYPE_AES_4, 723 * PCXHR_CLOCK_TYPE_AES_4,
636 * }; 724 * PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
725 * HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
726 * HR22_CLOCK_TYPE_AES_SYNC,
727 * HR22_CLOCK_TYPE_AES_1,
728 * HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
729 * };
637 */ 730 */
638 731
639static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol, 732static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_info *uinfo) 733 struct snd_ctl_elem_info *uinfo)
641{ 734{
642 static char *texts[7] = { 735 static const char *textsPCXHR[7] = {
643 "Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 736 "Internal", "WordClock", "AES Sync",
737 "AES 1", "AES 2", "AES 3", "AES 4"
738 };
739 static const char *textsHR22[3] = {
740 "Internal", "AES Sync", "AES 1"
644 }; 741 };
742 const char **texts;
645 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 743 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
646 int clock_items = 3 + mgr->capture_chips; 744 int clock_items = 2; /* at least Internal and AES Sync clock */
647 745 if (mgr->board_has_aes1) {
746 clock_items += mgr->capture_chips; /* add AES x */
747 if (!mgr->is_hr_stereo)
748 clock_items += 1; /* add word clock */
749 }
750 if (mgr->is_hr_stereo) {
751 texts = textsHR22;
752 snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
753 } else {
754 texts = textsPCXHR;
755 snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
756 }
648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 757 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
649 uinfo->count = 1; 758 uinfo->count = 1;
650 uinfo->value.enumerated.items = clock_items; 759 uinfo->value.enumerated.items = clock_items;
@@ -667,9 +776,13 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol) 776 struct snd_ctl_elem_value *ucontrol)
668{ 777{
669 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 778 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
670 unsigned int clock_items = 3 + mgr->capture_chips;
671 int rate, ret = 0; 779 int rate, ret = 0;
672 780 unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
781 if (mgr->board_has_aes1) {
782 clock_items += mgr->capture_chips; /* add AES x */
783 if (!mgr->is_hr_stereo)
784 clock_items += 1; /* add word clock */
785 }
673 if (ucontrol->value.enumerated.item[0] >= clock_items) 786 if (ucontrol->value.enumerated.item[0] >= clock_items)
674 return -EINVAL; 787 return -EINVAL;
675 mutex_lock(&mgr->mixer_mutex); 788 mutex_lock(&mgr->mixer_mutex);
@@ -677,7 +790,8 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
677 mutex_lock(&mgr->setup_mutex); 790 mutex_lock(&mgr->setup_mutex);
678 mgr->use_clock_type = ucontrol->value.enumerated.item[0]; 791 mgr->use_clock_type = ucontrol->value.enumerated.item[0];
679 if (mgr->use_clock_type) 792 if (mgr->use_clock_type)
680 pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); 793 pcxhr_get_external_clock(mgr, mgr->use_clock_type,
794 &rate);
681 else 795 else
682 rate = mgr->sample_rate; 796 rate = mgr->sample_rate;
683 if (rate) { 797 if (rate) {
@@ -686,7 +800,7 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
686 mgr->sample_rate = rate; 800 mgr->sample_rate = rate;
687 } 801 }
688 mutex_unlock(&mgr->setup_mutex); 802 mutex_unlock(&mgr->setup_mutex);
689 ret = 1; /* return 1 even if the set was not done. ok ? */ 803 ret = 1; /* return 1 even if the set was not done. ok ? */
690 } 804 }
691 mutex_unlock(&mgr->mixer_mutex); 805 mutex_unlock(&mgr->mixer_mutex);
692 return ret; 806 return ret;
@@ -747,14 +861,16 @@ static struct snd_kcontrol_new pcxhr_control_clock_rate = {
747/* 861/*
748 * IEC958 status bits 862 * IEC958 status bits
749 */ 863 */
750static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 864static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
865 struct snd_ctl_elem_info *uinfo)
751{ 866{
752 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 867 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
753 uinfo->count = 1; 868 uinfo->count = 1;
754 return 0; 869 return 0;
755} 870}
756 871
757static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits) 872static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
873 int aes_idx, unsigned char *aes_bits)
758{ 874{
759 int i, err; 875 int i, err;
760 unsigned char temp; 876 unsigned char temp;
@@ -763,39 +879,61 @@ static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsign
763 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 879 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
764 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 880 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
765 switch (chip->chip_idx) { 881 switch (chip->chip_idx) {
766 case 0: rmh.cmd[1] = CS8420_01_CS; break; /* use CS8416_01_CS for AES SYNC plug */ 882 /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
883 case 0: rmh.cmd[1] = CS8420_01_CS; break;
767 case 1: rmh.cmd[1] = CS8420_23_CS; break; 884 case 1: rmh.cmd[1] = CS8420_23_CS; break;
768 case 2: rmh.cmd[1] = CS8420_45_CS; break; 885 case 2: rmh.cmd[1] = CS8420_45_CS; break;
769 case 3: rmh.cmd[1] = CS8420_67_CS; break; 886 case 3: rmh.cmd[1] = CS8420_67_CS; break;
770 default: return -EINVAL; 887 default: return -EINVAL;
771 } 888 }
772 switch (aes_idx) { 889 if (chip->mgr->board_aes_in_192k) {
773 case 0: rmh.cmd[2] = CS8420_CSB0; break; /* use CS8416_CSBx for AES SYNC plug */ 890 switch (aes_idx) {
774 case 1: rmh.cmd[2] = CS8420_CSB1; break; 891 case 0: rmh.cmd[2] = CS8416_CSB0; break;
775 case 2: rmh.cmd[2] = CS8420_CSB2; break; 892 case 1: rmh.cmd[2] = CS8416_CSB1; break;
776 case 3: rmh.cmd[2] = CS8420_CSB3; break; 893 case 2: rmh.cmd[2] = CS8416_CSB2; break;
777 case 4: rmh.cmd[2] = CS8420_CSB4; break; 894 case 3: rmh.cmd[2] = CS8416_CSB3; break;
778 default: return -EINVAL; 895 case 4: rmh.cmd[2] = CS8416_CSB4; break;
896 default: return -EINVAL;
897 }
898 } else {
899 switch (aes_idx) {
900 /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
901 case 0: rmh.cmd[2] = CS8420_CSB0; break;
902 case 1: rmh.cmd[2] = CS8420_CSB1; break;
903 case 2: rmh.cmd[2] = CS8420_CSB2; break;
904 case 3: rmh.cmd[2] = CS8420_CSB3; break;
905 case 4: rmh.cmd[2] = CS8420_CSB4; break;
906 default: return -EINVAL;
907 }
779 } 908 }
780 rmh.cmd[1] &= 0x0fffff; /* size and code the chip id for the fpga */ 909 /* size and code the chip id for the fpga */
781 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI; /* chip signature + map for spi read */ 910 rmh.cmd[1] &= 0x0fffff;
911 /* chip signature + map for spi read */
912 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
782 rmh.cmd_len = 3; 913 rmh.cmd_len = 3;
783 err = pcxhr_send_msg(chip->mgr, &rmh); 914 err = pcxhr_send_msg(chip->mgr, &rmh);
784 if (err) 915 if (err)
785 return err; 916 return err;
786 temp = 0; 917
787 for (i = 0; i < 8; i++) { 918 if (chip->mgr->board_aes_in_192k) {
788 /* attention : reversed bit order (not with CS8416_01_CS) */ 919 temp = (unsigned char)rmh.stat[1];
789 temp <<= 1; 920 } else {
790 if (rmh.stat[1] & (1 << i)) 921 temp = 0;
791 temp |= 1; 922 /* reversed bit order (not with CS8416_01_CS) */
923 for (i = 0; i < 8; i++) {
924 temp <<= 1;
925 if (rmh.stat[1] & (1 << i))
926 temp |= 1;
927 }
792 } 928 }
793 snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp); 929 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
930 chip->chip_idx, aes_idx, temp);
794 *aes_bits = temp; 931 *aes_bits = temp;
795 return 0; 932 return 0;
796} 933}
797 934
798static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 935static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
936 struct snd_ctl_elem_value *ucontrol)
799{ 937{
800 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 938 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
801 unsigned char aes_bits; 939 unsigned char aes_bits;
@@ -806,7 +944,12 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
806 if (kcontrol->private_value == 0) /* playback */ 944 if (kcontrol->private_value == 0) /* playback */
807 aes_bits = chip->aes_bits[i]; 945 aes_bits = chip->aes_bits[i];
808 else { /* capture */ 946 else { /* capture */
809 err = pcxhr_iec958_capture_byte(chip, i, &aes_bits); 947 if (chip->mgr->is_hr_stereo)
948 err = hr222_iec958_capture_byte(chip, i,
949 &aes_bits);
950 else
951 err = pcxhr_iec958_capture_byte(chip, i,
952 &aes_bits);
810 if (err) 953 if (err)
811 break; 954 break;
812 } 955 }
@@ -825,7 +968,8 @@ static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
825 return 0; 968 return 0;
826} 969}
827 970
828static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits) 971static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
972 int aes_idx, unsigned char aes_bits)
829{ 973{
830 int i, err, cmd; 974 int i, err, cmd;
831 unsigned char new_bits = aes_bits; 975 unsigned char new_bits = aes_bits;
@@ -834,12 +978,12 @@ static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigne
834 978
835 for (i = 0; i < 8; i++) { 979 for (i = 0; i < 8; i++) {
836 if ((old_bits & 0x01) != (new_bits & 0x01)) { 980 if ((old_bits & 0x01) != (new_bits & 0x01)) {
837 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */ 981 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */
838 if(chip->chip_idx > 3) 982 if (chip->chip_idx > 3)
839 /* new bit used if chip_idx>3 (PCX1222HR) */ 983 /* new bit used if chip_idx>3 (PCX1222HR) */
840 cmd |= 1 << 22; 984 cmd |= 1 << 22;
841 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */ 985 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
842 cmd |= (new_bits & 0x01) << 23; /* add bit value */ 986 cmd |= (new_bits & 0x01) << 23; /* add bit value */
843 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 987 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
844 rmh.cmd[0] |= IO_NUM_REG_CUER; 988 rmh.cmd[0] |= IO_NUM_REG_CUER;
845 rmh.cmd[1] = cmd; 989 rmh.cmd[1] = cmd;
@@ -867,7 +1011,12 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
867 mutex_lock(&chip->mgr->mixer_mutex); 1011 mutex_lock(&chip->mgr->mixer_mutex);
868 for (i = 0; i < 5; i++) { 1012 for (i = 0; i < 5; i++) {
869 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { 1013 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
870 pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); 1014 if (chip->mgr->is_hr_stereo)
1015 hr222_iec958_update_byte(chip, i,
1016 ucontrol->value.iec958.status[i]);
1017 else
1018 pcxhr_iec958_update_byte(chip, i,
1019 ucontrol->value.iec958.status[i]);
871 changed = 1; 1020 changed = 1;
872 } 1021 }
873 } 1022 }
@@ -917,29 +1066,53 @@ static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
917 /* at boot time the digital volumes are unmuted 0dB */ 1066 /* at boot time the digital volumes are unmuted 0dB */
918 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) { 1067 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
919 chip->digital_playback_active[j][i] = 1; 1068 chip->digital_playback_active[j][i] = 1;
920 chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL; 1069 chip->digital_playback_volume[j][i] =
1070 PCXHR_DIGITAL_ZERO_LEVEL;
921 } 1071 }
922 /* after boot, only two bits are set on the uer interface */ 1072 /* after boot, only two bits are set on the uer
923 chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000; 1073 * interface
924/* only for test purpose, remove later */ 1074 */
1075 chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
1076 IEC958_AES0_PRO_FS_48000);
925#ifdef CONFIG_SND_DEBUG 1077#ifdef CONFIG_SND_DEBUG
926 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1078 /* analog volumes for playback
1079 * (is LEVEL_MIN after boot)
1080 */
927 chip->analog_playback_active[i] = 1; 1081 chip->analog_playback_active[i] = 1;
928 chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL; 1082 if (chip->mgr->is_hr_stereo)
929 pcxhr_update_analog_audio_level(chip, 0, i); 1083 chip->analog_playback_volume[i] =
1084 HR222_LINE_PLAYBACK_ZERO_LEVEL;
1085 else {
1086 chip->analog_playback_volume[i] =
1087 PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
1088 pcxhr_update_analog_audio_level(chip, 0, i);
1089 }
930#endif 1090#endif
931/* test end */ 1091 /* stereo cards need to be initialised after boot */
1092 if (chip->mgr->is_hr_stereo)
1093 hr222_update_analog_audio_level(chip, 0, i);
932 } 1094 }
933 if (chip->nb_streams_capt) { 1095 if (chip->nb_streams_capt) {
934 /* at boot time the digital volumes are unmuted 0dB */ 1096 /* at boot time the digital volumes are unmuted 0dB */
935 chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL; 1097 chip->digital_capture_volume[i] =
936/* only for test purpose, remove later */ 1098 PCXHR_DIGITAL_ZERO_LEVEL;
1099 chip->analog_capture_active = 1;
937#ifdef CONFIG_SND_DEBUG 1100#ifdef CONFIG_SND_DEBUG
938 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1101 /* analog volumes for playback
939 chip->analog_capture_volume[i] = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL; 1102 * (is LEVEL_MIN after boot)
940 pcxhr_update_analog_audio_level(chip, 1, i); 1103 */
1104 if (chip->mgr->is_hr_stereo)
1105 chip->analog_capture_volume[i] =
1106 HR222_LINE_CAPTURE_ZERO_LEVEL;
1107 else {
1108 chip->analog_capture_volume[i] =
1109 PCXHR_LINE_CAPTURE_ZERO_LEVEL;
1110 pcxhr_update_analog_audio_level(chip, 1, i);
1111 }
941#endif 1112#endif
942/* test end */ 1113 /* stereo cards need to be initialised after boot */
1114 if (chip->mgr->is_hr_stereo)
1115 hr222_update_analog_audio_level(chip, 1, i);
943 } 1116 }
944 } 1117 }
945 1118
@@ -963,90 +1136,125 @@ int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
963 temp = pcxhr_control_analog_level; 1136 temp = pcxhr_control_analog_level;
964 temp.name = "Master Playback Volume"; 1137 temp.name = "Master Playback Volume";
965 temp.private_value = 0; /* playback */ 1138 temp.private_value = 0; /* playback */
966 temp.tlv.p = db_scale_analog_playback; 1139 if (mgr->is_hr_stereo)
967 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1140 temp.tlv.p = db_scale_a_hr222_playback;
1141 else
1142 temp.tlv.p = db_scale_analog_playback;
1143 err = snd_ctl_add(chip->card,
1144 snd_ctl_new1(&temp, chip));
1145 if (err < 0)
968 return err; 1146 return err;
1147
969 /* output mute controls */ 1148 /* output mute controls */
970 if ((err = snd_ctl_add(chip->card, 1149 err = snd_ctl_add(chip->card,
971 snd_ctl_new1(&pcxhr_control_output_switch, 1150 snd_ctl_new1(&pcxhr_control_output_switch,
972 chip))) < 0) 1151 chip));
1152 if (err < 0)
973 return err; 1153 return err;
974 1154
975 temp = snd_pcxhr_pcm_vol; 1155 temp = snd_pcxhr_pcm_vol;
976 temp.name = "PCM Playback Volume"; 1156 temp.name = "PCM Playback Volume";
977 temp.count = PCXHR_PLAYBACK_STREAMS; 1157 temp.count = PCXHR_PLAYBACK_STREAMS;
978 temp.private_value = 0; /* playback */ 1158 temp.private_value = 0; /* playback */
979 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1159 err = snd_ctl_add(chip->card,
1160 snd_ctl_new1(&temp, chip));
1161 if (err < 0)
980 return err; 1162 return err;
981 1163
982 if ((err = snd_ctl_add(chip->card, 1164 err = snd_ctl_add(chip->card,
983 snd_ctl_new1(&pcxhr_control_pcm_switch, 1165 snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
984 chip))) < 0) 1166 if (err < 0)
985 return err; 1167 return err;
986 1168
987 /* IEC958 controls */ 1169 /* IEC958 controls */
988 if ((err = snd_ctl_add(chip->card, 1170 err = snd_ctl_add(chip->card,
989 snd_ctl_new1(&pcxhr_control_playback_iec958_mask, 1171 snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
990 chip))) < 0) 1172 chip));
1173 if (err < 0)
991 return err; 1174 return err;
992 if ((err = snd_ctl_add(chip->card, 1175
993 snd_ctl_new1(&pcxhr_control_playback_iec958, 1176 err = snd_ctl_add(chip->card,
994 chip))) < 0) 1177 snd_ctl_new1(&pcxhr_control_playback_iec958,
1178 chip));
1179 if (err < 0)
995 return err; 1180 return err;
996 } 1181 }
997 if (chip->nb_streams_capt) { 1182 if (chip->nb_streams_capt) {
998 /* analog input level control only on first two chips !*/ 1183 /* analog input level control */
999 temp = pcxhr_control_analog_level; 1184 temp = pcxhr_control_analog_level;
1000 temp.name = "Master Capture Volume"; 1185 temp.name = "Line Capture Volume";
1001 temp.private_value = 1; /* capture */ 1186 temp.private_value = 1; /* capture */
1002 temp.tlv.p = db_scale_analog_capture; 1187 if (mgr->is_hr_stereo)
1003 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1188 temp.tlv.p = db_scale_a_hr222_capture;
1189 else
1190 temp.tlv.p = db_scale_analog_capture;
1191
1192 err = snd_ctl_add(chip->card,
1193 snd_ctl_new1(&temp, chip));
1194 if (err < 0)
1004 return err; 1195 return err;
1005 1196
1006 temp = snd_pcxhr_pcm_vol; 1197 temp = snd_pcxhr_pcm_vol;
1007 temp.name = "PCM Capture Volume"; 1198 temp.name = "PCM Capture Volume";
1008 temp.count = 1; 1199 temp.count = 1;
1009 temp.private_value = 1; /* capture */ 1200 temp.private_value = 1; /* capture */
1010 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1201
1202 err = snd_ctl_add(chip->card,
1203 snd_ctl_new1(&temp, chip));
1204 if (err < 0)
1011 return err; 1205 return err;
1206
1012 /* Audio source */ 1207 /* Audio source */
1013 if ((err = snd_ctl_add(chip->card, 1208 err = snd_ctl_add(chip->card,
1014 snd_ctl_new1(&pcxhr_control_audio_src, 1209 snd_ctl_new1(&pcxhr_control_audio_src, chip));
1015 chip))) < 0) 1210 if (err < 0)
1016 return err; 1211 return err;
1212
1017 /* IEC958 controls */ 1213 /* IEC958 controls */
1018 if ((err = snd_ctl_add(chip->card, 1214 err = snd_ctl_add(chip->card,
1019 snd_ctl_new1(&pcxhr_control_capture_iec958_mask, 1215 snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
1020 chip))) < 0) 1216 chip));
1217 if (err < 0)
1021 return err; 1218 return err;
1022 if ((err = snd_ctl_add(chip->card, 1219
1023 snd_ctl_new1(&pcxhr_control_capture_iec958, 1220 err = snd_ctl_add(chip->card,
1024 chip))) < 0) 1221 snd_ctl_new1(&pcxhr_control_capture_iec958,
1222 chip));
1223 if (err < 0)
1025 return err; 1224 return err;
1225
1226 if (mgr->is_hr_stereo) {
1227 err = hr222_add_mic_controls(chip);
1228 if (err < 0)
1229 return err;
1230 }
1026 } 1231 }
1027 /* monitoring only if playback and capture device available */ 1232 /* monitoring only if playback and capture device available */
1028 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) { 1233 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
1029 /* monitoring */ 1234 /* monitoring */
1030 if ((err = snd_ctl_add(chip->card, 1235 err = snd_ctl_add(chip->card,
1031 snd_ctl_new1(&pcxhr_control_monitor_vol, 1236 snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
1032 chip))) < 0) 1237 if (err < 0)
1033 return err; 1238 return err;
1034 if ((err = snd_ctl_add(chip->card, 1239
1035 snd_ctl_new1(&pcxhr_control_monitor_sw, 1240 err = snd_ctl_add(chip->card,
1036 chip))) < 0) 1241 snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
1242 if (err < 0)
1037 return err; 1243 return err;
1038 } 1244 }
1039 1245
1040 if (i == 0) { 1246 if (i == 0) {
1041 /* clock mode only one control per pcxhr */ 1247 /* clock mode only one control per pcxhr */
1042 if ((err = snd_ctl_add(chip->card, 1248 err = snd_ctl_add(chip->card,
1043 snd_ctl_new1(&pcxhr_control_clock_type, 1249 snd_ctl_new1(&pcxhr_control_clock_type, mgr));
1044 mgr))) < 0) 1250 if (err < 0)
1045 return err; 1251 return err;
1046 /* non standard control used to scan the external clock presence/frequencies */ 1252 /* non standard control used to scan
1047 if ((err = snd_ctl_add(chip->card, 1253 * the external clock presence/frequencies
1048 snd_ctl_new1(&pcxhr_control_clock_rate, 1254 */
1049 mgr))) < 0) 1255 err = snd_ctl_add(chip->card,
1256 snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
1257 if (err < 0)
1050 return err; 1258 return err;
1051 } 1259 }
1052 1260
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index e9f0706ed3e4..3caacfb9d8e0 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -172,7 +172,7 @@ MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
172 172
173#define MAX_WRITE_RETRY 10 /* cmd interface limits */ 173#define MAX_WRITE_RETRY 10 /* cmd interface limits */
174#define MAX_ERROR_COUNT 10 174#define MAX_ERROR_COUNT 10
175#define CMDIF_TIMEOUT 500000 175#define CMDIF_TIMEOUT 50000
176#define RESET_TRIES 5 176#define RESET_TRIES 5
177 177
178#define READ_PORT_ULONG(p) inl((unsigned long)&(p)) 178#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
@@ -1754,7 +1754,7 @@ snd_riptide_interrupt(int irq, void *dev_id)
1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) || 1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
1755 IS_EOCIRQ(cif->hwport)) { 1755 IS_EOCIRQ(cif->hwport)) {
1756 chip->handled_irqs++; 1756 chip->handled_irqs++;
1757 tasklet_hi_schedule(&chip->riptide_tq); 1757 tasklet_schedule(&chip->riptide_tq);
1758 } 1758 }
1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) { 1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
1760 chip->handled_irqs++; 1760 chip->handled_irqs++;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index d723543beadd..44d0c15e2b71 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1452,7 +1452,7 @@ static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int i
1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) 1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
1453 return -1; 1453 return -1;
1454 1454
1455 sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1455 sprintf(hdsp->midi[id].rmidi->name, "HDSP MIDI %d", id+1);
1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id]; 1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
1457 1457
1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output); 1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
@@ -3750,7 +3750,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3750 } 3750 }
3751 } 3751 }
3752 if (hdsp->use_midi_tasklet && schedule) 3752 if (hdsp->use_midi_tasklet && schedule)
3753 tasklet_hi_schedule(&hdsp->midi_tasklet); 3753 tasklet_schedule(&hdsp->midi_tasklet);
3754 return IRQ_HANDLED; 3754 return IRQ_HANDLED;
3755} 3755}
3756 3756
@@ -4548,11 +4548,20 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4548{ 4548{
4549 struct hdsp *hdsp = (struct hdsp *)hw->private_data; 4549 struct hdsp *hdsp = (struct hdsp *)hw->private_data;
4550 void __user *argp = (void __user *)arg; 4550 void __user *argp = (void __user *)arg;
4551 int err;
4551 4552
4552 switch (cmd) { 4553 switch (cmd) {
4553 case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: { 4554 case SNDRV_HDSP_IOCTL_GET_PEAK_RMS: {
4554 struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg; 4555 struct hdsp_peak_rms __user *peak_rms = (struct hdsp_peak_rms __user *)arg;
4555 4556
4557 err = hdsp_check_for_iobox(hdsp);
4558 if (err < 0)
4559 return err;
4560
4561 err = hdsp_check_for_firmware(hdsp, 1);
4562 if (err < 0)
4563 return err;
4564
4556 if (!(hdsp->state & HDSP_FirmwareLoaded)) { 4565 if (!(hdsp->state & HDSP_FirmwareLoaded)) {
4557 snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n"); 4566 snd_printk(KERN_ERR "Hammerfall-DSP: firmware needs to be uploaded to the card.\n");
4558 return -EINVAL; 4567 return -EINVAL;
@@ -4572,10 +4581,14 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4572 unsigned long flags; 4581 unsigned long flags;
4573 int i; 4582 int i;
4574 4583
4575 if (!(hdsp->state & HDSP_FirmwareLoaded)) { 4584 err = hdsp_check_for_iobox(hdsp);
4576 snd_printk(KERN_ERR "Hammerfall-DSP: Firmware needs to be uploaded to the card.\n"); 4585 if (err < 0)
4577 return -EINVAL; 4586 return err;
4578 } 4587
4588 err = hdsp_check_for_firmware(hdsp, 1);
4589 if (err < 0)
4590 return err;
4591
4579 spin_lock_irqsave(&hdsp->lock, flags); 4592 spin_lock_irqsave(&hdsp->lock, flags);
4580 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp); 4593 info.pref_sync_ref = (unsigned char)hdsp_pref_sync_ref(hdsp);
4581 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp); 4594 info.wordclock_sync_check = (unsigned char)hdsp_wc_sync_check(hdsp);
@@ -5045,6 +5058,10 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5045 /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */ 5058 /* we wait 2 seconds to let freshly inserted cardbus cards do their hardware init */
5046 ssleep(2); 5059 ssleep(2);
5047 5060
5061 err = hdsp_check_for_iobox(hdsp);
5062 if (err < 0)
5063 return err;
5064
5048 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) { 5065 if ((hdsp_read (hdsp, HDSP_statusRegister) & HDSP_DllError) != 0) {
5049#ifdef HDSP_FW_LOADER 5066#ifdef HDSP_FW_LOADER
5050 if ((err = hdsp_request_fw_loader(hdsp)) < 0) 5067 if ((err = hdsp_request_fw_loader(hdsp)) < 0)
@@ -5057,7 +5074,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5057 /* init is complete, we return */ 5074 /* init is complete, we return */
5058 return 0; 5075 return 0;
5059#endif 5076#endif
5060 /* no iobox connected, we defer initialization */ 5077 /* we defer initialization */
5061 snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n"); 5078 snd_printk(KERN_INFO "Hammerfall-DSP: card initialization pending : waiting for firmware\n");
5062 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0) 5079 if ((err = snd_hdsp_create_hwdep(card, hdsp)) < 0)
5063 return err; 5080 return err;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 98762f909d64..71231cf1b2b0 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1293,7 +1293,7 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1293 if (err < 0) 1293 if (err < 0)
1294 return err; 1294 return err;
1295 1295
1296 sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1296 sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1);
1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; 1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1298 1298
1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
@@ -3476,7 +3476,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3476 schedule = 1; 3476 schedule = 1;
3477 } 3477 }
3478 if (schedule) 3478 if (schedule)
3479 tasklet_hi_schedule(&hdspm->midi_tasklet); 3479 tasklet_schedule(&hdspm->midi_tasklet);
3480 return IRQ_HANDLED; 3480 return IRQ_HANDLED;
3481} 3481}
3482 3482
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
index fa4b11398b1f..ea903c8e90dd 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
@@ -41,7 +41,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev)
41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */ 41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */
42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n"); 42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n");
43 if (chip->pcm_substream) 43 if (chip->pcm_substream)
44 tasklet_hi_schedule(&chip->tq); 44 tasklet_schedule(&chip->tq);
45 if (!(stat & PDAUDIOCF_IRQAKM)) 45 if (!(stat & PDAUDIOCF_IRQAKM))
46 stat |= PDAUDIOCF_IRQAKM; /* check rate */ 46 stat |= PDAUDIOCF_IRQAKM; /* check rate */
47 } 47 }
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a38c0c790d2b..af76ee862d27 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1033,7 +1033,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
1033 } 1033 }
1034 if (of_device_is_compatible(sound, "tumbler")) { 1034 if (of_device_is_compatible(sound, "tumbler")) {
1035 chip->model = PMAC_TUMBLER; 1035 chip->model = PMAC_TUMBLER;
1036 chip->can_capture = 0; /* no capture */ 1036 chip->can_capture = machine_is_compatible("PowerMac4,2");
1037 chip->can_duplex = 0; 1037 chip->can_duplex = 0;
1038 // chip->can_byte_swap = 0; /* FIXME: check this */ 1038 // chip->can_byte_swap = 0; /* FIXME: check this */
1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 20d0e328288a..8f9e3859c37c 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -666,6 +666,7 @@ static int snd_ps3_init_avsetting(struct snd_ps3_card_info *card)
666 card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16; 666 card->avs.avs_audio_width = PS3AV_CMD_AUDIO_WORD_BITS_16;
667 card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM; 667 card->avs.avs_audio_format = PS3AV_CMD_AUDIO_FORMAT_PCM;
668 card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL; 668 card->avs.avs_audio_source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
669 memcpy(card->avs.avs_cs_info, ps3av_mode_cs_info, 8);
669 670
670 ret = snd_ps3_change_avsetting(card); 671 ret = snd_ps3_change_avsetting(card);
671 672
@@ -685,6 +686,7 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
685{ 686{
686 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream); 687 struct snd_ps3_card_info *card = snd_pcm_substream_chip(substream);
687 struct snd_ps3_avsetting_info avs; 688 struct snd_ps3_avsetting_info avs;
689 int ret;
688 690
689 avs = card->avs; 691 avs = card->avs;
690 692
@@ -729,19 +731,92 @@ static int snd_ps3_set_avsetting(struct snd_pcm_substream *substream)
729 return 1; 731 return 1;
730 } 732 }
731 733
732 if ((card->avs.avs_audio_width != avs.avs_audio_width) || 734 memcpy(avs.avs_cs_info, ps3av_mode_cs_info, 8);
733 (card->avs.avs_audio_rate != avs.avs_audio_rate)) {
734 card->avs = avs;
735 snd_ps3_change_avsetting(card);
736 735
736 if (memcmp(&card->avs, &avs, sizeof(avs))) {
737 pr_debug("%s: after freq=%d width=%d\n", __func__, 737 pr_debug("%s: after freq=%d width=%d\n", __func__,
738 card->avs.avs_audio_rate, card->avs.avs_audio_width); 738 card->avs.avs_audio_rate, card->avs.avs_audio_width);
739 739
740 return 0; 740 card->avs = avs;
741 snd_ps3_change_avsetting(card);
742 ret = 0;
741 } else 743 } else
744 ret = 1;
745
746 /* check CS non-audio bit and mute accordingly */
747 if (avs.avs_cs_info[0] & 0x02)
748 ps3av_audio_mute_analog(1); /* mute if non-audio */
749 else
750 ps3av_audio_mute_analog(0);
751
752 return ret;
753}
754
755/*
756 * SPDIF status bits controls
757 */
758static int snd_ps3_spdif_mask_info(struct snd_kcontrol *kcontrol,
759 struct snd_ctl_elem_info *uinfo)
760{
761 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
762 uinfo->count = 1;
763 return 0;
764}
765
766/* FIXME: ps3av_set_audio_mode() assumes only consumer mode */
767static int snd_ps3_spdif_cmask_get(struct snd_kcontrol *kcontrol,
768 struct snd_ctl_elem_value *ucontrol)
769{
770 memset(ucontrol->value.iec958.status, 0xff, 8);
771 return 0;
772}
773
774static int snd_ps3_spdif_pmask_get(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *ucontrol)
776{
777 return 0;
778}
779
780static int snd_ps3_spdif_default_get(struct snd_kcontrol *kcontrol,
781 struct snd_ctl_elem_value *ucontrol)
782{
783 memcpy(ucontrol->value.iec958.status, ps3av_mode_cs_info, 8);
784 return 0;
785}
786
787static int snd_ps3_spdif_default_put(struct snd_kcontrol *kcontrol,
788 struct snd_ctl_elem_value *ucontrol)
789{
790 if (memcmp(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8)) {
791 memcpy(ps3av_mode_cs_info, ucontrol->value.iec958.status, 8);
742 return 1; 792 return 1;
793 }
794 return 0;
743} 795}
744 796
797static struct snd_kcontrol_new spdif_ctls[] = {
798 {
799 .access = SNDRV_CTL_ELEM_ACCESS_READ,
800 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
801 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
802 .info = snd_ps3_spdif_mask_info,
803 .get = snd_ps3_spdif_cmask_get,
804 },
805 {
806 .access = SNDRV_CTL_ELEM_ACCESS_READ,
807 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
808 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
809 .info = snd_ps3_spdif_mask_info,
810 .get = snd_ps3_spdif_pmask_get,
811 },
812 {
813 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
814 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
815 .info = snd_ps3_spdif_mask_info,
816 .get = snd_ps3_spdif_default_get,
817 .put = snd_ps3_spdif_default_put,
818 },
819};
745 820
746 821
747static int snd_ps3_map_mmio(void) 822static int snd_ps3_map_mmio(void)
@@ -842,7 +917,7 @@ static void snd_ps3_audio_set_base_addr(uint64_t ioaddr_start)
842 917
843static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev) 918static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
844{ 919{
845 int ret; 920 int i, ret;
846 u64 lpar_addr, lpar_size; 921 u64 lpar_addr, lpar_size;
847 922
848 BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1)); 923 BUG_ON(!firmware_has_feature(FW_FEATURE_PS3_LV1));
@@ -903,6 +978,15 @@ static int __init snd_ps3_driver_probe(struct ps3_system_bus_device *dev)
903 strcpy(the_card.card->driver, "PS3"); 978 strcpy(the_card.card->driver, "PS3");
904 strcpy(the_card.card->shortname, "PS3"); 979 strcpy(the_card.card->shortname, "PS3");
905 strcpy(the_card.card->longname, "PS3 sound"); 980 strcpy(the_card.card->longname, "PS3 sound");
981
982 /* create control elements */
983 for (i = 0; i < ARRAY_SIZE(spdif_ctls); i++) {
984 ret = snd_ctl_add(the_card.card,
985 snd_ctl_new1(&spdif_ctls[i], &the_card));
986 if (ret < 0)
987 goto clean_card;
988 }
989
906 /* create PCM devices instance */ 990 /* create PCM devices instance */
907 /* NOTE:this driver works assuming pcm:substream = 1:1 */ 991 /* NOTE:this driver works assuming pcm:substream = 1:1 */
908 ret = snd_pcm_new(the_card.card, 992 ret = snd_pcm_new(the_card.card,
diff --git a/sound/ppc/snd_ps3.h b/sound/ppc/snd_ps3.h
index 4b7e6fbbe500..326fb29e82d8 100644
--- a/sound/ppc/snd_ps3.h
+++ b/sound/ppc/snd_ps3.h
@@ -51,6 +51,7 @@ struct snd_ps3_avsetting_info {
51 uint32_t avs_audio_width; 51 uint32_t avs_audio_width;
52 uint32_t avs_audio_format; /* fixed */ 52 uint32_t avs_audio_format; /* fixed */
53 uint32_t avs_audio_source; /* fixed */ 53 uint32_t avs_audio_source; /* fixed */
54 unsigned char avs_cs_info[8];
54}; 55};
55/* 56/*
56 * PS3 audio 'card' instance 57 * PS3 audio 'card' instance
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index f746e15b8481..3eb223385416 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -875,7 +875,8 @@ static struct snd_kcontrol_new snapper_mixers[] __initdata = {
875 .put = tumbler_put_master_switch 875 .put = tumbler_put_master_switch
876 }, 876 },
877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM), 877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),
878 DEFINE_SNAPPER_MIX("PCM Playback Volume", 1, VOL_IDX_PCM2), 878 /* Alternative PCM is assigned to Mic analog loopback on iBook G4 */
879 DEFINE_SNAPPER_MIX("Mic Playback Volume", 0, VOL_IDX_PCM2),
879 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC), 880 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),
880 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass), 881 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
881 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble), 882 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 4dfda6674bec..ef025c66cc66 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -22,17 +22,16 @@ if SND_SOC
22config SND_SOC_AC97_BUS 22config SND_SOC_AC97_BUS
23 bool 23 bool
24 24
25# All the supported Soc's 25# All the supported SoCs
26source "sound/soc/at32/Kconfig" 26source "sound/soc/atmel/Kconfig"
27source "sound/soc/at91/Kconfig"
28source "sound/soc/au1x/Kconfig" 27source "sound/soc/au1x/Kconfig"
28source "sound/soc/blackfin/Kconfig"
29source "sound/soc/davinci/Kconfig"
30source "sound/soc/fsl/Kconfig"
31source "sound/soc/omap/Kconfig"
29source "sound/soc/pxa/Kconfig" 32source "sound/soc/pxa/Kconfig"
30source "sound/soc/s3c24xx/Kconfig" 33source "sound/soc/s3c24xx/Kconfig"
31source "sound/soc/sh/Kconfig" 34source "sound/soc/sh/Kconfig"
32source "sound/soc/fsl/Kconfig"
33source "sound/soc/davinci/Kconfig"
34source "sound/soc/omap/Kconfig"
35source "sound/soc/blackfin/Kconfig"
36 35
37# Supported codecs 36# Supported codecs
38source "sound/soc/codecs/Kconfig" 37source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d849349f2c66..86a9b1f5b0f3 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,13 @@
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/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ 4obj-$(CONFIG_SND_SOC) += codecs/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/ 5obj-$(CONFIG_SND_SOC) += atmel/
6obj-$(CONFIG_SND_SOC) += au1x/
7obj-$(CONFIG_SND_SOC) += blackfin/
8obj-$(CONFIG_SND_SOC) += davinci/
9obj-$(CONFIG_SND_SOC) += fsl/
10obj-$(CONFIG_SND_SOC) += omap/
11obj-$(CONFIG_SND_SOC) += pxa/
12obj-$(CONFIG_SND_SOC) += s3c24xx/
13obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/at32/Kconfig b/sound/soc/at32/Kconfig
deleted file mode 100644
index b0765e86c085..000000000000
--- a/sound/soc/at32/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
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
deleted file mode 100644
index c03e55ececeb..000000000000
--- a/sound/soc/at32/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
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
deleted file mode 100644
index c83584f989a9..000000000000
--- a/sound/soc/at32/at32-pcm.c
+++ /dev/null
@@ -1,492 +0,0 @@
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, ATMEL_PDC_PTCR,
438 params->mask->pdc_disable);
439
440 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
441 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
442 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
443 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
444
445 return 0;
446}
447
448
449
450static int at32_pcm_resume(struct platform_device *pdev,
451 struct snd_soc_dai *dai)
452{
453 struct snd_pcm_runtime *runtime = dai->runtime;
454 struct at32_runtime_data *prtd;
455 struct at32_pcm_dma_params *params;
456
457 if (runtime == NULL)
458 return 0;
459 prtd = runtime->private_data;
460 params = prtd->params;
461
462 /* Restore the PDC registers and enable the PDC */
463 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
464 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
466 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
467
468 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
469 return 0;
470}
471#else /* CONFIG_PM */
472# define at32_pcm_suspend NULL
473# define at32_pcm_resume NULL
474#endif /* CONFIG_PM */
475
476
477
478struct snd_soc_platform at32_soc_platform = {
479 .name = "at32-audio",
480 .pcm_ops = &at32_pcm_ops,
481 .pcm_new = at32_pcm_new,
482 .pcm_free = at32_pcm_free_dma_buffers,
483 .suspend = at32_pcm_suspend,
484 .resume = at32_pcm_resume,
485};
486EXPORT_SYMBOL_GPL(at32_soc_platform);
487
488
489
490MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
491MODULE_DESCRIPTION("Atmel AT32 PCM module");
492MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-pcm.h b/sound/soc/at32/at32-pcm.h
deleted file mode 100644
index 2a52430417da..000000000000
--- a/sound/soc/at32/at32-pcm.h
+++ /dev/null
@@ -1,79 +0,0 @@
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
deleted file mode 100644
index 4ef6492c902e..000000000000
--- a/sound/soc/at32/at32-ssc.c
+++ /dev/null
@@ -1,849 +0,0 @@
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
deleted file mode 100644
index 3c052dbbe460..000000000000
--- a/sound/soc/at32/at32-ssc.h
+++ /dev/null
@@ -1,59 +0,0 @@
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/at91/Kconfig b/sound/soc/at91/Kconfig
deleted file mode 100644
index 905186502e00..000000000000
--- a/sound/soc/at91/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
1config SND_AT91_SOC
2 tristate "SoC Audio for the Atmel AT91 System-on-Chip"
3 depends on ARCH_AT91
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT91 SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_AT91_SOC_SSC
10 tristate
11
12config SND_AT91_SOC_ETI_B1_WM8731
13 tristate "SoC Audio support for WM8731-based Endrelia ETI-B1 boards"
14 depends on SND_AT91_SOC && (MACH_ETI_B1 || MACH_ETI_C1)
15 select SND_AT91_SOC_SSC
16 select SND_SOC_WM8731
17 help
18 Say Y if you want to add support for SoC audio on WM8731-based
19 Endrelia Technologies Inc ETI-B1 or ETI-C1 boards.
20
21config SND_AT91_SOC_ETI_SLAVE
22 bool "Run codec in slave Mode on Endrelia boards"
23 depends on SND_AT91_SOC_ETI_B1_WM8731
24 default n
25 help
26 Say Y if you want to run with the AT91 SSC generating the BCLK
27 and LRC signals on Endrelia boards.
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
deleted file mode 100644
index f23da17cc328..000000000000
--- a/sound/soc/at91/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1# AT91 Platform Support
2snd-soc-at91-objs := at91-pcm.o
3snd-soc-at91-ssc-objs := at91-ssc.o
4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
7
8# AT91 Machine Support
9snd-soc-eti-b1-wm8731-objs := eti_b1_wm8731.o
10
11obj-$(CONFIG_SND_AT91_SOC_ETI_B1_WM8731) += snd-soc-eti-b1-wm8731.o
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
deleted file mode 100644
index 7ab48bd25e4c..000000000000
--- a/sound/soc/at91/at91-pcm.c
+++ /dev/null
@@ -1,434 +0,0 @@
1/*
2 * at91-pcm.c -- ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.c by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: (C) 2004 MontaVista Software, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
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#include <linux/atmel_pdc.h>
25
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_ssc.h>
33
34#include "at91-pcm.h"
35
36#if 0
37#define DBG(x...) printk(KERN_INFO "at91-pcm: " x)
38#else
39#define DBG(x...)
40#endif
41
42static const struct snd_pcm_hardware at91_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_INTERLEAVED |
46 SNDRV_PCM_INFO_PAUSE,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 .period_bytes_min = 32,
49 .period_bytes_max = 8192,
50 .periods_min = 2,
51 .periods_max = 1024,
52 .buffer_bytes_max = 32 * 1024,
53};
54
55struct at91_runtime_data {
56 struct at91_pcm_dma_params *params;
57 dma_addr_t dma_buffer; /* physical address of dma buffer */
58 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
59 size_t period_size;
60 dma_addr_t period_ptr; /* physical address of next period */
61 u32 pdc_xpr_save; /* PDC register save */
62 u32 pdc_xcr_save;
63 u32 pdc_xnpr_save;
64 u32 pdc_xncr_save;
65};
66
67static void at91_pcm_dma_irq(u32 ssc_sr,
68 struct snd_pcm_substream *substream)
69{
70 struct at91_runtime_data *prtd = substream->runtime->private_data;
71 struct at91_pcm_dma_params *params = prtd->params;
72 static int count = 0;
73
74 count++;
75
76 if (ssc_sr & params->mask->ssc_endbuf) {
77
78 printk(KERN_WARNING
79 "at91-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
80 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
81 ? "underrun" : "overrun",
82 params->name, ssc_sr, count);
83
84 /* re-start the PDC */
85 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
86
87 prtd->period_ptr += prtd->period_size;
88 if (prtd->period_ptr >= prtd->dma_buffer_end) {
89 prtd->period_ptr = prtd->dma_buffer;
90 }
91
92 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
93 at91_ssc_write(params->ssc_base + params->pdc->xcr,
94 prtd->period_size / params->pdc_xfer_size);
95
96 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
97 }
98
99 if (ssc_sr & params->mask->ssc_endx) {
100
101 /* Load the PDC next pointer and counter registers */
102 prtd->period_ptr += prtd->period_size;
103 if (prtd->period_ptr >= prtd->dma_buffer_end) {
104 prtd->period_ptr = prtd->dma_buffer;
105 }
106 at91_ssc_write(params->ssc_base + params->pdc->xnpr,
107 prtd->period_ptr);
108 at91_ssc_write(params->ssc_base + params->pdc->xncr,
109 prtd->period_size / params->pdc_xfer_size);
110 }
111
112 snd_pcm_period_elapsed(substream);
113}
114
115static int at91_pcm_hw_params(struct snd_pcm_substream *substream,
116 struct snd_pcm_hw_params *params)
117{
118 struct snd_pcm_runtime *runtime = substream->runtime;
119 struct at91_runtime_data *prtd = runtime->private_data;
120 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121
122 /* this may get called several times by oss emulation
123 * with different params */
124
125 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
126 runtime->dma_bytes = params_buffer_bytes(params);
127
128 prtd->params = rtd->dai->cpu_dai->dma_data;
129 prtd->params->dma_intr_handler = at91_pcm_dma_irq;
130
131 prtd->dma_buffer = runtime->dma_addr;
132 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
133 prtd->period_size = params_period_bytes(params);
134
135 DBG("hw_params: DMA for %s initialized (dma_bytes=%d, period_size=%d)\n",
136 prtd->params->name, runtime->dma_bytes, prtd->period_size);
137 return 0;
138}
139
140static int at91_pcm_hw_free(struct snd_pcm_substream *substream)
141{
142 struct at91_runtime_data *prtd = substream->runtime->private_data;
143 struct at91_pcm_dma_params *params = prtd->params;
144
145 if (params != NULL) {
146 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
147 prtd->params->dma_intr_handler = NULL;
148 }
149
150 return 0;
151}
152
153static int at91_pcm_prepare(struct snd_pcm_substream *substream)
154{
155 struct at91_runtime_data *prtd = substream->runtime->private_data;
156 struct at91_pcm_dma_params *params = prtd->params;
157
158 at91_ssc_write(params->ssc_base + AT91_SSC_IDR,
159 params->mask->ssc_endx | params->mask->ssc_endbuf);
160
161 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
162 return 0;
163}
164
165static int at91_pcm_trigger(struct snd_pcm_substream *substream,
166 int cmd)
167{
168 struct at91_runtime_data *prtd = substream->runtime->private_data;
169 struct at91_pcm_dma_params *params = prtd->params;
170 int ret = 0;
171
172 switch (cmd) {
173 case SNDRV_PCM_TRIGGER_START:
174 prtd->period_ptr = prtd->dma_buffer;
175
176 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
177 at91_ssc_write(params->ssc_base + params->pdc->xcr,
178 prtd->period_size / params->pdc_xfer_size);
179
180 prtd->period_ptr += prtd->period_size;
181 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
182 at91_ssc_write(params->ssc_base + params->pdc->xncr,
183 prtd->period_size / params->pdc_xfer_size);
184
185 DBG("trigger: period_ptr=%lx, xpr=%lx, xcr=%ld, xnpr=%lx, xncr=%ld\n",
186 (unsigned long) prtd->period_ptr,
187 at91_ssc_read(params->ssc_base + params->pdc->xpr),
188 at91_ssc_read(params->ssc_base + params->pdc->xcr),
189 at91_ssc_read(params->ssc_base + params->pdc->xnpr),
190 at91_ssc_read(params->ssc_base + params->pdc->xncr));
191
192 at91_ssc_write(params->ssc_base + AT91_SSC_IER,
193 params->mask->ssc_endx | params->mask->ssc_endbuf);
194
195 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
196 params->mask->pdc_enable);
197
198 DBG("sr=%lx imr=%lx\n",
199 at91_ssc_read(params->ssc_base + AT91_SSC_SR),
200 at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
201 break;
202
203 case SNDRV_PCM_TRIGGER_STOP:
204 case SNDRV_PCM_TRIGGER_SUSPEND:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
207 break;
208
209 case SNDRV_PCM_TRIGGER_RESUME:
210 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
211 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
212 break;
213
214 default:
215 ret = -EINVAL;
216 }
217
218 return ret;
219}
220
221static snd_pcm_uframes_t at91_pcm_pointer(
222 struct snd_pcm_substream *substream)
223{
224 struct snd_pcm_runtime *runtime = substream->runtime;
225 struct at91_runtime_data *prtd = runtime->private_data;
226 struct at91_pcm_dma_params *params = prtd->params;
227 dma_addr_t ptr;
228 snd_pcm_uframes_t x;
229
230 ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr);
231 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
232
233 if (x == runtime->buffer_size)
234 x = 0;
235 return x;
236}
237
238static int at91_pcm_open(struct snd_pcm_substream *substream)
239{
240 struct snd_pcm_runtime *runtime = substream->runtime;
241 struct at91_runtime_data *prtd;
242 int ret = 0;
243
244 snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware);
245
246 /* ensure that buffer size is a multiple of period size */
247 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
248 if (ret < 0)
249 goto out;
250
251 prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL);
252 if (prtd == NULL) {
253 ret = -ENOMEM;
254 goto out;
255 }
256 runtime->private_data = prtd;
257
258 out:
259 return ret;
260}
261
262static int at91_pcm_close(struct snd_pcm_substream *substream)
263{
264 struct at91_runtime_data *prtd = substream->runtime->private_data;
265
266 kfree(prtd);
267 return 0;
268}
269
270static int at91_pcm_mmap(struct snd_pcm_substream *substream,
271 struct vm_area_struct *vma)
272{
273 struct snd_pcm_runtime *runtime = substream->runtime;
274
275 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
276 runtime->dma_area,
277 runtime->dma_addr,
278 runtime->dma_bytes);
279}
280
281struct snd_pcm_ops at91_pcm_ops = {
282 .open = at91_pcm_open,
283 .close = at91_pcm_close,
284 .ioctl = snd_pcm_lib_ioctl,
285 .hw_params = at91_pcm_hw_params,
286 .hw_free = at91_pcm_hw_free,
287 .prepare = at91_pcm_prepare,
288 .trigger = at91_pcm_trigger,
289 .pointer = at91_pcm_pointer,
290 .mmap = at91_pcm_mmap,
291};
292
293static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
294 int stream)
295{
296 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
297 struct snd_dma_buffer *buf = &substream->dma_buffer;
298 size_t size = at91_pcm_hardware.buffer_bytes_max;
299
300 buf->dev.type = SNDRV_DMA_TYPE_DEV;
301 buf->dev.dev = pcm->card->dev;
302 buf->private_data = NULL;
303 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
304 &buf->addr, GFP_KERNEL);
305
306 DBG("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
307 (void *) buf->area,
308 (void *) buf->addr,
309 size);
310
311 if (!buf->area)
312 return -ENOMEM;
313
314 buf->bytes = size;
315 return 0;
316}
317
318static u64 at91_pcm_dmamask = 0xffffffff;
319
320static int at91_pcm_new(struct snd_card *card,
321 struct snd_soc_dai *dai, struct snd_pcm *pcm)
322{
323 int ret = 0;
324
325 if (!card->dev->dma_mask)
326 card->dev->dma_mask = &at91_pcm_dmamask;
327 if (!card->dev->coherent_dma_mask)
328 card->dev->coherent_dma_mask = 0xffffffff;
329
330 if (dai->playback.channels_min) {
331 ret = at91_pcm_preallocate_dma_buffer(pcm,
332 SNDRV_PCM_STREAM_PLAYBACK);
333 if (ret)
334 goto out;
335 }
336
337 if (dai->capture.channels_min) {
338 ret = at91_pcm_preallocate_dma_buffer(pcm,
339 SNDRV_PCM_STREAM_CAPTURE);
340 if (ret)
341 goto out;
342 }
343 out:
344 return ret;
345}
346
347static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm)
348{
349 struct snd_pcm_substream *substream;
350 struct snd_dma_buffer *buf;
351 int stream;
352
353 for (stream = 0; stream < 2; stream++) {
354 substream = pcm->streams[stream].substream;
355 if (!substream)
356 continue;
357
358 buf = &substream->dma_buffer;
359 if (!buf->area)
360 continue;
361
362 dma_free_writecombine(pcm->card->dev, buf->bytes,
363 buf->area, buf->addr);
364 buf->area = NULL;
365 }
366}
367
368#ifdef CONFIG_PM
369static int at91_pcm_suspend(struct platform_device *pdev,
370 struct snd_soc_dai *dai)
371{
372 struct snd_pcm_runtime *runtime = dai->runtime;
373 struct at91_runtime_data *prtd;
374 struct at91_pcm_dma_params *params;
375
376 if (!runtime)
377 return 0;
378
379 prtd = runtime->private_data;
380 params = prtd->params;
381
382 /* disable the PDC and save the PDC registers */
383
384 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
385
386 prtd->pdc_xpr_save = at91_ssc_read(params->ssc_base + params->pdc->xpr);
387 prtd->pdc_xcr_save = at91_ssc_read(params->ssc_base + params->pdc->xcr);
388 prtd->pdc_xnpr_save = at91_ssc_read(params->ssc_base + params->pdc->xnpr);
389 prtd->pdc_xncr_save = at91_ssc_read(params->ssc_base + params->pdc->xncr);
390
391 return 0;
392}
393
394static int at91_pcm_resume(struct platform_device *pdev,
395 struct snd_soc_dai *dai)
396{
397 struct snd_pcm_runtime *runtime = dai->runtime;
398 struct at91_runtime_data *prtd;
399 struct at91_pcm_dma_params *params;
400
401 if (!runtime)
402 return 0;
403
404 prtd = runtime->private_data;
405 params = prtd->params;
406
407 /* restore the PDC registers and enable the PDC */
408 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->pdc_xpr_save);
409 at91_ssc_write(params->ssc_base + params->pdc->xcr, prtd->pdc_xcr_save);
410 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->pdc_xnpr_save);
411 at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->pdc_xncr_save);
412
413 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
414 return 0;
415}
416#else
417#define at91_pcm_suspend NULL
418#define at91_pcm_resume NULL
419#endif
420
421struct snd_soc_platform at91_soc_platform = {
422 .name = "at91-audio",
423 .pcm_ops = &at91_pcm_ops,
424 .pcm_new = at91_pcm_new,
425 .pcm_free = at91_pcm_free_dma_buffers,
426 .suspend = at91_pcm_suspend,
427 .resume = at91_pcm_resume,
428};
429
430EXPORT_SYMBOL_GPL(at91_soc_platform);
431
432MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
433MODULE_DESCRIPTION("Atmel AT91 PCM module");
434MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h
deleted file mode 100644
index e5aada2cb102..000000000000
--- a/sound/soc/at91/at91-pcm.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.h by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: MontaVista Software, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#ifndef _AT91_PCM_H
20#define _AT91_PCM_H
21
22#include <mach/hardware.h>
23
24struct at91_ssc_periph {
25 void __iomem *base;
26 u32 pid;
27};
28
29/*
30 * Registers and status bits that are required by the PCM driver.
31 */
32struct at91_pdc_regs {
33 unsigned int xpr; /* PDC recv/trans pointer */
34 unsigned int xcr; /* PDC recv/trans counter */
35 unsigned int xnpr; /* PDC next recv/trans pointer */
36 unsigned int xncr; /* PDC next recv/trans counter */
37 unsigned int ptcr; /* PDC transfer control */
38};
39
40struct at91_ssc_mask {
41 u32 ssc_enable; /* SSC recv/trans enable */
42 u32 ssc_disable; /* SSC recv/trans disable */
43 u32 ssc_endx; /* SSC ENDTX or ENDRX */
44 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
45 u32 pdc_enable; /* PDC recv/trans enable */
46 u32 pdc_disable; /* PDC recv/trans disable */
47};
48
49/*
50 * This structure, shared between the PCM driver and the interface,
51 * contains all information required by the PCM driver to perform the
52 * PDC DMA operation. All fields except dma_intr_handler() are initialized
53 * by the interface. The dms_intr_handler() pointer is set by the PCM
54 * driver and called by the interface SSC interrupt handler if it is
55 * non-NULL.
56 */
57struct at91_pcm_dma_params {
58 char *name; /* stream identifier */
59 int pdc_xfer_size; /* PDC counter increment in bytes */
60 void __iomem *ssc_base; /* SSC base address */
61 struct at91_pdc_regs *pdc; /* PDC receive or transmit registers */
62 struct at91_ssc_mask *mask;/* SSC & PDC status bits */
63 struct snd_pcm_substream *substream;
64 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
65};
66
67extern struct snd_soc_platform at91_soc_platform;
68
69#define at91_ssc_read(a) ((unsigned long) __raw_readl(a))
70#define at91_ssc_write(a,v) __raw_writel((v),(a))
71
72#endif /* _AT91_PCM_H */
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
deleted file mode 100644
index a5b1a79ebffb..000000000000
--- a/sound/soc/at91/at91-ssc.c
+++ /dev/null
@@ -1,791 +0,0 @@
1/*
2 * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 *
7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
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
13 * option) any later version.
14 *
15 */
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/atmel_pdc.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_pmc.h>
33#include <mach/at91_ssc.h>
34
35#include "at91-pcm.h"
36#include "at91-ssc.h"
37
38#if 0
39#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
40#else
41#define DBG(x...)
42#endif
43
44#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
45#define NUM_SSC_DEVICES 1
46#else
47#define NUM_SSC_DEVICES 3
48#endif
49
50
51/*
52 * SSC PDC registers required by the PCM DMA engine.
53 */
54static struct at91_pdc_regs pdc_tx_reg = {
55 .xpr = ATMEL_PDC_TPR,
56 .xcr = ATMEL_PDC_TCR,
57 .xnpr = ATMEL_PDC_TNPR,
58 .xncr = ATMEL_PDC_TNCR,
59};
60
61static struct at91_pdc_regs pdc_rx_reg = {
62 .xpr = ATMEL_PDC_RPR,
63 .xcr = ATMEL_PDC_RCR,
64 .xnpr = ATMEL_PDC_RNPR,
65 .xncr = ATMEL_PDC_RNCR,
66};
67
68/*
69 * SSC & PDC status bits for transmit and receive.
70 */
71static struct at91_ssc_mask ssc_tx_mask = {
72 .ssc_enable = AT91_SSC_TXEN,
73 .ssc_disable = AT91_SSC_TXDIS,
74 .ssc_endx = AT91_SSC_ENDTX,
75 .ssc_endbuf = AT91_SSC_TXBUFE,
76 .pdc_enable = ATMEL_PDC_TXTEN,
77 .pdc_disable = ATMEL_PDC_TXTDIS,
78};
79
80static struct at91_ssc_mask ssc_rx_mask = {
81 .ssc_enable = AT91_SSC_RXEN,
82 .ssc_disable = AT91_SSC_RXDIS,
83 .ssc_endx = AT91_SSC_ENDRX,
84 .ssc_endbuf = AT91_SSC_RXBUFF,
85 .pdc_enable = ATMEL_PDC_RXTEN,
86 .pdc_disable = ATMEL_PDC_RXTDIS,
87};
88
89
90/*
91 * DMA parameters.
92 */
93static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
94 {{
95 .name = "SSC0 PCM out",
96 .pdc = &pdc_tx_reg,
97 .mask = &ssc_tx_mask,
98 },
99 {
100 .name = "SSC0 PCM in",
101 .pdc = &pdc_rx_reg,
102 .mask = &ssc_rx_mask,
103 }},
104#if NUM_SSC_DEVICES == 3
105 {{
106 .name = "SSC1 PCM out",
107 .pdc = &pdc_tx_reg,
108 .mask = &ssc_tx_mask,
109 },
110 {
111 .name = "SSC1 PCM in",
112 .pdc = &pdc_rx_reg,
113 .mask = &ssc_rx_mask,
114 }},
115 {{
116 .name = "SSC2 PCM out",
117 .pdc = &pdc_tx_reg,
118 .mask = &ssc_tx_mask,
119 },
120 {
121 .name = "SSC2 PCM in",
122 .pdc = &pdc_rx_reg,
123 .mask = &ssc_rx_mask,
124 }},
125#endif
126};
127
128struct at91_ssc_state {
129 u32 ssc_cmr;
130 u32 ssc_rcmr;
131 u32 ssc_rfmr;
132 u32 ssc_tcmr;
133 u32 ssc_tfmr;
134 u32 ssc_sr;
135 u32 ssc_imr;
136};
137
138static struct at91_ssc_info {
139 char *name;
140 struct at91_ssc_periph ssc;
141 spinlock_t lock; /* lock for dir_mask */
142 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
143 unsigned short initialized; /* 1=SSC has been initialized */
144 unsigned short daifmt;
145 unsigned short cmr_div;
146 unsigned short tcmr_period;
147 unsigned short rcmr_period;
148 struct at91_pcm_dma_params *dma_params[2];
149 struct at91_ssc_state ssc_state;
150
151} ssc_info[NUM_SSC_DEVICES] = {
152 {
153 .name = "ssc0",
154 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
155 .dir_mask = 0,
156 .initialized = 0,
157 },
158#if NUM_SSC_DEVICES == 3
159 {
160 .name = "ssc1",
161 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
162 .dir_mask = 0,
163 .initialized = 0,
164 },
165 {
166 .name = "ssc2",
167 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
168 .dir_mask = 0,
169 .initialized = 0,
170 },
171#endif
172};
173
174static unsigned int at91_ssc_sysclk;
175
176/*
177 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver.
179 */
180static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
181{
182 struct at91_ssc_info *ssc_p = dev_id;
183 struct at91_pcm_dma_params *dma_params;
184 u32 ssc_sr;
185 int i;
186
187 ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
188 & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
189
190 /*
191 * Loop through the substreams attached to this SSC. If
192 * a DMA-related interrupt occurred on that substream, call
193 * the DMA interrupt handler function, if one has been
194 * registered in the dma_params structure by the PCM driver.
195 */
196 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
197 dma_params = ssc_p->dma_params[i];
198
199 if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
200 (ssc_sr &
201 (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
202
203 dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
204 }
205
206 return IRQ_HANDLED;
207}
208
209/*
210 * Startup. Only that one substream allowed in each direction.
211 */
212static int at91_ssc_startup(struct snd_pcm_substream *substream)
213{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
216 int dir_mask;
217
218 DBG("ssc_startup: SSC_SR=0x%08lx\n",
219 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
220 dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
221
222 spin_lock_irq(&ssc_p->lock);
223 if (ssc_p->dir_mask & dir_mask) {
224 spin_unlock_irq(&ssc_p->lock);
225 return -EBUSY;
226 }
227 ssc_p->dir_mask |= dir_mask;
228 spin_unlock_irq(&ssc_p->lock);
229
230 return 0;
231}
232
233/*
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open.
236 */
237static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
238{
239 struct snd_soc_pcm_runtime *rtd = substream->private_data;
240 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
241 struct at91_pcm_dma_params *dma_params;
242 int dir, dir_mask;
243
244 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
245 dma_params = ssc_p->dma_params[dir];
246
247 if (dma_params != NULL) {
248 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
249 dma_params->mask->ssc_disable);
250 DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
251 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
252
253 dma_params->ssc_base = NULL;
254 dma_params->substream = NULL;
255 ssc_p->dma_params[dir] = NULL;
256 }
257
258 dir_mask = 1 << dir;
259
260 spin_lock_irq(&ssc_p->lock);
261 ssc_p->dir_mask &= ~dir_mask;
262 if (!ssc_p->dir_mask) {
263 /* Shutdown the SSC clock. */
264 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
265 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
266
267 if (ssc_p->initialized) {
268 free_irq(ssc_p->ssc.pid, ssc_p);
269 ssc_p->initialized = 0;
270 }
271
272 /* Reset the SSC */
273 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
274
275 /* Clear the SSC dividers */
276 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
277 }
278 spin_unlock_irq(&ssc_p->lock);
279}
280
281/*
282 * Record the SSC system clock rate.
283 */
284static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir)
286{
287 /*
288 * The only clock supplied to the SSC is the AT91 master clock,
289 * which is only used if the SSC is generating BCLK and/or
290 * LRC clocks.
291 */
292 switch (clk_id) {
293 case AT91_SYSCLK_MCK:
294 at91_ssc_sysclk = freq;
295 break;
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301}
302
303/*
304 * Record the DAI format for use in hw_params().
305 */
306static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
307 unsigned int fmt)
308{
309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
310
311 ssc_p->daifmt = fmt;
312 return 0;
313}
314
315/*
316 * Record SSC clock dividers for use in hw_params().
317 */
318static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
319 int div_id, int div)
320{
321 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
322
323 switch (div_id) {
324 case AT91SSC_CMR_DIV:
325 /*
326 * The same master clock divider is used for both
327 * transmit and receive, so if a value has already
328 * been set, it must match this value.
329 */
330 if (ssc_p->cmr_div == 0)
331 ssc_p->cmr_div = div;
332 else
333 if (div != ssc_p->cmr_div)
334 return -EBUSY;
335 break;
336
337 case AT91SSC_TCMR_PERIOD:
338 ssc_p->tcmr_period = div;
339 break;
340
341 case AT91SSC_RCMR_PERIOD:
342 ssc_p->rcmr_period = div;
343 break;
344
345 default:
346 return -EINVAL;
347 }
348
349 return 0;
350}
351
352/*
353 * Configure the SSC.
354 */
355static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params)
357{
358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
359 int id = rtd->dai->cpu_dai->id;
360 struct at91_ssc_info *ssc_p = &ssc_info[id];
361 struct at91_pcm_dma_params *dma_params;
362 int dir, channels, bits;
363 u32 tfmr, rfmr, tcmr, rcmr;
364 int start_event;
365 int ret;
366
367 /*
368 * Currently, there is only one set of dma params for
369 * each direction. If more are added, this code will
370 * have to be changed to select the proper set.
371 */
372 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
373
374 dma_params = &ssc_dma_params[id][dir];
375 dma_params->ssc_base = ssc_p->ssc.base;
376 dma_params->substream = substream;
377
378 ssc_p->dma_params[dir] = dma_params;
379
380 /*
381 * The cpu_dai->dma_data field is only used to communicate the
382 * appropriate DMA parameters to the pcm driver hw_params()
383 * function. It should not be used for other purposes
384 * as it is common to all substreams.
385 */
386 rtd->dai->cpu_dai->dma_data = dma_params;
387
388 channels = params_channels(params);
389
390 /*
391 * Determine sample size in bits and the PDC increment.
392 */
393 switch(params_format(params)) {
394 case SNDRV_PCM_FORMAT_S8:
395 bits = 8;
396 dma_params->pdc_xfer_size = 1;
397 break;
398 case SNDRV_PCM_FORMAT_S16_LE:
399 bits = 16;
400 dma_params->pdc_xfer_size = 2;
401 break;
402 case SNDRV_PCM_FORMAT_S24_LE:
403 bits = 24;
404 dma_params->pdc_xfer_size = 4;
405 break;
406 case SNDRV_PCM_FORMAT_S32_LE:
407 bits = 32;
408 dma_params->pdc_xfer_size = 4;
409 break;
410 default:
411 printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
412 return -EINVAL;
413 }
414
415 /*
416 * The SSC only supports up to 16-bit samples in I2S format, due
417 * to the size of the Frame Mode Register FSLEN field.
418 */
419 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
420 && bits > 16) {
421 printk(KERN_WARNING
422 "at91-ssc: sample size %d is too large for I2S\n", bits);
423 return -EINVAL;
424 }
425
426 /*
427 * Compute SSC register settings.
428 */
429 switch (ssc_p->daifmt
430 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
431
432 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
433 /*
434 * I2S format, SSC provides BCLK and LRC clocks.
435 *
436 * The SSC transmit and receive clocks are generated from the
437 * MCK divider, and the BCLK signal is output on the SSC TK line.
438 */
439 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
440 | (( 1 << 16) & AT91_SSC_STTDLY)
441 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
442 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
443 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
444 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
445
446 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
447 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
448 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
449 | (((channels - 1) << 8) & AT91_SSC_DATNB)
450 | (( 1 << 7) & AT91_SSC_MSBF)
451 | (( 0 << 5) & AT91_SSC_LOOP)
452 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
453
454 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
455 | (( 1 << 16) & AT91_SSC_STTDLY)
456 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
457 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
458 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
459 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
460
461 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
462 | (( 0 << 23) & AT91_SSC_FSDEN)
463 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
464 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
465 | (((channels - 1) << 8) & AT91_SSC_DATNB)
466 | (( 1 << 7) & AT91_SSC_MSBF)
467 | (( 0 << 5) & AT91_SSC_DATDEF)
468 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
469 break;
470
471 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
472 /*
473 * I2S format, CODEC supplies BCLK and LRC clocks.
474 *
475 * The SSC transmit clock is obtained from the BCLK signal on
476 * on the TK line, and the SSC receive clock is generated from the
477 * transmit clock.
478 *
479 * For single channel data, one sample is transferred on the falling
480 * edge of the LRC clock. For two channel data, one sample is
481 * transferred on both edges of the LRC clock.
482 */
483 start_event = channels == 1
484 ? AT91_SSC_START_FALLING_RF
485 : AT91_SSC_START_EDGE_RF;
486
487 rcmr = (( 0 << 24) & AT91_SSC_PERIOD)
488 | (( 1 << 16) & AT91_SSC_STTDLY)
489 | (( start_event ) & AT91_SSC_START)
490 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
491 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
492 | (( AT91_SSC_CKS_CLOCK ) & AT91_SSC_CKS);
493
494 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
495 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
496 | (( 0 << 16) & AT91_SSC_FSLEN)
497 | (( 0 << 8) & AT91_SSC_DATNB)
498 | (( 1 << 7) & AT91_SSC_MSBF)
499 | (( 0 << 5) & AT91_SSC_LOOP)
500 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
501
502 tcmr = (( 0 << 24) & AT91_SSC_PERIOD)
503 | (( 1 << 16) & AT91_SSC_STTDLY)
504 | (( start_event ) & AT91_SSC_START)
505 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
506 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
507 | (( AT91_SSC_CKS_PIN ) & AT91_SSC_CKS);
508
509 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
510 | (( 0 << 23) & AT91_SSC_FSDEN)
511 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
512 | (( 0 << 16) & AT91_SSC_FSLEN)
513 | (( 0 << 8) & AT91_SSC_DATNB)
514 | (( 1 << 7) & AT91_SSC_MSBF)
515 | (( 0 << 5) & AT91_SSC_DATDEF)
516 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
517 break;
518
519 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
520 /*
521 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
522 *
523 * The SSC transmit and receive clocks are generated from the
524 * MCK divider, and the BCLK signal is output on the SSC TK line.
525 */
526 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
527 | (( 1 << 16) & AT91_SSC_STTDLY)
528 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
529 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
530 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
531 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
532
533 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
534 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
535 | (( 0 << 16) & AT91_SSC_FSLEN)
536 | (((channels - 1) << 8) & AT91_SSC_DATNB)
537 | (( 1 << 7) & AT91_SSC_MSBF)
538 | (( 0 << 5) & AT91_SSC_LOOP)
539 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
540
541 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
542 | (( 1 << 16) & AT91_SSC_STTDLY)
543 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
544 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
545 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
546 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
547
548 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
549 | (( 0 << 23) & AT91_SSC_FSDEN)
550 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
551 | (( 0 << 16) & AT91_SSC_FSLEN)
552 | (((channels - 1) << 8) & AT91_SSC_DATNB)
553 | (( 1 << 7) & AT91_SSC_MSBF)
554 | (( 0 << 5) & AT91_SSC_DATDEF)
555 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
556
557
558
559 break;
560
561 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
562 default:
563 printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
564 ssc_p->daifmt);
565 return -EINVAL;
566 break;
567 }
568 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
569
570 if (!ssc_p->initialized) {
571
572 /* Enable PMC peripheral clock for this SSC */
573 DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
574 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
575
576 /* Reset the SSC and its PDC registers */
577 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
578
579 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
580 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
581 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
582 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
583 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
584 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
585 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
586 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
587
588 if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
589 0, ssc_p->name, ssc_p)) < 0) {
590 printk(KERN_WARNING "at91-ssc: request_irq failure\n");
591
592 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
593 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
594 return ret;
595 }
596
597 ssc_p->initialized = 1;
598 }
599
600 /* set SSC clock mode register */
601 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
602
603 /* set receive clock mode and format */
604 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
605 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
606
607 /* set transmit clock mode and format */
608 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
609 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
610
611 DBG("hw_params: SSC initialized\n");
612 return 0;
613}
614
615
616static int at91_ssc_prepare(struct snd_pcm_substream *substream)
617{
618 struct snd_soc_pcm_runtime *rtd = substream->private_data;
619 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
620 struct at91_pcm_dma_params *dma_params;
621 int dir;
622
623 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
624 dma_params = ssc_p->dma_params[dir];
625
626 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
627 dma_params->mask->ssc_enable);
628
629 DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
630 at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
631 return 0;
632}
633
634
635#ifdef CONFIG_PM
636static int at91_ssc_suspend(struct platform_device *pdev,
637 struct snd_soc_dai *cpu_dai)
638{
639 struct at91_ssc_info *ssc_p;
640
641 if(!cpu_dai->active)
642 return 0;
643
644 ssc_p = &ssc_info[cpu_dai->id];
645
646 /* Save the status register before disabling transmit and receive. */
647 ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
648 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
649 AT91_SSC_TXDIS | AT91_SSC_RXDIS);
650
651 /* Save the current interrupt mask, then disable unmasked interrupts. */
652 ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
653 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
654
655 ssc_p->ssc_state.ssc_cmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
656 ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
657 ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
658 ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
659 ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
660
661 return 0;
662}
663
664static int at91_ssc_resume(struct platform_device *pdev,
665 struct snd_soc_dai *cpu_dai)
666{
667 struct at91_ssc_info *ssc_p;
668
669 if(!cpu_dai->active)
670 return 0;
671
672 ssc_p = &ssc_info[cpu_dai->id];
673
674 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
675 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
676 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
677 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
678 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->ssc_state.ssc_cmr);
679
680 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr);
681
682 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
683 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
684 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
685
686 return 0;
687}
688
689#else
690#define at91_ssc_suspend NULL
691#define at91_ssc_resume NULL
692#endif
693
694#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
695 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
696 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
697 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
698 SNDRV_PCM_RATE_96000)
699
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)
702
703struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
704 { .name = "at91-ssc0",
705 .id = 0,
706 .type = SND_SOC_DAI_PCM,
707 .suspend = at91_ssc_suspend,
708 .resume = at91_ssc_resume,
709 .playback = {
710 .channels_min = 1,
711 .channels_max = 2,
712 .rates = AT91_SSC_RATES,
713 .formats = AT91_SSC_FORMATS,},
714 .capture = {
715 .channels_min = 1,
716 .channels_max = 2,
717 .rates = AT91_SSC_RATES,
718 .formats = AT91_SSC_FORMATS,},
719 .ops = {
720 .startup = at91_ssc_startup,
721 .shutdown = at91_ssc_shutdown,
722 .prepare = at91_ssc_prepare,
723 .hw_params = at91_ssc_hw_params,},
724 .dai_ops = {
725 .set_sysclk = at91_ssc_set_dai_sysclk,
726 .set_fmt = at91_ssc_set_dai_fmt,
727 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
728 .private_data = &ssc_info[0].ssc,
729 },
730#if NUM_SSC_DEVICES == 3
731 { .name = "at91-ssc1",
732 .id = 1,
733 .type = SND_SOC_DAI_PCM,
734 .suspend = at91_ssc_suspend,
735 .resume = at91_ssc_resume,
736 .playback = {
737 .channels_min = 1,
738 .channels_max = 2,
739 .rates = AT91_SSC_RATES,
740 .formats = AT91_SSC_FORMATS,},
741 .capture = {
742 .channels_min = 1,
743 .channels_max = 2,
744 .rates = AT91_SSC_RATES,
745 .formats = AT91_SSC_FORMATS,},
746 .ops = {
747 .startup = at91_ssc_startup,
748 .shutdown = at91_ssc_shutdown,
749 .prepare = at91_ssc_prepare,
750 .hw_params = at91_ssc_hw_params,},
751 .dai_ops = {
752 .set_sysclk = at91_ssc_set_dai_sysclk,
753 .set_fmt = at91_ssc_set_dai_fmt,
754 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
755 .private_data = &ssc_info[1].ssc,
756 },
757 { .name = "at91-ssc2",
758 .id = 2,
759 .type = SND_SOC_DAI_PCM,
760 .suspend = at91_ssc_suspend,
761 .resume = at91_ssc_resume,
762 .playback = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT91_SSC_RATES,
766 .formats = AT91_SSC_FORMATS,},
767 .capture = {
768 .channels_min = 1,
769 .channels_max = 2,
770 .rates = AT91_SSC_RATES,
771 .formats = AT91_SSC_FORMATS,},
772 .ops = {
773 .startup = at91_ssc_startup,
774 .shutdown = at91_ssc_shutdown,
775 .prepare = at91_ssc_prepare,
776 .hw_params = at91_ssc_hw_params,},
777 .dai_ops = {
778 .set_sysclk = at91_ssc_set_dai_sysclk,
779 .set_fmt = at91_ssc_set_dai_fmt,
780 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
781 .private_data = &ssc_info[2].ssc,
782 },
783#endif
784};
785
786EXPORT_SYMBOL_GPL(at91_ssc_dai);
787
788/* Module information */
789MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
790MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
791MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
deleted file mode 100644
index 6b7bf382d06f..000000000000
--- a/sound/soc/at91/at91-ssc.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Jan 9, 2007
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _AT91_SSC_H
14#define _AT91_SSC_H
15
16/* SSC system clock ids */
17#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
18
19/* SSC divider ids */
20#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */
21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
23
24extern struct snd_soc_dai at91_ssc_dai[];
25
26#endif /* _AT91_SSC_H */
27
diff --git a/sound/soc/at91/eti_b1_wm8731.c b/sound/soc/at91/eti_b1_wm8731.c
deleted file mode 100644
index 684781e4088b..000000000000
--- a/sound/soc/at91/eti_b1_wm8731.c
+++ /dev/null
@@ -1,349 +0,0 @@
1/*
2 * eti_b1_wm8731 -- SoC audio for AT91RM9200-based Endrelia ETI_B1 board.
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 29, 2006
7 *
8 * Based on corgi.c by:
9 *
10 * Copyright 2005 Wolfson Microelectronics PLC.
11 * Copyright 2005 Openedhand Ltd.
12 *
13 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 * Richard Purdie <richard@openedhand.com>
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License as published by the
18 * Free Software Foundation; either version 2 of the License, or (at your
19 * option) any later version.
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/kernel.h>
26#include <linux/clk.h>
27#include <linux/timer.h>
28#include <linux/interrupt.h>
29#include <linux/platform_device.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34
35#include <mach/hardware.h>
36#include <mach/gpio.h>
37
38#include "../codecs/wm8731.h"
39#include "at91-pcm.h"
40#include "at91-ssc.h"
41
42#if 0
43#define DBG(x...) printk(KERN_INFO "eti_b1_wm8731: " x)
44#else
45#define DBG(x...)
46#endif
47
48static struct clk *pck1_clk;
49static struct clk *pllb_clk;
50
51
52static int eti_b1_startup(struct snd_pcm_substream *substream)
53{
54 struct snd_soc_pcm_runtime *rtd = substream->private_data;
55 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
56 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
57 int ret;
58
59 /* cpu clock is the AT91 master clock sent to the SSC */
60 ret = snd_soc_dai_set_sysclk(cpu_dai, AT91_SYSCLK_MCK,
61 60000000, SND_SOC_CLOCK_IN);
62 if (ret < 0)
63 return ret;
64
65 /* codec system clock is supplied by PCK1, set to 12MHz */
66 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
67 12000000, SND_SOC_CLOCK_IN);
68 if (ret < 0)
69 return ret;
70
71 /* Start PCK1 clock. */
72 clk_enable(pck1_clk);
73 DBG("pck1 started\n");
74
75 return 0;
76}
77
78static void eti_b1_shutdown(struct snd_pcm_substream *substream)
79{
80 /* Stop PCK1 clock. */
81 clk_disable(pck1_clk);
82 DBG("pck1 stopped\n");
83}
84
85static int eti_b1_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
90 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
91 int ret;
92
93#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
94 unsigned int rate;
95 int cmr_div, period;
96
97 /* set codec DAI configuration */
98 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
99 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
100 if (ret < 0)
101 return ret;
102
103 /* set cpu DAI configuration */
104 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
105 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
106 if (ret < 0)
107 return ret;
108
109 /*
110 * The SSC clock dividers depend on the sample rate. The CMR.DIV
111 * field divides the system master clock MCK to drive the SSC TK
112 * signal which provides the codec BCLK. The TCMR.PERIOD and
113 * RCMR.PERIOD fields further divide the BCLK signal to drive
114 * the SSC TF and RF signals which provide the codec DACLRC and
115 * ADCLRC clocks.
116 *
117 * The dividers were determined through trial and error, where a
118 * CMR.DIV value is chosen such that the resulting BCLK value is
119 * divisible, or almost divisible, by (2 * sample rate), and then
120 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
121 */
122 rate = params_rate(params);
123
124 switch (rate) {
125 case 8000:
126 cmr_div = 25; /* BCLK = 60MHz/(2*25) = 1.2MHz */
127 period = 74; /* LRC = BCLK/(2*(74+1)) = 8000Hz */
128 break;
129 case 32000:
130 cmr_div = 7; /* BCLK = 60MHz/(2*7) ~= 4.28571428MHz */
131 period = 66; /* LRC = BCLK/(2*(66+1)) = 31982.942Hz */
132 break;
133 case 48000:
134 cmr_div = 13; /* BCLK = 60MHz/(2*13) ~= 2.3076923MHz */
135 period = 23; /* LRC = BCLK/(2*(23+1)) = 48076.923Hz */
136 break;
137 default:
138 printk(KERN_WARNING "unsupported rate %d on ETI-B1 board\n", rate);
139 return -EINVAL;
140 }
141
142 /* set the MCK divider for BCLK */
143 ret = snd_soc_dai_set_clkdiv(cpu_dai, AT91SSC_CMR_DIV, cmr_div);
144 if (ret < 0)
145 return ret;
146
147 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
148 /* set the BCLK divider for DACLRC */
149 ret = snd_soc_dai_set_clkdiv(cpu_dai,
150 AT91SSC_TCMR_PERIOD, period);
151 } else {
152 /* set the BCLK divider for ADCLRC */
153 ret = snd_soc_dai_set_clkdiv(cpu_dai,
154 AT91SSC_RCMR_PERIOD, period);
155 }
156 if (ret < 0)
157 return ret;
158
159#else /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
160 /*
161 * Codec in Master Mode.
162 */
163
164 /* set codec DAI configuration */
165 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
166 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
167 if (ret < 0)
168 return ret;
169
170 /* set cpu DAI configuration */
171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176#endif /* CONFIG_SND_AT91_SOC_ETI_SLAVE */
177
178 return 0;
179}
180
181static struct snd_soc_ops eti_b1_ops = {
182 .startup = eti_b1_startup,
183 .hw_params = eti_b1_hw_params,
184 .shutdown = eti_b1_shutdown,
185};
186
187
188static const struct snd_soc_dapm_widget eti_b1_dapm_widgets[] = {
189 SND_SOC_DAPM_MIC("Int Mic", NULL),
190 SND_SOC_DAPM_SPK("Ext Spk", NULL),
191};
192
193static const struct snd_soc_dapm_route intercon[] = {
194
195 /* speaker connected to LHPOUT */
196 {"Ext Spk", NULL, "LHPOUT"},
197
198 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
199 {"MICIN", NULL, "Mic Bias"},
200 {"Mic Bias", NULL, "Int Mic"},
201};
202
203/*
204 * Logic for a wm8731 as connected on a Endrelia ETI-B1 board.
205 */
206static int eti_b1_wm8731_init(struct snd_soc_codec *codec)
207{
208 DBG("eti_b1_wm8731_init() called\n");
209
210 /* Add specific widgets */
211 snd_soc_dapm_new_controls(codec, eti_b1_dapm_widgets,
212 ARRAY_SIZE(eti_b1_dapm_widgets));
213
214 /* Set up specific audio path interconnects */
215 snd_soc_dapm_add_route(codec, intercon, ARRAY_SIZE(intercon));
216
217 /* not connected */
218 snd_soc_dapm_disable_pin(codec, "RLINEIN");
219 snd_soc_dapm_disable_pin(codec, "LLINEIN");
220
221 /* always connected */
222 snd_soc_dapm_enable_pin(codec, "Int Mic");
223 snd_soc_dapm_enable_pin(codec, "Ext Spk");
224
225 snd_soc_dapm_sync(codec);
226
227 return 0;
228}
229
230static struct snd_soc_dai_link eti_b1_dai = {
231 .name = "WM8731",
232 .stream_name = "WM8731 PCM",
233 .cpu_dai = &at91_ssc_dai[1],
234 .codec_dai = &wm8731_dai,
235 .init = eti_b1_wm8731_init,
236 .ops = &eti_b1_ops,
237};
238
239static struct snd_soc_machine snd_soc_machine_eti_b1 = {
240 .name = "ETI_B1_WM8731",
241 .dai_link = &eti_b1_dai,
242 .num_links = 1,
243};
244
245static struct wm8731_setup_data eti_b1_wm8731_setup = {
246 .i2c_bus = 0,
247 .i2c_address = 0x1a,
248};
249
250static struct snd_soc_device eti_b1_snd_devdata = {
251 .machine = &snd_soc_machine_eti_b1,
252 .platform = &at91_soc_platform,
253 .codec_dev = &soc_codec_dev_wm8731,
254 .codec_data = &eti_b1_wm8731_setup,
255};
256
257static struct platform_device *eti_b1_snd_device;
258
259static int __init eti_b1_init(void)
260{
261 int ret;
262 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
263
264 if (!request_mem_region(AT91RM9200_BASE_SSC1, SZ_16K, "soc-audio")) {
265 DBG("SSC1 memory region is busy\n");
266 return -EBUSY;
267 }
268
269 ssc->base = ioremap(AT91RM9200_BASE_SSC1, SZ_16K);
270 if (!ssc->base) {
271 DBG("SSC1 memory ioremap failed\n");
272 ret = -ENOMEM;
273 goto fail_release_mem;
274 }
275
276 ssc->pid = AT91RM9200_ID_SSC1;
277
278 eti_b1_snd_device = platform_device_alloc("soc-audio", -1);
279 if (!eti_b1_snd_device) {
280 DBG("platform device allocation failed\n");
281 ret = -ENOMEM;
282 goto fail_io_unmap;
283 }
284
285 platform_set_drvdata(eti_b1_snd_device, &eti_b1_snd_devdata);
286 eti_b1_snd_devdata.dev = &eti_b1_snd_device->dev;
287
288 ret = platform_device_add(eti_b1_snd_device);
289 if (ret) {
290 DBG("platform device add failed\n");
291 platform_device_put(eti_b1_snd_device);
292 goto fail_io_unmap;
293 }
294
295 at91_set_A_periph(AT91_PIN_PB6, 0); /* TF1 */
296 at91_set_A_periph(AT91_PIN_PB7, 0); /* TK1 */
297 at91_set_A_periph(AT91_PIN_PB8, 0); /* TD1 */
298 at91_set_A_periph(AT91_PIN_PB9, 0); /* RD1 */
299/* at91_set_A_periph(AT91_PIN_PB10, 0);*/ /* RK1 */
300 at91_set_A_periph(AT91_PIN_PB11, 0); /* RF1 */
301
302 /*
303 * Set PCK1 parent to PLLB and its rate to 12 Mhz.
304 */
305 pllb_clk = clk_get(NULL, "pllb");
306 pck1_clk = clk_get(NULL, "pck1");
307
308 clk_set_parent(pck1_clk, pllb_clk);
309 clk_set_rate(pck1_clk, 12000000);
310
311 DBG("MCLK rate %luHz\n", clk_get_rate(pck1_clk));
312
313 /* assign the GPIO pin to PCK1 */
314 at91_set_B_periph(AT91_PIN_PA24, 0);
315
316#ifdef CONFIG_SND_AT91_SOC_ETI_SLAVE
317 printk(KERN_INFO "eti_b1_wm8731: Codec in Slave Mode\n");
318#else
319 printk(KERN_INFO "eti_b1_wm8731: Codec in Master Mode\n");
320#endif
321 return ret;
322
323fail_io_unmap:
324 iounmap(ssc->base);
325fail_release_mem:
326 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
327 return ret;
328}
329
330static void __exit eti_b1_exit(void)
331{
332 struct at91_ssc_periph *ssc = eti_b1_dai.cpu_dai->private_data;
333
334 clk_put(pck1_clk);
335 clk_put(pllb_clk);
336
337 platform_device_unregister(eti_b1_snd_device);
338
339 iounmap(ssc->base);
340 release_mem_region(AT91RM9200_BASE_SSC1, SZ_16K);
341}
342
343module_init(eti_b1_init);
344module_exit(eti_b1_exit);
345
346/* Module information */
347MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
348MODULE_DESCRIPTION("ALSA SoC ETI-B1-WM8731");
349MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
new file mode 100644
index 000000000000..a608d7009dbd
--- /dev/null
+++ b/sound/soc/atmel/Kconfig
@@ -0,0 +1,43 @@
1config SND_ATMEL_SOC
2 tristate "SoC Audio for the Atmel System-on-Chip"
3 depends on ARCH_AT91 || AVR32
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the ATMEL SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_ATMEL_SOC_SSC
10 tristate
11 depends on SND_ATMEL_SOC
12 help
13 Say Y or M if you want to add support for codecs the
14 ATMEL SSC interface. You will also needs to select the individual
15 machine drivers to support below.
16
17config SND_AT91_SOC_SAM9G20_WM8731
18 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
19 depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
20 select SND_ATMEL_SOC_SSC
21 select SND_SOC_WM8731
22 help
23 Say Y if you want to add support for SoC audio on WM8731-based
24 AT91sam9g20 evaluation board.
25
26config SND_AT32_SOC_PLAYPAQ
27 tristate "SoC Audio support for PlayPaq with WM8510"
28 depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
29 select SND_ATMEL_SOC_SSC
30 select SND_SOC_WM8510
31 help
32 Say Y or M here if you want to add support for SoC audio
33 on the LRS PlayPaq.
34
35config SND_AT32_SOC_PLAYPAQ_SLAVE
36 bool "Run CODEC on PlayPaq in slave mode"
37 depends on SND_AT32_SOC_PLAYPAQ
38 default n
39 help
40 Say Y if you want to run with the AT32 SSC generating the BCLK
41 and FRAME signals on the PlayPaq. Unless you want to play
42 with the AT32 as the SSC master, you probably want to say N here,
43 as this will give you better sound quality.
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
new file mode 100644
index 000000000000..f54a7cc68e66
--- /dev/null
+++ b/sound/soc/atmel/Makefile
@@ -0,0 +1,15 @@
1# AT91 Platform Support
2snd-soc-atmel-pcm-objs := atmel-pcm.o
3snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
4
5obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
6obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
7
8# AT91 Machine Support
9snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
10
11# AT32 Machine Support
12snd-soc-playpaq-objs := playpaq_wm8510.o
13
14obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
15obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
new file mode 100644
index 000000000000..1fac5efd285b
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -0,0 +1,494 @@
1/*
2 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38#include <linux/dma-mapping.h>
39#include <linux/atmel_pdc.h>
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46
47#include <mach/hardware.h>
48
49#include "atmel-pcm.h"
50
51
52/*--------------------------------------------------------------------------*\
53 * Hardware definition
54\*--------------------------------------------------------------------------*/
55/* TODO: These values were taken from the AT91 platform driver, check
56 * them against real values for AT32
57 */
58static const struct snd_pcm_hardware atmel_pcm_hardware = {
59 .info = SNDRV_PCM_INFO_MMAP |
60 SNDRV_PCM_INFO_MMAP_VALID |
61 SNDRV_PCM_INFO_INTERLEAVED |
62 SNDRV_PCM_INFO_PAUSE,
63 .formats = SNDRV_PCM_FMTBIT_S16_LE,
64 .period_bytes_min = 32,
65 .period_bytes_max = 8192,
66 .periods_min = 2,
67 .periods_max = 1024,
68 .buffer_bytes_max = 32 * 1024,
69};
70
71
72/*--------------------------------------------------------------------------*\
73 * Data types
74\*--------------------------------------------------------------------------*/
75struct atmel_runtime_data {
76 struct atmel_pcm_dma_params *params;
77 dma_addr_t dma_buffer; /* physical address of dma buffer */
78 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
79 size_t period_size;
80
81 dma_addr_t period_ptr; /* physical address of next period */
82 int periods; /* period index of period_ptr */
83
84 /* PDC register save */
85 u32 pdc_xpr_save;
86 u32 pdc_xcr_save;
87 u32 pdc_xnpr_save;
88 u32 pdc_xncr_save;
89};
90
91
92/*--------------------------------------------------------------------------*\
93 * Helper functions
94\*--------------------------------------------------------------------------*/
95static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
96 int stream)
97{
98 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
99 struct snd_dma_buffer *buf = &substream->dma_buffer;
100 size_t size = atmel_pcm_hardware.buffer_bytes_max;
101
102 buf->dev.type = SNDRV_DMA_TYPE_DEV;
103 buf->dev.dev = pcm->card->dev;
104 buf->private_data = NULL;
105 buf->area = dma_alloc_coherent(pcm->card->dev, size,
106 &buf->addr, GFP_KERNEL);
107 pr_debug("atmel-pcm:"
108 "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
109 (void *) buf->area,
110 (void *) buf->addr,
111 size);
112
113 if (!buf->area)
114 return -ENOMEM;
115
116 buf->bytes = size;
117 return 0;
118}
119/*--------------------------------------------------------------------------*\
120 * ISR
121\*--------------------------------------------------------------------------*/
122static void atmel_pcm_dma_irq(u32 ssc_sr,
123 struct snd_pcm_substream *substream)
124{
125 struct atmel_runtime_data *prtd = substream->runtime->private_data;
126 struct atmel_pcm_dma_params *params = prtd->params;
127 static int count;
128
129 count++;
130
131 if (ssc_sr & params->mask->ssc_endbuf) {
132 pr_warning("atmel-pcm: buffer %s on %s"
133 " (SSC_SR=%#x, count=%d)\n",
134 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
135 ? "underrun" : "overrun",
136 params->name, ssc_sr, count);
137
138 /* re-start the PDC */
139 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
140 params->mask->pdc_disable);
141 prtd->period_ptr += prtd->period_size;
142 if (prtd->period_ptr >= prtd->dma_buffer_end)
143 prtd->period_ptr = prtd->dma_buffer;
144
145 ssc_writex(params->ssc->regs, params->pdc->xpr,
146 prtd->period_ptr);
147 ssc_writex(params->ssc->regs, params->pdc->xcr,
148 prtd->period_size / params->pdc_xfer_size);
149 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
150 params->mask->pdc_enable);
151 }
152
153 if (ssc_sr & params->mask->ssc_endx) {
154 /* Load the PDC next pointer and counter registers */
155 prtd->period_ptr += prtd->period_size;
156 if (prtd->period_ptr >= prtd->dma_buffer_end)
157 prtd->period_ptr = prtd->dma_buffer;
158
159 ssc_writex(params->ssc->regs, params->pdc->xnpr,
160 prtd->period_ptr);
161 ssc_writex(params->ssc->regs, params->pdc->xncr,
162 prtd->period_size / params->pdc_xfer_size);
163 }
164
165 snd_pcm_period_elapsed(substream);
166}
167
168
169/*--------------------------------------------------------------------------*\
170 * PCM operations
171\*--------------------------------------------------------------------------*/
172static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
173 struct snd_pcm_hw_params *params)
174{
175 struct snd_pcm_runtime *runtime = substream->runtime;
176 struct atmel_runtime_data *prtd = runtime->private_data;
177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178
179 /* this may get called several times by oss emulation
180 * with different params */
181
182 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
183 runtime->dma_bytes = params_buffer_bytes(params);
184
185 prtd->params = rtd->dai->cpu_dai->dma_data;
186 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
187
188 prtd->dma_buffer = runtime->dma_addr;
189 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
190 prtd->period_size = params_period_bytes(params);
191
192 pr_debug("atmel-pcm: "
193 "hw_params: DMA for %s initialized "
194 "(dma_bytes=%u, period_size=%u)\n",
195 prtd->params->name,
196 runtime->dma_bytes,
197 prtd->period_size);
198 return 0;
199}
200
201static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
202{
203 struct atmel_runtime_data *prtd = substream->runtime->private_data;
204 struct atmel_pcm_dma_params *params = prtd->params;
205
206 if (params != NULL) {
207 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
208 params->mask->pdc_disable);
209 prtd->params->dma_intr_handler = NULL;
210 }
211
212 return 0;
213}
214
215static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
216{
217 struct atmel_runtime_data *prtd = substream->runtime->private_data;
218 struct atmel_pcm_dma_params *params = prtd->params;
219
220 ssc_writex(params->ssc->regs, SSC_IDR,
221 params->mask->ssc_endx | params->mask->ssc_endbuf);
222 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
223 params->mask->pdc_disable);
224 return 0;
225}
226
227static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
228 int cmd)
229{
230 struct snd_pcm_runtime *rtd = substream->runtime;
231 struct atmel_runtime_data *prtd = rtd->private_data;
232 struct atmel_pcm_dma_params *params = prtd->params;
233 int ret = 0;
234
235 pr_debug("atmel-pcm:buffer_size = %ld,"
236 "dma_area = %p, dma_bytes = %u\n",
237 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
238
239 switch (cmd) {
240 case SNDRV_PCM_TRIGGER_START:
241 prtd->period_ptr = prtd->dma_buffer;
242
243 ssc_writex(params->ssc->regs, params->pdc->xpr,
244 prtd->period_ptr);
245 ssc_writex(params->ssc->regs, params->pdc->xcr,
246 prtd->period_size / params->pdc_xfer_size);
247
248 prtd->period_ptr += prtd->period_size;
249 ssc_writex(params->ssc->regs, params->pdc->xnpr,
250 prtd->period_ptr);
251 ssc_writex(params->ssc->regs, params->pdc->xncr,
252 prtd->period_size / params->pdc_xfer_size);
253
254 pr_debug("atmel-pcm: trigger: "
255 "period_ptr=%lx, xpr=%u, "
256 "xcr=%u, xnpr=%u, xncr=%u\n",
257 (unsigned long)prtd->period_ptr,
258 ssc_readx(params->ssc->regs, params->pdc->xpr),
259 ssc_readx(params->ssc->regs, params->pdc->xcr),
260 ssc_readx(params->ssc->regs, params->pdc->xnpr),
261 ssc_readx(params->ssc->regs, params->pdc->xncr));
262
263 ssc_writex(params->ssc->regs, SSC_IER,
264 params->mask->ssc_endx | params->mask->ssc_endbuf);
265 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
266 params->mask->pdc_enable);
267
268 pr_debug("sr=%u imr=%u\n",
269 ssc_readx(params->ssc->regs, SSC_SR),
270 ssc_readx(params->ssc->regs, SSC_IER));
271 break; /* SNDRV_PCM_TRIGGER_START */
272
273 case SNDRV_PCM_TRIGGER_STOP:
274 case SNDRV_PCM_TRIGGER_SUSPEND:
275 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
276 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
277 params->mask->pdc_disable);
278 break;
279
280 case SNDRV_PCM_TRIGGER_RESUME:
281 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
282 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
283 params->mask->pdc_enable);
284 break;
285
286 default:
287 ret = -EINVAL;
288 }
289
290 return ret;
291}
292
293static snd_pcm_uframes_t atmel_pcm_pointer(
294 struct snd_pcm_substream *substream)
295{
296 struct snd_pcm_runtime *runtime = substream->runtime;
297 struct atmel_runtime_data *prtd = runtime->private_data;
298 struct atmel_pcm_dma_params *params = prtd->params;
299 dma_addr_t ptr;
300 snd_pcm_uframes_t x;
301
302 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
303 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
304
305 if (x == runtime->buffer_size)
306 x = 0;
307
308 return x;
309}
310
311static int atmel_pcm_open(struct snd_pcm_substream *substream)
312{
313 struct snd_pcm_runtime *runtime = substream->runtime;
314 struct atmel_runtime_data *prtd;
315 int ret = 0;
316
317 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
318
319 /* ensure that buffer size is a multiple of period size */
320 ret = snd_pcm_hw_constraint_integer(runtime,
321 SNDRV_PCM_HW_PARAM_PERIODS);
322 if (ret < 0)
323 goto out;
324
325 prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
326 if (prtd == NULL) {
327 ret = -ENOMEM;
328 goto out;
329 }
330 runtime->private_data = prtd;
331
332 out:
333 return ret;
334}
335
336static int atmel_pcm_close(struct snd_pcm_substream *substream)
337{
338 struct atmel_runtime_data *prtd = substream->runtime->private_data;
339
340 kfree(prtd);
341 return 0;
342}
343
344static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
345 struct vm_area_struct *vma)
346{
347 return remap_pfn_range(vma, vma->vm_start,
348 substream->dma_buffer.addr >> PAGE_SHIFT,
349 vma->vm_end - vma->vm_start, vma->vm_page_prot);
350}
351
352struct snd_pcm_ops atmel_pcm_ops = {
353 .open = atmel_pcm_open,
354 .close = atmel_pcm_close,
355 .ioctl = snd_pcm_lib_ioctl,
356 .hw_params = atmel_pcm_hw_params,
357 .hw_free = atmel_pcm_hw_free,
358 .prepare = atmel_pcm_prepare,
359 .trigger = atmel_pcm_trigger,
360 .pointer = atmel_pcm_pointer,
361 .mmap = atmel_pcm_mmap,
362};
363
364
365/*--------------------------------------------------------------------------*\
366 * ASoC platform driver
367\*--------------------------------------------------------------------------*/
368static u64 atmel_pcm_dmamask = 0xffffffff;
369
370static int atmel_pcm_new(struct snd_card *card,
371 struct snd_soc_dai *dai, struct snd_pcm *pcm)
372{
373 int ret = 0;
374
375 if (!card->dev->dma_mask)
376 card->dev->dma_mask = &atmel_pcm_dmamask;
377 if (!card->dev->coherent_dma_mask)
378 card->dev->coherent_dma_mask = 0xffffffff;
379
380 if (dai->playback.channels_min) {
381 ret = atmel_pcm_preallocate_dma_buffer(pcm,
382 SNDRV_PCM_STREAM_PLAYBACK);
383 if (ret)
384 goto out;
385 }
386
387 if (dai->capture.channels_min) {
388 pr_debug("at32-pcm:"
389 "Allocating PCM capture DMA buffer\n");
390 ret = atmel_pcm_preallocate_dma_buffer(pcm,
391 SNDRV_PCM_STREAM_CAPTURE);
392 if (ret)
393 goto out;
394 }
395 out:
396 return ret;
397}
398
399static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
400{
401 struct snd_pcm_substream *substream;
402 struct snd_dma_buffer *buf;
403 int stream;
404
405 for (stream = 0; stream < 2; stream++) {
406 substream = pcm->streams[stream].substream;
407 if (!substream)
408 continue;
409
410 buf = &substream->dma_buffer;
411 if (!buf->area)
412 continue;
413 dma_free_coherent(pcm->card->dev, buf->bytes,
414 buf->area, buf->addr);
415 buf->area = NULL;
416 }
417}
418
419#ifdef CONFIG_PM
420static int atmel_pcm_suspend(struct snd_soc_dai *dai)
421{
422 struct snd_pcm_runtime *runtime = dai->runtime;
423 struct atmel_runtime_data *prtd;
424 struct atmel_pcm_dma_params *params;
425
426 if (!runtime)
427 return 0;
428
429 prtd = runtime->private_data;
430 params = prtd->params;
431
432 /* disable the PDC and save the PDC registers */
433
434 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
435
436 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
437 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
438 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
439 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
440
441 return 0;
442}
443
444static int atmel_pcm_resume(struct snd_soc_dai *dai)
445{
446 struct snd_pcm_runtime *runtime = dai->runtime;
447 struct atmel_runtime_data *prtd;
448 struct atmel_pcm_dma_params *params;
449
450 if (!runtime)
451 return 0;
452
453 prtd = runtime->private_data;
454 params = prtd->params;
455
456 /* restore the PDC registers and enable the PDC */
457 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
458 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
459 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
460 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
461
462 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
463 return 0;
464}
465#else
466#define atmel_pcm_suspend NULL
467#define atmel_pcm_resume NULL
468#endif
469
470struct snd_soc_platform atmel_soc_platform = {
471 .name = "atmel-audio",
472 .pcm_ops = &atmel_pcm_ops,
473 .pcm_new = atmel_pcm_new,
474 .pcm_free = atmel_pcm_free_dma_buffers,
475 .suspend = atmel_pcm_suspend,
476 .resume = atmel_pcm_resume,
477};
478EXPORT_SYMBOL_GPL(atmel_soc_platform);
479
480static int __init atmel_pcm_modinit(void)
481{
482 return snd_soc_register_platform(&atmel_soc_platform);
483}
484module_init(atmel_pcm_modinit);
485
486static void __exit atmel_pcm_modexit(void)
487{
488 snd_soc_unregister_platform(&atmel_soc_platform);
489}
490module_exit(atmel_pcm_modexit);
491
492MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
493MODULE_DESCRIPTION("Atmel PCM module");
494MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
new file mode 100644
index 000000000000..ec9b2824b663
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -0,0 +1,86 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#ifndef _ATMEL_PCM_H
35#define _ATMEL_PCM_H
36
37#include <linux/atmel-ssc.h>
38
39/*
40 * Registers and status bits that are required by the PCM driver.
41 */
42struct atmel_pdc_regs {
43 unsigned int xpr; /* PDC recv/trans pointer */
44 unsigned int xcr; /* PDC recv/trans counter */
45 unsigned int xnpr; /* PDC next recv/trans pointer */
46 unsigned int xncr; /* PDC next recv/trans counter */
47 unsigned int ptcr; /* PDC transfer control */
48};
49
50struct atmel_ssc_mask {
51 u32 ssc_enable; /* SSC recv/trans enable */
52 u32 ssc_disable; /* SSC recv/trans disable */
53 u32 ssc_endx; /* SSC ENDTX or ENDRX */
54 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
55 u32 pdc_enable; /* PDC recv/trans enable */
56 u32 pdc_disable; /* PDC recv/trans disable */
57};
58
59/*
60 * This structure, shared between the PCM driver and the interface,
61 * contains all information required by the PCM driver to perform the
62 * PDC DMA operation. All fields except dma_intr_handler() are initialized
63 * by the interface. The dms_intr_handler() pointer is set by the PCM
64 * driver and called by the interface SSC interrupt handler if it is
65 * non-NULL.
66 */
67struct atmel_pcm_dma_params {
68 char *name; /* stream identifier */
69 int pdc_xfer_size; /* PDC counter increment in bytes */
70 struct ssc_device *ssc; /* SSC device for stream */
71 struct atmel_pdc_regs *pdc; /* PDC receive or transmit registers */
72 struct atmel_ssc_mask *mask; /* SSC & PDC status bits */
73 struct snd_pcm_substream *substream;
74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
75};
76
77extern struct snd_soc_platform atmel_soc_platform;
78
79
80/*
81 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
82 */
83#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
85
86#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
new file mode 100644
index 000000000000..c5d67900d666
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -0,0 +1,790 @@
1/*
2 * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/interrupt.h>
33#include <linux/device.h>
34#include <linux/delay.h>
35#include <linux/clk.h>
36#include <linux/atmel_pdc.h>
37
38#include <linux/atmel-ssc.h>
39#include <sound/core.h>
40#include <sound/pcm.h>
41#include <sound/pcm_params.h>
42#include <sound/initval.h>
43#include <sound/soc.h>
44
45#include <mach/hardware.h>
46
47#include "atmel-pcm.h"
48#include "atmel_ssc_dai.h"
49
50
51#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
52#define NUM_SSC_DEVICES 1
53#else
54#define NUM_SSC_DEVICES 3
55#endif
56
57/*
58 * SSC PDC registers required by the PCM DMA engine.
59 */
60static struct atmel_pdc_regs pdc_tx_reg = {
61 .xpr = ATMEL_PDC_TPR,
62 .xcr = ATMEL_PDC_TCR,
63 .xnpr = ATMEL_PDC_TNPR,
64 .xncr = ATMEL_PDC_TNCR,
65};
66
67static struct atmel_pdc_regs pdc_rx_reg = {
68 .xpr = ATMEL_PDC_RPR,
69 .xcr = ATMEL_PDC_RCR,
70 .xnpr = ATMEL_PDC_RNPR,
71 .xncr = ATMEL_PDC_RNCR,
72};
73
74/*
75 * SSC & PDC status bits for transmit and receive.
76 */
77static struct atmel_ssc_mask ssc_tx_mask = {
78 .ssc_enable = SSC_BIT(CR_TXEN),
79 .ssc_disable = SSC_BIT(CR_TXDIS),
80 .ssc_endx = SSC_BIT(SR_ENDTX),
81 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
82 .pdc_enable = ATMEL_PDC_TXTEN,
83 .pdc_disable = ATMEL_PDC_TXTDIS,
84};
85
86static struct atmel_ssc_mask ssc_rx_mask = {
87 .ssc_enable = SSC_BIT(CR_RXEN),
88 .ssc_disable = SSC_BIT(CR_RXDIS),
89 .ssc_endx = SSC_BIT(SR_ENDRX),
90 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
91 .pdc_enable = ATMEL_PDC_RXTEN,
92 .pdc_disable = ATMEL_PDC_RXTDIS,
93};
94
95
96/*
97 * DMA parameters.
98 */
99static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
100 {{
101 .name = "SSC0 PCM out",
102 .pdc = &pdc_tx_reg,
103 .mask = &ssc_tx_mask,
104 },
105 {
106 .name = "SSC0 PCM in",
107 .pdc = &pdc_rx_reg,
108 .mask = &ssc_rx_mask,
109 } },
110#if NUM_SSC_DEVICES == 3
111 {{
112 .name = "SSC1 PCM out",
113 .pdc = &pdc_tx_reg,
114 .mask = &ssc_tx_mask,
115 },
116 {
117 .name = "SSC1 PCM in",
118 .pdc = &pdc_rx_reg,
119 .mask = &ssc_rx_mask,
120 } },
121 {{
122 .name = "SSC2 PCM out",
123 .pdc = &pdc_tx_reg,
124 .mask = &ssc_tx_mask,
125 },
126 {
127 .name = "SSC2 PCM in",
128 .pdc = &pdc_rx_reg,
129 .mask = &ssc_rx_mask,
130 } },
131#endif
132};
133
134
135static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
136 {
137 .name = "ssc0",
138 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
139 .dir_mask = SSC_DIR_MASK_UNUSED,
140 .initialized = 0,
141 },
142#if NUM_SSC_DEVICES == 3
143 {
144 .name = "ssc1",
145 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
146 .dir_mask = SSC_DIR_MASK_UNUSED,
147 .initialized = 0,
148 },
149 {
150 .name = "ssc2",
151 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
152 .dir_mask = SSC_DIR_MASK_UNUSED,
153 .initialized = 0,
154 },
155#endif
156};
157
158
159/*
160 * SSC interrupt handler. Passes PDC interrupts to the DMA
161 * interrupt handler in the PCM driver.
162 */
163static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
164{
165 struct atmel_ssc_info *ssc_p = dev_id;
166 struct atmel_pcm_dma_params *dma_params;
167 u32 ssc_sr;
168 u32 ssc_substream_mask;
169 int i;
170
171 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
172 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
173
174 /*
175 * Loop through the substreams attached to this SSC. If
176 * a DMA-related interrupt occurred on that substream, call
177 * the DMA interrupt handler function, if one has been
178 * registered in the dma_params structure by the PCM driver.
179 */
180 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
181 dma_params = ssc_p->dma_params[i];
182
183 if ((dma_params != NULL) &&
184 (dma_params->dma_intr_handler != NULL)) {
185 ssc_substream_mask = (dma_params->mask->ssc_endx |
186 dma_params->mask->ssc_endbuf);
187 if (ssc_sr & ssc_substream_mask) {
188 dma_params->dma_intr_handler(ssc_sr,
189 dma_params->
190 substream);
191 }
192 }
193 }
194
195 return IRQ_HANDLED;
196}
197
198
199/*-------------------------------------------------------------------------*\
200 * DAI functions
201\*-------------------------------------------------------------------------*/
202/*
203 * Startup. Only that one substream allowed in each direction.
204 */
205static int atmel_ssc_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
209 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
210 int dir_mask;
211
212 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
213 ssc_readl(ssc_p->ssc->regs, SR));
214
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
216 dir_mask = SSC_DIR_MASK_PLAYBACK;
217 else
218 dir_mask = SSC_DIR_MASK_CAPTURE;
219
220 spin_lock_irq(&ssc_p->lock);
221 if (ssc_p->dir_mask & dir_mask) {
222 spin_unlock_irq(&ssc_p->lock);
223 return -EBUSY;
224 }
225 ssc_p->dir_mask |= dir_mask;
226 spin_unlock_irq(&ssc_p->lock);
227
228 return 0;
229}
230
231/*
232 * Shutdown. Clear DMA parameters and shutdown the SSC if there
233 * are no other substreams open.
234 */
235static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai)
237{
238 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
239 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
240 struct atmel_pcm_dma_params *dma_params;
241 int dir, dir_mask;
242
243 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
244 dir = 0;
245 else
246 dir = 1;
247
248 dma_params = ssc_p->dma_params[dir];
249
250 if (dma_params != NULL) {
251 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
252 pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
253 (dir ? "receive" : "transmit"),
254 ssc_readl(ssc_p->ssc->regs, SR));
255
256 dma_params->ssc = NULL;
257 dma_params->substream = NULL;
258 ssc_p->dma_params[dir] = NULL;
259 }
260
261 dir_mask = 1 << dir;
262
263 spin_lock_irq(&ssc_p->lock);
264 ssc_p->dir_mask &= ~dir_mask;
265 if (!ssc_p->dir_mask) {
266 if (ssc_p->initialized) {
267 /* Shutdown the SSC clock. */
268 pr_debug("atmel_ssc_dau: Stopping clock\n");
269 clk_disable(ssc_p->ssc->clk);
270
271 free_irq(ssc_p->ssc->irq, ssc_p);
272 ssc_p->initialized = 0;
273 }
274
275 /* Reset the SSC */
276 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
277 /* Clear the SSC dividers */
278 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
279 }
280 spin_unlock_irq(&ssc_p->lock);
281}
282
283
284/*
285 * Record the DAI format for use in hw_params().
286 */
287static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
288 unsigned int fmt)
289{
290 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
291
292 ssc_p->daifmt = fmt;
293 return 0;
294}
295
296/*
297 * Record SSC clock dividers for use in hw_params().
298 */
299static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
300 int div_id, int div)
301{
302 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
303
304 switch (div_id) {
305 case ATMEL_SSC_CMR_DIV:
306 /*
307 * The same master clock divider is used for both
308 * transmit and receive, so if a value has already
309 * been set, it must match this value.
310 */
311 if (ssc_p->cmr_div == 0)
312 ssc_p->cmr_div = div;
313 else
314 if (div != ssc_p->cmr_div)
315 return -EBUSY;
316 break;
317
318 case ATMEL_SSC_TCMR_PERIOD:
319 ssc_p->tcmr_period = div;
320 break;
321
322 case ATMEL_SSC_RCMR_PERIOD:
323 ssc_p->rcmr_period = div;
324 break;
325
326 default:
327 return -EINVAL;
328 }
329
330 return 0;
331}
332
333/*
334 * Configure the SSC.
335 */
336static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
337 struct snd_pcm_hw_params *params,
338 struct snd_soc_dai *dai)
339{
340 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
341 int id = rtd->dai->cpu_dai->id;
342 struct atmel_ssc_info *ssc_p = &ssc_info[id];
343 struct atmel_pcm_dma_params *dma_params;
344 int dir, channels, bits;
345 u32 tfmr, rfmr, tcmr, rcmr;
346 int start_event;
347 int ret;
348
349 /*
350 * Currently, there is only one set of dma params for
351 * each direction. If more are added, this code will
352 * have to be changed to select the proper set.
353 */
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355 dir = 0;
356 else
357 dir = 1;
358
359 dma_params = &ssc_dma_params[id][dir];
360 dma_params->ssc = ssc_p->ssc;
361 dma_params->substream = substream;
362
363 ssc_p->dma_params[dir] = dma_params;
364
365 /*
366 * The cpu_dai->dma_data field is only used to communicate the
367 * appropriate DMA parameters to the pcm driver hw_params()
368 * function. It should not be used for other purposes
369 * as it is common to all substreams.
370 */
371 rtd->dai->cpu_dai->dma_data = dma_params;
372
373 channels = params_channels(params);
374
375 /*
376 * Determine sample size in bits and the PDC increment.
377 */
378 switch (params_format(params)) {
379 case SNDRV_PCM_FORMAT_S8:
380 bits = 8;
381 dma_params->pdc_xfer_size = 1;
382 break;
383 case SNDRV_PCM_FORMAT_S16_LE:
384 bits = 16;
385 dma_params->pdc_xfer_size = 2;
386 break;
387 case SNDRV_PCM_FORMAT_S24_LE:
388 bits = 24;
389 dma_params->pdc_xfer_size = 4;
390 break;
391 case SNDRV_PCM_FORMAT_S32_LE:
392 bits = 32;
393 dma_params->pdc_xfer_size = 4;
394 break;
395 default:
396 printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
397 return -EINVAL;
398 }
399
400 /*
401 * The SSC only supports up to 16-bit samples in I2S format, due
402 * to the size of the Frame Mode Register FSLEN field.
403 */
404 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
405 && bits > 16) {
406 printk(KERN_WARNING
407 "atmel_ssc_dai: sample size %d"
408 "is too large for I2S\n", bits);
409 return -EINVAL;
410 }
411
412 /*
413 * Compute SSC register settings.
414 */
415 switch (ssc_p->daifmt
416 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
417
418 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
419 /*
420 * I2S format, SSC provides BCLK and LRC clocks.
421 *
422 * The SSC transmit and receive clocks are generated
423 * from the MCK divider, and the BCLK signal
424 * is output on the SSC TK line.
425 */
426 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
427 | SSC_BF(RCMR_STTDLY, START_DELAY)
428 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
429 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
430 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
431 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
432
433 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
434 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
435 | SSC_BF(RFMR_FSLEN, (bits - 1))
436 | SSC_BF(RFMR_DATNB, (channels - 1))
437 | SSC_BIT(RFMR_MSBF)
438 | SSC_BF(RFMR_LOOP, 0)
439 | SSC_BF(RFMR_DATLEN, (bits - 1));
440
441 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
442 | SSC_BF(TCMR_STTDLY, START_DELAY)
443 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
444 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
445 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
446 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
447
448 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
449 | SSC_BF(TFMR_FSDEN, 0)
450 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
451 | SSC_BF(TFMR_FSLEN, (bits - 1))
452 | SSC_BF(TFMR_DATNB, (channels - 1))
453 | SSC_BIT(TFMR_MSBF)
454 | SSC_BF(TFMR_DATDEF, 0)
455 | SSC_BF(TFMR_DATLEN, (bits - 1));
456 break;
457
458 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
459 /*
460 * I2S format, CODEC supplies BCLK and LRC clocks.
461 *
462 * The SSC transmit clock is obtained from the BCLK signal on
463 * on the TK line, and the SSC receive clock is
464 * generated from the transmit clock.
465 *
466 * For single channel data, one sample is transferred
467 * on the falling edge of the LRC clock.
468 * For two channel data, one sample is
469 * transferred on both edges of the LRC clock.
470 */
471 start_event = ((channels == 1)
472 ? SSC_START_FALLING_RF
473 : SSC_START_EDGE_RF);
474
475 rcmr = SSC_BF(RCMR_PERIOD, 0)
476 | SSC_BF(RCMR_STTDLY, START_DELAY)
477 | SSC_BF(RCMR_START, start_event)
478 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
479 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
480 | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
481
482 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
483 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
484 | SSC_BF(RFMR_FSLEN, 0)
485 | SSC_BF(RFMR_DATNB, 0)
486 | SSC_BIT(RFMR_MSBF)
487 | SSC_BF(RFMR_LOOP, 0)
488 | SSC_BF(RFMR_DATLEN, (bits - 1));
489
490 tcmr = SSC_BF(TCMR_PERIOD, 0)
491 | SSC_BF(TCMR_STTDLY, START_DELAY)
492 | SSC_BF(TCMR_START, start_event)
493 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
494 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
495 | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
496
497 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
498 | SSC_BF(TFMR_FSDEN, 0)
499 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
500 | SSC_BF(TFMR_FSLEN, 0)
501 | SSC_BF(TFMR_DATNB, 0)
502 | SSC_BIT(TFMR_MSBF)
503 | SSC_BF(TFMR_DATDEF, 0)
504 | SSC_BF(TFMR_DATLEN, (bits - 1));
505 break;
506
507 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
508 /*
509 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
510 *
511 * The SSC transmit and receive clocks are generated from the
512 * MCK divider, and the BCLK signal is output
513 * on the SSC TK line.
514 */
515 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
516 | SSC_BF(RCMR_STTDLY, 1)
517 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
518 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
519 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
520 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
521
522 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
523 | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
524 | SSC_BF(RFMR_FSLEN, 0)
525 | SSC_BF(RFMR_DATNB, (channels - 1))
526 | SSC_BIT(RFMR_MSBF)
527 | SSC_BF(RFMR_LOOP, 0)
528 | SSC_BF(RFMR_DATLEN, (bits - 1));
529
530 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
531 | SSC_BF(TCMR_STTDLY, 1)
532 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
533 | SSC_BF(TCMR_CKI, SSC_CKI_RISING)
534 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
535 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
536
537 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
538 | SSC_BF(TFMR_FSDEN, 0)
539 | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
540 | SSC_BF(TFMR_FSLEN, 0)
541 | SSC_BF(TFMR_DATNB, (channels - 1))
542 | SSC_BIT(TFMR_MSBF)
543 | SSC_BF(TFMR_DATDEF, 0)
544 | SSC_BF(TFMR_DATLEN, (bits - 1));
545 break;
546
547 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
548 default:
549 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
550 ssc_p->daifmt);
551 return -EINVAL;
552 break;
553 }
554 pr_debug("atmel_ssc_hw_params: "
555 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
556 rcmr, rfmr, tcmr, tfmr);
557
558 if (!ssc_p->initialized) {
559
560 /* Enable PMC peripheral clock for this SSC */
561 pr_debug("atmel_ssc_dai: Starting clock\n");
562 clk_enable(ssc_p->ssc->clk);
563
564 /* Reset the SSC and its PDC registers */
565 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
566
567 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
568 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
569 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
570 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
571
572 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
573 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
574 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
575 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
576
577 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
578 ssc_p->name, ssc_p);
579 if (ret < 0) {
580 printk(KERN_WARNING
581 "atmel_ssc_dai: request_irq failure\n");
582 pr_debug("Atmel_ssc_dai: Stoping clock\n");
583 clk_disable(ssc_p->ssc->clk);
584 return ret;
585 }
586
587 ssc_p->initialized = 1;
588 }
589
590 /* set SSC clock mode register */
591 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
592
593 /* set receive clock mode and format */
594 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
595 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
596
597 /* set transmit clock mode and format */
598 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
599 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
600
601 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
602 return 0;
603}
604
605
606static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
607 struct snd_soc_dai *dai)
608{
609 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
610 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
611 struct atmel_pcm_dma_params *dma_params;
612 int dir;
613
614 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
615 dir = 0;
616 else
617 dir = 1;
618
619 dma_params = ssc_p->dma_params[dir];
620
621 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
622
623 pr_debug("%s enabled SSC_SR=0x%08x\n",
624 dir ? "receive" : "transmit",
625 ssc_readl(ssc_p->ssc->regs, SR));
626 return 0;
627}
628
629
630#ifdef CONFIG_PM
631static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
632{
633 struct atmel_ssc_info *ssc_p;
634
635 if (!cpu_dai->active)
636 return 0;
637
638 ssc_p = &ssc_info[cpu_dai->id];
639
640 /* Save the status register before disabling transmit and receive */
641 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
642 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
643
644 /* Save the current interrupt mask, then disable unmasked interrupts */
645 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
646 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
647
648 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
649 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
650 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
651 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
652 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
653
654 return 0;
655}
656
657
658
659static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
660{
661 struct atmel_ssc_info *ssc_p;
662 u32 cr;
663
664 if (!cpu_dai->active)
665 return 0;
666
667 ssc_p = &ssc_info[cpu_dai->id];
668
669 /* restore SSC register settings */
670 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
671 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
672 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
673 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
674 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
675
676 /* re-enable interrupts */
677 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
678
679 /* Re-enable recieve and transmit as appropriate */
680 cr = 0;
681 cr |=
682 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
683 cr |=
684 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
685 ssc_writel(ssc_p->ssc->regs, CR, cr);
686
687 return 0;
688}
689#else /* CONFIG_PM */
690# define atmel_ssc_suspend NULL
691# define atmel_ssc_resume NULL
692#endif /* CONFIG_PM */
693
694
695#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
696
697#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
698 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
699
700struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
701 { .name = "atmel-ssc0",
702 .id = 0,
703 .suspend = atmel_ssc_suspend,
704 .resume = atmel_ssc_resume,
705 .playback = {
706 .channels_min = 1,
707 .channels_max = 2,
708 .rates = ATMEL_SSC_RATES,
709 .formats = ATMEL_SSC_FORMATS,},
710 .capture = {
711 .channels_min = 1,
712 .channels_max = 2,
713 .rates = ATMEL_SSC_RATES,
714 .formats = ATMEL_SSC_FORMATS,},
715 .ops = {
716 .startup = atmel_ssc_startup,
717 .shutdown = atmel_ssc_shutdown,
718 .prepare = atmel_ssc_prepare,
719 .hw_params = atmel_ssc_hw_params,
720 .set_fmt = atmel_ssc_set_dai_fmt,
721 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
722 .private_data = &ssc_info[0],
723 },
724#if NUM_SSC_DEVICES == 3
725 { .name = "atmel-ssc1",
726 .id = 1,
727 .suspend = atmel_ssc_suspend,
728 .resume = atmel_ssc_resume,
729 .playback = {
730 .channels_min = 1,
731 .channels_max = 2,
732 .rates = ATMEL_SSC_RATES,
733 .formats = ATMEL_SSC_FORMATS,},
734 .capture = {
735 .channels_min = 1,
736 .channels_max = 2,
737 .rates = ATMEL_SSC_RATES,
738 .formats = ATMEL_SSC_FORMATS,},
739 .ops = {
740 .startup = atmel_ssc_startup,
741 .shutdown = atmel_ssc_shutdown,
742 .prepare = atmel_ssc_prepare,
743 .hw_params = atmel_ssc_hw_params,
744 .set_fmt = atmel_ssc_set_dai_fmt,
745 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
746 .private_data = &ssc_info[1],
747 },
748 { .name = "atmel-ssc2",
749 .id = 2,
750 .suspend = atmel_ssc_suspend,
751 .resume = atmel_ssc_resume,
752 .playback = {
753 .channels_min = 1,
754 .channels_max = 2,
755 .rates = ATMEL_SSC_RATES,
756 .formats = ATMEL_SSC_FORMATS,},
757 .capture = {
758 .channels_min = 1,
759 .channels_max = 2,
760 .rates = ATMEL_SSC_RATES,
761 .formats = ATMEL_SSC_FORMATS,},
762 .ops = {
763 .startup = atmel_ssc_startup,
764 .shutdown = atmel_ssc_shutdown,
765 .prepare = atmel_ssc_prepare,
766 .hw_params = atmel_ssc_hw_params,
767 .set_fmt = atmel_ssc_set_dai_fmt,
768 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
769 .private_data = &ssc_info[2],
770 },
771#endif
772};
773EXPORT_SYMBOL_GPL(atmel_ssc_dai);
774
775static int __init atmel_ssc_modinit(void)
776{
777 return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
778}
779module_init(atmel_ssc_modinit);
780
781static void __exit atmel_ssc_modexit(void)
782{
783 snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
784}
785module_exit(atmel_ssc_modexit);
786
787/* Module information */
788MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
789MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
790MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
new file mode 100644
index 000000000000..a828746e8a2f
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -0,0 +1,121 @@
1/*
2 * atmel_ssc_dai.h - ALSA SSC interface for the Atmel SoC
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#ifndef _ATMEL_SSC_DAI_H
31#define _ATMEL_SSC_DAI_H
32
33#include <linux/types.h>
34#include <linux/atmel-ssc.h>
35
36#include "atmel-pcm.h"
37
38/* SSC system clock ids */
39#define ATMEL_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
40
41/* SSC divider ids */
42#define ATMEL_SSC_CMR_DIV 0 /* MCK divider for BCLK */
43#define ATMEL_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
44#define ATMEL_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
45/*
46 * SSC direction masks
47 */
48#define SSC_DIR_MASK_UNUSED 0
49#define SSC_DIR_MASK_PLAYBACK 1
50#define SSC_DIR_MASK_CAPTURE 2
51
52/*
53 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
54 * are expected to be used with SSC_BF
55 */
56/* START bit field values */
57#define SSC_START_CONTINUOUS 0
58#define SSC_START_TX_RX 1
59#define SSC_START_LOW_RF 2
60#define SSC_START_HIGH_RF 3
61#define SSC_START_FALLING_RF 4
62#define SSC_START_RISING_RF 5
63#define SSC_START_LEVEL_RF 6
64#define SSC_START_EDGE_RF 7
65#define SSS_START_COMPARE_0 8
66
67/* CKI bit field values */
68#define SSC_CKI_FALLING 0
69#define SSC_CKI_RISING 1
70
71/* CKO bit field values */
72#define SSC_CKO_NONE 0
73#define SSC_CKO_CONTINUOUS 1
74#define SSC_CKO_TRANSFER 2
75
76/* CKS bit field values */
77#define SSC_CKS_DIV 0
78#define SSC_CKS_CLOCK 1
79#define SSC_CKS_PIN 2
80
81/* FSEDGE bit field values */
82#define SSC_FSEDGE_POSITIVE 0
83#define SSC_FSEDGE_NEGATIVE 1
84
85/* FSOS bit field values */
86#define SSC_FSOS_NONE 0
87#define SSC_FSOS_NEGATIVE 1
88#define SSC_FSOS_POSITIVE 2
89#define SSC_FSOS_LOW 3
90#define SSC_FSOS_HIGH 4
91#define SSC_FSOS_TOGGLE 5
92
93#define START_DELAY 1
94
95struct atmel_ssc_state {
96 u32 ssc_cmr;
97 u32 ssc_rcmr;
98 u32 ssc_rfmr;
99 u32 ssc_tcmr;
100 u32 ssc_tfmr;
101 u32 ssc_sr;
102 u32 ssc_imr;
103};
104
105
106struct atmel_ssc_info {
107 char *name;
108 struct ssc_device *ssc;
109 spinlock_t lock; /* lock for dir_mask */
110 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
111 unsigned short initialized; /* true if SSC has been initialized */
112 unsigned short daifmt;
113 unsigned short cmr_div;
114 unsigned short tcmr_period;
115 unsigned short rcmr_period;
116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state;
118};
119extern struct snd_soc_dai atmel_ssc_dai[];
120
121#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 98a2d5826a85..43dd8cee83c6 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -22,7 +22,6 @@
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/version.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/clk.h> 27#include <linux/clk.h>
@@ -40,8 +39,8 @@
40#include <mach/portmux.h> 39#include <mach/portmux.h>
41 40
42#include "../codecs/wm8510.h" 41#include "../codecs/wm8510.h"
43#include "at32-pcm.h" 42#include "atmel-pcm.h"
44#include "at32-ssc.h" 43#include "atmel_ssc_dai.h"
45 44
46 45
47/*-------------------------------------------------------------------------*\ 46/*-------------------------------------------------------------------------*\
@@ -304,7 +303,7 @@ static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = {
304 303
305 304
306 305
307static const char *intercon[][3] = { 306static const struct snd_soc_dapm_route intercon[] = {
308 /* speaker connected to SPKOUT */ 307 /* speaker connected to SPKOUT */
309 {"Ext Spk", NULL, "SPKOUTP"}, 308 {"Ext Spk", NULL, "SPKOUTP"},
310 {"Ext Spk", NULL, "SPKOUTN"}, 309 {"Ext Spk", NULL, "SPKOUTN"},
@@ -312,9 +311,6 @@ static const char *intercon[][3] = {
312 {"Mic Bias", NULL, "Int Mic"}, 311 {"Mic Bias", NULL, "Int Mic"},
313 {"MICN", NULL, "Mic Bias"}, 312 {"MICN", NULL, "Mic Bias"},
314 {"MICP", NULL, "Mic Bias"}, 313 {"MICP", NULL, "Mic Bias"},
315
316 /* Terminator */
317 {NULL, NULL, NULL},
318}; 314};
319 315
320 316
@@ -334,11 +330,8 @@ static int playpaq_wm8510_init(struct snd_soc_codec *codec)
334 /* 330 /*
335 * Setup audio path interconnects 331 * Setup audio path interconnects
336 */ 332 */
337 for (i = 0; intercon[i][0] != NULL; i++) { 333 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
338 snd_soc_dapm_connect_input(codec, 334
339 intercon[i][0],
340 intercon[i][1], intercon[i][2]);
341 }
342 335
343 336
344 /* always connected pins */ 337 /* always connected pins */
@@ -368,8 +361,9 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
368 361
369 362
370 363
371static struct snd_soc_machine snd_soc_machine_playpaq = { 364static struct snd_soc_card snd_soc_playpaq = {
372 .name = "LRS_PlayPaq_WM8510", 365 .name = "LRS_PlayPaq_WM8510",
366 .platform = &at32_soc_platform,
373 .dai_link = &playpaq_wm8510_dai, 367 .dai_link = &playpaq_wm8510_dai,
374 .num_links = 1, 368 .num_links = 1,
375}; 369};
@@ -384,8 +378,7 @@ static struct wm8510_setup_data playpaq_wm8510_setup = {
384 378
385 379
386static struct snd_soc_device playpaq_wm8510_snd_devdata = { 380static struct snd_soc_device playpaq_wm8510_snd_devdata = {
387 .machine = &snd_soc_machine_playpaq, 381 .card = &snd_soc_playpaq,
388 .platform = &at32_soc_platform,
389 .codec_dev = &soc_codec_dev_wm8510, 382 .codec_dev = &soc_codec_dev_wm8510,
390 .codec_data = &playpaq_wm8510_setup, 383 .codec_data = &playpaq_wm8510_setup,
391}; 384};
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
new file mode 100644
index 000000000000..6ea04be911d0
--- /dev/null
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -0,0 +1,328 @@
1/*
2 * sam9g20_wm8731 -- SoC audio for AT91SAM9G20-based
3 * ATMEL AT91SAM9G20ek board.
4 *
5 * Copyright (C) 2005 SAN People
6 * Copyright (C) 2008 Atmel
7 *
8 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
9 *
10 * Based on ati_b1_wm8731.c by:
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Copyright 2006 Endrelia Technologies Inc.
13 * Based on corgi.c by:
14 * Copyright 2005 Wolfson Microelectronics PLC.
15 * Copyright 2005 Openedhand Ltd.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/clk.h>
36#include <linux/timer.h>
37#include <linux/interrupt.h>
38#include <linux/platform_device.h>
39
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46#include <sound/soc-dapm.h>
47
48#include <mach/hardware.h>
49#include <mach/gpio.h>
50
51#include "../codecs/wm8731.h"
52#include "atmel-pcm.h"
53#include "atmel_ssc_dai.h"
54
55
56static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
57{
58 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
59 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
60 int ret;
61
62 /* codec system clock is supplied by PCK0, set to 12MHz */
63 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
64 12000000, SND_SOC_CLOCK_IN);
65 if (ret < 0)
66 return ret;
67
68 return 0;
69}
70
71static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
72{
73 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
74
75 dev_dbg(rtd->socdev->dev, "shutdown");
76}
77
78static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params)
80{
81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
83 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
84 struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
85 struct ssc_device *ssc = ssc_p->ssc;
86 int ret;
87
88 unsigned int rate;
89 int cmr_div, period;
90
91 if (ssc == NULL) {
92 printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
93 return -EINVAL;
94 }
95
96 /* set codec DAI configuration */
97 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
98 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
99 if (ret < 0)
100 return ret;
101
102 /* set cpu DAI configuration */
103 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
104 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
105 if (ret < 0)
106 return ret;
107
108 /*
109 * The SSC clock dividers depend on the sample rate. The CMR.DIV
110 * field divides the system master clock MCK to drive the SSC TK
111 * signal which provides the codec BCLK. The TCMR.PERIOD and
112 * RCMR.PERIOD fields further divide the BCLK signal to drive
113 * the SSC TF and RF signals which provide the codec DACLRC and
114 * ADCLRC clocks.
115 *
116 * The dividers were determined through trial and error, where a
117 * CMR.DIV value is chosen such that the resulting BCLK value is
118 * divisible, or almost divisible, by (2 * sample rate), and then
119 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
120 */
121 rate = params_rate(params);
122
123 switch (rate) {
124 case 8000:
125 cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */
126 period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
127 break;
128 case 11025:
129 cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */
130 period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
131 break;
132 case 16000:
133 cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */
134 period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
135 break;
136 case 22050:
137 cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */
138 period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */
139 break;
140 case 32000:
141 cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */
142 period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
143 break;
144 case 44100:
145 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
146 period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */
147 break;
148 case 48000:
149 cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */
150 period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
151 break;
152 case 88200:
153 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
154 period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */
155 break;
156 case 96000:
157 cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */
158 period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */
159 break;
160 default:
161 printk(KERN_WARNING "unsupported rate %d"
162 " on at91sam9g20ek board\n", rate);
163 return -EINVAL;
164 }
165
166 /* set the MCK divider for BCLK */
167 ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
168 if (ret < 0)
169 return ret;
170
171 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
172 /* set the BCLK divider for DACLRC */
173 ret = snd_soc_dai_set_clkdiv(cpu_dai,
174 ATMEL_SSC_TCMR_PERIOD, period);
175 } else {
176 /* set the BCLK divider for ADCLRC */
177 ret = snd_soc_dai_set_clkdiv(cpu_dai,
178 ATMEL_SSC_RCMR_PERIOD, period);
179 }
180 if (ret < 0)
181 return ret;
182
183 return 0;
184}
185
186static struct snd_soc_ops at91sam9g20ek_ops = {
187 .startup = at91sam9g20ek_startup,
188 .hw_params = at91sam9g20ek_hw_params,
189 .shutdown = at91sam9g20ek_shutdown,
190};
191
192
193static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
194 SND_SOC_DAPM_MIC("Int Mic", NULL),
195 SND_SOC_DAPM_SPK("Ext Spk", NULL),
196};
197
198static const struct snd_soc_dapm_route intercon[] = {
199
200 /* speaker connected to LHPOUT */
201 {"Ext Spk", NULL, "LHPOUT"},
202
203 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
204 {"MICIN", NULL, "Mic Bias"},
205 {"Mic Bias", NULL, "Int Mic"},
206};
207
208/*
209 * Logic for a wm8731 as connected on a at91sam9g20ek board.
210 */
211static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
212{
213 printk(KERN_DEBUG
214 "at91sam9g20ek_wm8731 "
215 ": at91sam9g20ek_wm8731_init() called\n");
216
217 /* Add specific widgets */
218 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
219 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
220 /* Set up specific audio path interconnects */
221 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
222
223 /* not connected */
224 snd_soc_dapm_nc_pin(codec, "RLINEIN");
225 snd_soc_dapm_nc_pin(codec, "LLINEIN");
226
227 /* always connected */
228 snd_soc_dapm_enable_pin(codec, "Int Mic");
229 snd_soc_dapm_enable_pin(codec, "Ext Spk");
230
231 snd_soc_dapm_sync(codec);
232
233 return 0;
234}
235
236static struct snd_soc_dai_link at91sam9g20ek_dai = {
237 .name = "WM8731",
238 .stream_name = "WM8731 PCM",
239 .cpu_dai = &atmel_ssc_dai[0],
240 .codec_dai = &wm8731_dai,
241 .init = at91sam9g20ek_wm8731_init,
242 .ops = &at91sam9g20ek_ops,
243};
244
245static struct snd_soc_card snd_soc_at91sam9g20ek = {
246 .name = "WM8731",
247 .platform = &atmel_soc_platform,
248 .dai_link = &at91sam9g20ek_dai,
249 .num_links = 1,
250};
251
252static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = {
253 .i2c_bus = 0,
254 .i2c_address = 0x1b,
255};
256
257static struct snd_soc_device at91sam9g20ek_snd_devdata = {
258 .card = &snd_soc_at91sam9g20ek,
259 .codec_dev = &soc_codec_dev_wm8731,
260 .codec_data = &at91sam9g20ek_wm8731_setup,
261};
262
263static struct platform_device *at91sam9g20ek_snd_device;
264
265static int __init at91sam9g20ek_init(void)
266{
267 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
268 struct ssc_device *ssc = NULL;
269 int ret;
270
271 /*
272 * Request SSC device
273 */
274 ssc = ssc_request(0);
275 if (IS_ERR(ssc)) {
276 ret = PTR_ERR(ssc);
277 ssc = NULL;
278 goto err_ssc;
279 }
280 ssc_p->ssc = ssc;
281
282 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
283 if (!at91sam9g20ek_snd_device) {
284 printk(KERN_DEBUG
285 "platform device allocation failed\n");
286 ret = -ENOMEM;
287 }
288
289 platform_set_drvdata(at91sam9g20ek_snd_device,
290 &at91sam9g20ek_snd_devdata);
291 at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
292
293 ret = platform_device_add(at91sam9g20ek_snd_device);
294 if (ret) {
295 printk(KERN_DEBUG
296 "platform device allocation failed\n");
297 platform_device_put(at91sam9g20ek_snd_device);
298 }
299
300 return ret;
301
302err_ssc:
303 return ret;
304}
305
306static void __exit at91sam9g20ek_exit(void)
307{
308 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
309 struct ssc_device *ssc;
310
311 if (ssc_p != NULL) {
312 ssc = ssc_p->ssc;
313 if (ssc != NULL)
314 ssc_free(ssc);
315 ssc_p->ssc = NULL;
316 }
317
318 platform_device_unregister(at91sam9g20ek_snd_device);
319 at91sam9g20ek_snd_device = NULL;
320}
321
322module_init(at91sam9g20ek_init);
323module_exit(at91sam9g20ek_exit);
324
325/* Module information */
326MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
327MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
328MODULE_LICENSE("GPL");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 1466d9328800..bc8d654576c0 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -187,7 +187,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd,
187 au1x_pcm_dmatx_cb, (void *)pcd); 187 au1x_pcm_dmatx_cb, (void *)pcd);
188 188
189 if (!pcd->ddma_chan) 189 if (!pcd->ddma_chan)
190 return -ENOMEM;; 190 return -ENOMEM;
191 191
192 au1xxx_dbdma_set_devwidth(pcd->ddma_chan, msbits); 192 au1xxx_dbdma_set_devwidth(pcd->ddma_chan, msbits);
193 au1xxx_dbdma_ring_alloc(pcd->ddma_chan, 2); 193 au1xxx_dbdma_ring_alloc(pcd->ddma_chan, 2);
@@ -406,11 +406,12 @@ static int __init au1xpsc_audio_dbdma_init(void)
406{ 406{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 407 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 408 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return 0; 409 return snd_soc_register_platform(&au1xpsc_soc_platform);
410} 410}
411 411
412static void __exit au1xpsc_audio_dbdma_exit(void) 412static void __exit au1xpsc_audio_dbdma_exit(void)
413{ 413{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform);
414} 415}
415 416
416module_init(au1xpsc_audio_dbdma_init); 417module_init(au1xpsc_audio_dbdma_init);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 57facbad6825..f0e30aec7f23 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -160,7 +160,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
160EXPORT_SYMBOL_GPL(soc_ac97_ops); 160EXPORT_SYMBOL_GPL(soc_ac97_ops);
161 161
162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, 162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
163 struct snd_pcm_hw_params *params) 163 struct snd_pcm_hw_params *params,
164 struct snd_soc_dai *dai)
164{ 165{
165 /* FIXME */ 166 /* FIXME */
166 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 167 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -210,7 +211,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
210} 211}
211 212
212static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, 213static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
213 int cmd) 214 int cmd, struct snd_soc_dai *dai)
214{ 215{
215 /* FIXME */ 216 /* FIXME */
216 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 217 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -313,8 +314,7 @@ static void au1xpsc_ac97_remove(struct platform_device *pdev,
313 au1xpsc_ac97_workdata = NULL; 314 au1xpsc_ac97_workdata = NULL;
314} 315}
315 316
316static int au1xpsc_ac97_suspend(struct platform_device *pdev, 317static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai)
317 struct snd_soc_dai *dai)
318{ 318{
319 /* save interesting registers and disable PSC */ 319 /* save interesting registers and disable PSC */
320 au1xpsc_ac97_workdata->pm[0] = 320 au1xpsc_ac97_workdata->pm[0] =
@@ -328,8 +328,7 @@ static int au1xpsc_ac97_suspend(struct platform_device *pdev,
328 return 0; 328 return 0;
329} 329}
330 330
331static int au1xpsc_ac97_resume(struct platform_device *pdev, 331static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
332 struct snd_soc_dai *dai)
333{ 332{
334 /* restore PSC clock config */ 333 /* restore PSC clock config */
335 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 334 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE,
@@ -345,7 +344,7 @@ static int au1xpsc_ac97_resume(struct platform_device *pdev,
345 344
346struct snd_soc_dai au1xpsc_ac97_dai = { 345struct snd_soc_dai au1xpsc_ac97_dai = {
347 .name = "au1xpsc_ac97", 346 .name = "au1xpsc_ac97",
348 .type = SND_SOC_DAI_AC97, 347 .ac97_control = 1,
349 .probe = au1xpsc_ac97_probe, 348 .probe = au1xpsc_ac97_probe,
350 .remove = au1xpsc_ac97_remove, 349 .remove = au1xpsc_ac97_remove,
351 .suspend = au1xpsc_ac97_suspend, 350 .suspend = au1xpsc_ac97_suspend,
@@ -372,11 +371,12 @@ EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
372static int __init au1xpsc_ac97_init(void) 371static int __init au1xpsc_ac97_init(void)
373{ 372{
374 au1xpsc_ac97_workdata = NULL; 373 au1xpsc_ac97_workdata = NULL;
375 return 0; 374 return snd_soc_register_dai(&au1xpsc_ac97_dai);
376} 375}
377 376
378static void __exit au1xpsc_ac97_exit(void) 377static void __exit au1xpsc_ac97_exit(void)
379{ 378{
379 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
380} 380}
381 381
382module_init(au1xpsc_ac97_init); 382module_init(au1xpsc_ac97_init);
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 9384702c7ebd..f916de4400ed 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -116,7 +116,8 @@ out:
116} 116}
117 117
118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, 118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params) 119 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai)
120{ 121{
121 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 122 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
122 123
@@ -240,7 +241,8 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
240 return 0; 241 return 0;
241} 242}
242 243
243static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 244static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
245 struct snd_soc_dai *dai)
244{ 246{
245 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 247 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
246 int ret, stype = SUBSTREAM_TYPE(substream); 248 int ret, stype = SUBSTREAM_TYPE(substream);
@@ -337,8 +339,7 @@ static void au1xpsc_i2s_remove(struct platform_device *pdev,
337 au1xpsc_i2s_workdata = NULL; 339 au1xpsc_i2s_workdata = NULL;
338} 340}
339 341
340static int au1xpsc_i2s_suspend(struct platform_device *pdev, 342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai)
341 struct snd_soc_dai *cpu_dai)
342{ 343{
343 /* save interesting register and disable PSC */ 344 /* save interesting register and disable PSC */
344 au1xpsc_i2s_workdata->pm[0] = 345 au1xpsc_i2s_workdata->pm[0] =
@@ -352,8 +353,7 @@ static int au1xpsc_i2s_suspend(struct platform_device *pdev,
352 return 0; 353 return 0;
353} 354}
354 355
355static int au1xpsc_i2s_resume(struct platform_device *pdev, 356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai)
356 struct snd_soc_dai *cpu_dai)
357{ 357{
358 /* select I2S mode and PSC clock */ 358 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
@@ -369,7 +369,6 @@ static int au1xpsc_i2s_resume(struct platform_device *pdev,
369 369
370struct snd_soc_dai au1xpsc_i2s_dai = { 370struct snd_soc_dai au1xpsc_i2s_dai = {
371 .name = "au1xpsc_i2s", 371 .name = "au1xpsc_i2s",
372 .type = SND_SOC_DAI_I2S,
373 .probe = au1xpsc_i2s_probe, 372 .probe = au1xpsc_i2s_probe,
374 .remove = au1xpsc_i2s_remove, 373 .remove = au1xpsc_i2s_remove,
375 .suspend = au1xpsc_i2s_suspend, 374 .suspend = au1xpsc_i2s_suspend,
@@ -389,8 +388,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
389 .ops = { 388 .ops = {
390 .trigger = au1xpsc_i2s_trigger, 389 .trigger = au1xpsc_i2s_trigger,
391 .hw_params = au1xpsc_i2s_hw_params, 390 .hw_params = au1xpsc_i2s_hw_params,
392 },
393 .dai_ops = {
394 .set_fmt = au1xpsc_i2s_set_fmt, 391 .set_fmt = au1xpsc_i2s_set_fmt,
395 }, 392 },
396}; 393};
@@ -399,11 +396,12 @@ EXPORT_SYMBOL(au1xpsc_i2s_dai);
399static int __init au1xpsc_i2s_init(void) 396static int __init au1xpsc_i2s_init(void)
400{ 397{
401 au1xpsc_i2s_workdata = NULL; 398 au1xpsc_i2s_workdata = NULL;
402 return 0; 399 return snd_soc_register_dai(&au1xpsc_i2s_dai);
403} 400}
404 401
405static void __exit au1xpsc_i2s_exit(void) 402static void __exit au1xpsc_i2s_exit(void)
406{ 403{
404 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
407} 405}
408 406
409module_init(au1xpsc_i2s_init); 407module_init(au1xpsc_i2s_init);
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
index f75ae7f62c3d..27683eb7905e 100644
--- a/sound/soc/au1x/sample-ac97.c
+++ b/sound/soc/au1x/sample-ac97.c
@@ -42,14 +42,14 @@ static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
42 .ops = NULL, 42 .ops = NULL,
43}; 43};
44 44
45static struct snd_soc_machine au1xpsc_sample_ac97_machine = { 45static struct snd_soc_card au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio", 46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai, 47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1, 48 .num_links = 1,
49}; 49};
50 50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = { 51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .machine = &au1xpsc_sample_ac97_machine, 52 .card = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ 53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97, 54 .codec_dev = &soc_codec_dev_ac97,
55}; 55};
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index f98331d099e7..0a2f8f9eff53 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -1,6 +1,6 @@
1config SND_BF5XX_I2S 1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip" 2 tristate "SoC I2S Audio for the ADI BF5xx chip"
3 depends on BLACKFIN && SND_SOC 3 depends on BLACKFIN
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 Blackfin SPORT (synchronous serial ports) interface in I2S 6 the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -13,13 +13,28 @@ config SND_BF5XX_SOC_SSM2602
13 select SND_BF5XX_SOC_I2S 13 select SND_BF5XX_SOC_I2S
14 select SND_SOC_SSM2602 14 select SND_SOC_SSM2602
15 select I2C 15 select I2C
16 select I2C_BLACKFIN_TWI
17 help 16 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT. 17 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19 18
19config SND_BF5XX_SOC_AD73311
20 tristate "SoC AD73311 Audio support for Blackfin"
21 depends on SND_BF5XX_I2S
22 select SND_BF5XX_SOC_I2S
23 select SND_SOC_AD73311
24 help
25 Say Y if you want to add support for AD73311 codec on Blackfin.
26
27config SND_BFIN_AD73311_SE
28 int "PF pin for AD73311L Chip Select"
29 depends on SND_BF5XX_SOC_AD73311
30 default 4
31 help
32 Enter the GPIO used to control AD73311's SE pin. Acceptable
33 values are 0 to 7
34
20config SND_BF5XX_AC97 35config SND_BF5XX_AC97
21 tristate "SoC AC97 Audio for the ADI BF5xx chip" 36 tristate "SoC AC97 Audio for the ADI BF5xx chip"
22 depends on BLACKFIN && SND_SOC 37 depends on BLACKFIN
23 help 38 help
24 Say Y or M if you want to add support for codecs attached to 39 Say Y or M if you want to add support for codecs attached to
25 the Blackfin SPORT (synchronous serial ports) interface in slot 16 40 the Blackfin SPORT (synchronous serial ports) interface in slot 16
@@ -31,7 +46,7 @@ config SND_BF5XX_AC97
31 properly with this driver. This driver is known to work with the 46 properly with this driver. This driver is known to work with the
32 Analog Devices line of AC97 codecs. 47 Analog Devices line of AC97 codecs.
33 48
34config SND_MMAP_SUPPORT 49config SND_BF5XX_MMAP_SUPPORT
35 bool "Enable MMAP Support" 50 bool "Enable MMAP Support"
36 depends on SND_BF5XX_AC97 51 depends on SND_BF5XX_AC97
37 default y 52 default y
@@ -39,9 +54,17 @@ config SND_MMAP_SUPPORT
39 Say y if you want AC97 driver to support mmap mode. 54 Say y if you want AC97 driver to support mmap mode.
40 We introduce an intermediate buffer to simulate mmap. 55 We introduce an intermediate buffer to simulate mmap.
41 56
57config SND_BF5XX_MULTICHAN_SUPPORT
58 bool "Enable Multichannel Support"
59 depends on SND_BF5XX_AC97
60 default n
61 help
62 Say y if you want AC97 driver to support up to 5.1 channel audio.
63 this mode will consume much more memory for DMA.
64
42config SND_BF5XX_SOC_SPORT 65config SND_BF5XX_SOC_SPORT
43 tristate 66 tristate
44 67
45config SND_BF5XX_SOC_I2S 68config SND_BF5XX_SOC_I2S
46 tristate 69 tristate
47 select SND_BF5XX_SOC_SPORT 70 select SND_BF5XX_SOC_SPORT
@@ -64,7 +87,7 @@ config SND_BF5XX_SPORT_NUM
64 int "Set a SPORT for Sound chip" 87 int "Set a SPORT for Sound chip"
65 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97) 88 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
66 range 0 3 if BF54x 89 range 0 3 if BF54x
67 range 0 1 if (BF53x || BF561) 90 range 0 1 if !BF54x
68 default 0 91 default 0
69 help 92 help
70 Set the correct SPORT for sound chip. 93 Set the correct SPORT for sound chip.
@@ -74,12 +97,13 @@ config SND_BF5XX_HAVE_COLD_RESET
74 depends on SND_BF5XX_AC97 97 depends on SND_BF5XX_AC97
75 default y if BFIN548_EZKIT 98 default y if BFIN548_EZKIT
76 default n if !BFIN548_EZKIT 99 default n if !BFIN548_EZKIT
77 100
78config SND_BF5XX_RESET_GPIO_NUM 101config SND_BF5XX_RESET_GPIO_NUM
79 int "Set a GPIO for cold reset" 102 int "Set a GPIO for cold reset"
80 depends on SND_BF5XX_HAVE_COLD_RESET 103 depends on SND_BF5XX_HAVE_COLD_RESET
81 range 0 159 104 range 0 159
82 default 19 if BFIN548_EZKIT 105 default 19 if BFIN548_EZKIT
83 default 5 if BFIN537_STAMP 106 default 5 if BFIN537_STAMP
107 default 0
84 help 108 help
85 Set the correct GPIO for RESET the sound chip. 109 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 9ea8bd9e0ba3..97bb37a6359c 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -14,7 +14,8 @@ obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
14# Blackfin Machine Support 14# Blackfin Machine Support
15snd-ad1980-objs := bf5xx-ad1980.o 15snd-ad1980-objs := bf5xx-ad1980.o
16snd-ssm2602-objs := bf5xx-ssm2602.o 16snd-ssm2602-objs := bf5xx-ssm2602.o
17 17snd-ad73311-objs := bf5xx-ad73311.o
18 18
19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o 19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
21obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 51f4907c4831..8067cfafa3a7 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -43,23 +43,34 @@
43#include "bf5xx-ac97.h" 43#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#if defined(CONFIG_SND_MMAP_SUPPORT) 46static unsigned int ac97_chan_mask[] = {
47 SP_FL, /* Mono */
48 SP_STEREO, /* Stereo */
49 SP_2DOT1, /* 2.1*/
50 SP_QUAD,/*Quadraquic*/
51 SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
52 SP_5DOT1, /* 5.1 */
53};
54
55#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
47static void bf5xx_mmap_copy(struct snd_pcm_substream *substream, 56static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
48 snd_pcm_uframes_t count) 57 snd_pcm_uframes_t count)
49{ 58{
50 struct snd_pcm_runtime *runtime = substream->runtime; 59 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct sport_device *sport = runtime->private_data; 60 struct sport_device *sport = runtime->private_data;
61 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
52 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 62 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
53 bf5xx_pcm_to_ac97( 63 bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
54 (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos, 64 sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
55 (__u32 *)runtime->dma_area + sport->tx_pos, count); 65 runtime->channels, count, chan_mask);
56 sport->tx_pos += runtime->period_size; 66 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size) 67 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size; 68 sport->tx_pos %= runtime->buffer_size;
69 sport->tx_delay_pos = sport->tx_pos;
59 } else { 70 } else {
60 bf5xx_ac97_to_pcm( 71 bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
61 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos, 72 sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
62 (__u32 *)runtime->dma_area + sport->rx_pos, count); 73 runtime->channels, count);
63 sport->rx_pos += runtime->period_size; 74 sport->rx_pos += runtime->period_size;
64 if (sport->rx_pos >= runtime->buffer_size) 75 if (sport->rx_pos >= runtime->buffer_size)
65 sport->rx_pos %= runtime->buffer_size; 76 sport->rx_pos %= runtime->buffer_size;
@@ -70,9 +81,17 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
70static void bf5xx_dma_irq(void *data) 81static void bf5xx_dma_irq(void *data)
71{ 82{
72 struct snd_pcm_substream *pcm = data; 83 struct snd_pcm_substream *pcm = data;
73#if defined(CONFIG_SND_MMAP_SUPPORT) 84#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
74 struct snd_pcm_runtime *runtime = pcm->runtime; 85 struct snd_pcm_runtime *runtime = pcm->runtime;
86 struct sport_device *sport = runtime->private_data;
75 bf5xx_mmap_copy(pcm, runtime->period_size); 87 bf5xx_mmap_copy(pcm, runtime->period_size);
88 if (pcm->stream == SNDRV_PCM_STREAM_PLAYBACK) {
89 if (sport->once == 0) {
90 snd_pcm_period_elapsed(pcm);
91 bf5xx_mmap_copy(pcm, runtime->period_size);
92 sport->once = 1;
93 }
94 }
76#endif 95#endif
77 snd_pcm_period_elapsed(pcm); 96 snd_pcm_period_elapsed(pcm);
78} 97}
@@ -81,17 +100,14 @@ static void bf5xx_dma_irq(void *data)
81 * The total rx/tx buffer is for ac97 frame to hold all pcm data 100 * The total rx/tx buffer is for ac97 frame to hold all pcm data
82 * is 0x20000 * sizeof(struct ac97_frame) / 4. 101 * is 0x20000 * sizeof(struct ac97_frame) / 4.
83 */ 102 */
84#ifdef CONFIG_SND_MMAP_SUPPORT
85static const struct snd_pcm_hardware bf5xx_pcm_hardware = { 103static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
86 .info = SNDRV_PCM_INFO_INTERLEAVED | 104 .info = SNDRV_PCM_INFO_INTERLEAVED |
105#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
87 SNDRV_PCM_INFO_MMAP | 106 SNDRV_PCM_INFO_MMAP |
88 SNDRV_PCM_INFO_MMAP_VALID | 107 SNDRV_PCM_INFO_MMAP_VALID |
89 SNDRV_PCM_INFO_BLOCK_TRANSFER,
90#else
91static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
92 .info = SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_BLOCK_TRANSFER,
94#endif 108#endif
109 SNDRV_PCM_INFO_BLOCK_TRANSFER,
110
95 .formats = SNDRV_PCM_FMTBIT_S16_LE, 111 .formats = SNDRV_PCM_FMTBIT_S16_LE,
96 .period_bytes_min = 32, 112 .period_bytes_min = 32,
97 .period_bytes_max = 0x10000, 113 .period_bytes_max = 0x10000,
@@ -114,6 +130,20 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
114 130
115static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) 131static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
116{ 132{
133#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
134 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct sport_device *sport = runtime->private_data;
136
137 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
138 sport->once = 0;
139 if (runtime->dma_area)
140 memset(runtime->dma_area, 0, runtime->buffer_size);
141 memset(sport->tx_dma_buf, 0, runtime->buffer_size *
142 sizeof(struct ac97_frame));
143 } else
144 memset(sport->rx_dma_buf, 0, runtime->buffer_size *
145 sizeof(struct ac97_frame));
146#endif
117 snd_pcm_lib_free_pages(substream); 147 snd_pcm_lib_free_pages(substream);
118 return 0; 148 return 0;
119} 149}
@@ -126,17 +156,12 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
126 /* An intermediate buffer is introduced for implementing mmap for 156 /* An intermediate buffer is introduced for implementing mmap for
127 * SPORT working in TMD mode(include AC97). 157 * SPORT working in TMD mode(include AC97).
128 */ 158 */
129#if defined(CONFIG_SND_MMAP_SUPPORT) 159#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
130 size_t size = bf5xx_pcm_hardware.buffer_bytes_max
131 * sizeof(struct ac97_frame) / 4;
132 /*clean up intermediate buffer*/
133 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
134 memset(sport->tx_dma_buf, 0, size);
135 sport_set_tx_callback(sport, bf5xx_dma_irq, substream); 161 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
136 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods, 162 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
137 runtime->period_size * sizeof(struct ac97_frame)); 163 runtime->period_size * sizeof(struct ac97_frame));
138 } else { 164 } else {
139 memset(sport->rx_dma_buf, 0, size);
140 sport_set_rx_callback(sport, bf5xx_dma_irq, substream); 165 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
141 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods, 166 sport_config_rx_dma(sport, sport->rx_dma_buf, runtime->periods,
142 runtime->period_size * sizeof(struct ac97_frame)); 167 runtime->period_size * sizeof(struct ac97_frame));
@@ -164,21 +189,25 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
164 pr_debug("%s enter\n", __func__); 189 pr_debug("%s enter\n", __func__);
165 switch (cmd) { 190 switch (cmd) {
166 case SNDRV_PCM_TRIGGER_START: 191 case SNDRV_PCM_TRIGGER_START:
167 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 192 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
193#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
194 bf5xx_mmap_copy(substream, runtime->period_size);
195 sport->tx_delay_pos = 0;
196#endif
168 sport_tx_start(sport); 197 sport_tx_start(sport);
169 else 198 } else
170 sport_rx_start(sport); 199 sport_rx_start(sport);
171 break; 200 break;
172 case SNDRV_PCM_TRIGGER_STOP: 201 case SNDRV_PCM_TRIGGER_STOP:
173 case SNDRV_PCM_TRIGGER_SUSPEND: 202 case SNDRV_PCM_TRIGGER_SUSPEND:
174 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 203 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
176#if defined(CONFIG_SND_MMAP_SUPPORT) 205#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
177 sport->tx_pos = 0; 206 sport->tx_pos = 0;
178#endif 207#endif
179 sport_tx_stop(sport); 208 sport_tx_stop(sport);
180 } else { 209 } else {
181#if defined(CONFIG_SND_MMAP_SUPPORT) 210#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
182 sport->rx_pos = 0; 211 sport->rx_pos = 0;
183#endif 212#endif
184 sport_rx_stop(sport); 213 sport_rx_stop(sport);
@@ -196,9 +225,9 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
196 struct sport_device *sport = runtime->private_data; 225 struct sport_device *sport = runtime->private_data;
197 unsigned int curr; 226 unsigned int curr;
198 227
199#if defined(CONFIG_SND_MMAP_SUPPORT) 228#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 229 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
201 curr = sport->tx_pos; 230 curr = sport->tx_delay_pos;
202 else 231 else
203 curr = sport->rx_pos; 232 curr = sport->rx_pos;
204#else 233#else
@@ -237,7 +266,7 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
237 return ret; 266 return ret;
238} 267}
239 268
240#ifdef CONFIG_SND_MMAP_SUPPORT 269#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
241static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, 270static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
242 struct vm_area_struct *vma) 271 struct vm_area_struct *vma)
243{ 272{
@@ -254,18 +283,16 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
254 void __user *buf, snd_pcm_uframes_t count) 283 void __user *buf, snd_pcm_uframes_t count)
255{ 284{
256 struct snd_pcm_runtime *runtime = substream->runtime; 285 struct snd_pcm_runtime *runtime = substream->runtime;
257 286 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
258 pr_debug("%s copy pos:0x%lx count:0x%lx\n", 287 pr_debug("%s copy pos:0x%lx count:0x%lx\n",
259 substream->stream ? "Capture" : "Playback", pos, count); 288 substream->stream ? "Capture" : "Playback", pos, count);
260 289
261 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 290 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
262 bf5xx_pcm_to_ac97( 291 bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos,
263 (struct ac97_frame *)runtime->dma_area + pos, 292 (__u16 *)buf, count, chan_mask);
264 buf, count);
265 else 293 else
266 bf5xx_ac97_to_pcm( 294 bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos,
267 (struct ac97_frame *)runtime->dma_area + pos, 295 (__u16 *)buf, count);
268 buf, count);
269 return 0; 296 return 0;
270} 297}
271#endif 298#endif
@@ -278,7 +305,7 @@ struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
278 .prepare = bf5xx_pcm_prepare, 305 .prepare = bf5xx_pcm_prepare,
279 .trigger = bf5xx_pcm_trigger, 306 .trigger = bf5xx_pcm_trigger,
280 .pointer = bf5xx_pcm_pointer, 307 .pointer = bf5xx_pcm_pointer,
281#ifdef CONFIG_SND_MMAP_SUPPORT 308#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
282 .mmap = bf5xx_pcm_mmap, 309 .mmap = bf5xx_pcm_mmap,
283#else 310#else
284 .copy = bf5xx_pcm_copy, 311 .copy = bf5xx_pcm_copy,
@@ -316,7 +343,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316 * Need to allocate local buffer when enable 343 * Need to allocate local buffer when enable
317 * MMAP for SPORT working in TMD mode (include AC97). 344 * MMAP for SPORT working in TMD mode (include AC97).
318 */ 345 */
319#if defined(CONFIG_SND_MMAP_SUPPORT) 346#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
320 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
321 if (!sport_handle->tx_dma_buf) { 348 if (!sport_handle->tx_dma_buf) {
322 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
@@ -353,7 +380,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
353 struct snd_pcm_substream *substream; 380 struct snd_pcm_substream *substream;
354 struct snd_dma_buffer *buf; 381 struct snd_dma_buffer *buf;
355 int stream; 382 int stream;
356#if defined(CONFIG_SND_MMAP_SUPPORT) 383#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
357 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 384 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
358 sizeof(struct ac97_frame) / 4; 385 sizeof(struct ac97_frame) / 4;
359#endif 386#endif
@@ -367,7 +394,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
367 continue; 394 continue;
368 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 395 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
369 buf->area = NULL; 396 buf->area = NULL;
370#if defined(CONFIG_SND_MMAP_SUPPORT) 397#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
371 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
372 if (sport_handle->tx_dma_buf) 399 if (sport_handle->tx_dma_buf)
373 dma_free_coherent(NULL, size, \ 400 dma_free_coherent(NULL, size, \
@@ -424,6 +451,18 @@ struct snd_soc_platform bf5xx_ac97_soc_platform = {
424}; 451};
425EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform); 452EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
426 453
454static int __init bfin_ac97_init(void)
455{
456 return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
457}
458module_init(bfin_ac97_init);
459
460static void __exit bfin_ac97_exit(void)
461{
462 snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
463}
464module_exit(bfin_ac97_exit);
465
427MODULE_AUTHOR("Cliff Cai"); 466MODULE_AUTHOR("Cliff Cai");
428MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module"); 467MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
429MODULE_LICENSE("GPL"); 468MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index c782e311fd56..3be2be60576d 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -54,71 +54,103 @@
54static int *cmd_count; 54static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56 56
57#if defined(CONFIG_BF54x) 57static u16 sport_req[][7] = {
58 PIN_REQ_SPORT_0,
59#ifdef PIN_REQ_SPORT_1
60 PIN_REQ_SPORT_1,
61#endif
62#ifdef PIN_REQ_SPORT_2
63 PIN_REQ_SPORT_2,
64#endif
65#ifdef PIN_REQ_SPORT_3
66 PIN_REQ_SPORT_3,
67#endif
68 };
69
58static struct sport_param sport_params[4] = { 70static struct sport_param sport_params[4] = {
59 { 71 {
60 .dma_rx_chan = CH_SPORT0_RX, 72 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX, 73 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERR, 74 .err_irq = IRQ_SPORT0_ERROR,
63 .regs = (struct sport_register *)SPORT0_TCR1, 75 .regs = (struct sport_register *)SPORT0_TCR1,
64 }, 76 },
77#ifdef PIN_REQ_SPORT_1
65 { 78 {
66 .dma_rx_chan = CH_SPORT1_RX, 79 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX, 80 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERR, 81 .err_irq = IRQ_SPORT1_ERROR,
69 .regs = (struct sport_register *)SPORT1_TCR1, 82 .regs = (struct sport_register *)SPORT1_TCR1,
70 }, 83 },
84#endif
85#ifdef PIN_REQ_SPORT_2
71 { 86 {
72 .dma_rx_chan = CH_SPORT2_RX, 87 .dma_rx_chan = CH_SPORT2_RX,
73 .dma_tx_chan = CH_SPORT2_TX, 88 .dma_tx_chan = CH_SPORT2_TX,
74 .err_irq = IRQ_SPORT2_ERR, 89 .err_irq = IRQ_SPORT2_ERROR,
75 .regs = (struct sport_register *)SPORT2_TCR1, 90 .regs = (struct sport_register *)SPORT2_TCR1,
76 }, 91 },
92#endif
93#ifdef PIN_REQ_SPORT_3
77 { 94 {
78 .dma_rx_chan = CH_SPORT3_RX, 95 .dma_rx_chan = CH_SPORT3_RX,
79 .dma_tx_chan = CH_SPORT3_TX, 96 .dma_tx_chan = CH_SPORT3_TX,
80 .err_irq = IRQ_SPORT3_ERR, 97 .err_irq = IRQ_SPORT3_ERROR,
81 .regs = (struct sport_register *)SPORT3_TCR1, 98 .regs = (struct sport_register *)SPORT3_TCR1,
82 } 99 }
83};
84#else
85static struct sport_param sport_params[2] = {
86 {
87 .dma_rx_chan = CH_SPORT0_RX,
88 .dma_tx_chan = CH_SPORT0_TX,
89 .err_irq = IRQ_SPORT0_ERROR,
90 .regs = (struct sport_register *)SPORT0_TCR1,
91 },
92 {
93 .dma_rx_chan = CH_SPORT1_RX,
94 .dma_tx_chan = CH_SPORT1_TX,
95 .err_irq = IRQ_SPORT1_ERROR,
96 .regs = (struct sport_register *)SPORT1_TCR1,
97 }
98};
99#endif 100#endif
101};
100 102
101void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 103void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
102 size_t count) 104 size_t count, unsigned int chan_mask)
103{ 105{
104 while (count--) { 106 while (count--) {
105 dst->ac97_tag = TAG_VALID | TAG_PCM; 107 dst->ac97_tag = TAG_VALID;
106 (dst++)->ac97_pcm = *src++; 108 if (chan_mask & SP_FL) {
109 dst->ac97_pcm_r = *src++;
110 dst->ac97_tag |= TAG_PCM_RIGHT;
111 }
112 if (chan_mask & SP_FR) {
113 dst->ac97_pcm_l = *src++;
114 dst->ac97_tag |= TAG_PCM_LEFT;
115
116 }
117#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
118 if (chan_mask & SP_SR) {
119 dst->ac97_sl = *src++;
120 dst->ac97_tag |= TAG_PCM_SL;
121 }
122 if (chan_mask & SP_SL) {
123 dst->ac97_sr = *src++;
124 dst->ac97_tag |= TAG_PCM_SR;
125 }
126 if (chan_mask & SP_LFE) {
127 dst->ac97_lfe = *src++;
128 dst->ac97_tag |= TAG_PCM_LFE;
129 }
130 if (chan_mask & SP_FC) {
131 dst->ac97_center = *src++;
132 dst->ac97_tag |= TAG_PCM_CENTER;
133 }
134#endif
135 dst++;
107 } 136 }
108} 137}
109EXPORT_SYMBOL(bf5xx_pcm_to_ac97); 138EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
110 139
111void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 140void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
112 size_t count) 141 size_t count)
113{ 142{
114 while (count--) 143 while (count--) {
115 *(dst++) = (src++)->ac97_pcm; 144 *(dst++) = src->ac97_pcm_l;
145 *(dst++) = src->ac97_pcm_r;
146 src++;
147 }
116} 148}
117EXPORT_SYMBOL(bf5xx_ac97_to_pcm); 149EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
118 150
119static unsigned int sport_tx_curr_frag(struct sport_device *sport) 151static unsigned int sport_tx_curr_frag(struct sport_device *sport)
120{ 152{
121 return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \ 153 return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
122 sport->tx_fragsize; 154 sport->tx_fragsize;
123} 155}
124 156
@@ -129,9 +161,8 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
129 struct ac97_frame *nextwrite; 161 struct ac97_frame *nextwrite;
130 162
131 sport_incfrag(sport, &nextfrag, 1); 163 sport_incfrag(sport, &nextfrag, 1);
132 sport_incfrag(sport, &nextfrag, 1);
133 164
134 nextwrite = (struct ac97_frame *)(sport->tx_buf + \ 165 nextwrite = (struct ac97_frame *)(sport->tx_buf +
135 nextfrag * sport->tx_fragsize); 166 nextfrag * sport->tx_fragsize);
136 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n", 167 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
137 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]); 168 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
@@ -238,8 +269,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
238EXPORT_SYMBOL_GPL(soc_ac97_ops); 269EXPORT_SYMBOL_GPL(soc_ac97_ops);
239 270
240#ifdef CONFIG_PM 271#ifdef CONFIG_PM
241static int bf5xx_ac97_suspend(struct platform_device *pdev, 272static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
242 struct snd_soc_dai *dai)
243{ 273{
244 struct sport_device *sport = 274 struct sport_device *sport =
245 (struct sport_device *)dai->private_data; 275 (struct sport_device *)dai->private_data;
@@ -254,8 +284,7 @@ static int bf5xx_ac97_suspend(struct platform_device *pdev,
254 return 0; 284 return 0;
255} 285}
256 286
257static int bf5xx_ac97_resume(struct platform_device *pdev, 287static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
258 struct snd_soc_dai *dai)
259{ 288{
260 int ret; 289 int ret;
261 struct sport_device *sport = 290 struct sport_device *sport =
@@ -298,20 +327,15 @@ static int bf5xx_ac97_resume(struct platform_device *pdev,
298static int bf5xx_ac97_probe(struct platform_device *pdev, 327static int bf5xx_ac97_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai) 328 struct snd_soc_dai *dai)
300{ 329{
301 int ret; 330 int ret = 0;
302#if defined(CONFIG_BF54x)
303 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1,
304 PIN_REQ_SPORT_2, PIN_REQ_SPORT_3};
305#else
306 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1};
307#endif
308 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 331 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
309 if (cmd_count == NULL) 332 if (cmd_count == NULL)
310 return -ENOMEM; 333 return -ENOMEM;
311 334
312 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 335 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
313 pr_err("Requesting Peripherals failed\n"); 336 pr_err("Requesting Peripherals failed\n");
314 return -EFAULT; 337 ret = -EFAULT;
338 goto peripheral_err;
315 } 339 }
316 340
317#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
@@ -319,54 +343,54 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
319 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { 343 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
320 pr_err("Failed to request GPIO_%d for reset\n", 344 pr_err("Failed to request GPIO_%d for reset\n",
321 CONFIG_SND_BF5XX_RESET_GPIO_NUM); 345 CONFIG_SND_BF5XX_RESET_GPIO_NUM);
322 peripheral_free_list(&sport_req[sport_num][0]); 346 ret = -1;
323 return -1; 347 goto gpio_err;
324 } 348 }
325 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 349 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
326#endif 350#endif
327 sport_handle = sport_init(&sport_params[sport_num], 2, \ 351 sport_handle = sport_init(&sport_params[sport_num], 2, \
328 sizeof(struct ac97_frame), NULL); 352 sizeof(struct ac97_frame), NULL);
329 if (!sport_handle) { 353 if (!sport_handle) {
330 peripheral_free_list(&sport_req[sport_num][0]); 354 ret = -ENODEV;
331#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 355 goto sport_err;
332 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
333#endif
334 return -ENODEV;
335 } 356 }
336 /*SPORT works in TDM mode to simulate AC97 transfers*/ 357 /*SPORT works in TDM mode to simulate AC97 transfers*/
337 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); 358 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
338 if (ret) { 359 if (ret) {
339 pr_err("SPORT is busy!\n"); 360 pr_err("SPORT is busy!\n");
340 kfree(sport_handle); 361 ret = -EBUSY;
341 peripheral_free_list(&sport_req[sport_num][0]); 362 goto sport_config_err;
342#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
343 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
344#endif
345 return -EBUSY;
346 } 363 }
347 364
348 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1)); 365 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
349 if (ret) { 366 if (ret) {
350 pr_err("SPORT is busy!\n"); 367 pr_err("SPORT is busy!\n");
351 kfree(sport_handle); 368 ret = -EBUSY;
352 peripheral_free_list(&sport_req[sport_num][0]); 369 goto sport_config_err;
353#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
354 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
355#endif
356 return -EBUSY;
357 } 370 }
358 371
359 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1)); 372 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
360 if (ret) { 373 if (ret) {
361 pr_err("SPORT is busy!\n"); 374 pr_err("SPORT is busy!\n");
362 kfree(sport_handle); 375 ret = -EBUSY;
363 peripheral_free_list(&sport_req[sport_num][0]); 376 goto sport_config_err;
364#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
365 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
366#endif
367 return -EBUSY;
368 } 377 }
378
369 return 0; 379 return 0;
380
381sport_config_err:
382 kfree(sport_handle);
383sport_err:
384#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
385 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
386#endif
387gpio_err:
388 peripheral_free_list(&sport_req[sport_num][0]);
389peripheral_err:
390 free_page((unsigned long)cmd_count);
391 cmd_count = NULL;
392
393 return ret;
370} 394}
371 395
372static void bf5xx_ac97_remove(struct platform_device *pdev, 396static void bf5xx_ac97_remove(struct platform_device *pdev,
@@ -374,6 +398,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
374{ 398{
375 free_page((unsigned long)cmd_count); 399 free_page((unsigned long)cmd_count);
376 cmd_count = NULL; 400 cmd_count = NULL;
401 peripheral_free_list(&sport_req[sport_num][0]);
377#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 402#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
378 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 403 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
379#endif 404#endif
@@ -382,7 +407,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
382struct snd_soc_dai bfin_ac97_dai = { 407struct snd_soc_dai bfin_ac97_dai = {
383 .name = "bf5xx-ac97", 408 .name = "bf5xx-ac97",
384 .id = 0, 409 .id = 0,
385 .type = SND_SOC_DAI_AC97, 410 .ac97_control = 1,
386 .probe = bf5xx_ac97_probe, 411 .probe = bf5xx_ac97_probe,
387 .remove = bf5xx_ac97_remove, 412 .remove = bf5xx_ac97_remove,
388 .suspend = bf5xx_ac97_suspend, 413 .suspend = bf5xx_ac97_suspend,
@@ -390,7 +415,11 @@ struct snd_soc_dai bfin_ac97_dai = {
390 .playback = { 415 .playback = {
391 .stream_name = "AC97 Playback", 416 .stream_name = "AC97 Playback",
392 .channels_min = 2, 417 .channels_min = 2,
418#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
419 .channels_max = 6,
420#else
393 .channels_max = 2, 421 .channels_max = 2,
422#endif
394 .rates = SNDRV_PCM_RATE_48000, 423 .rates = SNDRV_PCM_RATE_48000,
395 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 424 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
396 .capture = { 425 .capture = {
@@ -402,6 +431,18 @@ struct snd_soc_dai bfin_ac97_dai = {
402}; 431};
403EXPORT_SYMBOL_GPL(bfin_ac97_dai); 432EXPORT_SYMBOL_GPL(bfin_ac97_dai);
404 433
434static int __init bfin_ac97_init(void)
435{
436 return snd_soc_register_dai(&bfin_ac97_dai);
437}
438module_init(bfin_ac97_init);
439
440static void __exit bfin_ac97_exit(void)
441{
442 snd_soc_unregister_dai(&bfin_ac97_dai);
443}
444module_exit(bfin_ac97_exit);
445
405MODULE_AUTHOR("Roy Huang"); 446MODULE_AUTHOR("Roy Huang");
406MODULE_DESCRIPTION("AC97 driver for ADI Blackfin"); 447MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
407MODULE_LICENSE("GPL"); 448MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index 3f77cc558dc0..3f2a911fe0cb 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -16,21 +16,46 @@ struct ac97_frame {
16 u16 ac97_tag; /* slot 0 */ 16 u16 ac97_tag; /* slot 0 */
17 u16 ac97_addr; /* slot 1 */ 17 u16 ac97_addr; /* slot 1 */
18 u16 ac97_data; /* slot 2 */ 18 u16 ac97_data; /* slot 2 */
19 u32 ac97_pcm; /* slot 3 and 4: left and right pcm data */ 19 u16 ac97_pcm_l; /*slot 3:front left*/
20 u16 ac97_pcm_r; /*slot 4:front left*/
21#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
22 u16 ac97_mdm_l1;
23 u16 ac97_center; /*slot 6:center*/
24 u16 ac97_sl; /*slot 7:surround left*/
25 u16 ac97_sr; /*slot 8:surround right*/
26 u16 ac97_lfe; /*slot 9:lfe*/
27#endif
20} __attribute__ ((packed)); 28} __attribute__ ((packed));
21 29
30/* Speaker location */
31#define SP_FL 0x0001
32#define SP_FR 0x0010
33#define SP_FC 0x0002
34#define SP_LFE 0x0020
35#define SP_SL 0x0004
36#define SP_SR 0x0040
37
38#define SP_STEREO (SP_FL | SP_FR)
39#define SP_2DOT1 (SP_FL | SP_FR | SP_LFE)
40#define SP_QUAD (SP_FL | SP_FR | SP_SL | SP_SR)
41#define SP_5DOT1 (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
42
22#define TAG_VALID 0x8000 43#define TAG_VALID 0x8000
23#define TAG_CMD 0x6000 44#define TAG_CMD 0x6000
24#define TAG_PCM_LEFT 0x1000 45#define TAG_PCM_LEFT 0x1000
25#define TAG_PCM_RIGHT 0x0800 46#define TAG_PCM_RIGHT 0x0800
26#define TAG_PCM (TAG_PCM_LEFT | TAG_PCM_RIGHT) 47#define TAG_PCM_MDM_L1 0x0400
48#define TAG_PCM_CENTER 0x0200
49#define TAG_PCM_SL 0x0100
50#define TAG_PCM_SR 0x0080
51#define TAG_PCM_LFE 0x0040
27 52
28extern struct snd_soc_dai bfin_ac97_dai; 53extern struct snd_soc_dai bfin_ac97_dai;
29 54
30void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 55void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
31 size_t count); 56 size_t count, unsigned int chan_mask);
32 57
33void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 58void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
34 size_t count); 59 size_t count);
35 60
36#endif 61#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index 124425d22320..d8f591273778 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -43,7 +43,7 @@
43#include "bf5xx-ac97-pcm.h" 43#include "bf5xx-ac97-pcm.h"
44#include "bf5xx-ac97.h" 44#include "bf5xx-ac97.h"
45 45
46static struct snd_soc_machine bf5xx_board; 46static struct snd_soc_card bf5xx_board;
47 47
48static int bf5xx_board_startup(struct snd_pcm_substream *substream) 48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{ 49{
@@ -67,15 +67,15 @@ static struct snd_soc_dai_link bf5xx_board_dai = {
67 .ops = &bf5xx_board_ops, 67 .ops = &bf5xx_board_ops,
68}; 68};
69 69
70static struct snd_soc_machine bf5xx_board = { 70static struct snd_soc_card bf5xx_board = {
71 .name = "bf5xx-board", 71 .name = "bf5xx-board",
72 .platform = &bf5xx_ac97_soc_platform,
72 .dai_link = &bf5xx_board_dai, 73 .dai_link = &bf5xx_board_dai,
73 .num_links = 1, 74 .num_links = 1,
74}; 75};
75 76
76static struct snd_soc_device bf5xx_board_snd_devdata = { 77static struct snd_soc_device bf5xx_board_snd_devdata = {
77 .machine = &bf5xx_board, 78 .card = &bf5xx_board,
78 .platform = &bf5xx_ac97_soc_platform,
79 .codec_dev = &soc_codec_dev_ad1980, 79 .codec_dev = &soc_codec_dev_ad1980,
80}; 80};
81 81
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
new file mode 100644
index 000000000000..7f2a5e199075
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -0,0 +1,240 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad73311.c
3 * Author: Cliff Cai <Cliff.Cai@analog.com>
4 *
5 * Created: Thur Sep 25 2008
6 * Description: Board driver for ad73311 sound chip
7 *
8 * Modified:
9 * Copyright 2008 Analog Devices Inc.
10 *
11 * Bugs: Enter bugs at http://blackfin.uclinux.org/
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see the file COPYING, or write
25 * to the Free Software Foundation, Inc.,
26 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 */
28
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/device.h>
32#include <linux/delay.h>
33#include <linux/gpio.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/pcm_params.h>
40
41#include <asm/blackfin.h>
42#include <asm/cacheflush.h>
43#include <asm/irq.h>
44#include <asm/dma.h>
45#include <asm/portmux.h>
46
47#include "../codecs/ad73311.h"
48#include "bf5xx-sport.h"
49#include "bf5xx-i2s-pcm.h"
50#include "bf5xx-i2s.h"
51
52#if CONFIG_SND_BF5XX_SPORT_NUM == 0
53#define bfin_write_SPORT_TCR1 bfin_write_SPORT0_TCR1
54#define bfin_read_SPORT_TCR1 bfin_read_SPORT0_TCR1
55#define bfin_write_SPORT_TCR2 bfin_write_SPORT0_TCR2
56#define bfin_write_SPORT_TX16 bfin_write_SPORT0_TX16
57#define bfin_read_SPORT_STAT bfin_read_SPORT0_STAT
58#else
59#define bfin_write_SPORT_TCR1 bfin_write_SPORT1_TCR1
60#define bfin_read_SPORT_TCR1 bfin_read_SPORT1_TCR1
61#define bfin_write_SPORT_TCR2 bfin_write_SPORT1_TCR2
62#define bfin_write_SPORT_TX16 bfin_write_SPORT1_TX16
63#define bfin_read_SPORT_STAT bfin_read_SPORT1_STAT
64#endif
65
66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
67
68static struct snd_soc_card bf5xx_ad73311;
69
70static int snd_ad73311_startup(void)
71{
72 pr_debug("%s enter\n", __func__);
73
74 /* Pull up SE pin on AD73311L */
75 gpio_set_value(GPIO_SE, 1);
76 return 0;
77}
78
79static int snd_ad73311_configure(void)
80{
81 unsigned short ctrl_regs[6];
82 unsigned short status = 0;
83 int count = 0;
84
85 /* DMCLK = MCLK = 16.384 MHz
86 * SCLK = DMCLK/8 = 2.048 MHz
87 * Sample Rate = DMCLK/2048 = 8 KHz
88 */
89 ctrl_regs[0] = AD_CONTROL | AD_WRITE | CTRL_REG_B | REGB_MCDIV(0) | \
90 REGB_SCDIV(0) | REGB_DIRATE(0);
91 ctrl_regs[1] = AD_CONTROL | AD_WRITE | CTRL_REG_C | REGC_PUDEV | \
92 REGC_PUADC | REGC_PUDAC | REGC_PUREF | REGC_REFUSE ;
93 ctrl_regs[2] = AD_CONTROL | AD_WRITE | CTRL_REG_D | REGD_OGS(2) | \
94 REGD_IGS(2);
95 ctrl_regs[3] = AD_CONTROL | AD_WRITE | CTRL_REG_E | REGE_DA(0x1f);
96 ctrl_regs[4] = AD_CONTROL | AD_WRITE | CTRL_REG_F | REGF_SEEN ;
97 ctrl_regs[5] = AD_CONTROL | AD_WRITE | CTRL_REG_A | REGA_MODE_DATA;
98
99 local_irq_disable();
100 snd_ad73311_startup();
101 udelay(1);
102
103 bfin_write_SPORT_TCR1(TFSR);
104 bfin_write_SPORT_TCR2(0xF);
105 SSYNC();
106
107 /* SPORT Tx Register is a 8 x 16 FIFO, all the data can be put to
108 * FIFO before enable SPORT to transfer the data
109 */
110 for (count = 0; count < 6; count++)
111 bfin_write_SPORT_TX16(ctrl_regs[count]);
112 SSYNC();
113 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() | TSPEN);
114 SSYNC();
115
116 /* When TUVF is set, the data is already send out */
117 while (!(status & TUVF) && count++ < 10000) {
118 udelay(1);
119 status = bfin_read_SPORT_STAT();
120 SSYNC();
121 }
122 bfin_write_SPORT_TCR1(bfin_read_SPORT_TCR1() & ~TSPEN);
123 SSYNC();
124 local_irq_enable();
125
126 if (count == 10000) {
127 printk(KERN_ERR "ad73311: failed to configure codec\n");
128 return -1;
129 }
130 return 0;
131}
132
133static int bf5xx_probe(struct platform_device *pdev)
134{
135 int err;
136 if (gpio_request(GPIO_SE, "AD73311_SE")) {
137 printk(KERN_ERR "%s: Failed ro request GPIO_%d\n", __func__, GPIO_SE);
138 return -EBUSY;
139 }
140
141 gpio_direction_output(GPIO_SE, 0);
142
143 err = snd_ad73311_configure();
144 if (err < 0)
145 return -EFAULT;
146
147 return 0;
148}
149
150static int bf5xx_ad73311_startup(struct snd_pcm_substream *substream)
151{
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
154
155 pr_debug("%s enter\n", __func__);
156 cpu_dai->private_data = sport_handle;
157 return 0;
158}
159
160static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params)
162{
163 struct snd_soc_pcm_runtime *rtd = substream->private_data;
164 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
165 int ret = 0;
166
167 pr_debug("%s rate %d format %x\n", __func__, params_rate(params),
168 params_format(params));
169
170 /* set cpu DAI configuration */
171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179
180static struct snd_soc_ops bf5xx_ad73311_ops = {
181 .startup = bf5xx_ad73311_startup,
182 .hw_params = bf5xx_ad73311_hw_params,
183};
184
185static struct snd_soc_dai_link bf5xx_ad73311_dai = {
186 .name = "ad73311",
187 .stream_name = "AD73311",
188 .cpu_dai = &bf5xx_i2s_dai,
189 .codec_dai = &ad73311_dai,
190 .ops = &bf5xx_ad73311_ops,
191};
192
193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311",
195 .platform = &bf5xx_i2s_soc_platform,
196 .probe = bf5xx_probe,
197 .dai_link = &bf5xx_ad73311_dai,
198 .num_links = 1,
199};
200
201static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
202 .card = &bf5xx_ad73311,
203 .codec_dev = &soc_codec_dev_ad73311,
204};
205
206static struct platform_device *bf52x_ad73311_snd_device;
207
208static int __init bf5xx_ad73311_init(void)
209{
210 int ret;
211
212 pr_debug("%s enter\n", __func__);
213 bf52x_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
214 if (!bf52x_ad73311_snd_device)
215 return -ENOMEM;
216
217 platform_set_drvdata(bf52x_ad73311_snd_device, &bf5xx_ad73311_snd_devdata);
218 bf5xx_ad73311_snd_devdata.dev = &bf52x_ad73311_snd_device->dev;
219 ret = platform_device_add(bf52x_ad73311_snd_device);
220
221 if (ret)
222 platform_device_put(bf52x_ad73311_snd_device);
223
224 return ret;
225}
226
227static void __exit bf5xx_ad73311_exit(void)
228{
229 pr_debug("%s enter\n", __func__);
230 platform_device_unregister(bf52x_ad73311_snd_device);
231}
232
233module_init(bf5xx_ad73311_init);
234module_exit(bf5xx_ad73311_exit);
235
236/* Module information */
237MODULE_AUTHOR("Cliff Cai");
238MODULE_DESCRIPTION("ALSA SoC AD73311 Blackfin");
239MODULE_LICENSE("GPL");
240
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 61fccf925192..53d290b3ea47 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -283,6 +283,18 @@ struct snd_soc_platform bf5xx_i2s_soc_platform = {
283}; 283};
284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform); 284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
285 285
286static int __init bfin_i2s_init(void)
287{
288 return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
289}
290module_init(bfin_i2s_init);
291
292static void __exit bfin_i2s_exit(void)
293{
294 snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
295}
296module_exit(bfin_i2s_exit);
297
286MODULE_AUTHOR("Cliff Cai"); 298MODULE_AUTHOR("Cliff Cai");
287MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module"); 299MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
288MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 43a4092eeb89..d1d95d2393fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -70,6 +70,25 @@ static struct sport_param sport_params[2] = {
70 } 70 }
71}; 71};
72 72
73/*
74 * Setting the TFS pin selector for SPORT 0 based on whether the selected
75 * port id F or G. If the port is F then no conflict should exist for the
76 * TFS. When Port G is selected and EMAC then there is a conflict between
77 * the PHY interrupt line and TFS. Current settings prevent the conflict
78 * by ignoring the TFS pin when Port G is selected. This allows both
79 * ssm2602 using Port G and EMAC concurrently.
80 */
81#ifdef CONFIG_BF527_SPORT0_PORTF
82#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
83#else
84#define LOCAL_SPORT0_TFS (0)
85#endif
86
87static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
88 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
89 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
90 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
91
73static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 92static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
74 unsigned int fmt) 93 unsigned int fmt)
75{ 94{
@@ -78,28 +97,34 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
78 /* interface format:support I2S,slave mode */ 97 /* interface format:support I2S,slave mode */
79 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 98 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
80 case SND_SOC_DAIFMT_I2S: 99 case SND_SOC_DAIFMT_I2S:
100 bf5xx_i2s.tcr1 |= TFSR | TCKFE;
101 bf5xx_i2s.rcr1 |= RFSR | RCKFE;
102 bf5xx_i2s.tcr2 |= TSFSE;
103 bf5xx_i2s.rcr2 |= RSFSE;
104 break;
105 case SND_SOC_DAIFMT_DSP_A:
106 bf5xx_i2s.tcr1 |= TFSR;
107 bf5xx_i2s.rcr1 |= RFSR;
81 break; 108 break;
82 case SND_SOC_DAIFMT_LEFT_J: 109 case SND_SOC_DAIFMT_LEFT_J:
83 ret = -EINVAL; 110 ret = -EINVAL;
84 break; 111 break;
85 default: 112 default:
113 printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
86 ret = -EINVAL; 114 ret = -EINVAL;
87 break; 115 break;
88 } 116 }
89 117
90 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 118 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
91 case SND_SOC_DAIFMT_CBS_CFS:
92 ret = -EINVAL;
93 break;
94 case SND_SOC_DAIFMT_CBM_CFS:
95 ret = -EINVAL;
96 break;
97 case SND_SOC_DAIFMT_CBM_CFM: 119 case SND_SOC_DAIFMT_CBM_CFM:
98 break; 120 break;
121 case SND_SOC_DAIFMT_CBS_CFS:
122 case SND_SOC_DAIFMT_CBM_CFS:
99 case SND_SOC_DAIFMT_CBS_CFM: 123 case SND_SOC_DAIFMT_CBS_CFM:
100 ret = -EINVAL; 124 ret = -EINVAL;
101 break; 125 break;
102 default: 126 default:
127 printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
103 ret = -EINVAL; 128 ret = -EINVAL;
104 break; 129 break;
105 } 130 }
@@ -107,7 +132,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
107 return ret; 132 return ret;
108} 133}
109 134
110static int bf5xx_i2s_startup(struct snd_pcm_substream *substream) 135static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
136 struct snd_soc_dai *dai)
111{ 137{
112 pr_debug("%s enter\n", __func__); 138 pr_debug("%s enter\n", __func__);
113 139
@@ -117,7 +143,8 @@ static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
117} 143}
118 144
119static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 145static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params) 146 struct snd_pcm_hw_params *params,
147 struct snd_soc_dai *dai)
121{ 148{
122 int ret = 0; 149 int ret = 0;
123 150
@@ -127,14 +154,17 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
127 case SNDRV_PCM_FORMAT_S16_LE: 154 case SNDRV_PCM_FORMAT_S16_LE:
128 bf5xx_i2s.tcr2 |= 15; 155 bf5xx_i2s.tcr2 |= 15;
129 bf5xx_i2s.rcr2 |= 15; 156 bf5xx_i2s.rcr2 |= 15;
157 sport_handle->wdsize = 2;
130 break; 158 break;
131 case SNDRV_PCM_FORMAT_S24_LE: 159 case SNDRV_PCM_FORMAT_S24_LE:
132 bf5xx_i2s.tcr2 |= 23; 160 bf5xx_i2s.tcr2 |= 23;
133 bf5xx_i2s.rcr2 |= 23; 161 bf5xx_i2s.rcr2 |= 23;
162 sport_handle->wdsize = 3;
134 break; 163 break;
135 case SNDRV_PCM_FORMAT_S32_LE: 164 case SNDRV_PCM_FORMAT_S32_LE:
136 bf5xx_i2s.tcr2 |= 31; 165 bf5xx_i2s.tcr2 |= 31;
137 bf5xx_i2s.rcr2 |= 31; 166 bf5xx_i2s.rcr2 |= 31;
167 sport_handle->wdsize = 4;
138 break; 168 break;
139 } 169 }
140 170
@@ -145,17 +175,17 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
145 * need to configure both of them at the time when the first 175 * need to configure both of them at the time when the first
146 * stream is opened. 176 * stream is opened.
147 * 177 *
148 * CPU DAI format:I2S, slave mode. 178 * CPU DAI:slave mode.
149 */ 179 */
150 ret = sport_config_rx(sport_handle, RFSR | RCKFE, 180 ret = sport_config_rx(sport_handle, bf5xx_i2s.rcr1,
151 RSFSE|bf5xx_i2s.rcr2, 0, 0); 181 bf5xx_i2s.rcr2, 0, 0);
152 if (ret) { 182 if (ret) {
153 pr_err("SPORT is busy!\n"); 183 pr_err("SPORT is busy!\n");
154 return -EBUSY; 184 return -EBUSY;
155 } 185 }
156 186
157 ret = sport_config_tx(sport_handle, TFSR | TCKFE, 187 ret = sport_config_tx(sport_handle, bf5xx_i2s.tcr1,
158 TSFSE|bf5xx_i2s.tcr2, 0, 0); 188 bf5xx_i2s.tcr2, 0, 0);
159 if (ret) { 189 if (ret) {
160 pr_err("SPORT is busy!\n"); 190 pr_err("SPORT is busy!\n");
161 return -EBUSY; 191 return -EBUSY;
@@ -165,7 +195,8 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
165 return 0; 195 return 0;
166} 196}
167 197
168static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream) 198static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
199 struct snd_soc_dai *dai)
169{ 200{
170 pr_debug("%s enter\n", __func__); 201 pr_debug("%s enter\n", __func__);
171 bf5xx_i2s.counter--; 202 bf5xx_i2s.counter--;
@@ -174,13 +205,6 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream)
174static int bf5xx_i2s_probe(struct platform_device *pdev, 205static int bf5xx_i2s_probe(struct platform_device *pdev,
175 struct snd_soc_dai *dai) 206 struct snd_soc_dai *dai)
176{ 207{
177 u16 sport_req[][7] = {
178 { P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
179 P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0},
180 { P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
181 P_SPORT1_DRPRI, P_SPORT1_RSCLK, 0},
182 };
183
184 pr_debug("%s enter\n", __func__); 208 pr_debug("%s enter\n", __func__);
185 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 209 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
186 pr_err("Requesting Peripherals failed\n"); 210 pr_err("Requesting Peripherals failed\n");
@@ -198,9 +222,14 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
198 return 0; 222 return 0;
199} 223}
200 224
225static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
226{
227 pr_debug("%s enter\n", __func__);
228 peripheral_free_list(&sport_req[sport_num][0]);
229}
230
201#ifdef CONFIG_PM 231#ifdef CONFIG_PM
202static int bf5xx_i2s_suspend(struct platform_device *dev, 232static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
203 struct snd_soc_dai *dai)
204{ 233{
205 struct sport_device *sport = 234 struct sport_device *sport =
206 (struct sport_device *)dai->private_data; 235 (struct sport_device *)dai->private_data;
@@ -261,30 +290,41 @@ static int bf5xx_i2s_resume(struct platform_device *pdev,
261struct snd_soc_dai bf5xx_i2s_dai = { 290struct snd_soc_dai bf5xx_i2s_dai = {
262 .name = "bf5xx-i2s", 291 .name = "bf5xx-i2s",
263 .id = 0, 292 .id = 0,
264 .type = SND_SOC_DAI_I2S,
265 .probe = bf5xx_i2s_probe, 293 .probe = bf5xx_i2s_probe,
294 .remove = bf5xx_i2s_remove,
266 .suspend = bf5xx_i2s_suspend, 295 .suspend = bf5xx_i2s_suspend,
267 .resume = bf5xx_i2s_resume, 296 .resume = bf5xx_i2s_resume,
268 .playback = { 297 .playback = {
269 .channels_min = 2, 298 .channels_min = 1,
270 .channels_max = 2, 299 .channels_max = 2,
271 .rates = BF5XX_I2S_RATES, 300 .rates = BF5XX_I2S_RATES,
272 .formats = BF5XX_I2S_FORMATS,}, 301 .formats = BF5XX_I2S_FORMATS,},
273 .capture = { 302 .capture = {
274 .channels_min = 2, 303 .channels_min = 1,
275 .channels_max = 2, 304 .channels_max = 2,
276 .rates = BF5XX_I2S_RATES, 305 .rates = BF5XX_I2S_RATES,
277 .formats = BF5XX_I2S_FORMATS,}, 306 .formats = BF5XX_I2S_FORMATS,},
278 .ops = { 307 .ops = {
279 .startup = bf5xx_i2s_startup, 308 .startup = bf5xx_i2s_startup,
280 .shutdown = bf5xx_i2s_shutdown, 309 .shutdown = bf5xx_i2s_shutdown,
281 .hw_params = bf5xx_i2s_hw_params,}, 310 .hw_params = bf5xx_i2s_hw_params,
282 .dai_ops = {
283 .set_fmt = bf5xx_i2s_set_dai_fmt, 311 .set_fmt = bf5xx_i2s_set_dai_fmt,
284 }, 312 },
285}; 313};
286EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); 314EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
287 315
316static int __init bfin_i2s_init(void)
317{
318 return snd_soc_register_dai(&bf5xx_i2s_dai);
319}
320module_init(bfin_i2s_init);
321
322static void __exit bfin_i2s_exit(void)
323{
324 snd_soc_unregister_dai(&bf5xx_i2s_dai);
325}
326module_exit(bfin_i2s_exit);
327
288/* Module information */ 328/* Module information */
289MODULE_AUTHOR("Cliff Cai"); 329MODULE_AUTHOR("Cliff Cai");
290MODULE_DESCRIPTION("I2S driver for ADI Blackfin"); 330MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index 4c163454bbf8..2e63dea73e9c 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -116,13 +116,15 @@ struct sport_device {
116 void *err_data; 116 void *err_data;
117 unsigned char *tx_dma_buf; 117 unsigned char *tx_dma_buf;
118 unsigned char *rx_dma_buf; 118 unsigned char *rx_dma_buf;
119#ifdef CONFIG_SND_MMAP_SUPPORT 119#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
120 dma_addr_t tx_dma_phy; 120 dma_addr_t tx_dma_phy;
121 dma_addr_t rx_dma_phy; 121 dma_addr_t rx_dma_phy;
122 int tx_pos;/*pcm sample count*/ 122 int tx_pos;/*pcm sample count*/
123 int rx_pos; 123 int rx_pos;
124 unsigned int tx_buffer_size; 124 unsigned int tx_buffer_size;
125 unsigned int rx_buffer_size; 125 unsigned int rx_buffer_size;
126 int tx_delay_pos;
127 int once;
126#endif 128#endif
127 void *private_data; 129 void *private_data;
128}; 130};
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index e15f67fd7769..bc0cdded7116 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,7 +44,7 @@
44#include "bf5xx-i2s-pcm.h" 44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h" 45#include "bf5xx-i2s.h"
46 46
47static struct snd_soc_machine bf5xx_ssm2602; 47static struct snd_soc_card bf5xx_ssm2602;
48 48
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream) 49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{ 50{
@@ -92,17 +92,17 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
92 */ 92 */
93 93
94 /* set codec DAI configuration */ 94 /* set codec DAI configuration */
95 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 95 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0) 97 if (ret < 0)
98 return ret; 98 return ret;
99 /* set cpu DAI configuration */ 99 /* set cpu DAI configuration */
100 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 100 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0) 102 if (ret < 0)
103 return ret; 103 return ret;
104 104
105 ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk, 105 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
106 SND_SOC_CLOCK_IN); 106 SND_SOC_CLOCK_IN);
107 if (ret < 0) 107 if (ret < 0)
108 return ret; 108 return ret;
@@ -135,15 +135,15 @@ static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
135 .i2c_address = 0x1b, 135 .i2c_address = 0x1b,
136}; 136};
137 137
138static struct snd_soc_machine bf5xx_ssm2602 = { 138static struct snd_soc_card bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602", 139 .name = "bf5xx_ssm2602",
140 .platform = &bf5xx_i2s_soc_platform,
140 .dai_link = &bf5xx_ssm2602_dai, 141 .dai_link = &bf5xx_ssm2602_dai,
141 .num_links = 1, 142 .num_links = 1,
142}; 143};
143 144
144static struct snd_soc_device bf5xx_ssm2602_snd_devdata = { 145static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
145 .machine = &bf5xx_ssm2602, 146 .card = &bf5xx_ssm2602,
146 .platform = &bf5xx_i2s_soc_platform,
147 .codec_dev = &soc_codec_dev_ssm2602, 147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup, 148 .codec_data = &bf5xx_ssm2602_setup,
149}; 149};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index e0b9869df0f1..d0e0d691ae51 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,29 +1,50 @@
1# Helper to resolve issues with configs that have SPI enabled but I2C
2# modular, meaning we can't build the codec driver in with I2C support.
3# We use an ordered list of conditional defaults to pick the appropriate
4# setting - SPI can't be modular so that case doesn't need to be covered.
5config SND_SOC_I2C_AND_SPI
6 tristate
7 default m if I2C=m
8 default y if I2C=y
9 default y if SPI_MASTER=y
10
1config SND_SOC_ALL_CODECS 11config SND_SOC_ALL_CODECS
2 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
3 depends on I2C 13 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
4 select SPI 14 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
5 select SPI_MASTER 15 select SND_SOC_AD73311 if I2C
6 select SND_SOC_AK4535 16 select SND_SOC_AK4535 if I2C
7 select SND_SOC_CS4270 17 select SND_SOC_CS4270 if I2C
8 select SND_SOC_SSM2602 18 select SND_SOC_PCM3008
9 select SND_SOC_TLV320AIC26 19 select SND_SOC_SSM2602 if I2C
10 select SND_SOC_TLV320AIC3X 20 select SND_SOC_TLV320AIC23 if I2C
11 select SND_SOC_UDA1380 21 select SND_SOC_TLV320AIC26 if SPI_MASTER
12 select SND_SOC_WM8510 22 select SND_SOC_TLV320AIC3X if I2C
13 select SND_SOC_WM8580 23 select SND_SOC_TWL4030 if TWL4030_CORE
14 select SND_SOC_WM8731 24 select SND_SOC_UDA134X
15 select SND_SOC_WM8750 25 select SND_SOC_UDA1380 if I2C
16 select SND_SOC_WM8753 26 select SND_SOC_WM8350 if MFD_WM8350
17 select SND_SOC_WM8900 27 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
18 select SND_SOC_WM8903 28 select SND_SOC_WM8580 if I2C
19 select SND_SOC_WM8971 29 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
20 select SND_SOC_WM8990 30 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
31 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
32 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
33 select SND_SOC_WM8900 if I2C
34 select SND_SOC_WM8903 if I2C
35 select SND_SOC_WM8971 if I2C
36 select SND_SOC_WM8990 if I2C
37 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
38 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
21 help 39 help
22 Normally ASoC codec drivers are only built if a machine driver which 40 Normally ASoC codec drivers are only built if a machine driver which
23 uses them is also built since they are only usable with a machine 41 uses them is also built since they are only usable with a machine
24 driver. Selecting this option will allow these drivers to be built 42 driver. Selecting this option will allow these drivers to be built
25 without an explicit machine driver for test and development purposes. 43 without an explicit machine driver for test and development purposes.
26 44
45 Support for the bus types used to access the codecs to be built must
46 be selected separately.
47
27 If unsure select "N". 48 If unsure select "N".
28 49
29 50
@@ -34,6 +55,9 @@ config SND_SOC_AC97_CODEC
34config SND_SOC_AD1980 55config SND_SOC_AD1980
35 tristate 56 tristate
36 57
58config SND_SOC_AD73311
59 tristate
60
37config SND_SOC_AK4535 61config SND_SOC_AK4535
38 tristate 62 tristate
39 63
@@ -55,26 +79,50 @@ config SND_SOC_CS4270_VD33_ERRATA
55 bool 79 bool
56 depends on SND_SOC_CS4270 80 depends on SND_SOC_CS4270
57 81
82config SND_SOC_L3
83 tristate
84
85config SND_SOC_PCM3008
86 tristate
87
58config SND_SOC_SSM2602 88config SND_SOC_SSM2602
59 tristate 89 tristate
60 90
91config SND_SOC_TLV320AIC23
92 tristate
93 depends on I2C
94
61config SND_SOC_TLV320AIC26 95config SND_SOC_TLV320AIC26
62 tristate "TI TLV320AIC26 Codec support" 96 tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE
63 depends on SND_SOC && SPI 97 depends on SPI
64 98
65config SND_SOC_TLV320AIC3X 99config SND_SOC_TLV320AIC3X
66 tristate 100 tristate
67 depends on I2C 101 depends on I2C
68 102
103config SND_SOC_TWL4030
104 tristate
105 depends on TWL4030_CORE
106
107config SND_SOC_UDA134X
108 tristate
109 select SND_SOC_L3
110
69config SND_SOC_UDA1380 111config SND_SOC_UDA1380
70 tristate 112 tristate
71 113
114config SND_SOC_WM8350
115 tristate
116
72config SND_SOC_WM8510 117config SND_SOC_WM8510
73 tristate 118 tristate
74 119
75config SND_SOC_WM8580 120config SND_SOC_WM8580
76 tristate 121 tristate
77 122
123config SND_SOC_WM8728
124 tristate
125
78config SND_SOC_WM8731 126config SND_SOC_WM8731
79 tristate 127 tristate
80 128
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f977978a3409..c4ddc9aa2bbd 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,13 +1,21 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1980-objs := ad1980.o 2snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o
3snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
4snd-soc-cs4270-objs := cs4270.o 5snd-soc-cs4270-objs := cs4270.o
6snd-soc-l3-objs := l3.o
7snd-soc-pcm3008-objs := pcm3008.o
5snd-soc-ssm2602-objs := ssm2602.o 8snd-soc-ssm2602-objs := ssm2602.o
9snd-soc-tlv320aic23-objs := tlv320aic23.o
6snd-soc-tlv320aic26-objs := tlv320aic26.o 10snd-soc-tlv320aic26-objs := tlv320aic26.o
7snd-soc-tlv320aic3x-objs := tlv320aic3x.o 11snd-soc-tlv320aic3x-objs := tlv320aic3x.o
12snd-soc-twl4030-objs := twl4030.o
13snd-soc-uda134x-objs := uda134x.o
8snd-soc-uda1380-objs := uda1380.o 14snd-soc-uda1380-objs := uda1380.o
15snd-soc-wm8350-objs := wm8350.o
9snd-soc-wm8510-objs := wm8510.o 16snd-soc-wm8510-objs := wm8510.o
10snd-soc-wm8580-objs := wm8580.o 17snd-soc-wm8580-objs := wm8580.o
18snd-soc-wm8728-objs := wm8728.o
11snd-soc-wm8731-objs := wm8731.o 19snd-soc-wm8731-objs := wm8731.o
12snd-soc-wm8750-objs := wm8750.o 20snd-soc-wm8750-objs := wm8750.o
13snd-soc-wm8753-objs := wm8753.o 21snd-soc-wm8753-objs := wm8753.o
@@ -20,14 +28,22 @@ snd-soc-wm9713-objs := wm9713.o
20 28
21obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 29obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
22obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 30obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
31obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
23obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 32obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
24obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 33obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
34obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
35obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
25obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 36obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
37obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
26obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 38obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
27obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 39obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
40obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
41obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
28obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 42obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
43obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
29obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 44obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
30obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 45obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
46obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
31obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 47obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
32obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 48obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
33obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 49obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 61fd96ca7bc7..fb53e6511af2 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -2,8 +2,7 @@
2 * ac97.c -- ALSA Soc AC97 codec support 2 * ac97.c -- ALSA Soc AC97 codec support
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -25,7 +24,8 @@
25 24
26#define AC97_VERSION "0.6" 25#define AC97_VERSION "0.6"
27 26
28static int ac97_prepare(struct snd_pcm_substream *substream) 27static int ac97_prepare(struct snd_pcm_substream *substream,
28 struct snd_soc_dai *dai)
29{ 29{
30 struct snd_pcm_runtime *runtime = substream->runtime; 30 struct snd_pcm_runtime *runtime = substream->runtime;
31 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -43,7 +43,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
43 43
44struct snd_soc_dai ac97_dai = { 44struct snd_soc_dai ac97_dai = {
45 .name = "AC97 HiFi", 45 .name = "AC97 HiFi",
46 .type = SND_SOC_DAI_AC97, 46 .ac97_control = 1,
47 .playback = { 47 .playback = {
48 .stream_name = "AC97 Playback", 48 .stream_name = "AC97 Playback",
49 .channels_min = 1, 49 .channels_min = 1,
@@ -114,7 +114,7 @@ static int ac97_soc_probe(struct platform_device *pdev)
114 if (ret < 0) 114 if (ret < 0)
115 goto bus_err; 115 goto bus_err;
116 116
117 ret = snd_soc_register_card(socdev); 117 ret = snd_soc_init_card(socdev);
118 if (ret < 0) 118 if (ret < 0)
119 goto bus_err; 119 goto bus_err;
120 return 0; 120 return 0;
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 4e09c1f2c063..73fdbb4d4a3d 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/init.h> 14#include <linux/init.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/version.h>
17#include <linux/kernel.h> 16#include <linux/kernel.h>
18#include <linux/device.h> 17#include <linux/device.h>
19#include <sound/core.h> 18#include <sound/core.h>
@@ -86,6 +85,9 @@ SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
86SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), 85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
87SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1), 86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
88 87
88SOC_DOUBLE("Center/LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 0, 31, 1),
89SOC_DOUBLE("Center/LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 7, 1, 1),
90
89SOC_ENUM("Capture Source", ad1980_cap_src), 91SOC_ENUM("Capture Source", ad1980_cap_src),
90 92
91SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), 93SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
@@ -143,10 +145,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
143 145
144struct snd_soc_dai ad1980_dai = { 146struct snd_soc_dai ad1980_dai = {
145 .name = "AC97", 147 .name = "AC97",
148 .ac97_control = 1,
146 .playback = { 149 .playback = {
147 .stream_name = "Playback", 150 .stream_name = "Playback",
148 .channels_min = 2, 151 .channels_min = 2,
149 .channels_max = 2, 152 .channels_max = 6,
150 .rates = SNDRV_PCM_RATE_48000, 153 .rates = SNDRV_PCM_RATE_48000,
151 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 154 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
152 .capture = { 155 .capture = {
@@ -193,6 +196,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
193 struct snd_soc_codec *codec; 196 struct snd_soc_codec *codec;
194 int ret = 0; 197 int ret = 0;
195 u16 vendor_id2; 198 u16 vendor_id2;
199 u16 ext_status;
196 200
197 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 201 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
198 202
@@ -235,7 +239,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
235 239
236 ret = ad1980_reset(codec, 0); 240 ret = ad1980_reset(codec, 0);
237 if (ret < 0) { 241 if (ret < 0) {
238 printk(KERN_ERR "AC97 link error\n"); 242 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
239 goto reset_err; 243 goto reset_err;
240 } 244 }
241 245
@@ -254,12 +258,19 @@ static int ad1980_soc_probe(struct platform_device *pdev)
254 "supported\n"); 258 "supported\n");
255 } 259 }
256 260
257 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */ 261 /* unmute captures and playbacks volume */
258 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */ 262 ac97_write(codec, AC97_MASTER, 0x0000);
259 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */ 263 ac97_write(codec, AC97_PCM, 0x0000);
264 ac97_write(codec, AC97_REC_GAIN, 0x0000);
265 ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
266 ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
267
268 /*power on LFE/CENTER/Surround DACs*/
269 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
270 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
260 271
261 ad1980_add_controls(codec); 272 ad1980_add_controls(codec);
262 ret = snd_soc_register_card(socdev); 273 ret = snd_soc_init_card(socdev);
263 if (ret < 0) { 274 if (ret < 0) {
264 printk(KERN_ERR "ad1980: failed to register card\n"); 275 printk(KERN_ERR "ad1980: failed to register card\n");
265 goto reset_err; 276 goto reset_err;
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
new file mode 100644
index 000000000000..b09289a1e55a
--- /dev/null
+++ b/sound/soc/codecs/ad73311.c
@@ -0,0 +1,115 @@
1/*
2 * ad73311.c -- ALSA Soc AD73311 codec support
3 *
4 * Copyright: Analog Device Inc.
5 * Author: Cliff Cai <cliff.cai@analog.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/kernel.h>
16#include <linux/device.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/ac97_codec.h>
20#include <sound/initval.h>
21#include <sound/soc.h>
22
23#include "ad73311.h"
24
25struct snd_soc_dai ad73311_dai = {
26 .name = "AD73311",
27 .playback = {
28 .stream_name = "Playback",
29 .channels_min = 1,
30 .channels_max = 1,
31 .rates = SNDRV_PCM_RATE_8000,
32 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
33 .capture = {
34 .stream_name = "Capture",
35 .channels_min = 1,
36 .channels_max = 1,
37 .rates = SNDRV_PCM_RATE_8000,
38 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
39};
40EXPORT_SYMBOL_GPL(ad73311_dai);
41
42static int ad73311_soc_probe(struct platform_device *pdev)
43{
44 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
45 struct snd_soc_codec *codec;
46 int ret = 0;
47
48 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
49 if (codec == NULL)
50 return -ENOMEM;
51 mutex_init(&codec->mutex);
52 codec->name = "AD73311";
53 codec->owner = THIS_MODULE;
54 codec->dai = &ad73311_dai;
55 codec->num_dai = 1;
56 socdev->codec = codec;
57 INIT_LIST_HEAD(&codec->dapm_widgets);
58 INIT_LIST_HEAD(&codec->dapm_paths);
59
60 /* register pcms */
61 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
62 if (ret < 0) {
63 printk(KERN_ERR "ad73311: failed to create pcms\n");
64 goto pcm_err;
65 }
66
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret;
74
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err:
78 kfree(socdev->codec);
79 socdev->codec = NULL;
80 return ret;
81}
82
83static int ad73311_soc_remove(struct platform_device *pdev)
84{
85 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
86 struct snd_soc_codec *codec = socdev->codec;
87
88 if (codec == NULL)
89 return 0;
90 snd_soc_free_pcms(socdev);
91 kfree(codec);
92 return 0;
93}
94
95struct snd_soc_codec_device soc_codec_dev_ad73311 = {
96 .probe = ad73311_soc_probe,
97 .remove = ad73311_soc_remove,
98};
99EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
100
101static int __init ad73311_init(void)
102{
103 return snd_soc_register_dai(&ad73311_dai);
104}
105module_init(ad73311_init);
106
107static void __exit ad73311_exit(void)
108{
109 snd_soc_unregister_dai(&ad73311_dai);
110}
111module_exit(ad73311_exit);
112
113MODULE_DESCRIPTION("ASoC ad73311 driver");
114MODULE_AUTHOR("Cliff Cai ");
115MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad73311.h b/sound/soc/codecs/ad73311.h
new file mode 100644
index 000000000000..507ce0c30edf
--- /dev/null
+++ b/sound/soc/codecs/ad73311.h
@@ -0,0 +1,90 @@
1/*
2 * File: sound/soc/codec/ad73311.h
3 * Based on:
4 * Author: Cliff Cai <cliff.cai@analog.com>
5 *
6 * Created: Thur Sep 25, 2008
7 * Description: definitions for AD73311 registers
8 *
9 *
10 * Modified:
11 * Copyright 2006 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#ifndef __AD73311_H__
32#define __AD73311_H__
33
34#define AD_CONTROL 0x8000
35#define AD_DATA 0x0000
36#define AD_READ 0x4000
37#define AD_WRITE 0x0000
38
39/* Control register A */
40#define CTRL_REG_A (0 << 8)
41
42#define REGA_MODE_PRO 0x00
43#define REGA_MODE_DATA 0x01
44#define REGA_MODE_MIXED 0x03
45#define REGA_DLB 0x04
46#define REGA_SLB 0x08
47#define REGA_DEVC(x) ((x & 0x7) << 4)
48#define REGA_RESET 0x80
49
50/* Control register B */
51#define CTRL_REG_B (1 << 8)
52
53#define REGB_DIRATE(x) (x & 0x3)
54#define REGB_SCDIV(x) ((x & 0x3) << 2)
55#define REGB_MCDIV(x) ((x & 0x7) << 4)
56#define REGB_CEE (1 << 7)
57
58/* Control register C */
59#define CTRL_REG_C (2 << 8)
60
61#define REGC_PUDEV (1 << 0)
62#define REGC_PUADC (1 << 3)
63#define REGC_PUDAC (1 << 4)
64#define REGC_PUREF (1 << 5)
65#define REGC_REFUSE (1 << 6)
66
67/* Control register D */
68#define CTRL_REG_D (3 << 8)
69
70#define REGD_IGS(x) (x & 0x7)
71#define REGD_RMOD (1 << 3)
72#define REGD_OGS(x) ((x & 0x7) << 4)
73#define REGD_MUTE (x << 7)
74
75/* Control register E */
76#define CTRL_REG_E (4 << 8)
77
78#define REGE_DA(x) (x & 0x1f)
79#define REGE_IBYP (1 << 5)
80
81/* Control register F */
82#define CTRL_REG_F (5 << 8)
83
84#define REGF_SEEN (1 << 5)
85#define REGF_INV (1 << 6)
86#define REGF_ALB (1 << 7)
87
88extern struct snd_soc_dai ad73311_dai;
89extern struct snd_soc_codec_device soc_codec_dev_ad73311;
90#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 088cf9927720..81300d8d42ca 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -28,7 +28,6 @@
28 28
29#include "ak4535.h" 29#include "ak4535.h"
30 30
31#define AUDIO_NAME "ak4535"
32#define AK4535_VERSION "0.3" 31#define AK4535_VERSION "0.3"
33 32
34struct snd_soc_codec_device soc_codec_dev_ak4535; 33struct snd_soc_codec_device soc_codec_dev_ak4535;
@@ -340,7 +339,8 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
340} 339}
341 340
342static int ak4535_hw_params(struct snd_pcm_substream *substream, 341static int ak4535_hw_params(struct snd_pcm_substream *substream,
343 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params,
343 struct snd_soc_dai *dai)
344{ 344{
345 struct snd_soc_pcm_runtime *rtd = substream->private_data; 345 struct snd_soc_pcm_runtime *rtd = substream->private_data;
346 struct snd_soc_device *socdev = rtd->socdev; 346 struct snd_soc_device *socdev = rtd->socdev;
@@ -452,8 +452,6 @@ struct snd_soc_dai ak4535_dai = {
452 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 452 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
453 .ops = { 453 .ops = {
454 .hw_params = ak4535_hw_params, 454 .hw_params = ak4535_hw_params,
455 },
456 .dai_ops = {
457 .set_fmt = ak4535_set_dai_fmt, 455 .set_fmt = ak4535_set_dai_fmt,
458 .digital_mute = ak4535_mute, 456 .digital_mute = ak4535_mute,
459 .set_sysclk = ak4535_set_dai_sysclk, 457 .set_sysclk = ak4535_set_dai_sysclk,
@@ -514,7 +512,7 @@ static int ak4535_init(struct snd_soc_device *socdev)
514 512
515 ak4535_add_controls(codec); 513 ak4535_add_controls(codec);
516 ak4535_add_widgets(codec); 514 ak4535_add_widgets(codec);
517 ret = snd_soc_register_card(socdev); 515 ret = snd_soc_init_card(socdev);
518 if (ret < 0) { 516 if (ret < 0) {
519 printk(KERN_ERR "ak4535: failed to register card\n"); 517 printk(KERN_ERR "ak4535: failed to register card\n");
520 goto card_err; 518 goto card_err;
@@ -690,6 +688,18 @@ struct snd_soc_codec_device soc_codec_dev_ak4535 = {
690}; 688};
691EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535); 689EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
692 690
691static int __init ak4535_modinit(void)
692{
693 return snd_soc_register_dai(&ak4535_dai);
694}
695module_init(ak4535_modinit);
696
697static void __exit ak4535_exit(void)
698{
699 snd_soc_unregister_dai(&ak4535_dai);
700}
701module_exit(ak4535_exit);
702
693MODULE_DESCRIPTION("Soc AK4535 driver"); 703MODULE_DESCRIPTION("Soc AK4535 driver");
694MODULE_AUTHOR("Richard Purdie"); 704MODULE_AUTHOR("Richard Purdie");
695MODULE_LICENSE("GPL"); 705MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 0bbd94501d7e..f1aa0c34421c 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -360,13 +360,14 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
360/* 360/*
361 * Program the CS4270 with the given hardware parameters. 361 * Program the CS4270 with the given hardware parameters.
362 * 362 *
363 * The .dai_ops functions are used to provide board-specific data, like 363 * The .ops functions are used to provide board-specific data, like
364 * input frequencies, to this driver. This function takes that information, 364 * input frequencies, to this driver. This function takes that information,
365 * combines it with the hardware parameters provided, and programs the 365 * combines it with the hardware parameters provided, and programs the
366 * hardware accordingly. 366 * hardware accordingly.
367 */ 367 */
368static int cs4270_hw_params(struct snd_pcm_substream *substream, 368static int cs4270_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params) 369 struct snd_pcm_hw_params *params,
370 struct snd_soc_dai *dai)
370{ 371{
371 struct snd_soc_pcm_runtime *rtd = substream->private_data; 372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
372 struct snd_soc_device *socdev = rtd->socdev; 373 struct snd_soc_device *socdev = rtd->socdev;
@@ -450,6 +451,19 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
450 return ret; 451 return ret;
451 } 452 }
452 453
454 /* Disable automatic volume control. It's enabled by default, and
455 * it causes volume change commands to be delayed, sometimes until
456 * after playback has started.
457 */
458
459 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
460 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
461 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
462 if (ret < 0) {
463 printk(KERN_ERR "I2C write failed\n");
464 return ret;
465 }
466
453 /* Thaw and power-up the codec */ 467 /* Thaw and power-up the codec */
454 468
455 ret = snd_soc_write(codec, CS4270_PWRCTL, 0); 469 ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
@@ -697,10 +711,10 @@ static int cs4270_probe(struct platform_device *pdev)
697 if (codec->control_data) { 711 if (codec->control_data) {
698 /* Initialize codec ops */ 712 /* Initialize codec ops */
699 cs4270_dai.ops.hw_params = cs4270_hw_params; 713 cs4270_dai.ops.hw_params = cs4270_hw_params;
700 cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk; 714 cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk;
701 cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt; 715 cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
702#ifdef CONFIG_SND_SOC_CS4270_HWMUTE 716#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
703 cs4270_dai.dai_ops.digital_mute = cs4270_mute; 717 cs4270_dai.ops.digital_mute = cs4270_mute;
704#endif 718#endif
705 } else 719 } else
706 printk(KERN_INFO "cs4270: no I2C device found, " 720 printk(KERN_INFO "cs4270: no I2C device found, "
@@ -709,7 +723,7 @@ static int cs4270_probe(struct platform_device *pdev)
709 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); 723 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
710#endif 724#endif
711 725
712 ret = snd_soc_register_card(socdev); 726 ret = snd_soc_init_card(socdev);
713 if (ret < 0) { 727 if (ret < 0) {
714 printk(KERN_ERR "cs4270: failed to register card\n"); 728 printk(KERN_ERR "cs4270: failed to register card\n");
715 goto error_del_driver; 729 goto error_del_driver;
@@ -760,6 +774,18 @@ struct snd_soc_codec_device soc_codec_device_cs4270 = {
760}; 774};
761EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); 775EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
762 776
777static int __init cs4270_init(void)
778{
779 return snd_soc_register_dai(&cs4270_dai);
780}
781module_init(cs4270_init);
782
783static void __exit cs4270_exit(void)
784{
785 snd_soc_unregister_dai(&cs4270_dai);
786}
787module_exit(cs4270_exit);
788
763MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 789MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
764MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); 790MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
765MODULE_LICENSE("GPL"); 791MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c
new file mode 100644
index 000000000000..5353af58862c
--- /dev/null
+++ b/sound/soc/codecs/l3.c
@@ -0,0 +1,91 @@
1/*
2 * L3 code
3 *
4 * Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *
11 * based on:
12 *
13 * L3 bus algorithm module.
14 *
15 * Copyright (C) 2001 Russell King, All Rights Reserved.
16 *
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/delay.h>
23
24#include <sound/l3.h>
25
26/*
27 * Send one byte of data to the chip. Data is latched into the chip on
28 * the rising edge of the clock.
29 */
30static void sendbyte(struct l3_pins *adap, unsigned int byte)
31{
32 int i;
33
34 for (i = 0; i < 8; i++) {
35 adap->setclk(0);
36 udelay(adap->data_hold);
37 adap->setdat(byte & 1);
38 udelay(adap->data_setup);
39 adap->setclk(1);
40 udelay(adap->clock_high);
41 byte >>= 1;
42 }
43}
44
45/*
46 * Send a set of bytes to the chip. We need to pulse the MODE line
47 * between each byte, but never at the start nor at the end of the
48 * transfer.
49 */
50static void sendbytes(struct l3_pins *adap, const u8 *buf,
51 int len)
52{
53 int i;
54
55 for (i = 0; i < len; i++) {
56 if (i) {
57 udelay(adap->mode_hold);
58 adap->setmode(0);
59 udelay(adap->mode);
60 }
61 adap->setmode(1);
62 udelay(adap->mode_setup);
63 sendbyte(adap, buf[i]);
64 }
65}
66
67int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
68{
69 adap->setclk(1);
70 adap->setdat(1);
71 adap->setmode(1);
72 udelay(adap->mode);
73
74 adap->setmode(0);
75 udelay(adap->mode_setup);
76 sendbyte(adap, addr);
77 udelay(adap->mode_hold);
78
79 sendbytes(adap, data, len);
80
81 adap->setclk(1);
82 adap->setdat(1);
83 adap->setmode(0);
84
85 return len;
86}
87EXPORT_SYMBOL_GPL(l3_write);
88
89MODULE_DESCRIPTION("L3 bit-banging driver");
90MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
91MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
new file mode 100644
index 000000000000..9a3e67e5319c
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.c
@@ -0,0 +1,212 @@
1/*
2 * ALSA Soc PCM3008 codec support
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on AC97 Soc codec, original copyright follow:
8 * Copyright 2005 Wolfson Microelectronics PLC.
9 *
10 * This program is free software; you can redistribute it and/or modify it
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
13 * option) any later version.
14 *
15 * Generic PCM3008 support.
16 */
17
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "pcm3008.h"
28
29#define PCM3008_VERSION "0.2"
30
31#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
32 SNDRV_PCM_RATE_48000)
33
34struct snd_soc_dai pcm3008_dai = {
35 .name = "PCM3008 HiFi",
36 .playback = {
37 .stream_name = "PCM3008 Playback",
38 .channels_min = 1,
39 .channels_max = 2,
40 .rates = PCM3008_RATES,
41 .formats = SNDRV_PCM_FMTBIT_S16_LE,
42 },
43 .capture = {
44 .stream_name = "PCM3008 Capture",
45 .channels_min = 1,
46 .channels_max = 2,
47 .rates = PCM3008_RATES,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE,
49 },
50};
51EXPORT_SYMBOL_GPL(pcm3008_dai);
52
53static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
54{
55 gpio_free(setup->dem0_pin);
56 gpio_free(setup->dem1_pin);
57 gpio_free(setup->pdad_pin);
58 gpio_free(setup->pdda_pin);
59}
60
61static int pcm3008_soc_probe(struct platform_device *pdev)
62{
63 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
64 struct snd_soc_codec *codec;
65 struct pcm3008_setup_data *setup = socdev->codec_data;
66 int ret = 0;
67
68 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
69
70 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
71 if (!socdev->codec)
72 return -ENOMEM;
73
74 codec = socdev->codec;
75 mutex_init(&codec->mutex);
76
77 codec->name = "PCM3008";
78 codec->owner = THIS_MODULE;
79 codec->dai = &pcm3008_dai;
80 codec->num_dai = 1;
81 codec->write = NULL;
82 codec->read = NULL;
83 INIT_LIST_HEAD(&codec->dapm_widgets);
84 INIT_LIST_HEAD(&codec->dapm_paths);
85
86 /* Register PCMs. */
87 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
88 if (ret < 0) {
89 printk(KERN_ERR "pcm3008: failed to create pcms\n");
90 goto pcm_err;
91 }
92
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF
103 * High Low De-emphasis 48 kHz ON
104 * High High De-emphasis 32 kHz ON
105 */
106
107 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
108 ret = gpio_request(setup->dem0_pin, "codec_dem0");
109 if (ret == 0)
110 ret = gpio_direction_output(setup->dem0_pin, 1);
111 if (ret != 0)
112 goto gpio_err;
113
114 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
115 ret = gpio_request(setup->dem1_pin, "codec_dem1");
116 if (ret == 0)
117 ret = gpio_direction_output(setup->dem1_pin, 0);
118 if (ret != 0)
119 goto gpio_err;
120
121 /* Configure PDAD GPIO. */
122 ret = gpio_request(setup->pdad_pin, "codec_pdad");
123 if (ret == 0)
124 ret = gpio_direction_output(setup->pdad_pin, 1);
125 if (ret != 0)
126 goto gpio_err;
127
128 /* Configure PDDA GPIO. */
129 ret = gpio_request(setup->pdda_pin, "codec_pdda");
130 if (ret == 0)
131 ret = gpio_direction_output(setup->pdda_pin, 1);
132 if (ret != 0)
133 goto gpio_err;
134
135 return ret;
136
137gpio_err:
138 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err:
142 kfree(socdev->codec);
143
144 return ret;
145}
146
147static int pcm3008_soc_remove(struct platform_device *pdev)
148{
149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
150 struct snd_soc_codec *codec = socdev->codec;
151 struct pcm3008_setup_data *setup = socdev->codec_data;
152
153 if (!codec)
154 return 0;
155
156 pcm3008_gpio_free(setup);
157 snd_soc_free_pcms(socdev);
158 kfree(socdev->codec);
159
160 return 0;
161}
162
163#ifdef CONFIG_PM
164static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
165{
166 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
167 struct pcm3008_setup_data *setup = socdev->codec_data;
168
169 gpio_set_value(setup->pdad_pin, 0);
170 gpio_set_value(setup->pdda_pin, 0);
171
172 return 0;
173}
174
175static int pcm3008_soc_resume(struct platform_device *pdev)
176{
177 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
178 struct pcm3008_setup_data *setup = socdev->codec_data;
179
180 gpio_set_value(setup->pdad_pin, 1);
181 gpio_set_value(setup->pdda_pin, 1);
182
183 return 0;
184}
185#else
186#define pcm3008_soc_suspend NULL
187#define pcm3008_soc_resume NULL
188#endif
189
190struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
191 .probe = pcm3008_soc_probe,
192 .remove = pcm3008_soc_remove,
193 .suspend = pcm3008_soc_suspend,
194 .resume = pcm3008_soc_resume,
195};
196EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
197
198static int __init pcm3008_init(void)
199{
200 return snd_soc_register_dai(&pcm3008_dai);
201}
202module_init(pcm3008_init);
203
204static void __exit pcm3008_exit(void)
205{
206 snd_soc_unregister_dai(&pcm3008_dai);
207}
208module_exit(pcm3008_exit);
209
210MODULE_DESCRIPTION("Soc PCM3008 driver");
211MODULE_AUTHOR("Hugo Villeneuve");
212MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
new file mode 100644
index 000000000000..d04e87d3c060
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.h
@@ -0,0 +1,25 @@
1/*
2 * PCM3008 ALSA SoC Layer
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
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 __LINUX_SND_SOC_PCM3008_H
13#define __LINUX_SND_SOC_PCM3008_H
14
15struct pcm3008_setup_data {
16 unsigned dem0_pin;
17 unsigned dem1_pin;
18 unsigned pdad_pin;
19 unsigned pdda_pin;
20};
21
22extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
23extern struct snd_soc_dai pcm3008_dai;
24
25#endif
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 940ce1c3522e..cac373616768 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -42,7 +42,6 @@
42 42
43#include "ssm2602.h" 43#include "ssm2602.h"
44 44
45#define AUDIO_NAME "ssm2602"
46#define SSM2602_VERSION "0.1" 45#define SSM2602_VERSION "0.1"
47 46
48struct snd_soc_codec_device soc_codec_dev_ssm2602; 47struct snd_soc_codec_device soc_codec_dev_ssm2602;
@@ -286,16 +285,23 @@ static inline int get_coeff(int mclk, int rate)
286} 285}
287 286
288static int ssm2602_hw_params(struct snd_pcm_substream *substream, 287static int ssm2602_hw_params(struct snd_pcm_substream *substream,
289 struct snd_pcm_hw_params *params) 288 struct snd_pcm_hw_params *params,
289 struct snd_soc_dai *dai)
290{ 290{
291 u16 srate; 291 u16 srate;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data; 292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 struct snd_soc_device *socdev = rtd->socdev; 293 struct snd_soc_device *socdev = rtd->socdev;
294 struct snd_soc_codec *codec = socdev->codec; 294 struct snd_soc_codec *codec = socdev->codec;
295 struct ssm2602_priv *ssm2602 = codec->private_data; 295 struct ssm2602_priv *ssm2602 = codec->private_data;
296 struct i2c_client *i2c = codec->control_data;
296 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 297 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
297 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 298 int i = get_coeff(ssm2602->sysclk, params_rate(params));
298 299
300 if (substream == ssm2602->slave_substream) {
301 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
302 return 0;
303 }
304
299 /*no match is found*/ 305 /*no match is found*/
300 if (i == ARRAY_SIZE(coeff_div)) 306 if (i == ARRAY_SIZE(coeff_div))
301 return -EINVAL; 307 return -EINVAL;
@@ -325,19 +331,26 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
325 return 0; 331 return 0;
326} 332}
327 333
328static int ssm2602_startup(struct snd_pcm_substream *substream) 334static int ssm2602_startup(struct snd_pcm_substream *substream,
335 struct snd_soc_dai *dai)
329{ 336{
330 struct snd_soc_pcm_runtime *rtd = substream->private_data; 337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
331 struct snd_soc_device *socdev = rtd->socdev; 338 struct snd_soc_device *socdev = rtd->socdev;
332 struct snd_soc_codec *codec = socdev->codec; 339 struct snd_soc_codec *codec = socdev->codec;
333 struct ssm2602_priv *ssm2602 = codec->private_data; 340 struct ssm2602_priv *ssm2602 = codec->private_data;
341 struct i2c_client *i2c = codec->control_data;
334 struct snd_pcm_runtime *master_runtime; 342 struct snd_pcm_runtime *master_runtime;
335 343
336 /* The DAI has shared clocks so if we already have a playback or 344 /* The DAI has shared clocks so if we already have a playback or
337 * capture going then constrain this substream to match it. 345 * capture going then constrain this substream to match it.
346 * TODO: the ssm2602 allows pairs of non-matching PB/REC rates
338 */ 347 */
339 if (ssm2602->master_substream) { 348 if (ssm2602->master_substream) {
340 master_runtime = ssm2602->master_substream->runtime; 349 master_runtime = ssm2602->master_substream->runtime;
350 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
351 master_runtime->sample_bits,
352 master_runtime->rate);
353
341 snd_pcm_hw_constraint_minmax(substream->runtime, 354 snd_pcm_hw_constraint_minmax(substream->runtime,
342 SNDRV_PCM_HW_PARAM_RATE, 355 SNDRV_PCM_HW_PARAM_RATE,
343 master_runtime->rate, 356 master_runtime->rate,
@@ -355,7 +368,8 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
355 return 0; 368 return 0;
356} 369}
357 370
358static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream) 371static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai)
359{ 373{
360 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
361 struct snd_soc_device *socdev = rtd->socdev; 375 struct snd_soc_device *socdev = rtd->socdev;
@@ -366,14 +380,21 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
366 return 0; 380 return 0;
367} 381}
368 382
369static void ssm2602_shutdown(struct snd_pcm_substream *substream) 383static void ssm2602_shutdown(struct snd_pcm_substream *substream,
384 struct snd_soc_dai *dai)
370{ 385{
371 struct snd_soc_pcm_runtime *rtd = substream->private_data; 386 struct snd_soc_pcm_runtime *rtd = substream->private_data;
372 struct snd_soc_device *socdev = rtd->socdev; 387 struct snd_soc_device *socdev = rtd->socdev;
373 struct snd_soc_codec *codec = socdev->codec; 388 struct snd_soc_codec *codec = socdev->codec;
389 struct ssm2602_priv *ssm2602 = codec->private_data;
374 /* deactivate */ 390 /* deactivate */
375 if (!codec->active) 391 if (!codec->active)
376 ssm2602_write(codec, SSM2602_ACTIVE, 0); 392 ssm2602_write(codec, SSM2602_ACTIVE, 0);
393
394 if (ssm2602->master_substream == substream)
395 ssm2602->master_substream = ssm2602->slave_substream;
396
397 ssm2602->slave_substream = NULL;
377} 398}
378 399
379static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 400static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
@@ -433,10 +454,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
433 iface |= 0x0001; 454 iface |= 0x0001;
434 break; 455 break;
435 case SND_SOC_DAIFMT_DSP_A: 456 case SND_SOC_DAIFMT_DSP_A:
436 iface |= 0x0003; 457 iface |= 0x0013;
437 break; 458 break;
438 case SND_SOC_DAIFMT_DSP_B: 459 case SND_SOC_DAIFMT_DSP_B:
439 iface |= 0x0013; 460 iface |= 0x0003;
440 break; 461 break;
441 default: 462 default:
442 return -EINVAL; 463 return -EINVAL;
@@ -497,6 +518,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
497 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ 518 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
498 SNDRV_PCM_RATE_96000) 519 SNDRV_PCM_RATE_96000)
499 520
521#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
522 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
523
500struct snd_soc_dai ssm2602_dai = { 524struct snd_soc_dai ssm2602_dai = {
501 .name = "SSM2602", 525 .name = "SSM2602",
502 .playback = { 526 .playback = {
@@ -504,20 +528,18 @@ struct snd_soc_dai ssm2602_dai = {
504 .channels_min = 2, 528 .channels_min = 2,
505 .channels_max = 2, 529 .channels_max = 2,
506 .rates = SSM2602_RATES, 530 .rates = SSM2602_RATES,
507 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 531 .formats = SSM2602_FORMATS,},
508 .capture = { 532 .capture = {
509 .stream_name = "Capture", 533 .stream_name = "Capture",
510 .channels_min = 2, 534 .channels_min = 2,
511 .channels_max = 2, 535 .channels_max = 2,
512 .rates = SSM2602_RATES, 536 .rates = SSM2602_RATES,
513 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 537 .formats = SSM2602_FORMATS,},
514 .ops = { 538 .ops = {
515 .startup = ssm2602_startup, 539 .startup = ssm2602_startup,
516 .prepare = ssm2602_pcm_prepare, 540 .prepare = ssm2602_pcm_prepare,
517 .hw_params = ssm2602_hw_params, 541 .hw_params = ssm2602_hw_params,
518 .shutdown = ssm2602_shutdown, 542 .shutdown = ssm2602_shutdown,
519 },
520 .dai_ops = {
521 .digital_mute = ssm2602_mute, 543 .digital_mute = ssm2602_mute,
522 .set_sysclk = ssm2602_set_dai_sysclk, 544 .set_sysclk = ssm2602_set_dai_sysclk,
523 .set_fmt = ssm2602_set_dai_fmt, 545 .set_fmt = ssm2602_set_dai_fmt,
@@ -602,7 +624,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
602 624
603 ssm2602_add_controls(codec); 625 ssm2602_add_controls(codec);
604 ssm2602_add_widgets(codec); 626 ssm2602_add_widgets(codec);
605 ret = snd_soc_register_card(socdev); 627 ret = snd_soc_init_card(socdev);
606 if (ret < 0) { 628 if (ret < 0) {
607 pr_err("ssm2602: failed to register card\n"); 629 pr_err("ssm2602: failed to register card\n");
608 goto card_err; 630 goto card_err;
@@ -771,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
771}; 793};
772EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602); 794EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
773 795
796static int __init ssm2602_modinit(void)
797{
798 return snd_soc_register_dai(&ssm2602_dai);
799}
800module_init(ssm2602_modinit);
801
802static void __exit ssm2602_exit(void)
803{
804 snd_soc_unregister_dai(&ssm2602_dai);
805}
806module_exit(ssm2602_exit);
807
774MODULE_DESCRIPTION("ASoC ssm2602 driver"); 808MODULE_DESCRIPTION("ASoC ssm2602 driver");
775MODULE_AUTHOR("Cliff Cai"); 809MODULE_AUTHOR("Cliff Cai");
776MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
new file mode 100644
index 000000000000..cfdea007c4cb
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -0,0 +1,864 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd.,
6 *
7 * Based on sound/soc/codecs/wm8731.c by Richard Purdie
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * Notes:
14 * The AIC23 is a driver for a low power stereo audio
15 * codec tlv320aic23
16 *
17 * The machine layer should disable unsupported inputs/outputs by
18 * snd_soc_dapm_disable_pin(codec, "LHPOUT"), etc.
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/pm.h>
26#include <linux/i2c.h>
27#include <linux/platform_device.h>
28#include <sound/core.h>
29#include <sound/pcm.h>
30#include <sound/pcm_params.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h>
34#include <sound/initval.h>
35
36#include "tlv320aic23.h"
37
38#define AIC23_VERSION "0.1"
39
40/*
41 * AIC23 register cache
42 */
43static const u16 tlv320aic23_reg[] = {
44 0x0097, 0x0097, 0x00F9, 0x00F9, /* 0 */
45 0x001A, 0x0004, 0x0007, 0x0001, /* 4 */
46 0x0020, 0x0000, 0x0000, 0x0000, /* 8 */
47 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
48};
49
50/*
51 * read tlv320aic23 register cache
52 */
53static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
54 *codec, unsigned int reg)
55{
56 u16 *cache = codec->reg_cache;
57 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
58 return -1;
59 return cache[reg];
60}
61
62/*
63 * write tlv320aic23 register cache
64 */
65static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
66 u8 reg, u16 value)
67{
68 u16 *cache = codec->reg_cache;
69 if (reg >= ARRAY_SIZE(tlv320aic23_reg))
70 return;
71 cache[reg] = value;
72}
73
74/*
75 * write to the tlv320aic23 register space
76 */
77static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
78 unsigned int value)
79{
80
81 u8 data[2];
82
83 /* TLV320AIC23 has 7 bit address and 9 bits of data
84 * so we need to switch one data bit into reg and rest
85 * of data into val
86 */
87
88 if ((reg < 0 || reg > 9) && (reg != 15)) {
89 printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg);
90 return -1;
91 }
92
93 data[0] = (reg << 1) | (value >> 8 & 0x01);
94 data[1] = value & 0xff;
95
96 tlv320aic23_write_reg_cache(codec, reg, value);
97
98 if (codec->hw_write(codec->control_data, data, 2) == 2)
99 return 0;
100
101 printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__,
102 value, reg);
103
104 return -EIO;
105}
106
107static const char *rec_src_text[] = { "Line", "Mic" };
108static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
109
110static const struct soc_enum rec_src_enum =
111 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
112
113static const struct snd_kcontrol_new tlv320aic23_rec_src_mux_controls =
114SOC_DAPM_ENUM("Input Select", rec_src_enum);
115
116static const struct soc_enum tlv320aic23_rec_src =
117 SOC_ENUM_SINGLE(TLV320AIC23_ANLG, 2, 2, rec_src_text);
118static const struct soc_enum tlv320aic23_deemph =
119 SOC_ENUM_SINGLE(TLV320AIC23_DIGT, 1, 4, deemph_text);
120
121static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -12100, 100, 0);
122static const DECLARE_TLV_DB_SCALE(input_gain_tlv, -1725, 75, 0);
123static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0);
124
125static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
126 struct snd_ctl_elem_value *ucontrol)
127{
128 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
129 u16 val, reg;
130
131 val = (ucontrol->value.integer.value[0] & 0x07);
132
133 /* linear conversion to userspace
134 * 000 = -6db
135 * 001 = -9db
136 * 010 = -12db
137 * 011 = -18db (Min)
138 * 100 = 0db (Max)
139 */
140 val = (val >= 4) ? 4 : (3 - val);
141
142 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
143 tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
144
145 return 0;
146}
147
148static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
149 struct snd_ctl_elem_value *ucontrol)
150{
151 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
152 u16 val;
153
154 val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
155 val = val >> 6;
156 val = (val >= 4) ? 4 : (3 - val);
157 ucontrol->value.integer.value[0] = val;
158 return 0;
159
160}
161
162#define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
163{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
164 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
165 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
166 .tlv.p = (tlv_array), \
167 .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\
168 .put = snd_soc_tlv320aic23_put_volsw, \
169 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
170
171static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = {
172 SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL,
173 TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv),
174 SOC_SINGLE("Digital Playback Switch", TLV320AIC23_DIGT, 3, 1, 1),
175 SOC_DOUBLE_R("Line Input Switch", TLV320AIC23_LINVOL,
176 TLV320AIC23_RINVOL, 7, 1, 0),
177 SOC_DOUBLE_R_TLV("Line Input Volume", TLV320AIC23_LINVOL,
178 TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv),
179 SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1),
180 SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0),
181 SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG,
182 6, 4, 0, sidetone_vol_tlv),
183 SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph),
184};
185
186/* add non dapm controls */
187static int tlv320aic23_add_controls(struct snd_soc_codec *codec)
188{
189
190 int err, i;
191
192 for (i = 0; i < ARRAY_SIZE(tlv320aic23_snd_controls); i++) {
193 err = snd_ctl_add(codec->card,
194 snd_soc_cnew(&tlv320aic23_snd_controls[i],
195 codec, NULL));
196 if (err < 0)
197 return err;
198 }
199
200 return 0;
201
202}
203
204/* PGA Mixer controls for Line and Mic switch */
205static const struct snd_kcontrol_new tlv320aic23_output_mixer_controls[] = {
206 SOC_DAPM_SINGLE("Line Bypass Switch", TLV320AIC23_ANLG, 3, 1, 0),
207 SOC_DAPM_SINGLE("Mic Sidetone Switch", TLV320AIC23_ANLG, 5, 1, 0),
208 SOC_DAPM_SINGLE("Playback Switch", TLV320AIC23_ANLG, 4, 1, 0),
209};
210
211static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
212 SND_SOC_DAPM_DAC("DAC", "Playback", TLV320AIC23_PWR, 3, 1),
213 SND_SOC_DAPM_ADC("ADC", "Capture", TLV320AIC23_PWR, 2, 1),
214 SND_SOC_DAPM_MUX("Capture Source", SND_SOC_NOPM, 0, 0,
215 &tlv320aic23_rec_src_mux_controls),
216 SND_SOC_DAPM_MIXER("Output Mixer", TLV320AIC23_PWR, 4, 1,
217 &tlv320aic23_output_mixer_controls[0],
218 ARRAY_SIZE(tlv320aic23_output_mixer_controls)),
219 SND_SOC_DAPM_PGA("Line Input", TLV320AIC23_PWR, 0, 1, NULL, 0),
220 SND_SOC_DAPM_PGA("Mic Input", TLV320AIC23_PWR, 1, 1, NULL, 0),
221
222 SND_SOC_DAPM_OUTPUT("LHPOUT"),
223 SND_SOC_DAPM_OUTPUT("RHPOUT"),
224 SND_SOC_DAPM_OUTPUT("LOUT"),
225 SND_SOC_DAPM_OUTPUT("ROUT"),
226
227 SND_SOC_DAPM_INPUT("LLINEIN"),
228 SND_SOC_DAPM_INPUT("RLINEIN"),
229
230 SND_SOC_DAPM_INPUT("MICIN"),
231};
232
233static const struct snd_soc_dapm_route intercon[] = {
234 /* Output Mixer */
235 {"Output Mixer", "Line Bypass Switch", "Line Input"},
236 {"Output Mixer", "Playback Switch", "DAC"},
237 {"Output Mixer", "Mic Sidetone Switch", "Mic Input"},
238
239 /* Outputs */
240 {"RHPOUT", NULL, "Output Mixer"},
241 {"LHPOUT", NULL, "Output Mixer"},
242 {"LOUT", NULL, "Output Mixer"},
243 {"ROUT", NULL, "Output Mixer"},
244
245 /* Inputs */
246 {"Line Input", "NULL", "LLINEIN"},
247 {"Line Input", "NULL", "RLINEIN"},
248
249 {"Mic Input", "NULL", "MICIN"},
250
251 /* input mux */
252 {"Capture Source", "Line", "Line Input"},
253 {"Capture Source", "Mic", "Mic Input"},
254 {"ADC", NULL, "Capture Source"},
255
256};
257
258/* AIC23 driver data */
259struct aic23 {
260 struct snd_soc_codec codec;
261 int mclk;
262 int requested_adc;
263 int requested_dac;
264};
265
266/*
267 * Common Crystals used
268 * 11.2896 Mhz /128 = *88.2k /192 = 58.8k
269 * 12.0000 Mhz /125 = *96k /136 = 88.235K
270 * 12.2880 Mhz /128 = *96k /192 = 64k
271 * 16.9344 Mhz /128 = 132.3k /192 = *88.2k
272 * 18.4320 Mhz /128 = 144k /192 = *96k
273 */
274
275/*
276 * Normal BOSR 0-256/2 = 128, 1-384/2 = 192
277 * USB BOSR 0-250/2 = 125, 1-272/2 = 136
278 */
279static const int bosr_usb_divisor_table[] = {
280 128, 125, 192, 136
281};
282#define LOWER_GROUP ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7))
283#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
284static const unsigned short sr_valid_mask[] = {
285 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
286 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
287 LOWER_GROUP, /* Usb, bosr - 0*/
288 UPPER_GROUP, /* Usb, bosr - 1*/
289};
290/*
291 * Every divisor is a factor of 11*12
292 */
293#define SR_MULT (11*12)
294#define A(x) (x) ? (SR_MULT/x) : 0
295static const unsigned char sr_adc_mult_table[] = {
296 A(2), A(2), A(12), A(12), A(0), A(0), A(3), A(1),
297 A(2), A(2), A(11), A(11), A(0), A(0), A(0), A(1)
298};
299static const unsigned char sr_dac_mult_table[] = {
300 A(2), A(12), A(2), A(12), A(0), A(0), A(3), A(1),
301 A(2), A(11), A(2), A(11), A(0), A(0), A(0), A(1)
302};
303
304static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
305 int dac, int dac_l, int dac_h, int need_dac)
306{
307 if ((adc >= adc_l) && (adc <= adc_h) &&
308 (dac >= dac_l) && (dac <= dac_h)) {
309 int diff_adc = need_adc - adc;
310 int diff_dac = need_dac - dac;
311 return abs(diff_adc) + abs(diff_dac);
312 }
313 return UINT_MAX;
314}
315
316static int find_rate(int mclk, u32 need_adc, u32 need_dac)
317{
318 int i, j;
319 int best_i = -1;
320 int best_j = -1;
321 int best_div = 0;
322 unsigned best_score = UINT_MAX;
323 int adc_l, adc_h, dac_l, dac_h;
324
325 need_adc *= SR_MULT;
326 need_dac *= SR_MULT;
327 /*
328 * rates given are +/- 1/32
329 */
330 adc_l = need_adc - (need_adc >> 5);
331 adc_h = need_adc + (need_adc >> 5);
332 dac_l = need_dac - (need_dac >> 5);
333 dac_h = need_dac + (need_dac >> 5);
334 for (i = 0; i < ARRAY_SIZE(bosr_usb_divisor_table); i++) {
335 int base = mclk / bosr_usb_divisor_table[i];
336 int mask = sr_valid_mask[i];
337 for (j = 0; j < ARRAY_SIZE(sr_adc_mult_table);
338 j++, mask >>= 1) {
339 int adc;
340 int dac;
341 int score;
342 if ((mask & 1) == 0)
343 continue;
344 adc = base * sr_adc_mult_table[j];
345 dac = base * sr_dac_mult_table[j];
346 score = get_score(adc, adc_l, adc_h, need_adc,
347 dac, dac_l, dac_h, need_dac);
348 if (best_score > score) {
349 best_score = score;
350 best_i = i;
351 best_j = j;
352 best_div = 0;
353 }
354 score = get_score((adc >> 1), adc_l, adc_h, need_adc,
355 (dac >> 1), dac_l, dac_h, need_dac);
356 /* prefer to have a /2 */
357 if ((score != UINT_MAX) && (best_score >= score)) {
358 best_score = score;
359 best_i = i;
360 best_j = j;
361 best_div = 1;
362 }
363 }
364 }
365 return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT);
366}
367
368#ifdef DEBUG
369static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
370 u32 *sample_rate_adc, u32 *sample_rate_dac)
371{
372 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE);
373 int sr = (src >> 2) & 0x0f;
374 int val = (mclk / bosr_usb_divisor_table[src & 3]);
375 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
376 int dac = (val * sr_dac_mult_table[sr]) / SR_MULT;
377 if (src & TLV320AIC23_CLKIN_HALF) {
378 adc >>= 1;
379 dac >>= 1;
380 }
381 *sample_rate_adc = adc;
382 *sample_rate_dac = dac;
383}
384#endif
385
386static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
387 u32 sample_rate_adc, u32 sample_rate_dac)
388{
389 /* Search for the right sample rate */
390 int data = find_rate(mclk, sample_rate_adc, sample_rate_dac);
391 if (data < 0) {
392 printk(KERN_ERR "%s:Invalid rate %u,%u requested\n",
393 __func__, sample_rate_adc, sample_rate_dac);
394 return -EINVAL;
395 }
396 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
397#ifdef DEBUG
398 {
399 u32 adc, dac;
400 get_current_sample_rates(codec, mclk, &adc, &dac);
401 printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
402 adc, dac, data);
403 }
404#endif
405 return 0;
406}
407
408static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
409{
410 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
411 ARRAY_SIZE(tlv320aic23_dapm_widgets));
412
413 /* set up audio path interconnects */
414 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
415
416 snd_soc_dapm_new_widgets(codec);
417 return 0;
418}
419
420static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
421 struct snd_pcm_hw_params *params,
422 struct snd_soc_dai *dai)
423{
424 struct snd_soc_pcm_runtime *rtd = substream->private_data;
425 struct snd_soc_device *socdev = rtd->socdev;
426 struct snd_soc_codec *codec = socdev->codec;
427 u16 iface_reg;
428 int ret;
429 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
430 u32 sample_rate_adc = aic23->requested_adc;
431 u32 sample_rate_dac = aic23->requested_dac;
432 u32 sample_rate = params_rate(params);
433
434 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
435 aic23->requested_dac = sample_rate_dac = sample_rate;
436 if (!sample_rate_adc)
437 sample_rate_adc = sample_rate;
438 } else {
439 aic23->requested_adc = sample_rate_adc = sample_rate;
440 if (!sample_rate_dac)
441 sample_rate_dac = sample_rate;
442 }
443 ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
444 sample_rate_dac);
445 if (ret < 0)
446 return ret;
447
448 iface_reg =
449 tlv320aic23_read_reg_cache(codec,
450 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
451 switch (params_format(params)) {
452 case SNDRV_PCM_FORMAT_S16_LE:
453 break;
454 case SNDRV_PCM_FORMAT_S20_3LE:
455 iface_reg |= (0x01 << 2);
456 break;
457 case SNDRV_PCM_FORMAT_S24_LE:
458 iface_reg |= (0x02 << 2);
459 break;
460 case SNDRV_PCM_FORMAT_S32_LE:
461 iface_reg |= (0x03 << 2);
462 break;
463 }
464 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
465
466 return 0;
467}
468
469static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
470 struct snd_soc_dai *dai)
471{
472 struct snd_soc_pcm_runtime *rtd = substream->private_data;
473 struct snd_soc_device *socdev = rtd->socdev;
474 struct snd_soc_codec *codec = socdev->codec;
475
476 /* set active */
477 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
478
479 return 0;
480}
481
482static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
484{
485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
486 struct snd_soc_device *socdev = rtd->socdev;
487 struct snd_soc_codec *codec = socdev->codec;
488 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
489
490 /* deactivate */
491 if (!codec->active) {
492 udelay(50);
493 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
494 }
495 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
496 aic23->requested_dac = 0;
497 else
498 aic23->requested_adc = 0;
499}
500
501static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
502{
503 struct snd_soc_codec *codec = dai->codec;
504 u16 reg;
505
506 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
507 if (mute)
508 reg |= TLV320AIC23_DACM_MUTE;
509
510 else
511 reg &= ~TLV320AIC23_DACM_MUTE;
512
513 tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
514
515 return 0;
516}
517
518static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
519 unsigned int fmt)
520{
521 struct snd_soc_codec *codec = codec_dai->codec;
522 u16 iface_reg;
523
524 iface_reg =
525 tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
526
527 /* set master/slave audio interface */
528 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
529 case SND_SOC_DAIFMT_CBM_CFM:
530 iface_reg |= TLV320AIC23_MS_MASTER;
531 break;
532 case SND_SOC_DAIFMT_CBS_CFS:
533 break;
534 default:
535 return -EINVAL;
536
537 }
538
539 /* interface format */
540 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
541 case SND_SOC_DAIFMT_I2S:
542 iface_reg |= TLV320AIC23_FOR_I2S;
543 break;
544 case SND_SOC_DAIFMT_DSP_B:
545 iface_reg |= TLV320AIC23_FOR_DSP;
546 break;
547 case SND_SOC_DAIFMT_RIGHT_J:
548 break;
549 case SND_SOC_DAIFMT_LEFT_J:
550 iface_reg |= TLV320AIC23_FOR_LJUST;
551 break;
552 default:
553 return -EINVAL;
554
555 }
556
557 tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
558
559 return 0;
560}
561
562static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
563 int clk_id, unsigned int freq, int dir)
564{
565 struct snd_soc_codec *codec = codec_dai->codec;
566 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
567 aic23->mclk = freq;
568 return 0;
569}
570
571static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
572 enum snd_soc_bias_level level)
573{
574 u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
575
576 switch (level) {
577 case SND_SOC_BIAS_ON:
578 /* vref/mid, osc on, dac unmute */
579 tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
580 break;
581 case SND_SOC_BIAS_PREPARE:
582 break;
583 case SND_SOC_BIAS_STANDBY:
584 /* everything off except vref/vmid, */
585 tlv320aic23_write(codec, TLV320AIC23_PWR, reg | 0x0040);
586 break;
587 case SND_SOC_BIAS_OFF:
588 /* everything off, dac mute, inactive */
589 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
590 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
591 break;
592 }
593 codec->bias_level = level;
594 return 0;
595}
596
597#define AIC23_RATES SNDRV_PCM_RATE_8000_96000
598#define AIC23_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
599 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
600
601struct snd_soc_dai tlv320aic23_dai = {
602 .name = "tlv320aic23",
603 .playback = {
604 .stream_name = "Playback",
605 .channels_min = 2,
606 .channels_max = 2,
607 .rates = AIC23_RATES,
608 .formats = AIC23_FORMATS,},
609 .capture = {
610 .stream_name = "Capture",
611 .channels_min = 2,
612 .channels_max = 2,
613 .rates = AIC23_RATES,
614 .formats = AIC23_FORMATS,},
615 .ops = {
616 .prepare = tlv320aic23_pcm_prepare,
617 .hw_params = tlv320aic23_hw_params,
618 .shutdown = tlv320aic23_shutdown,
619 .digital_mute = tlv320aic23_mute,
620 .set_fmt = tlv320aic23_set_dai_fmt,
621 .set_sysclk = tlv320aic23_set_dai_sysclk,
622 }
623};
624EXPORT_SYMBOL_GPL(tlv320aic23_dai);
625
626static int tlv320aic23_suspend(struct platform_device *pdev,
627 pm_message_t state)
628{
629 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
630 struct snd_soc_codec *codec = socdev->codec;
631
632 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
633 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
634
635 return 0;
636}
637
638static int tlv320aic23_resume(struct platform_device *pdev)
639{
640 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
641 struct snd_soc_codec *codec = socdev->codec;
642 int i;
643 u16 reg;
644
645 /* Sync reg_cache with the hardware */
646 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) {
647 u16 val = tlv320aic23_read_reg_cache(codec, reg);
648 tlv320aic23_write(codec, reg, val);
649 }
650
651 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
652 tlv320aic23_set_bias_level(codec, codec->suspend_bias_level);
653
654 return 0;
655}
656
657/*
658 * initialise the AIC23 driver
659 * register the mixer and dsp interfaces with the kernel
660 */
661static int tlv320aic23_init(struct snd_soc_device *socdev)
662{
663 struct snd_soc_codec *codec = socdev->codec;
664 int ret = 0;
665 u16 reg;
666
667 codec->name = "tlv320aic23";
668 codec->owner = THIS_MODULE;
669 codec->read = tlv320aic23_read_reg_cache;
670 codec->write = tlv320aic23_write;
671 codec->set_bias_level = tlv320aic23_set_bias_level;
672 codec->dai = &tlv320aic23_dai;
673 codec->num_dai = 1;
674 codec->reg_cache_size = ARRAY_SIZE(tlv320aic23_reg);
675 codec->reg_cache =
676 kmemdup(tlv320aic23_reg, sizeof(tlv320aic23_reg), GFP_KERNEL);
677 if (codec->reg_cache == NULL)
678 return -ENOMEM;
679
680 /* Reset codec */
681 tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
682
683 /* register pcms */
684 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
685 if (ret < 0) {
686 printk(KERN_ERR "tlv320aic23: failed to create pcms\n");
687 goto pcm_err;
688 }
689
690 /* power on device */
691 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
692
693 tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
694
695 /* Unmute input */
696 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
697 tlv320aic23_write(codec, TLV320AIC23_LINVOL,
698 (reg & (~TLV320AIC23_LIM_MUTED)) |
699 (TLV320AIC23_LRS_ENABLED));
700
701 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
702 tlv320aic23_write(codec, TLV320AIC23_RINVOL,
703 (reg & (~TLV320AIC23_LIM_MUTED)) |
704 TLV320AIC23_LRS_ENABLED);
705
706 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
707 tlv320aic23_write(codec, TLV320AIC23_ANLG,
708 (reg) & (~TLV320AIC23_BYPASS_ON) &
709 (~TLV320AIC23_MICM_MUTED));
710
711 /* Default output volume */
712 tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
713 TLV320AIC23_DEFAULT_OUT_VOL &
714 TLV320AIC23_OUT_VOL_MASK);
715 tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
716 TLV320AIC23_DEFAULT_OUT_VOL &
717 TLV320AIC23_OUT_VOL_MASK);
718
719 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
720
721 tlv320aic23_add_controls(codec);
722 tlv320aic23_add_widgets(codec);
723 ret = snd_soc_init_card(socdev);
724 if (ret < 0) {
725 printk(KERN_ERR "tlv320aic23: failed to register card\n");
726 goto card_err;
727 }
728
729 return ret;
730
731card_err:
732 snd_soc_free_pcms(socdev);
733 snd_soc_dapm_free(socdev);
734pcm_err:
735 kfree(codec->reg_cache);
736 return ret;
737}
738static struct snd_soc_device *tlv320aic23_socdev;
739
740#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
741/*
742 * If the i2c layer weren't so broken, we could pass this kind of data
743 * around
744 */
745static int tlv320aic23_codec_probe(struct i2c_client *i2c,
746 const struct i2c_device_id *i2c_id)
747{
748 struct snd_soc_device *socdev = tlv320aic23_socdev;
749 struct snd_soc_codec *codec = socdev->codec;
750 int ret;
751
752 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
753 return -EINVAL;
754
755 i2c_set_clientdata(i2c, codec);
756 codec->control_data = i2c;
757
758 ret = tlv320aic23_init(socdev);
759 if (ret < 0) {
760 printk(KERN_ERR "tlv320aic23: failed to initialise AIC23\n");
761 goto err;
762 }
763 return ret;
764
765err:
766 kfree(codec);
767 kfree(i2c);
768 return ret;
769}
770static int __exit tlv320aic23_i2c_remove(struct i2c_client *i2c)
771{
772 put_device(&i2c->dev);
773 return 0;
774}
775
776static const struct i2c_device_id tlv320aic23_id[] = {
777 {"tlv320aic23", 0},
778 {}
779};
780
781MODULE_DEVICE_TABLE(i2c, tlv320aic23_id);
782
783static struct i2c_driver tlv320aic23_i2c_driver = {
784 .driver = {
785 .name = "tlv320aic23",
786 },
787 .probe = tlv320aic23_codec_probe,
788 .remove = __exit_p(tlv320aic23_i2c_remove),
789 .id_table = tlv320aic23_id,
790};
791
792#endif
793
794static int tlv320aic23_probe(struct platform_device *pdev)
795{
796 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
797 struct snd_soc_codec *codec;
798 struct aic23 *aic23;
799 int ret = 0;
800
801 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
802
803 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
804 if (aic23 == NULL)
805 return -ENOMEM;
806 codec = &aic23->codec;
807 socdev->codec = codec;
808 mutex_init(&codec->mutex);
809 INIT_LIST_HEAD(&codec->dapm_widgets);
810 INIT_LIST_HEAD(&codec->dapm_paths);
811
812 tlv320aic23_socdev = socdev;
813#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
814 codec->hw_write = (hw_write_t) i2c_master_send;
815 codec->hw_read = NULL;
816 ret = i2c_add_driver(&tlv320aic23_i2c_driver);
817 if (ret != 0)
818 printk(KERN_ERR "can't add i2c driver");
819#endif
820 return ret;
821}
822
823static int tlv320aic23_remove(struct platform_device *pdev)
824{
825 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
826 struct snd_soc_codec *codec = socdev->codec;
827 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
828
829 if (codec->control_data)
830 tlv320aic23_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(&tlv320aic23_i2c_driver);
836#endif
837 kfree(codec->reg_cache);
838 kfree(aic23);
839
840 return 0;
841}
842struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
843 .probe = tlv320aic23_probe,
844 .remove = tlv320aic23_remove,
845 .suspend = tlv320aic23_suspend,
846 .resume = tlv320aic23_resume,
847};
848EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
849
850static int __init tlv320aic23_modinit(void)
851{
852 return snd_soc_register_dai(&tlv320aic23_dai);
853}
854module_init(tlv320aic23_modinit);
855
856static void __exit tlv320aic23_exit(void)
857{
858 snd_soc_unregister_dai(&tlv320aic23_dai);
859}
860module_exit(tlv320aic23_exit);
861
862MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
863MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
864MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.h b/sound/soc/codecs/tlv320aic23.h
new file mode 100644
index 000000000000..79d1faf8e570
--- /dev/null
+++ b/sound/soc/codecs/tlv320aic23.h
@@ -0,0 +1,122 @@
1/*
2 * ALSA SoC TLV320AIC23 codec driver
3 *
4 * Author: Arun KS, <arunks@mistralsolutions.com>
5 * Copyright: (C) 2008 Mistral Solutions Pvt Ltd
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 _TLV320AIC23_H
13#define _TLV320AIC23_H
14
15/* Codec TLV320AIC23 */
16#define TLV320AIC23_LINVOL 0x00
17#define TLV320AIC23_RINVOL 0x01
18#define TLV320AIC23_LCHNVOL 0x02
19#define TLV320AIC23_RCHNVOL 0x03
20#define TLV320AIC23_ANLG 0x04
21#define TLV320AIC23_DIGT 0x05
22#define TLV320AIC23_PWR 0x06
23#define TLV320AIC23_DIGT_FMT 0x07
24#define TLV320AIC23_SRATE 0x08
25#define TLV320AIC23_ACTIVE 0x09
26#define TLV320AIC23_RESET 0x0F
27
28/* Left (right) line input volume control register */
29#define TLV320AIC23_LRS_ENABLED 0x0100
30#define TLV320AIC23_LIM_MUTED 0x0080
31#define TLV320AIC23_LIV_DEFAULT 0x0017
32#define TLV320AIC23_LIV_MAX 0x001f
33#define TLV320AIC23_LIV_MIN 0x0000
34
35/* Left (right) channel headphone volume control register */
36#define TLV320AIC23_LZC_ON 0x0080
37#define TLV320AIC23_LHV_DEFAULT 0x0079
38#define TLV320AIC23_LHV_MAX 0x007f
39#define TLV320AIC23_LHV_MIN 0x0000
40
41/* Analog audio path control register */
42#define TLV320AIC23_STA_REG(x) ((x)<<6)
43#define TLV320AIC23_STE_ENABLED 0x0020
44#define TLV320AIC23_DAC_SELECTED 0x0010
45#define TLV320AIC23_BYPASS_ON 0x0008
46#define TLV320AIC23_INSEL_MIC 0x0004
47#define TLV320AIC23_MICM_MUTED 0x0002
48#define TLV320AIC23_MICB_20DB 0x0001
49
50/* Digital audio path control register */
51#define TLV320AIC23_DACM_MUTE 0x0008
52#define TLV320AIC23_DEEMP_32K 0x0002
53#define TLV320AIC23_DEEMP_44K 0x0004
54#define TLV320AIC23_DEEMP_48K 0x0006
55#define TLV320AIC23_ADCHP_ON 0x0001
56
57/* Power control down register */
58#define TLV320AIC23_DEVICE_PWR_OFF 0x0080
59#define TLV320AIC23_CLK_OFF 0x0040
60#define TLV320AIC23_OSC_OFF 0x0020
61#define TLV320AIC23_OUT_OFF 0x0010
62#define TLV320AIC23_DAC_OFF 0x0008
63#define TLV320AIC23_ADC_OFF 0x0004
64#define TLV320AIC23_MIC_OFF 0x0002
65#define TLV320AIC23_LINE_OFF 0x0001
66
67/* Digital audio interface register */
68#define TLV320AIC23_MS_MASTER 0x0040
69#define TLV320AIC23_LRSWAP_ON 0x0020
70#define TLV320AIC23_LRP_ON 0x0010
71#define TLV320AIC23_IWL_16 0x0000
72#define TLV320AIC23_IWL_20 0x0004
73#define TLV320AIC23_IWL_24 0x0008
74#define TLV320AIC23_IWL_32 0x000C
75#define TLV320AIC23_FOR_I2S 0x0002
76#define TLV320AIC23_FOR_DSP 0x0003
77#define TLV320AIC23_FOR_LJUST 0x0001
78
79/* Sample rate control register */
80#define TLV320AIC23_CLKOUT_HALF 0x0080
81#define TLV320AIC23_CLKIN_HALF 0x0040
82#define TLV320AIC23_BOSR_384fs 0x0002 /* BOSR_272fs in USB mode */
83#define TLV320AIC23_USB_CLK_ON 0x0001
84#define TLV320AIC23_SR_MASK 0xf
85#define TLV320AIC23_CLKOUT_SHIFT 7
86#define TLV320AIC23_CLKIN_SHIFT 6
87#define TLV320AIC23_SR_SHIFT 2
88#define TLV320AIC23_BOSR_SHIFT 1
89
90/* Digital interface register */
91#define TLV320AIC23_ACT_ON 0x0001
92
93/*
94 * AUDIO related MACROS
95 */
96
97#define TLV320AIC23_DEFAULT_OUT_VOL 0x70
98#define TLV320AIC23_DEFAULT_IN_VOLUME 0x10
99
100#define TLV320AIC23_OUT_VOL_MIN TLV320AIC23_LHV_MIN
101#define TLV320AIC23_OUT_VOL_MAX TLV320AIC23_LHV_MAX
102#define TLV320AIC23_OUT_VO_RANGE (TLV320AIC23_OUT_VOL_MAX - \
103 TLV320AIC23_OUT_VOL_MIN)
104#define TLV320AIC23_OUT_VOL_MASK TLV320AIC23_OUT_VOL_MAX
105
106#define TLV320AIC23_IN_VOL_MIN TLV320AIC23_LIV_MIN
107#define TLV320AIC23_IN_VOL_MAX TLV320AIC23_LIV_MAX
108#define TLV320AIC23_IN_VOL_RANGE (TLV320AIC23_IN_VOL_MAX - \
109 TLV320AIC23_IN_VOL_MIN)
110#define TLV320AIC23_IN_VOL_MASK TLV320AIC23_IN_VOL_MAX
111
112#define TLV320AIC23_SIDETONE_MASK 0x1c0
113#define TLV320AIC23_SIDETONE_0 0x100
114#define TLV320AIC23_SIDETONE_6 0x000
115#define TLV320AIC23_SIDETONE_9 0x040
116#define TLV320AIC23_SIDETONE_12 0x080
117#define TLV320AIC23_SIDETONE_18 0x0c0
118
119extern struct snd_soc_dai tlv320aic23_dai;
120extern struct snd_soc_codec_device soc_codec_dev_tlv320aic23;
121
122#endif /* _TLV320AIC23_H */
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index bed8a9e63ddc..29f2f1a017fd 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -125,7 +125,8 @@ static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
125 * Digital Audio Interface Operations 125 * Digital Audio Interface Operations
126 */ 126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream, 127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params) 128 struct snd_pcm_hw_params *params,
129 struct snd_soc_dai *dai)
129{ 130{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_device *socdev = rtd->socdev;
@@ -287,8 +288,6 @@ struct snd_soc_dai aic26_dai = {
287 }, 288 },
288 .ops = { 289 .ops = {
289 .hw_params = aic26_hw_params, 290 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute, 291 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk, 292 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt, 293 .set_fmt = aic26_set_fmt,
@@ -360,7 +359,7 @@ static int aic26_probe(struct platform_device *pdev)
360 359
361 /* CODEC is setup, we can register the card now */ 360 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n"); 361 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev); 362 ret = snd_soc_init_card(socdev);
364 if (ret < 0) { 363 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n"); 364 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err; 365 goto card_err;
@@ -427,7 +426,7 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
427static int aic26_spi_probe(struct spi_device *spi) 426static int aic26_spi_probe(struct spi_device *spi)
428{ 427{
429 struct aic26 *aic26; 428 struct aic26 *aic26;
430 int rc, i, reg; 429 int ret, i, reg;
431 430
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n"); 431 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433 432
@@ -457,6 +456,14 @@ static int aic26_spi_probe(struct spi_device *spi)
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS; 456 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache; 457 aic26->codec.reg_cache = aic26->reg_cache;
459 458
459 aic26_dai.dev = &spi->dev;
460 ret = snd_soc_register_dai(&aic26_dai);
461 if (ret != 0) {
462 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
463 kfree(aic26);
464 return ret;
465 }
466
460 /* Reset the codec to power on defaults */ 467 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00); 468 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462 469
@@ -475,8 +482,8 @@ static int aic26_spi_probe(struct spi_device *spi)
475 482
476 /* Register the sysfs files for debugging */ 483 /* Register the sysfs files for debugging */
477 /* Create SysFS files */ 484 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick); 485 ret = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc) 486 if (ret)
480 dev_info(&spi->dev, "error creating sysfs files\n"); 487 dev_info(&spi->dev, "error creating sysfs files\n");
481 488
482#if defined(CONFIG_SND_SOC_OF_SIMPLE) 489#if defined(CONFIG_SND_SOC_OF_SIMPLE)
@@ -493,6 +500,7 @@ static int aic26_spi_remove(struct spi_device *spi)
493{ 500{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 501 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495 502
503 snd_soc_unregister_dai(&aic26_dai);
496 kfree(aic26); 504 kfree(aic26);
497 505
498 return 0; 506 return 0;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 566a427c928f..b47a749c5ea2 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -48,7 +48,6 @@
48 48
49#include "tlv320aic3x.h" 49#include "tlv320aic3x.h"
50 50
51#define AUDIO_NAME "aic3x"
52#define AIC3X_VERSION "0.2" 51#define AIC3X_VERSION "0.2"
53 52
54/* codec private data */ 53/* codec private data */
@@ -254,11 +253,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
254 253
255 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, 254 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL,
256 DACR1_2_RLOPM_VOL, 0, 0x7f, 1), 255 DACR1_2_RLOPM_VOL, 0, 0x7f, 1),
257 SOC_DOUBLE_R("Line DAC Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3, 256 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0),
258 0x01, 0), 257 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0),
259 SOC_DOUBLE_R("Line PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, 258 SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL,
260 PGAR_2_RLOPM_VOL, 0, 0x7f, 1), 259 DACR1_2_LLOPM_VOL, 0, 0x7f, 1),
261 SOC_DOUBLE_R("Line Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, 260 SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL,
261 0, 0x7f, 1),
262 SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL,
263 0, 0x7f, 1),
264 SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL,
265 LINE2R_2_LLOPM_VOL, 0, 0x7f, 1),
266 SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL,
262 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), 267 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1),
263 268
264 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, 269 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL,
@@ -273,8 +278,12 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
273 DACR1_2_HPROUT_VOL, 0, 0x7f, 1), 278 DACR1_2_HPROUT_VOL, 0, 0x7f, 1),
274 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 279 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
275 0x01, 0), 280 0x01, 0),
276 SOC_DOUBLE_R("HP PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, 281 SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL,
277 PGAR_2_HPROUT_VOL, 0, 0x7f, 1), 282 PGAR_2_HPROUT_VOL, 0, 0x7f, 1),
283 SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL,
284 0, 0x7f, 1),
285 SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL,
286 0, 0x7f, 1),
278 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, 287 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL,
279 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), 288 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1),
280 289
@@ -282,8 +291,10 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
282 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), 291 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1),
283 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 292 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
284 0x01, 0), 293 0x01, 0),
285 SOC_DOUBLE_R("HPCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, 294 SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL,
286 PGAR_2_HPRCOM_VOL, 0, 0x7f, 1), 295 0, 0x7f, 1),
296 SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL,
297 0, 0x7f, 1),
287 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, 298 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL,
288 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), 299 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1),
289 300
@@ -334,7 +345,8 @@ SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
334 345
335/* Left DAC_L1 Mixer */ 346/* Left DAC_L1 Mixer */
336static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = { 347static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
337 SOC_DAPM_SINGLE("Line Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), 348 SOC_DAPM_SINGLE("LineL Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
349 SOC_DAPM_SINGLE("LineR Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
338 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0), 350 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
339 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), 351 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
340 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), 352 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
@@ -342,7 +354,8 @@ static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
342 354
343/* Right DAC_R1 Mixer */ 355/* Right DAC_R1 Mixer */
344static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = { 356static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
345 SOC_DAPM_SINGLE("Line Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), 357 SOC_DAPM_SINGLE("LineL Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
358 SOC_DAPM_SINGLE("LineR Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
346 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0), 359 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
347 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), 360 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
348 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), 361 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
@@ -351,14 +364,18 @@ static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
351/* Left PGA Mixer */ 364/* Left PGA Mixer */
352static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = { 365static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
353 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1), 366 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
367 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
354 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1), 368 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
355 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1), 369 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
370 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
356}; 371};
357 372
358/* Right PGA Mixer */ 373/* Right PGA Mixer */
359static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = { 374static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
360 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1), 375 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
376 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
361 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1), 377 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
378 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
362 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), 379 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
363}; 380};
364 381
@@ -380,34 +397,42 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
380 397
381/* Left PGA Bypass Mixer */ 398/* Left PGA Bypass Mixer */
382static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = { 399static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = {
383 SOC_DAPM_SINGLE("Line Switch", PGAL_2_LLOPM_VOL, 7, 1, 0), 400 SOC_DAPM_SINGLE("LineL Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("LineR Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
384 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0), 402 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
385 SOC_DAPM_SINGLE("HP Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0), 403 SOC_DAPM_SINGLE("HPL Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
386 SOC_DAPM_SINGLE("HPCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0), 404 SOC_DAPM_SINGLE("HPR Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
405 SOC_DAPM_SINGLE("HPLCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
406 SOC_DAPM_SINGLE("HPRCOM Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
387}; 407};
388 408
389/* Right PGA Bypass Mixer */ 409/* Right PGA Bypass Mixer */
390static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = { 410static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = {
391 SOC_DAPM_SINGLE("Line Switch", PGAR_2_RLOPM_VOL, 7, 1, 0), 411 SOC_DAPM_SINGLE("LineL Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
412 SOC_DAPM_SINGLE("LineR Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
392 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0), 413 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
393 SOC_DAPM_SINGLE("HP Switch", PGAR_2_HPROUT_VOL, 7, 1, 0), 414 SOC_DAPM_SINGLE("HPL Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
394 SOC_DAPM_SINGLE("HPCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0), 415 SOC_DAPM_SINGLE("HPR Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
416 SOC_DAPM_SINGLE("HPLCOM Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
417 SOC_DAPM_SINGLE("HPRCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
395}; 418};
396 419
397/* Left Line2 Bypass Mixer */ 420/* Left Line2 Bypass Mixer */
398static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = { 421static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = {
399 SOC_DAPM_SINGLE("Line Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0), 422 SOC_DAPM_SINGLE("LineL Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
423 SOC_DAPM_SINGLE("LineR Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
400 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0), 424 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0), 425 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
402 SOC_DAPM_SINGLE("HPCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0), 426 SOC_DAPM_SINGLE("HPLCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
403}; 427};
404 428
405/* Right Line2 Bypass Mixer */ 429/* Right Line2 Bypass Mixer */
406static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = { 430static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = {
407 SOC_DAPM_SINGLE("Line Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0), 431 SOC_DAPM_SINGLE("LineL Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
432 SOC_DAPM_SINGLE("LineR Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
408 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0), 433 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
409 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0), 434 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
410 SOC_DAPM_SINGLE("HPCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0), 435 SOC_DAPM_SINGLE("HPRCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
411}; 436};
412 437
413static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 438static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
@@ -440,22 +465,26 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
440 /* Mono Output */ 465 /* Mono Output */
441 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0), 466 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
442 467
443 /* Left Inputs to Left ADC */ 468 /* Inputs to Left ADC */
444 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), 469 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
445 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, 470 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
446 &aic3x_left_pga_mixer_controls[0], 471 &aic3x_left_pga_mixer_controls[0],
447 ARRAY_SIZE(aic3x_left_pga_mixer_controls)), 472 ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
448 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, 473 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
449 &aic3x_left_line1_mux_controls), 474 &aic3x_left_line1_mux_controls),
475 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
476 &aic3x_left_line1_mux_controls),
450 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, 477 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
451 &aic3x_left_line2_mux_controls), 478 &aic3x_left_line2_mux_controls),
452 479
453 /* Right Inputs to Right ADC */ 480 /* Inputs to Right ADC */
454 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", 481 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
455 LINE1R_2_RADC_CTRL, 2, 0), 482 LINE1R_2_RADC_CTRL, 2, 0),
456 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, 483 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
457 &aic3x_right_pga_mixer_controls[0], 484 &aic3x_right_pga_mixer_controls[0],
458 ARRAY_SIZE(aic3x_right_pga_mixer_controls)), 485 ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
486 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
487 &aic3x_right_line1_mux_controls),
459 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, 488 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
460 &aic3x_right_line1_mux_controls), 489 &aic3x_right_line1_mux_controls),
461 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, 490 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
@@ -532,7 +561,8 @@ static const struct snd_soc_dapm_route intercon[] = {
532 {"Left DAC Mux", "DAC_L2", "Left DAC"}, 561 {"Left DAC Mux", "DAC_L2", "Left DAC"},
533 {"Left DAC Mux", "DAC_L3", "Left DAC"}, 562 {"Left DAC Mux", "DAC_L3", "Left DAC"},
534 563
535 {"Left DAC_L1 Mixer", "Line Switch", "Left DAC Mux"}, 564 {"Left DAC_L1 Mixer", "LineL Switch", "Left DAC Mux"},
565 {"Left DAC_L1 Mixer", "LineR Switch", "Left DAC Mux"},
536 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"}, 566 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"},
537 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"}, 567 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"},
538 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"}, 568 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"},
@@ -558,7 +588,8 @@ static const struct snd_soc_dapm_route intercon[] = {
558 {"Right DAC Mux", "DAC_R2", "Right DAC"}, 588 {"Right DAC Mux", "DAC_R2", "Right DAC"},
559 {"Right DAC Mux", "DAC_R3", "Right DAC"}, 589 {"Right DAC Mux", "DAC_R3", "Right DAC"},
560 590
561 {"Right DAC_R1 Mixer", "Line Switch", "Right DAC Mux"}, 591 {"Right DAC_R1 Mixer", "LineL Switch", "Right DAC Mux"},
592 {"Right DAC_R1 Mixer", "LineR Switch", "Right DAC Mux"},
562 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"}, 593 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"},
563 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"}, 594 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"},
564 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"}, 595 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"},
@@ -593,8 +624,10 @@ static const struct snd_soc_dapm_route intercon[] = {
593 {"Left Line2L Mux", "differential", "LINE2L"}, 624 {"Left Line2L Mux", "differential", "LINE2L"},
594 625
595 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, 626 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
627 {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
596 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, 628 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
597 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, 629 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
630 {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
598 631
599 {"Left ADC", NULL, "Left PGA Mixer"}, 632 {"Left ADC", NULL, "Left PGA Mixer"},
600 {"Left ADC", NULL, "GPIO1 dmic modclk"}, 633 {"Left ADC", NULL, "GPIO1 dmic modclk"},
@@ -606,18 +639,23 @@ static const struct snd_soc_dapm_route intercon[] = {
606 {"Right Line2R Mux", "single-ended", "LINE2R"}, 639 {"Right Line2R Mux", "single-ended", "LINE2R"},
607 {"Right Line2R Mux", "differential", "LINE2R"}, 640 {"Right Line2R Mux", "differential", "LINE2R"},
608 641
642 {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
609 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"}, 643 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
610 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"}, 644 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
645 {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
611 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, 646 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
612 647
613 {"Right ADC", NULL, "Right PGA Mixer"}, 648 {"Right ADC", NULL, "Right PGA Mixer"},
614 {"Right ADC", NULL, "GPIO1 dmic modclk"}, 649 {"Right ADC", NULL, "GPIO1 dmic modclk"},
615 650
616 /* Left PGA Bypass */ 651 /* Left PGA Bypass */
617 {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"}, 652 {"Left PGA Bypass Mixer", "LineL Switch", "Left PGA Mixer"},
653 {"Left PGA Bypass Mixer", "LineR Switch", "Left PGA Mixer"},
618 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"}, 654 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"},
619 {"Left PGA Bypass Mixer", "HP Switch", "Left PGA Mixer"}, 655 {"Left PGA Bypass Mixer", "HPL Switch", "Left PGA Mixer"},
620 {"Left PGA Bypass Mixer", "HPCOM Switch", "Left PGA Mixer"}, 656 {"Left PGA Bypass Mixer", "HPR Switch", "Left PGA Mixer"},
657 {"Left PGA Bypass Mixer", "HPLCOM Switch", "Left PGA Mixer"},
658 {"Left PGA Bypass Mixer", "HPRCOM Switch", "Left PGA Mixer"},
621 659
622 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"}, 660 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"},
623 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"}, 661 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"},
@@ -628,10 +666,13 @@ static const struct snd_soc_dapm_route intercon[] = {
628 {"Left HP Out", NULL, "Left PGA Bypass Mixer"}, 666 {"Left HP Out", NULL, "Left PGA Bypass Mixer"},
629 667
630 /* Right PGA Bypass */ 668 /* Right PGA Bypass */
631 {"Right PGA Bypass Mixer", "Line Switch", "Right PGA Mixer"}, 669 {"Right PGA Bypass Mixer", "LineL Switch", "Right PGA Mixer"},
670 {"Right PGA Bypass Mixer", "LineR Switch", "Right PGA Mixer"},
632 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"}, 671 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"},
633 {"Right PGA Bypass Mixer", "HP Switch", "Right PGA Mixer"}, 672 {"Right PGA Bypass Mixer", "HPL Switch", "Right PGA Mixer"},
634 {"Right PGA Bypass Mixer", "HPCOM Switch", "Right PGA Mixer"}, 673 {"Right PGA Bypass Mixer", "HPR Switch", "Right PGA Mixer"},
674 {"Right PGA Bypass Mixer", "HPLCOM Switch", "Right PGA Mixer"},
675 {"Right PGA Bypass Mixer", "HPRCOM Switch", "Right PGA Mixer"},
635 676
636 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"}, 677 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"},
637 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"}, 678 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"},
@@ -644,10 +685,11 @@ static const struct snd_soc_dapm_route intercon[] = {
644 {"Right HP Out", NULL, "Right PGA Bypass Mixer"}, 685 {"Right HP Out", NULL, "Right PGA Bypass Mixer"},
645 686
646 /* Left Line2 Bypass */ 687 /* Left Line2 Bypass */
647 {"Left Line2 Bypass Mixer", "Line Switch", "Left Line2L Mux"}, 688 {"Left Line2 Bypass Mixer", "LineL Switch", "Left Line2L Mux"},
689 {"Left Line2 Bypass Mixer", "LineR Switch", "Left Line2L Mux"},
648 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"}, 690 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"},
649 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"}, 691 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"},
650 {"Left Line2 Bypass Mixer", "HPCOM Switch", "Left Line2L Mux"}, 692 {"Left Line2 Bypass Mixer", "HPLCOM Switch", "Left Line2L Mux"},
651 693
652 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"}, 694 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"},
653 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"}, 695 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"},
@@ -658,10 +700,11 @@ static const struct snd_soc_dapm_route intercon[] = {
658 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"}, 700 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"},
659 701
660 /* Right Line2 Bypass */ 702 /* Right Line2 Bypass */
661 {"Right Line2 Bypass Mixer", "Line Switch", "Right Line2R Mux"}, 703 {"Right Line2 Bypass Mixer", "LineL Switch", "Right Line2R Mux"},
704 {"Right Line2 Bypass Mixer", "LineR Switch", "Right Line2R Mux"},
662 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"}, 705 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"},
663 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"}, 706 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"},
664 {"Right Line2 Bypass Mixer", "HPCOM Switch", "Right Line2R Mux"}, 707 {"Right Line2 Bypass Mixer", "HPRCOM Switch", "Right Line2R Mux"},
665 708
666 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"}, 709 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"},
667 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"}, 710 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"},
@@ -695,7 +738,8 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
695} 738}
696 739
697static int aic3x_hw_params(struct snd_pcm_substream *substream, 740static int aic3x_hw_params(struct snd_pcm_substream *substream,
698 struct snd_pcm_hw_params *params) 741 struct snd_pcm_hw_params *params,
742 struct snd_soc_dai *dai)
699{ 743{
700 struct snd_soc_pcm_runtime *rtd = substream->private_data; 744 struct snd_soc_pcm_runtime *rtd = substream->private_data;
701 struct snd_soc_device *socdev = rtd->socdev; 745 struct snd_soc_device *socdev = rtd->socdev;
@@ -847,6 +891,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
847 struct snd_soc_codec *codec = codec_dai->codec; 891 struct snd_soc_codec *codec = codec_dai->codec;
848 struct aic3x_priv *aic3x = codec->private_data; 892 struct aic3x_priv *aic3x = codec->private_data;
849 u8 iface_areg, iface_breg; 893 u8 iface_areg, iface_breg;
894 int delay = 0;
850 895
851 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f; 896 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; 897 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
@@ -864,17 +909,23 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
864 return -EINVAL; 909 return -EINVAL;
865 } 910 }
866 911
867 /* interface format */ 912 /*
868 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 913 * match both interface format and signal polarities since they
869 case SND_SOC_DAIFMT_I2S: 914 * are fixed
915 */
916 switch (fmt & (SND_SOC_DAIFMT_FORMAT_MASK |
917 SND_SOC_DAIFMT_INV_MASK)) {
918 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
870 break; 919 break;
871 case SND_SOC_DAIFMT_DSP_A: 920 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
921 delay = 1;
922 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
872 iface_breg |= (0x01 << 6); 923 iface_breg |= (0x01 << 6);
873 break; 924 break;
874 case SND_SOC_DAIFMT_RIGHT_J: 925 case (SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_NB_NF):
875 iface_breg |= (0x02 << 6); 926 iface_breg |= (0x02 << 6);
876 break; 927 break;
877 case SND_SOC_DAIFMT_LEFT_J: 928 case (SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_NB_NF):
878 iface_breg |= (0x03 << 6); 929 iface_breg |= (0x03 << 6);
879 break; 930 break;
880 default: 931 default:
@@ -884,6 +935,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
884 /* set iface */ 935 /* set iface */
885 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg); 936 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
886 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg); 937 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
938 aic3x_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
887 939
888 return 0; 940 return 0;
889} 941}
@@ -978,20 +1030,47 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
978} 1030}
979EXPORT_SYMBOL_GPL(aic3x_get_gpio); 1031EXPORT_SYMBOL_GPL(aic3x_get_gpio);
980 1032
1033void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1034 int headset_debounce, int button_debounce)
1035{
1036 u8 val;
1037
1038 val = ((detect & AIC3X_HEADSET_DETECT_MASK)
1039 << AIC3X_HEADSET_DETECT_SHIFT) |
1040 ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
1041 << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
1042 ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
1043 << AIC3X_BUTTON_DEBOUNCE_SHIFT);
1044
1045 if (detect & AIC3X_HEADSET_DETECT_MASK)
1046 val |= AIC3X_HEADSET_DETECT_ENABLED;
1047
1048 aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1049}
1050EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1051
981int aic3x_headset_detected(struct snd_soc_codec *codec) 1052int aic3x_headset_detected(struct snd_soc_codec *codec)
982{ 1053{
983 u8 val; 1054 u8 val;
984 aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val); 1055 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
985 return (val >> 2) & 1; 1056 return (val >> 4) & 1;
986} 1057}
987EXPORT_SYMBOL_GPL(aic3x_headset_detected); 1058EXPORT_SYMBOL_GPL(aic3x_headset_detected);
988 1059
1060int aic3x_button_pressed(struct snd_soc_codec *codec)
1061{
1062 u8 val;
1063 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1064 return (val >> 5) & 1;
1065}
1066EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1067
989#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1068#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
990#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1069#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
991 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1070 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
992 1071
993struct snd_soc_dai aic3x_dai = { 1072struct snd_soc_dai aic3x_dai = {
994 .name = "aic3x", 1073 .name = "tlv320aic3x",
995 .playback = { 1074 .playback = {
996 .stream_name = "Playback", 1075 .stream_name = "Playback",
997 .channels_min = 1, 1076 .channels_min = 1,
@@ -1006,8 +1085,6 @@ struct snd_soc_dai aic3x_dai = {
1006 .formats = AIC3X_FORMATS,}, 1085 .formats = AIC3X_FORMATS,},
1007 .ops = { 1086 .ops = {
1008 .hw_params = aic3x_hw_params, 1087 .hw_params = aic3x_hw_params,
1009 },
1010 .dai_ops = {
1011 .digital_mute = aic3x_mute, 1088 .digital_mute = aic3x_mute,
1012 .set_sysclk = aic3x_set_dai_sysclk, 1089 .set_sysclk = aic3x_set_dai_sysclk,
1013 .set_fmt = aic3x_set_dai_fmt, 1090 .set_fmt = aic3x_set_dai_fmt,
@@ -1055,7 +1132,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1055 struct aic3x_setup_data *setup = socdev->codec_data; 1132 struct aic3x_setup_data *setup = socdev->codec_data;
1056 int reg, ret = 0; 1133 int reg, ret = 0;
1057 1134
1058 codec->name = "aic3x"; 1135 codec->name = "tlv320aic3x";
1059 codec->owner = THIS_MODULE; 1136 codec->owner = THIS_MODULE;
1060 codec->read = aic3x_read_reg_cache; 1137 codec->read = aic3x_read_reg_cache;
1061 codec->write = aic3x_write; 1138 codec->write = aic3x_write;
@@ -1149,7 +1226,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1149 1226
1150 aic3x_add_controls(codec); 1227 aic3x_add_controls(codec);
1151 aic3x_add_widgets(codec); 1228 aic3x_add_widgets(codec);
1152 ret = snd_soc_register_card(socdev); 1229 ret = snd_soc_init_card(socdev);
1153 if (ret < 0) { 1230 if (ret < 0) {
1154 printk(KERN_ERR "aic3x: failed to register card\n"); 1231 printk(KERN_ERR "aic3x: failed to register card\n");
1155 goto card_err; 1232 goto card_err;
@@ -1338,6 +1415,18 @@ struct snd_soc_codec_device soc_codec_dev_aic3x = {
1338}; 1415};
1339EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x); 1416EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1340 1417
1418static int __init aic3x_modinit(void)
1419{
1420 return snd_soc_register_dai(&aic3x_dai);
1421}
1422module_init(aic3x_modinit);
1423
1424static void __exit aic3x_exit(void)
1425{
1426 snd_soc_unregister_dai(&aic3x_dai);
1427}
1428module_exit(aic3x_exit);
1429
1341MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); 1430MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1342MODULE_AUTHOR("Vladimir Barinov"); 1431MODULE_AUTHOR("Vladimir Barinov");
1343MODULE_LICENSE("GPL"); 1432MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 00a195aa02e4..ac827e578c4d 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -35,11 +35,15 @@
35#define AIC3X_ASD_INTF_CTRLA 8 35#define AIC3X_ASD_INTF_CTRLA 8
36/* Audio serial data interface control register B */ 36/* Audio serial data interface control register B */
37#define AIC3X_ASD_INTF_CTRLB 9 37#define AIC3X_ASD_INTF_CTRLB 9
38/* Audio serial data interface control register C */
39#define AIC3X_ASD_INTF_CTRLC 10
38/* Audio overflow status and PLL R value programming register */ 40/* Audio overflow status and PLL R value programming register */
39#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 41#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
40/* Audio codec digital filter control register */ 42/* Audio codec digital filter control register */
41#define AIC3X_CODEC_DFILT_CTRL 12 43#define AIC3X_CODEC_DFILT_CTRL 12
42 44/* Headset/button press detection register */
45#define AIC3X_HEADSET_DETECT_CTRL_A 13
46#define AIC3X_HEADSET_DETECT_CTRL_B 14
43/* ADC PGA Gain control registers */ 47/* ADC PGA Gain control registers */
44#define LADC_VOL 15 48#define LADC_VOL 15
45#define RADC_VOL 16 49#define RADC_VOL 16
@@ -48,7 +52,9 @@
48#define MIC3LR_2_RADC_CTRL 18 52#define MIC3LR_2_RADC_CTRL 18
49/* Line1 Input control registers */ 53/* Line1 Input control registers */
50#define LINE1L_2_LADC_CTRL 19 54#define LINE1L_2_LADC_CTRL 19
55#define LINE1R_2_LADC_CTRL 21
51#define LINE1R_2_RADC_CTRL 22 56#define LINE1R_2_RADC_CTRL 22
57#define LINE1L_2_RADC_CTRL 24
52/* Line2 Input control registers */ 58/* Line2 Input control registers */
53#define LINE2L_2_LADC_CTRL 20 59#define LINE2L_2_LADC_CTRL 20
54#define LINE2R_2_RADC_CTRL 23 60#define LINE2R_2_RADC_CTRL 23
@@ -79,6 +85,8 @@
79#define LINE2L_2_HPLOUT_VOL 45 85#define LINE2L_2_HPLOUT_VOL 45
80#define LINE2R_2_HPROUT_VOL 62 86#define LINE2R_2_HPROUT_VOL 62
81#define PGAL_2_HPLOUT_VOL 46 87#define PGAL_2_HPLOUT_VOL 46
88#define PGAL_2_HPROUT_VOL 60
89#define PGAR_2_HPLOUT_VOL 49
82#define PGAR_2_HPROUT_VOL 63 90#define PGAR_2_HPROUT_VOL 63
83#define DACL1_2_HPLOUT_VOL 47 91#define DACL1_2_HPLOUT_VOL 47
84#define DACR1_2_HPROUT_VOL 64 92#define DACR1_2_HPROUT_VOL 64
@@ -88,6 +96,8 @@
88#define LINE2L_2_HPLCOM_VOL 52 96#define LINE2L_2_HPLCOM_VOL 52
89#define LINE2R_2_HPRCOM_VOL 69 97#define LINE2R_2_HPRCOM_VOL 69
90#define PGAL_2_HPLCOM_VOL 53 98#define PGAL_2_HPLCOM_VOL 53
99#define PGAR_2_HPLCOM_VOL 56
100#define PGAL_2_HPRCOM_VOL 67
91#define PGAR_2_HPRCOM_VOL 70 101#define PGAR_2_HPRCOM_VOL 70
92#define DACL1_2_HPLCOM_VOL 54 102#define DACL1_2_HPLCOM_VOL 54
93#define DACR1_2_HPRCOM_VOL 71 103#define DACR1_2_HPRCOM_VOL 71
@@ -103,11 +113,17 @@
103#define MONOLOPM_CTRL 79 113#define MONOLOPM_CTRL 79
104/* Line Output Plus/Minus control registers */ 114/* Line Output Plus/Minus control registers */
105#define LINE2L_2_LLOPM_VOL 80 115#define LINE2L_2_LLOPM_VOL 80
116#define LINE2L_2_RLOPM_VOL 87
117#define LINE2R_2_LLOPM_VOL 83
106#define LINE2R_2_RLOPM_VOL 90 118#define LINE2R_2_RLOPM_VOL 90
107#define PGAL_2_LLOPM_VOL 81 119#define PGAL_2_LLOPM_VOL 81
120#define PGAL_2_RLOPM_VOL 88
121#define PGAR_2_LLOPM_VOL 84
108#define PGAR_2_RLOPM_VOL 91 122#define PGAR_2_RLOPM_VOL 91
109#define DACL1_2_LLOPM_VOL 82 123#define DACL1_2_LLOPM_VOL 82
124#define DACL1_2_RLOPM_VOL 89
110#define DACR1_2_RLOPM_VOL 92 125#define DACR1_2_RLOPM_VOL 92
126#define DACR1_2_LLOPM_VOL 85
111#define LLOPM_CTRL 86 127#define LLOPM_CTRL 86
112#define RLOPM_CTRL 93 128#define RLOPM_CTRL 93
113/* GPIO/IRQ registers */ 129/* GPIO/IRQ registers */
@@ -221,7 +237,49 @@ enum {
221 237
222void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 238void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
223int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 239int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
240
241/* headset detection / button API */
242
243/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
244 * and cellular headsets (GND + speaker output + microphone input).
245 * It is recommended to enable MIC bias for this function to work properly.
246 * For more information, please refer to the datasheet. */
247enum {
248 AIC3X_HEADSET_DETECT_OFF = 0,
249 AIC3X_HEADSET_DETECT_STEREO = 1,
250 AIC3X_HEADSET_DETECT_CELLULAR = 2,
251 AIC3X_HEADSET_DETECT_BOTH = 3
252};
253
254enum {
255 AIC3X_HEADSET_DEBOUNCE_16MS = 0,
256 AIC3X_HEADSET_DEBOUNCE_32MS = 1,
257 AIC3X_HEADSET_DEBOUNCE_64MS = 2,
258 AIC3X_HEADSET_DEBOUNCE_128MS = 3,
259 AIC3X_HEADSET_DEBOUNCE_256MS = 4,
260 AIC3X_HEADSET_DEBOUNCE_512MS = 5
261};
262
263enum {
264 AIC3X_BUTTON_DEBOUNCE_0MS = 0,
265 AIC3X_BUTTON_DEBOUNCE_8MS = 1,
266 AIC3X_BUTTON_DEBOUNCE_16MS = 2,
267 AIC3X_BUTTON_DEBOUNCE_32MS = 3
268};
269
270#define AIC3X_HEADSET_DETECT_ENABLED 0x80
271#define AIC3X_HEADSET_DETECT_SHIFT 5
272#define AIC3X_HEADSET_DETECT_MASK 3
273#define AIC3X_HEADSET_DEBOUNCE_SHIFT 2
274#define AIC3X_HEADSET_DEBOUNCE_MASK 7
275#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
276#define AIC3X_BUTTON_DEBOUNCE_MASK 3
277
278/* see the enums above for valid parameters to this function */
279void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
280 int headset_debounce, int button_debounce);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 281int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec);
225 283
226struct aic3x_setup_data { 284struct aic3x_setup_data {
227 int i2c_bus; 285 int i2c_bus;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
new file mode 100644
index 000000000000..ea370a4f86d5
--- /dev/null
+++ b/sound/soc/codecs/twl4030.c
@@ -0,0 +1,1312 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman, <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38#include "twl4030.h"
39
40/*
41 * twl4030 register cache & default register settings
42 */
43static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
44 0x00, /* this register not used */
45 0x93, /* REG_CODEC_MODE (0x1) */
46 0xc3, /* REG_OPTION (0x2) */
47 0x00, /* REG_UNKNOWN (0x3) */
48 0x00, /* REG_MICBIAS_CTL (0x4) */
49 0x20, /* REG_ANAMICL (0x5) */
50 0x00, /* REG_ANAMICR (0x6) */
51 0x00, /* REG_AVADC_CTL (0x7) */
52 0x00, /* REG_ADCMICSEL (0x8) */
53 0x00, /* REG_DIGMIXING (0x9) */
54 0x0c, /* REG_ATXL1PGA (0xA) */
55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */
62 0x6c, /* REG_ARXR2PGA (0x12) */
63 0x6c, /* REG_ARXL2PGA (0x13) */
64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */
83 0x00, /* REG_PRECKL_CTL (0x27) */
84 0x00, /* REG_PRECKR_CTL (0x28) */
85 0x00, /* REG_HFL_CTL (0x29) */
86 0x00, /* REG_HFR_CTL (0x2A) */
87 0x00, /* REG_ALC_CTL (0x2B) */
88 0x00, /* REG_ALC_SET1 (0x2C) */
89 0x00, /* REG_ALC_SET2 (0x2D) */
90 0x00, /* REG_BOOST_CTL (0x2E) */
91 0x00, /* REG_SOFTVOL_CTL (0x2F) */
92 0x00, /* REG_DTMF_FREQSEL (0x30) */
93 0x00, /* REG_DTMF_TONEXT1H (0x31) */
94 0x00, /* REG_DTMF_TONEXT1L (0x32) */
95 0x00, /* REG_DTMF_TONEXT2H (0x33) */
96 0x00, /* REG_DTMF_TONEXT2L (0x34) */
97 0x00, /* REG_DTMF_TONOFF (0x35) */
98 0x00, /* REG_DTMF_WANONOFF (0x36) */
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
106 0x00, /* REG_MISC_SET_1 (0x3E) */
107 0x00, /* REG_PCMBTMUX (0x3F) */
108 0x00, /* not used (0x40) */
109 0x00, /* not used (0x41) */
110 0x00, /* not used (0x42) */
111 0x00, /* REG_RX_PATH_SEL (0x43) */
112 0x00, /* REG_VDL_APGA_CTL (0x44) */
113 0x00, /* REG_VIBRA_CTL (0x45) */
114 0x00, /* REG_VIBRA_SET (0x46) */
115 0x00, /* REG_VIBRA_PWM_SET (0x47) */
116 0x00, /* REG_ANAMIC_GAIN (0x48) */
117 0x00, /* REG_MISC_SET_2 (0x49) */
118};
119
120/*
121 * read twl4030 register cache
122 */
123static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
124 unsigned int reg)
125{
126 u8 *cache = codec->reg_cache;
127
128 return cache[reg];
129}
130
131/*
132 * write twl4030 register cache
133 */
134static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
135 u8 reg, u8 value)
136{
137 u8 *cache = codec->reg_cache;
138
139 if (reg >= TWL4030_CACHEREGNUM)
140 return;
141 cache[reg] = value;
142}
143
144/*
145 * write to the twl4030 register space
146 */
147static int twl4030_write(struct snd_soc_codec *codec,
148 unsigned int reg, unsigned int value)
149{
150 twl4030_write_reg_cache(codec, reg, value);
151 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
152}
153
154static void twl4030_clear_codecpdz(struct snd_soc_codec *codec)
155{
156 u8 mode;
157
158 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
159 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
160 mode & ~TWL4030_CODECPDZ);
161
162 /* REVISIT: this delay is present in TI sample drivers */
163 /* but there seems to be no TRM requirement for it */
164 udelay(10);
165}
166
167static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
168{
169 u8 mode;
170
171 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
172 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
173 mode | TWL4030_CODECPDZ);
174
175 /* REVISIT: this delay is present in TI sample drivers */
176 /* but there seems to be no TRM requirement for it */
177 udelay(10);
178}
179
180static void twl4030_init_chip(struct snd_soc_codec *codec)
181{
182 int i;
183
184 /* clear CODECPDZ prior to setting register defaults */
185 twl4030_clear_codecpdz(codec);
186
187 /* set all audio section registers to reasonable defaults */
188 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
189 twl4030_write(codec, i, twl4030_reg[i]);
190
191}
192
193/* Earpiece */
194static const char *twl4030_earpiece_texts[] =
195 {"Off", "DACL1", "DACL2", "DACR1"};
196
197static const unsigned int twl4030_earpiece_values[] =
198 {0x0, 0x1, 0x2, 0x4};
199
200static const struct soc_enum twl4030_earpiece_enum =
201 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
202 ARRAY_SIZE(twl4030_earpiece_texts),
203 twl4030_earpiece_texts,
204 twl4030_earpiece_values);
205
206static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
207SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum);
208
209/* PreDrive Left */
210static const char *twl4030_predrivel_texts[] =
211 {"Off", "DACL1", "DACL2", "DACR2"};
212
213static const unsigned int twl4030_predrivel_values[] =
214 {0x0, 0x1, 0x2, 0x4};
215
216static const struct soc_enum twl4030_predrivel_enum =
217 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
218 ARRAY_SIZE(twl4030_predrivel_texts),
219 twl4030_predrivel_texts,
220 twl4030_predrivel_values);
221
222static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
223SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum);
224
225/* PreDrive Right */
226static const char *twl4030_predriver_texts[] =
227 {"Off", "DACR1", "DACR2", "DACL2"};
228
229static const unsigned int twl4030_predriver_values[] =
230 {0x0, 0x1, 0x2, 0x4};
231
232static const struct soc_enum twl4030_predriver_enum =
233 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
234 ARRAY_SIZE(twl4030_predriver_texts),
235 twl4030_predriver_texts,
236 twl4030_predriver_values);
237
238static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
239SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum);
240
241/* Headset Left */
242static const char *twl4030_hsol_texts[] =
243 {"Off", "DACL1", "DACL2"};
244
245static const struct soc_enum twl4030_hsol_enum =
246 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
247 ARRAY_SIZE(twl4030_hsol_texts),
248 twl4030_hsol_texts);
249
250static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
251SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
252
253/* Headset Right */
254static const char *twl4030_hsor_texts[] =
255 {"Off", "DACR1", "DACR2"};
256
257static const struct soc_enum twl4030_hsor_enum =
258 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
259 ARRAY_SIZE(twl4030_hsor_texts),
260 twl4030_hsor_texts);
261
262static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
263SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
264
265/* Carkit Left */
266static const char *twl4030_carkitl_texts[] =
267 {"Off", "DACL1", "DACL2"};
268
269static const struct soc_enum twl4030_carkitl_enum =
270 SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
271 ARRAY_SIZE(twl4030_carkitl_texts),
272 twl4030_carkitl_texts);
273
274static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
275SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
276
277/* Carkit Right */
278static const char *twl4030_carkitr_texts[] =
279 {"Off", "DACR1", "DACR2"};
280
281static const struct soc_enum twl4030_carkitr_enum =
282 SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
283 ARRAY_SIZE(twl4030_carkitr_texts),
284 twl4030_carkitr_texts);
285
286static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
287SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
288
289/* Handsfree Left */
290static const char *twl4030_handsfreel_texts[] =
291 {"Voice", "DACL1", "DACL2", "DACR2"};
292
293static const struct soc_enum twl4030_handsfreel_enum =
294 SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
295 ARRAY_SIZE(twl4030_handsfreel_texts),
296 twl4030_handsfreel_texts);
297
298static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
299SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
300
301/* Handsfree Right */
302static const char *twl4030_handsfreer_texts[] =
303 {"Voice", "DACR1", "DACR2", "DACL2"};
304
305static const struct soc_enum twl4030_handsfreer_enum =
306 SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
307 ARRAY_SIZE(twl4030_handsfreer_texts),
308 twl4030_handsfreer_texts);
309
310static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
311SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
312
313/* Left analog microphone selection */
314static const char *twl4030_analoglmic_texts[] =
315 {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"};
316
317static const unsigned int twl4030_analoglmic_values[] =
318 {0x0, 0x1, 0x2, 0x4, 0x8};
319
320static const struct soc_enum twl4030_analoglmic_enum =
321 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
322 ARRAY_SIZE(twl4030_analoglmic_texts),
323 twl4030_analoglmic_texts,
324 twl4030_analoglmic_values);
325
326static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control =
327SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum);
328
329/* Right analog microphone selection */
330static const char *twl4030_analogrmic_texts[] =
331 {"Off", "Sub mic", "AUXR"};
332
333static const unsigned int twl4030_analogrmic_values[] =
334 {0x0, 0x1, 0x4};
335
336static const struct soc_enum twl4030_analogrmic_enum =
337 SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
338 ARRAY_SIZE(twl4030_analogrmic_texts),
339 twl4030_analogrmic_texts,
340 twl4030_analogrmic_values);
341
342static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control =
343SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum);
344
345/* TX1 L/R Analog/Digital microphone selection */
346static const char *twl4030_micpathtx1_texts[] =
347 {"Analog", "Digimic0"};
348
349static const struct soc_enum twl4030_micpathtx1_enum =
350 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 0,
351 ARRAY_SIZE(twl4030_micpathtx1_texts),
352 twl4030_micpathtx1_texts);
353
354static const struct snd_kcontrol_new twl4030_dapm_micpathtx1_control =
355SOC_DAPM_ENUM("Route", twl4030_micpathtx1_enum);
356
357/* TX2 L/R Analog/Digital microphone selection */
358static const char *twl4030_micpathtx2_texts[] =
359 {"Analog", "Digimic1"};
360
361static const struct soc_enum twl4030_micpathtx2_enum =
362 SOC_ENUM_SINGLE(TWL4030_REG_ADCMICSEL, 2,
363 ARRAY_SIZE(twl4030_micpathtx2_texts),
364 twl4030_micpathtx2_texts);
365
366static const struct snd_kcontrol_new twl4030_dapm_micpathtx2_control =
367SOC_DAPM_ENUM("Route", twl4030_micpathtx2_enum);
368
369static int micpath_event(struct snd_soc_dapm_widget *w,
370 struct snd_kcontrol *kcontrol, int event)
371{
372 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
373 unsigned char adcmicsel, micbias_ctl;
374
375 adcmicsel = twl4030_read_reg_cache(w->codec, TWL4030_REG_ADCMICSEL);
376 micbias_ctl = twl4030_read_reg_cache(w->codec, TWL4030_REG_MICBIAS_CTL);
377 /* Prepare the bits for the given TX path:
378 * shift_l == 0: TX1 microphone path
379 * shift_l == 2: TX2 microphone path */
380 if (e->shift_l) {
381 /* TX2 microphone path */
382 if (adcmicsel & TWL4030_TX2IN_SEL)
383 micbias_ctl |= TWL4030_MICBIAS2_CTL; /* digimic */
384 else
385 micbias_ctl &= ~TWL4030_MICBIAS2_CTL;
386 } else {
387 /* TX1 microphone path */
388 if (adcmicsel & TWL4030_TX1IN_SEL)
389 micbias_ctl |= TWL4030_MICBIAS1_CTL; /* digimic */
390 else
391 micbias_ctl &= ~TWL4030_MICBIAS1_CTL;
392 }
393
394 twl4030_write(w->codec, TWL4030_REG_MICBIAS_CTL, micbias_ctl);
395
396 return 0;
397}
398
399static int handsfree_event(struct snd_soc_dapm_widget *w,
400 struct snd_kcontrol *kcontrol, int event)
401{
402 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
403 unsigned char hs_ctl;
404
405 hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
406
407 if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
408 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
409 twl4030_write(w->codec, e->reg, hs_ctl);
410 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
411 twl4030_write(w->codec, e->reg, hs_ctl);
412 hs_ctl |= TWL4030_HF_CTL_HB_EN;
413 twl4030_write(w->codec, e->reg, hs_ctl);
414 } else {
415 hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
416 | TWL4030_HF_CTL_HB_EN);
417 twl4030_write(w->codec, e->reg, hs_ctl);
418 }
419
420 return 0;
421}
422
423/*
424 * Some of the gain controls in TWL (mostly those which are associated with
425 * the outputs) are implemented in an interesting way:
426 * 0x0 : Power down (mute)
427 * 0x1 : 6dB
428 * 0x2 : 0 dB
429 * 0x3 : -6 dB
430 * Inverting not going to help with these.
431 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
432 */
433#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
434 xinvert, tlv_array) \
435{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
436 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
437 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
438 .tlv.p = (tlv_array), \
439 .info = snd_soc_info_volsw, \
440 .get = snd_soc_get_volsw_twl4030, \
441 .put = snd_soc_put_volsw_twl4030, \
442 .private_value = (unsigned long)&(struct soc_mixer_control) \
443 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
444 .max = xmax, .invert = xinvert} }
445#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
446 xinvert, tlv_array) \
447{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
448 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
449 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
450 .tlv.p = (tlv_array), \
451 .info = snd_soc_info_volsw_2r, \
452 .get = snd_soc_get_volsw_r2_twl4030,\
453 .put = snd_soc_put_volsw_r2_twl4030, \
454 .private_value = (unsigned long)&(struct soc_mixer_control) \
455 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
456 .rshift = xshift, .max = xmax, .invert = xinvert} }
457#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
458 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
459 xinvert, tlv_array)
460
461static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
462 struct snd_ctl_elem_value *ucontrol)
463{
464 struct soc_mixer_control *mc =
465 (struct soc_mixer_control *)kcontrol->private_value;
466 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
467 unsigned int reg = mc->reg;
468 unsigned int shift = mc->shift;
469 unsigned int rshift = mc->rshift;
470 int max = mc->max;
471 int mask = (1 << fls(max)) - 1;
472
473 ucontrol->value.integer.value[0] =
474 (snd_soc_read(codec, reg) >> shift) & mask;
475 if (ucontrol->value.integer.value[0])
476 ucontrol->value.integer.value[0] =
477 max + 1 - ucontrol->value.integer.value[0];
478
479 if (shift != rshift) {
480 ucontrol->value.integer.value[1] =
481 (snd_soc_read(codec, reg) >> rshift) & mask;
482 if (ucontrol->value.integer.value[1])
483 ucontrol->value.integer.value[1] =
484 max + 1 - ucontrol->value.integer.value[1];
485 }
486
487 return 0;
488}
489
490static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492{
493 struct soc_mixer_control *mc =
494 (struct soc_mixer_control *)kcontrol->private_value;
495 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
496 unsigned int reg = mc->reg;
497 unsigned int shift = mc->shift;
498 unsigned int rshift = mc->rshift;
499 int max = mc->max;
500 int mask = (1 << fls(max)) - 1;
501 unsigned short val, val2, val_mask;
502
503 val = (ucontrol->value.integer.value[0] & mask);
504
505 val_mask = mask << shift;
506 if (val)
507 val = max + 1 - val;
508 val = val << shift;
509 if (shift != rshift) {
510 val2 = (ucontrol->value.integer.value[1] & mask);
511 val_mask |= mask << rshift;
512 if (val2)
513 val2 = max + 1 - val2;
514 val |= val2 << rshift;
515 }
516 return snd_soc_update_bits(codec, reg, val_mask, val);
517}
518
519static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
520 struct snd_ctl_elem_value *ucontrol)
521{
522 struct soc_mixer_control *mc =
523 (struct soc_mixer_control *)kcontrol->private_value;
524 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
525 unsigned int reg = mc->reg;
526 unsigned int reg2 = mc->rreg;
527 unsigned int shift = mc->shift;
528 int max = mc->max;
529 int mask = (1<<fls(max))-1;
530
531 ucontrol->value.integer.value[0] =
532 (snd_soc_read(codec, reg) >> shift) & mask;
533 ucontrol->value.integer.value[1] =
534 (snd_soc_read(codec, reg2) >> shift) & mask;
535
536 if (ucontrol->value.integer.value[0])
537 ucontrol->value.integer.value[0] =
538 max + 1 - ucontrol->value.integer.value[0];
539 if (ucontrol->value.integer.value[1])
540 ucontrol->value.integer.value[1] =
541 max + 1 - ucontrol->value.integer.value[1];
542
543 return 0;
544}
545
546static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
547 struct snd_ctl_elem_value *ucontrol)
548{
549 struct soc_mixer_control *mc =
550 (struct soc_mixer_control *)kcontrol->private_value;
551 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
552 unsigned int reg = mc->reg;
553 unsigned int reg2 = mc->rreg;
554 unsigned int shift = mc->shift;
555 int max = mc->max;
556 int mask = (1 << fls(max)) - 1;
557 int err;
558 unsigned short val, val2, val_mask;
559
560 val_mask = mask << shift;
561 val = (ucontrol->value.integer.value[0] & mask);
562 val2 = (ucontrol->value.integer.value[1] & mask);
563
564 if (val)
565 val = max + 1 - val;
566 if (val2)
567 val2 = max + 1 - val2;
568
569 val = val << shift;
570 val2 = val2 << shift;
571
572 err = snd_soc_update_bits(codec, reg, val_mask, val);
573 if (err < 0)
574 return err;
575
576 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
577 return err;
578}
579
580/*
581 * FGAIN volume control:
582 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
583 */
584static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
585
586/*
587 * CGAIN volume control:
588 * 0 dB to 12 dB in 6 dB steps
589 * value 2 and 3 means 12 dB
590 */
591static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
592
593/*
594 * Analog playback gain
595 * -24 dB to 12 dB in 2 dB steps
596 */
597static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
598
599/*
600 * Gain controls tied to outputs
601 * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
602 */
603static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
604
605/*
606 * Capture gain after the ADCs
607 * from 0 dB to 31 dB in 1 dB steps
608 */
609static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
610
611/*
612 * Gain control for input amplifiers
613 * 0 dB to 30 dB in 6 dB steps
614 */
615static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
616
617static const struct snd_kcontrol_new twl4030_snd_controls[] = {
618 /* Common playback gain controls */
619 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
620 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
621 0, 0x3f, 0, digital_fine_tlv),
622 SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
623 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
624 0, 0x3f, 0, digital_fine_tlv),
625
626 SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
627 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
628 6, 0x2, 0, digital_coarse_tlv),
629 SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
630 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
631 6, 0x2, 0, digital_coarse_tlv),
632
633 SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
634 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
635 3, 0x12, 1, analog_tlv),
636 SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
637 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
638 3, 0x12, 1, analog_tlv),
639 SOC_DOUBLE_R("DAC1 Analog Playback Switch",
640 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
641 1, 1, 0),
642 SOC_DOUBLE_R("DAC2 Analog Playback Switch",
643 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
644 1, 1, 0),
645
646 /* Separate output gain controls */
647 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
648 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
649 4, 3, 0, output_tvl),
650
651 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
652 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
653
654 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
655 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
656 4, 3, 0, output_tvl),
657
658 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
659 TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
660
661 /* Common capture gain controls */
662 SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume",
663 TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
664 0, 0x1f, 0, digital_capture_tlv),
665 SOC_DOUBLE_R_TLV("TX2 Digital Capture Volume",
666 TWL4030_REG_AVTXL2PGA, TWL4030_REG_AVTXR2PGA,
667 0, 0x1f, 0, digital_capture_tlv),
668
669 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
670 0, 3, 5, 0, input_gain_tlv),
671};
672
673/* add non dapm controls */
674static int twl4030_add_controls(struct snd_soc_codec *codec)
675{
676 int err, i;
677
678 for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
679 err = snd_ctl_add(codec->card,
680 snd_soc_cnew(&twl4030_snd_controls[i],
681 codec, NULL));
682 if (err < 0)
683 return err;
684 }
685
686 return 0;
687}
688
689static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
690 /* Left channel inputs */
691 SND_SOC_DAPM_INPUT("MAINMIC"),
692 SND_SOC_DAPM_INPUT("HSMIC"),
693 SND_SOC_DAPM_INPUT("AUXL"),
694 SND_SOC_DAPM_INPUT("CARKITMIC"),
695 /* Right channel inputs */
696 SND_SOC_DAPM_INPUT("SUBMIC"),
697 SND_SOC_DAPM_INPUT("AUXR"),
698 /* Digital microphones (Stereo) */
699 SND_SOC_DAPM_INPUT("DIGIMIC0"),
700 SND_SOC_DAPM_INPUT("DIGIMIC1"),
701
702 /* Outputs */
703 SND_SOC_DAPM_OUTPUT("OUTL"),
704 SND_SOC_DAPM_OUTPUT("OUTR"),
705 SND_SOC_DAPM_OUTPUT("EARPIECE"),
706 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
707 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
708 SND_SOC_DAPM_OUTPUT("HSOL"),
709 SND_SOC_DAPM_OUTPUT("HSOR"),
710 SND_SOC_DAPM_OUTPUT("CARKITL"),
711 SND_SOC_DAPM_OUTPUT("CARKITR"),
712 SND_SOC_DAPM_OUTPUT("HFL"),
713 SND_SOC_DAPM_OUTPUT("HFR"),
714
715 /* DACs */
716 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
717 TWL4030_REG_AVDAC_CTL, 0, 0),
718 SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
719 TWL4030_REG_AVDAC_CTL, 1, 0),
720 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
721 TWL4030_REG_AVDAC_CTL, 2, 0),
722 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
723 TWL4030_REG_AVDAC_CTL, 3, 0),
724
725 /* Analog PGAs */
726 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
727 0, 0, NULL, 0),
728 SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
729 0, 0, NULL, 0),
730 SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
731 0, 0, NULL, 0),
732 SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
733 0, 0, NULL, 0),
734
735 /* Output MUX controls */
736 /* Earpiece */
737 SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0,
738 &twl4030_dapm_earpiece_control),
739 /* PreDrivL/R */
740 SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0,
741 &twl4030_dapm_predrivel_control),
742 SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0,
743 &twl4030_dapm_predriver_control),
744 /* HeadsetL/R */
745 SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
746 &twl4030_dapm_hsol_control),
747 SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
748 &twl4030_dapm_hsor_control),
749 /* CarkitL/R */
750 SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
751 &twl4030_dapm_carkitl_control),
752 SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
753 &twl4030_dapm_carkitr_control),
754 /* HandsfreeL/R */
755 SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
756 &twl4030_dapm_handsfreel_control, handsfree_event,
757 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
758 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
759 &twl4030_dapm_handsfreer_control, handsfree_event,
760 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
761
762 /* Introducing four virtual ADC, since TWL4030 have four channel for
763 capture */
764 SND_SOC_DAPM_ADC("ADC Virtual Left1", "Left Front Capture",
765 SND_SOC_NOPM, 0, 0),
766 SND_SOC_DAPM_ADC("ADC Virtual Right1", "Right Front Capture",
767 SND_SOC_NOPM, 0, 0),
768 SND_SOC_DAPM_ADC("ADC Virtual Left2", "Left Rear Capture",
769 SND_SOC_NOPM, 0, 0),
770 SND_SOC_DAPM_ADC("ADC Virtual Right2", "Right Rear Capture",
771 SND_SOC_NOPM, 0, 0),
772
773 /* Analog/Digital mic path selection.
774 TX1 Left/Right: either analog Left/Right or Digimic0
775 TX2 Left/Right: either analog Left/Right or Digimic1 */
776 SND_SOC_DAPM_MUX_E("TX1 Capture Route", SND_SOC_NOPM, 0, 0,
777 &twl4030_dapm_micpathtx1_control, micpath_event,
778 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
779 SND_SOC_DAPM_POST_REG),
780 SND_SOC_DAPM_MUX_E("TX2 Capture Route", SND_SOC_NOPM, 0, 0,
781 &twl4030_dapm_micpathtx2_control, micpath_event,
782 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD|
783 SND_SOC_DAPM_POST_REG),
784
785 /* Analog input muxes with power switch for the physical ADCL/R */
786 SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route",
787 TWL4030_REG_AVADC_CTL, 3, 0, &twl4030_dapm_analoglmic_control),
788 SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route",
789 TWL4030_REG_AVADC_CTL, 1, 0, &twl4030_dapm_analogrmic_control),
790
791 SND_SOC_DAPM_PGA("Analog Left Amplifier",
792 TWL4030_REG_ANAMICL, 4, 0, NULL, 0),
793 SND_SOC_DAPM_PGA("Analog Right Amplifier",
794 TWL4030_REG_ANAMICR, 4, 0, NULL, 0),
795
796 SND_SOC_DAPM_PGA("Digimic0 Enable",
797 TWL4030_REG_ADCMICSEL, 1, 0, NULL, 0),
798 SND_SOC_DAPM_PGA("Digimic1 Enable",
799 TWL4030_REG_ADCMICSEL, 3, 0, NULL, 0),
800
801 SND_SOC_DAPM_MICBIAS("Mic Bias 1", TWL4030_REG_MICBIAS_CTL, 0, 0),
802 SND_SOC_DAPM_MICBIAS("Mic Bias 2", TWL4030_REG_MICBIAS_CTL, 1, 0),
803 SND_SOC_DAPM_MICBIAS("Headset Mic Bias", TWL4030_REG_MICBIAS_CTL, 2, 0),
804};
805
806static const struct snd_soc_dapm_route intercon[] = {
807 {"ARXL1_APGA", NULL, "DAC Left1"},
808 {"ARXR1_APGA", NULL, "DAC Right1"},
809 {"ARXL2_APGA", NULL, "DAC Left2"},
810 {"ARXR2_APGA", NULL, "DAC Right2"},
811
812 /* Internal playback routings */
813 /* Earpiece */
814 {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
815 {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
816 {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
817 /* PreDrivL */
818 {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
819 {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
820 {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
821 /* PreDrivR */
822 {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
823 {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
824 {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
825 /* HeadsetL */
826 {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
827 {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
828 /* HeadsetR */
829 {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
830 {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
831 /* CarkitL */
832 {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
833 {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
834 /* CarkitR */
835 {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
836 {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
837 /* HandsfreeL */
838 {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
839 {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
840 {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
841 /* HandsfreeR */
842 {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
843 {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
844 {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
845
846 /* outputs */
847 {"OUTL", NULL, "ARXL2_APGA"},
848 {"OUTR", NULL, "ARXR2_APGA"},
849 {"EARPIECE", NULL, "Earpiece Mux"},
850 {"PREDRIVEL", NULL, "PredriveL Mux"},
851 {"PREDRIVER", NULL, "PredriveR Mux"},
852 {"HSOL", NULL, "HeadsetL Mux"},
853 {"HSOR", NULL, "HeadsetR Mux"},
854 {"CARKITL", NULL, "CarkitL Mux"},
855 {"CARKITR", NULL, "CarkitR Mux"},
856 {"HFL", NULL, "HandsfreeL Mux"},
857 {"HFR", NULL, "HandsfreeR Mux"},
858
859 /* Capture path */
860 {"Analog Left Capture Route", "Main mic", "MAINMIC"},
861 {"Analog Left Capture Route", "Headset mic", "HSMIC"},
862 {"Analog Left Capture Route", "AUXL", "AUXL"},
863 {"Analog Left Capture Route", "Carkit mic", "CARKITMIC"},
864
865 {"Analog Right Capture Route", "Sub mic", "SUBMIC"},
866 {"Analog Right Capture Route", "AUXR", "AUXR"},
867
868 {"Analog Left Amplifier", NULL, "Analog Left Capture Route"},
869 {"Analog Right Amplifier", NULL, "Analog Right Capture Route"},
870
871 {"Digimic0 Enable", NULL, "DIGIMIC0"},
872 {"Digimic1 Enable", NULL, "DIGIMIC1"},
873
874 /* TX1 Left capture path */
875 {"TX1 Capture Route", "Analog", "Analog Left Amplifier"},
876 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
877 /* TX1 Right capture path */
878 {"TX1 Capture Route", "Analog", "Analog Right Amplifier"},
879 {"TX1 Capture Route", "Digimic0", "Digimic0 Enable"},
880 /* TX2 Left capture path */
881 {"TX2 Capture Route", "Analog", "Analog Left Amplifier"},
882 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
883 /* TX2 Right capture path */
884 {"TX2 Capture Route", "Analog", "Analog Right Amplifier"},
885 {"TX2 Capture Route", "Digimic1", "Digimic1 Enable"},
886
887 {"ADC Virtual Left1", NULL, "TX1 Capture Route"},
888 {"ADC Virtual Right1", NULL, "TX1 Capture Route"},
889 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
890 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
891
892};
893
894static int twl4030_add_widgets(struct snd_soc_codec *codec)
895{
896 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
897 ARRAY_SIZE(twl4030_dapm_widgets));
898
899 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
900
901 snd_soc_dapm_new_widgets(codec);
902 return 0;
903}
904
905static void twl4030_power_up(struct snd_soc_codec *codec)
906{
907 u8 anamicl, regmisc1, byte, popn;
908 int i = 0;
909
910 /* set CODECPDZ to turn on codec */
911 twl4030_set_codecpdz(codec);
912
913 /* initiate offset cancellation */
914 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
915 twl4030_write(codec, TWL4030_REG_ANAMICL,
916 anamicl | TWL4030_CNCL_OFFSET_START);
917
918
919 /* wait for offset cancellation to complete */
920 do {
921 /* this takes a little while, so don't slam i2c */
922 udelay(2000);
923 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
924 TWL4030_REG_ANAMICL);
925 } while ((i++ < 100) &&
926 ((byte & TWL4030_CNCL_OFFSET_START) ==
927 TWL4030_CNCL_OFFSET_START));
928
929 /* anti-pop when changing analog gain */
930 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
931 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
932 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
933
934 /* toggle CODECPDZ as per TRM */
935 twl4030_clear_codecpdz(codec);
936 twl4030_set_codecpdz(codec);
937
938 /* program anti-pop with bias ramp delay */
939 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
940 popn &= TWL4030_RAMP_DELAY;
941 popn |= TWL4030_RAMP_DELAY_645MS;
942 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
943 popn |= TWL4030_VMID_EN;
944 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
945
946 /* enable anti-pop ramp */
947 popn |= TWL4030_RAMP_EN;
948 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
949}
950
951static void twl4030_power_down(struct snd_soc_codec *codec)
952{
953 u8 popn;
954
955 /* disable anti-pop ramp */
956 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
957 popn &= ~TWL4030_RAMP_EN;
958 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
959
960 /* disable bias out */
961 popn &= ~TWL4030_VMID_EN;
962 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
963
964 /* power down */
965 twl4030_clear_codecpdz(codec);
966}
967
968static int twl4030_set_bias_level(struct snd_soc_codec *codec,
969 enum snd_soc_bias_level level)
970{
971 switch (level) {
972 case SND_SOC_BIAS_ON:
973 twl4030_power_up(codec);
974 break;
975 case SND_SOC_BIAS_PREPARE:
976 /* TODO: develop a twl4030_prepare function */
977 break;
978 case SND_SOC_BIAS_STANDBY:
979 /* TODO: develop a twl4030_standby function */
980 twl4030_power_down(codec);
981 break;
982 case SND_SOC_BIAS_OFF:
983 twl4030_power_down(codec);
984 break;
985 }
986 codec->bias_level = level;
987
988 return 0;
989}
990
991static int twl4030_hw_params(struct snd_pcm_substream *substream,
992 struct snd_pcm_hw_params *params,
993 struct snd_soc_dai *dai)
994{
995 struct snd_soc_pcm_runtime *rtd = substream->private_data;
996 struct snd_soc_device *socdev = rtd->socdev;
997 struct snd_soc_codec *codec = socdev->codec;
998 u8 mode, old_mode, format, old_format;
999
1000
1001 /* bit rate */
1002 old_mode = twl4030_read_reg_cache(codec,
1003 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1004 mode = old_mode & ~TWL4030_APLL_RATE;
1005
1006 switch (params_rate(params)) {
1007 case 8000:
1008 mode |= TWL4030_APLL_RATE_8000;
1009 break;
1010 case 11025:
1011 mode |= TWL4030_APLL_RATE_11025;
1012 break;
1013 case 12000:
1014 mode |= TWL4030_APLL_RATE_12000;
1015 break;
1016 case 16000:
1017 mode |= TWL4030_APLL_RATE_16000;
1018 break;
1019 case 22050:
1020 mode |= TWL4030_APLL_RATE_22050;
1021 break;
1022 case 24000:
1023 mode |= TWL4030_APLL_RATE_24000;
1024 break;
1025 case 32000:
1026 mode |= TWL4030_APLL_RATE_32000;
1027 break;
1028 case 44100:
1029 mode |= TWL4030_APLL_RATE_44100;
1030 break;
1031 case 48000:
1032 mode |= TWL4030_APLL_RATE_48000;
1033 break;
1034 default:
1035 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
1036 params_rate(params));
1037 return -EINVAL;
1038 }
1039
1040 if (mode != old_mode) {
1041 /* change rate and set CODECPDZ */
1042 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1043 twl4030_set_codecpdz(codec);
1044 }
1045
1046 /* sample size */
1047 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1048 format = old_format;
1049 format &= ~TWL4030_DATA_WIDTH;
1050 switch (params_format(params)) {
1051 case SNDRV_PCM_FORMAT_S16_LE:
1052 format |= TWL4030_DATA_WIDTH_16S_16W;
1053 break;
1054 case SNDRV_PCM_FORMAT_S24_LE:
1055 format |= TWL4030_DATA_WIDTH_32S_24W;
1056 break;
1057 default:
1058 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
1059 params_format(params));
1060 return -EINVAL;
1061 }
1062
1063 if (format != old_format) {
1064
1065 /* clear CODECPDZ before changing format (codec requirement) */
1066 twl4030_clear_codecpdz(codec);
1067
1068 /* change format */
1069 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1070
1071 /* set CODECPDZ afterwards */
1072 twl4030_set_codecpdz(codec);
1073 }
1074 return 0;
1075}
1076
1077static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1078 int clk_id, unsigned int freq, int dir)
1079{
1080 struct snd_soc_codec *codec = codec_dai->codec;
1081 u8 infreq;
1082
1083 switch (freq) {
1084 case 19200000:
1085 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1086 break;
1087 case 26000000:
1088 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1089 break;
1090 case 38400000:
1091 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1092 break;
1093 default:
1094 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
1095 freq);
1096 return -EINVAL;
1097 }
1098
1099 infreq |= TWL4030_APLL_EN;
1100 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
1101
1102 return 0;
1103}
1104
1105static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1106 unsigned int fmt)
1107{
1108 struct snd_soc_codec *codec = codec_dai->codec;
1109 u8 old_format, format;
1110
1111 /* get format */
1112 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1113 format = old_format;
1114
1115 /* set master/slave audio interface */
1116 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1117 case SND_SOC_DAIFMT_CBM_CFM:
1118 format &= ~(TWL4030_AIF_SLAVE_EN);
1119 format &= ~(TWL4030_CLK256FS_EN);
1120 break;
1121 case SND_SOC_DAIFMT_CBS_CFS:
1122 format |= TWL4030_AIF_SLAVE_EN;
1123 format |= TWL4030_CLK256FS_EN;
1124 break;
1125 default:
1126 return -EINVAL;
1127 }
1128
1129 /* interface format */
1130 format &= ~TWL4030_AIF_FORMAT;
1131 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1132 case SND_SOC_DAIFMT_I2S:
1133 format |= TWL4030_AIF_FORMAT_CODEC;
1134 break;
1135 default:
1136 return -EINVAL;
1137 }
1138
1139 if (format != old_format) {
1140
1141 /* clear CODECPDZ before changing format (codec requirement) */
1142 twl4030_clear_codecpdz(codec);
1143
1144 /* change format */
1145 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1146
1147 /* set CODECPDZ afterwards */
1148 twl4030_set_codecpdz(codec);
1149 }
1150
1151 return 0;
1152}
1153
1154#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1155#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1156
1157struct snd_soc_dai twl4030_dai = {
1158 .name = "twl4030",
1159 .playback = {
1160 .stream_name = "Playback",
1161 .channels_min = 2,
1162 .channels_max = 2,
1163 .rates = TWL4030_RATES,
1164 .formats = TWL4030_FORMATS,},
1165 .capture = {
1166 .stream_name = "Capture",
1167 .channels_min = 2,
1168 .channels_max = 2,
1169 .rates = TWL4030_RATES,
1170 .formats = TWL4030_FORMATS,},
1171 .ops = {
1172 .hw_params = twl4030_hw_params,
1173 .set_sysclk = twl4030_set_dai_sysclk,
1174 .set_fmt = twl4030_set_dai_fmt,
1175 }
1176};
1177EXPORT_SYMBOL_GPL(twl4030_dai);
1178
1179static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
1180{
1181 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1182 struct snd_soc_codec *codec = socdev->codec;
1183
1184 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
1185
1186 return 0;
1187}
1188
1189static int twl4030_resume(struct platform_device *pdev)
1190{
1191 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1192 struct snd_soc_codec *codec = socdev->codec;
1193
1194 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1195 twl4030_set_bias_level(codec, codec->suspend_bias_level);
1196 return 0;
1197}
1198
1199/*
1200 * initialize the driver
1201 * register the mixer and dsp interfaces with the kernel
1202 */
1203
1204static int twl4030_init(struct snd_soc_device *socdev)
1205{
1206 struct snd_soc_codec *codec = socdev->codec;
1207 int ret = 0;
1208
1209 printk(KERN_INFO "TWL4030 Audio Codec init \n");
1210
1211 codec->name = "twl4030";
1212 codec->owner = THIS_MODULE;
1213 codec->read = twl4030_read_reg_cache;
1214 codec->write = twl4030_write;
1215 codec->set_bias_level = twl4030_set_bias_level;
1216 codec->dai = &twl4030_dai;
1217 codec->num_dai = 1;
1218 codec->reg_cache_size = sizeof(twl4030_reg);
1219 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
1220 GFP_KERNEL);
1221 if (codec->reg_cache == NULL)
1222 return -ENOMEM;
1223
1224 /* register pcms */
1225 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1226 if (ret < 0) {
1227 printk(KERN_ERR "twl4030: failed to create pcms\n");
1228 goto pcm_err;
1229 }
1230
1231 twl4030_init_chip(codec);
1232
1233 /* power on device */
1234 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1235
1236 twl4030_add_controls(codec);
1237 twl4030_add_widgets(codec);
1238
1239 ret = snd_soc_init_card(socdev);
1240 if (ret < 0) {
1241 printk(KERN_ERR "twl4030: failed to register card\n");
1242 goto card_err;
1243 }
1244
1245 return ret;
1246
1247card_err:
1248 snd_soc_free_pcms(socdev);
1249 snd_soc_dapm_free(socdev);
1250pcm_err:
1251 kfree(codec->reg_cache);
1252 return ret;
1253}
1254
1255static struct snd_soc_device *twl4030_socdev;
1256
1257static int twl4030_probe(struct platform_device *pdev)
1258{
1259 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1260 struct snd_soc_codec *codec;
1261
1262 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1263 if (codec == NULL)
1264 return -ENOMEM;
1265
1266 socdev->codec = codec;
1267 mutex_init(&codec->mutex);
1268 INIT_LIST_HEAD(&codec->dapm_widgets);
1269 INIT_LIST_HEAD(&codec->dapm_paths);
1270
1271 twl4030_socdev = socdev;
1272 twl4030_init(socdev);
1273
1274 return 0;
1275}
1276
1277static int twl4030_remove(struct platform_device *pdev)
1278{
1279 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1280 struct snd_soc_codec *codec = socdev->codec;
1281
1282 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1283 snd_soc_free_pcms(socdev);
1284 snd_soc_dapm_free(socdev);
1285 kfree(codec);
1286
1287 return 0;
1288}
1289
1290struct snd_soc_codec_device soc_codec_dev_twl4030 = {
1291 .probe = twl4030_probe,
1292 .remove = twl4030_remove,
1293 .suspend = twl4030_suspend,
1294 .resume = twl4030_resume,
1295};
1296EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
1297
1298static int __init twl4030_modinit(void)
1299{
1300 return snd_soc_register_dai(&twl4030_dai);
1301}
1302module_init(twl4030_modinit);
1303
1304static void __exit twl4030_exit(void)
1305{
1306 snd_soc_unregister_dai(&twl4030_dai);
1307}
1308module_exit(twl4030_exit);
1309
1310MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
1311MODULE_AUTHOR("Steve Sakoman");
1312MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
new file mode 100644
index 000000000000..442e5a828617
--- /dev/null
+++ b/sound/soc/codecs/twl4030.h
@@ -0,0 +1,226 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__
24
25#define TWL4030_REG_CODEC_MODE 0x1
26#define TWL4030_REG_OPTION 0x2
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95
96#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
97
98/* Bitfield Definitions */
99
100/* TWL4030_CODEC_MODE (0x01) Fields */
101
102#define TWL4030_APLL_RATE 0xF0
103#define TWL4030_APLL_RATE_8000 0x00
104#define TWL4030_APLL_RATE_11025 0x10
105#define TWL4030_APLL_RATE_12000 0x20
106#define TWL4030_APLL_RATE_16000 0x40
107#define TWL4030_APLL_RATE_22050 0x50
108#define TWL4030_APLL_RATE_24000 0x60
109#define TWL4030_APLL_RATE_32000 0x80
110#define TWL4030_APLL_RATE_44100 0x90
111#define TWL4030_APLL_RATE_48000 0xA0
112#define TWL4030_SEL_16K 0x04
113#define TWL4030_CODECPDZ 0x02
114#define TWL4030_OPT_MODE 0x01
115
116/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
117
118#define TWL4030_MICBIAS2_CTL 0x40
119#define TWL4030_MICBIAS1_CTL 0x20
120#define TWL4030_HSMICBIAS_EN 0x04
121#define TWL4030_MICBIAS2_EN 0x02
122#define TWL4030_MICBIAS1_EN 0x01
123
124/* ANAMICL (0x05) Fields */
125
126#define TWL4030_CNCL_OFFSET_START 0x80
127#define TWL4030_OFFSET_CNCL_SEL 0x60
128#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
129#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
130#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
131#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
132#define TWL4030_MICAMPL_EN 0x10
133#define TWL4030_CKMIC_EN 0x08
134#define TWL4030_AUXL_EN 0x04
135#define TWL4030_HSMIC_EN 0x02
136#define TWL4030_MAINMIC_EN 0x01
137
138/* ANAMICR (0x06) Fields */
139
140#define TWL4030_MICAMPR_EN 0x10
141#define TWL4030_AUXR_EN 0x04
142#define TWL4030_SUBMIC_EN 0x01
143
144/* AVADC_CTL (0x07) Fields */
145
146#define TWL4030_ADCL_EN 0x08
147#define TWL4030_AVADC_CLK_PRIORITY 0x04
148#define TWL4030_ADCR_EN 0x02
149
150/* TWL4030_REG_ADCMICSEL (0x08) Fields */
151
152#define TWL4030_DIGMIC1_EN 0x08
153#define TWL4030_TX2IN_SEL 0x04
154#define TWL4030_DIGMIC0_EN 0x02
155#define TWL4030_TX1IN_SEL 0x01
156
157/* AUDIO_IF (0x0E) Fields */
158
159#define TWL4030_AIF_SLAVE_EN 0x80
160#define TWL4030_DATA_WIDTH 0x60
161#define TWL4030_DATA_WIDTH_16S_16W 0x00
162#define TWL4030_DATA_WIDTH_32S_16W 0x40
163#define TWL4030_DATA_WIDTH_32S_24W 0x60
164#define TWL4030_AIF_FORMAT 0x18
165#define TWL4030_AIF_FORMAT_CODEC 0x00
166#define TWL4030_AIF_FORMAT_LEFT 0x08
167#define TWL4030_AIF_FORMAT_RIGHT 0x10
168#define TWL4030_AIF_FORMAT_TDM 0x18
169#define TWL4030_AIF_TRI_EN 0x04
170#define TWL4030_CLK256FS_EN 0x02
171#define TWL4030_AIF_EN 0x01
172
173/* HS_GAIN_SET (0x23) Fields */
174
175#define TWL4030_HSR_GAIN 0x0C
176#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
177#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
178#define TWL4030_HSR_GAIN_0DB 0x08
179#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
180#define TWL4030_HSL_GAIN 0x03
181#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
182#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
183#define TWL4030_HSL_GAIN_0DB 0x02
184#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
185
186/* HS_POPN_SET (0x24) Fields */
187
188#define TWL4030_VMID_EN 0x40
189#define TWL4030_EXTMUTE 0x20
190#define TWL4030_RAMP_DELAY 0x1C
191#define TWL4030_RAMP_DELAY_20MS 0x00
192#define TWL4030_RAMP_DELAY_40MS 0x04
193#define TWL4030_RAMP_DELAY_81MS 0x08
194#define TWL4030_RAMP_DELAY_161MS 0x0C
195#define TWL4030_RAMP_DELAY_323MS 0x10
196#define TWL4030_RAMP_DELAY_645MS 0x14
197#define TWL4030_RAMP_DELAY_1291MS 0x18
198#define TWL4030_RAMP_DELAY_2581MS 0x1C
199#define TWL4030_RAMP_EN 0x02
200
201/* HFL_CTL (0x29, 0x2A) Fields */
202#define TWL4030_HF_CTL_HB_EN 0x04
203#define TWL4030_HF_CTL_LOOP_EN 0x08
204#define TWL4030_HF_CTL_RAMP_EN 0x10
205#define TWL4030_HF_CTL_REF_EN 0x20
206
207/* APLL_CTL (0x3A) Fields */
208
209#define TWL4030_APLL_EN 0x10
210#define TWL4030_APLL_INFREQ 0x0F
211#define TWL4030_APLL_INFREQ_19200KHZ 0x05
212#define TWL4030_APLL_INFREQ_26000KHZ 0x06
213#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
214
215/* REG_MISC_SET_1 (0x3E) Fields */
216
217#define TWL4030_CLK64_EN 0x80
218#define TWL4030_SCRAMBLE_EN 0x40
219#define TWL4030_FMLOOP_EN 0x20
220#define TWL4030_SMOOTH_ANAVOL_EN 0x02
221#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
222
223extern struct snd_soc_dai twl4030_dai;
224extern struct snd_soc_codec_device soc_codec_dev_twl4030;
225
226#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
new file mode 100644
index 000000000000..a2c5064a774b
--- /dev/null
+++ b/sound/soc/codecs/uda134x.c
@@ -0,0 +1,668 @@
1/*
2 * uda134x.c -- UDA134X ALSA SoC Codec driver
3 *
4 * Modifications by Christian Pellegrin <chripell@evolware.org>
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/initval.h>
23
24#include <sound/uda134x.h>
25#include <sound/l3.h>
26
27#include "uda134x.h"
28
29
30#define POWER_OFF_ON_STANDBY 1
31/*
32 ALSA SOC usually puts the device in standby mode when it's not used
33 for sometime. If you define POWER_OFF_ON_STANDBY the driver will
34 turn off the ADC/DAC when this callback is invoked and turn it back
35 on when needed. Unfortunately this will result in a very light bump
36 (it can be audible only with good earphones). If this bothers you
37 just comment this line, you will have slightly higher power
38 consumption . Please note that sending the L3 command for ADC is
39 enough to make the bump, so it doesn't make difference if you
40 completely take off power from the codec.
41 */
42
43#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
44#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
45 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
46
47struct uda134x_priv {
48 int sysclk;
49 int dai_fmt;
50
51 struct snd_pcm_substream *master_substream;
52 struct snd_pcm_substream *slave_substream;
53};
54
55/* In-data addresses are hard-coded into the reg-cache values */
56static const char uda134x_reg[UDA134X_REGS_NUM] = {
57 /* Extended address registers */
58 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
59 /* Status, data regs */
60 0x00, 0x83, 0x00, 0x40, 0x80, 0x00,
61};
62
63/*
64 * The codec has no support for reading its registers except for peak level...
65 */
66static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
67 unsigned int reg)
68{
69 u8 *cache = codec->reg_cache;
70
71 if (reg >= UDA134X_REGS_NUM)
72 return -1;
73 return cache[reg];
74}
75
76/*
77 * Write the register cache
78 */
79static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
80 u8 reg, unsigned int value)
81{
82 u8 *cache = codec->reg_cache;
83
84 if (reg >= UDA134X_REGS_NUM)
85 return;
86 cache[reg] = value;
87}
88
89/*
90 * Write to the uda134x registers
91 *
92 */
93static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value)
95{
96 int ret;
97 u8 addr;
98 u8 data = value;
99 struct uda134x_platform_data *pd = codec->control_data;
100
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102
103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %d",
105 __func__, reg);
106 return -EINVAL;
107 }
108
109 uda134x_write_reg_cache(codec, reg, value);
110
111 switch (reg) {
112 case UDA134X_STATUS0:
113 case UDA134X_STATUS1:
114 addr = UDA134X_STATUS_ADDR;
115 break;
116 case UDA134X_DATA000:
117 case UDA134X_DATA001:
118 case UDA134X_DATA010:
119 addr = UDA134X_DATA0_ADDR;
120 break;
121 case UDA134X_DATA1:
122 addr = UDA134X_DATA1_ADDR;
123 break;
124 default:
125 /* It's an extended address register */
126 addr = (reg | UDA134X_EXTADDR_PREFIX);
127
128 ret = l3_write(&pd->l3,
129 UDA134X_DATA0_ADDR, &addr, 1);
130 if (ret != 1)
131 return -EIO;
132
133 addr = UDA134X_DATA0_ADDR;
134 data = (value | UDA134X_EXTDATA_PREFIX);
135 break;
136 }
137
138 ret = l3_write(&pd->l3,
139 addr, &data, 1);
140 if (ret != 1)
141 return -EIO;
142
143 return 0;
144}
145
146static inline void uda134x_reset(struct snd_soc_codec *codec)
147{
148 u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
149 uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
150 msleep(1);
151 uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
152}
153
154static int uda134x_mute(struct snd_soc_dai *dai, int mute)
155{
156 struct snd_soc_codec *codec = dai->codec;
157 u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
158
159 pr_debug("%s mute: %d\n", __func__, mute);
160
161 if (mute)
162 mute_reg |= (1<<2);
163 else
164 mute_reg &= ~(1<<2);
165
166 uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
167
168 return 0;
169}
170
171static int uda134x_startup(struct snd_pcm_substream *substream,
172 struct snd_soc_dai *dai)
173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->codec;
177 struct uda134x_priv *uda134x = codec->private_data;
178 struct snd_pcm_runtime *master_runtime;
179
180 if (uda134x->master_substream) {
181 master_runtime = uda134x->master_substream->runtime;
182
183 pr_debug("%s constraining to %d bits at %d\n", __func__,
184 master_runtime->sample_bits,
185 master_runtime->rate);
186
187 snd_pcm_hw_constraint_minmax(substream->runtime,
188 SNDRV_PCM_HW_PARAM_RATE,
189 master_runtime->rate,
190 master_runtime->rate);
191
192 snd_pcm_hw_constraint_minmax(substream->runtime,
193 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
194 master_runtime->sample_bits,
195 master_runtime->sample_bits);
196
197 uda134x->slave_substream = substream;
198 } else
199 uda134x->master_substream = substream;
200
201 return 0;
202}
203
204static void uda134x_shutdown(struct snd_pcm_substream *substream,
205 struct snd_soc_dai *dai)
206{
207 struct snd_soc_pcm_runtime *rtd = substream->private_data;
208 struct snd_soc_device *socdev = rtd->socdev;
209 struct snd_soc_codec *codec = socdev->codec;
210 struct uda134x_priv *uda134x = codec->private_data;
211
212 if (uda134x->master_substream == substream)
213 uda134x->master_substream = uda134x->slave_substream;
214
215 uda134x->slave_substream = NULL;
216}
217
218static int uda134x_hw_params(struct snd_pcm_substream *substream,
219 struct snd_pcm_hw_params *params,
220 struct snd_soc_dai *dai)
221{
222 struct snd_soc_pcm_runtime *rtd = substream->private_data;
223 struct snd_soc_device *socdev = rtd->socdev;
224 struct snd_soc_codec *codec = socdev->codec;
225 struct uda134x_priv *uda134x = codec->private_data;
226 u8 hw_params;
227
228 if (substream == uda134x->slave_substream) {
229 pr_debug("%s ignoring hw_params for slave substream\n",
230 __func__);
231 return 0;
232 }
233
234 hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
235 hw_params &= STATUS0_SYSCLK_MASK;
236 hw_params &= STATUS0_DAIFMT_MASK;
237
238 pr_debug("%s sysclk: %d, rate:%d\n", __func__,
239 uda134x->sysclk, params_rate(params));
240
241 /* set SYSCLK / fs ratio */
242 switch (uda134x->sysclk / params_rate(params)) {
243 case 512:
244 break;
245 case 384:
246 hw_params |= (1<<4);
247 break;
248 case 256:
249 hw_params |= (1<<5);
250 break;
251 default:
252 printk(KERN_ERR "%s unsupported fs\n", __func__);
253 return -EINVAL;
254 }
255
256 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
257 uda134x->dai_fmt, params_format(params));
258
259 /* set DAI format and word length */
260 switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
261 case SND_SOC_DAIFMT_I2S:
262 break;
263 case SND_SOC_DAIFMT_RIGHT_J:
264 switch (params_format(params)) {
265 case SNDRV_PCM_FORMAT_S16_LE:
266 hw_params |= (1<<1);
267 break;
268 case SNDRV_PCM_FORMAT_S18_3LE:
269 hw_params |= (1<<2);
270 break;
271 case SNDRV_PCM_FORMAT_S20_3LE:
272 hw_params |= ((1<<2) | (1<<1));
273 break;
274 default:
275 printk(KERN_ERR "%s unsupported format (right)\n",
276 __func__);
277 return -EINVAL;
278 }
279 break;
280 case SND_SOC_DAIFMT_LEFT_J:
281 hw_params |= (1<<3);
282 break;
283 default:
284 printk(KERN_ERR "%s unsupported format\n", __func__);
285 return -EINVAL;
286 }
287
288 uda134x_write(codec, UDA134X_STATUS0, hw_params);
289
290 return 0;
291}
292
293static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 struct uda134x_priv *uda134x = codec->private_data;
298
299 pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
300 clk_id, freq, dir);
301
302 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
303 because the codec is slave. Of course limitations of the clock
304 master (the IIS controller) apply.
305 We'll error out on set_hw_params if it's not OK */
306 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
307 uda134x->sysclk = freq;
308 return 0;
309 }
310
311 printk(KERN_ERR "%s unsupported sysclk\n", __func__);
312 return -EINVAL;
313}
314
315static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
316 unsigned int fmt)
317{
318 struct snd_soc_codec *codec = codec_dai->codec;
319 struct uda134x_priv *uda134x = codec->private_data;
320
321 pr_debug("%s fmt: %08X\n", __func__, fmt);
322
323 /* codec supports only full slave mode */
324 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
325 printk(KERN_ERR "%s unsupported slave mode\n", __func__);
326 return -EINVAL;
327 }
328
329 /* no support for clock inversion */
330 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
331 printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
332 return -EINVAL;
333 }
334
335 /* We can't setup DAI format here as it depends on the word bit num */
336 /* so let's just store the value for later */
337 uda134x->dai_fmt = fmt;
338
339 return 0;
340}
341
342static int uda134x_set_bias_level(struct snd_soc_codec *codec,
343 enum snd_soc_bias_level level)
344{
345 u8 reg;
346 struct uda134x_platform_data *pd = codec->control_data;
347 int i;
348 u8 *cache = codec->reg_cache;
349
350 pr_debug("%s bias level %d\n", __func__, level);
351
352 switch (level) {
353 case SND_SOC_BIAS_ON:
354 /* ADC, DAC on */
355 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
356 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
357 break;
358 case SND_SOC_BIAS_PREPARE:
359 /* power on */
360 if (pd->power) {
361 pd->power(1);
362 /* Sync reg_cache with the hardware */
363 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
364 codec->write(codec, i, *cache++);
365 }
366 break;
367 case SND_SOC_BIAS_STANDBY:
368 /* ADC, DAC power off */
369 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
370 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
371 break;
372 case SND_SOC_BIAS_OFF:
373 /* power off */
374 if (pd->power)
375 pd->power(0);
376 break;
377 }
378 codec->bias_level = level;
379 return 0;
380}
381
382static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
383 "Minimum2", "Maximum"};
384static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
385static const char *uda134x_mixmode[] = {"Differential", "Analog1",
386 "Analog2", "Both"};
387
388static const struct soc_enum uda134x_mixer_enum[] = {
389SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
390SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
391SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
392};
393
394static const struct snd_kcontrol_new uda1341_snd_controls[] = {
395SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
396SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
397SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
398SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
399
400SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
401SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
402
403SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
404SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
405
406SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
407SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
408SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
409
410SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
411SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
412SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
413
414SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
415SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
416SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
417SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
418SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
419SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
420};
421
422static const struct snd_kcontrol_new uda1340_snd_controls[] = {
423SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
424
425SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
426SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
427
428SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
429SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
430
431SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
432};
433
434static int uda134x_add_controls(struct snd_soc_codec *codec)
435{
436 int err, i, n;
437 const struct snd_kcontrol_new *ctrls;
438 struct uda134x_platform_data *pd = codec->control_data;
439
440 switch (pd->model) {
441 case UDA134X_UDA1340:
442 case UDA134X_UDA1344:
443 n = ARRAY_SIZE(uda1340_snd_controls);
444 ctrls = uda1340_snd_controls;
445 break;
446 case UDA134X_UDA1341:
447 n = ARRAY_SIZE(uda1341_snd_controls);
448 ctrls = uda1341_snd_controls;
449 break;
450 default:
451 printk(KERN_ERR "%s unkown codec type: %d",
452 __func__, pd->model);
453 return -EINVAL;
454 }
455
456 for (i = 0; i < n; i++) {
457 err = snd_ctl_add(codec->card,
458 snd_soc_cnew(&ctrls[i],
459 codec, NULL));
460 if (err < 0)
461 return err;
462 }
463
464 return 0;
465}
466
467struct snd_soc_dai uda134x_dai = {
468 .name = "UDA134X",
469 /* playback capabilities */
470 .playback = {
471 .stream_name = "Playback",
472 .channels_min = 1,
473 .channels_max = 2,
474 .rates = UDA134X_RATES,
475 .formats = UDA134X_FORMATS,
476 },
477 /* capture capabilities */
478 .capture = {
479 .stream_name = "Capture",
480 .channels_min = 1,
481 .channels_max = 2,
482 .rates = UDA134X_RATES,
483 .formats = UDA134X_FORMATS,
484 },
485 /* pcm operations */
486 .ops = {
487 .startup = uda134x_startup,
488 .shutdown = uda134x_shutdown,
489 .hw_params = uda134x_hw_params,
490 .digital_mute = uda134x_mute,
491 .set_sysclk = uda134x_set_dai_sysclk,
492 .set_fmt = uda134x_set_dai_fmt,
493 }
494};
495EXPORT_SYMBOL(uda134x_dai);
496
497
498static int uda134x_soc_probe(struct platform_device *pdev)
499{
500 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
501 struct snd_soc_codec *codec;
502 struct uda134x_priv *uda134x;
503 void *codec_setup_data = socdev->codec_data;
504 int ret = -ENOMEM;
505 struct uda134x_platform_data *pd;
506
507 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
508
509 if (!codec_setup_data) {
510 printk(KERN_ERR "UDA134X SoC codec: "
511 "missing L3 bitbang function\n");
512 return -ENODEV;
513 }
514
515 pd = codec_setup_data;
516 switch (pd->model) {
517 case UDA134X_UDA1340:
518 case UDA134X_UDA1341:
519 case UDA134X_UDA1344:
520 break;
521 default:
522 printk(KERN_ERR "UDA134X SoC codec: "
523 "unsupported model %d\n",
524 pd->model);
525 return -EINVAL;
526 }
527
528 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
529 if (socdev->codec == NULL)
530 return ret;
531
532 codec = socdev->codec;
533
534 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
535 if (uda134x == NULL)
536 goto priv_err;
537 codec->private_data = uda134x;
538
539 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
540 GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 goto reg_err;
543
544 mutex_init(&codec->mutex);
545
546 codec->reg_cache_size = sizeof(uda134x_reg);
547 codec->reg_cache_step = 1;
548
549 codec->name = "UDA134X";
550 codec->owner = THIS_MODULE;
551 codec->dai = &uda134x_dai;
552 codec->num_dai = 1;
553 codec->read = uda134x_read_reg_cache;
554 codec->write = uda134x_write;
555#ifdef POWER_OFF_ON_STANDBY
556 codec->set_bias_level = uda134x_set_bias_level;
557#endif
558 INIT_LIST_HEAD(&codec->dapm_widgets);
559 INIT_LIST_HEAD(&codec->dapm_paths);
560
561 codec->control_data = codec_setup_data;
562
563 if (pd->power)
564 pd->power(1);
565
566 uda134x_reset(codec);
567
568 /* register pcms */
569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
570 if (ret < 0) {
571 printk(KERN_ERR "UDA134X: failed to register pcms\n");
572 goto pcm_err;
573 }
574
575 ret = uda134x_add_controls(codec);
576 if (ret < 0) {
577 printk(KERN_ERR "UDA134X: failed to register controls\n");
578 goto pcm_err;
579 }
580
581 ret = snd_soc_init_card(socdev);
582 if (ret < 0) {
583 printk(KERN_ERR "UDA134X: failed to register card\n");
584 goto card_err;
585 }
586
587 return 0;
588
589card_err:
590 snd_soc_free_pcms(socdev);
591 snd_soc_dapm_free(socdev);
592pcm_err:
593 kfree(codec->reg_cache);
594reg_err:
595 kfree(codec->private_data);
596priv_err:
597 kfree(codec);
598 return ret;
599}
600
601/* power down chip */
602static int uda134x_soc_remove(struct platform_device *pdev)
603{
604 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
605 struct snd_soc_codec *codec = socdev->codec;
606
607 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
608 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
609
610 snd_soc_free_pcms(socdev);
611 snd_soc_dapm_free(socdev);
612
613 kfree(codec->private_data);
614 kfree(codec->reg_cache);
615 kfree(codec);
616
617 return 0;
618}
619
620#if defined(CONFIG_PM)
621static int uda134x_soc_suspend(struct platform_device *pdev,
622 pm_message_t state)
623{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_codec *codec = socdev->codec;
626
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
629 return 0;
630}
631
632static int uda134x_soc_resume(struct platform_device *pdev)
633{
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_codec *codec = socdev->codec;
636
637 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
639 return 0;
640}
641#else
642#define uda134x_soc_suspend NULL
643#define uda134x_soc_resume NULL
644#endif /* CONFIG_PM */
645
646struct snd_soc_codec_device soc_codec_dev_uda134x = {
647 .probe = uda134x_soc_probe,
648 .remove = uda134x_soc_remove,
649 .suspend = uda134x_soc_suspend,
650 .resume = uda134x_soc_resume,
651};
652EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
653
654static int __init uda134x_init(void)
655{
656 return snd_soc_register_dai(&uda134x_dai);
657}
658module_init(uda134x_init);
659
660static void __exit uda134x_exit(void)
661{
662 snd_soc_unregister_dai(&uda134x_dai);
663}
664module_exit(uda134x_exit);
665
666MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
667MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
668MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
new file mode 100644
index 000000000000..94f440490b31
--- /dev/null
+++ b/sound/soc/codecs/uda134x.h
@@ -0,0 +1,36 @@
1#ifndef _UDA134X_CODEC_H
2#define _UDA134X_CODEC_H
3
4#define UDA134X_L3ADDR 5
5#define UDA134X_DATA0_ADDR ((UDA134X_L3ADDR << 2) | 0)
6#define UDA134X_DATA1_ADDR ((UDA134X_L3ADDR << 2) | 1)
7#define UDA134X_STATUS_ADDR ((UDA134X_L3ADDR << 2) | 2)
8
9#define UDA134X_EXTADDR_PREFIX 0xC0
10#define UDA134X_EXTDATA_PREFIX 0xE0
11
12/* UDA134X registers */
13#define UDA134X_EA000 0
14#define UDA134X_EA001 1
15#define UDA134X_EA010 2
16#define UDA134X_EA011 3
17#define UDA134X_EA100 4
18#define UDA134X_EA101 5
19#define UDA134X_EA110 6
20#define UDA134X_EA111 7
21#define UDA134X_STATUS0 8
22#define UDA134X_STATUS1 9
23#define UDA134X_DATA000 10
24#define UDA134X_DATA001 11
25#define UDA134X_DATA010 12
26#define UDA134X_DATA1 13
27
28#define UDA134X_REGS_NUM 14
29
30#define STATUS0_DAIFMT_MASK (~(7<<1))
31#define STATUS0_SYSCLK_MASK (~(3<<4))
32
33extern struct snd_soc_dai uda134x_dai;
34extern struct snd_soc_codec_device soc_codec_dev_uda134x;
35
36#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index d206d7f892b6..e6bf0844fbf3 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -36,7 +36,6 @@
36#include "uda1380.h" 36#include "uda1380.h"
37 37
38#define UDA1380_VERSION "0.6" 38#define UDA1380_VERSION "0.6"
39#define AUDIO_NAME "uda1380"
40 39
41/* 40/*
42 * uda1380 register cache 41 * uda1380 register cache
@@ -408,7 +407,8 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
408 * when the DAI is being clocked by the CPU DAI. It's up to the 407 * 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. 408 * machine and cpu DAI driver to do this before we are called.
410 */ 409 */
411static int uda1380_pcm_prepare(struct snd_pcm_substream *substream) 410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
411 struct snd_soc_dai *dai)
412{ 412{
413 struct snd_soc_pcm_runtime *rtd = substream->private_data; 413 struct snd_soc_pcm_runtime *rtd = substream->private_data;
414 struct snd_soc_device *socdev = rtd->socdev; 414 struct snd_soc_device *socdev = rtd->socdev;
@@ -440,7 +440,8 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
440} 440}
441 441
442static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, 442static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
443 struct snd_pcm_hw_params *params) 443 struct snd_pcm_hw_params *params,
444 struct snd_soc_dai *dai)
444{ 445{
445 struct snd_soc_pcm_runtime *rtd = substream->private_data; 446 struct snd_soc_pcm_runtime *rtd = substream->private_data;
446 struct snd_soc_device *socdev = rtd->socdev; 447 struct snd_soc_device *socdev = rtd->socdev;
@@ -478,7 +479,8 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
478 return 0; 479 return 0;
479} 480}
480 481
481static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream) 482static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
482{ 484{
483 struct snd_soc_pcm_runtime *rtd = substream->private_data; 485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
484 struct snd_soc_device *socdev = rtd->socdev; 486 struct snd_soc_device *socdev = rtd->socdev;
@@ -561,8 +563,6 @@ struct snd_soc_dai uda1380_dai[] = {
561 .hw_params = uda1380_pcm_hw_params, 563 .hw_params = uda1380_pcm_hw_params,
562 .shutdown = uda1380_pcm_shutdown, 564 .shutdown = uda1380_pcm_shutdown,
563 .prepare = uda1380_pcm_prepare, 565 .prepare = uda1380_pcm_prepare,
564 },
565 .dai_ops = {
566 .digital_mute = uda1380_mute, 566 .digital_mute = uda1380_mute,
567 .set_fmt = uda1380_set_dai_fmt, 567 .set_fmt = uda1380_set_dai_fmt,
568 }, 568 },
@@ -580,8 +580,6 @@ struct snd_soc_dai uda1380_dai[] = {
580 .hw_params = uda1380_pcm_hw_params, 580 .hw_params = uda1380_pcm_hw_params,
581 .shutdown = uda1380_pcm_shutdown, 581 .shutdown = uda1380_pcm_shutdown,
582 .prepare = uda1380_pcm_prepare, 582 .prepare = uda1380_pcm_prepare,
583 },
584 .dai_ops = {
585 .digital_mute = uda1380_mute, 583 .digital_mute = uda1380_mute,
586 .set_fmt = uda1380_set_dai_fmt, 584 .set_fmt = uda1380_set_dai_fmt,
587 }, 585 },
@@ -599,8 +597,6 @@ struct snd_soc_dai uda1380_dai[] = {
599 .hw_params = uda1380_pcm_hw_params, 597 .hw_params = uda1380_pcm_hw_params,
600 .shutdown = uda1380_pcm_shutdown, 598 .shutdown = uda1380_pcm_shutdown,
601 .prepare = uda1380_pcm_prepare, 599 .prepare = uda1380_pcm_prepare,
602 },
603 .dai_ops = {
604 .set_fmt = uda1380_set_dai_fmt, 600 .set_fmt = uda1380_set_dai_fmt,
605 }, 601 },
606}, 602},
@@ -681,7 +677,7 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
681 /* uda1380 init */ 677 /* uda1380 init */
682 uda1380_add_controls(codec); 678 uda1380_add_controls(codec);
683 uda1380_add_widgets(codec); 679 uda1380_add_widgets(codec);
684 ret = snd_soc_register_card(socdev); 680 ret = snd_soc_init_card(socdev);
685 if (ret < 0) { 681 if (ret < 0) {
686 pr_err("uda1380: failed to register card\n"); 682 pr_err("uda1380: failed to register card\n");
687 goto card_err; 683 goto card_err;
@@ -845,6 +841,18 @@ struct snd_soc_codec_device soc_codec_dev_uda1380 = {
845}; 841};
846EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 842EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
847 843
844static int __init uda1380_modinit(void)
845{
846 return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
847}
848module_init(uda1380_modinit);
849
850static void __exit uda1380_exit(void)
851{
852 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
853}
854module_exit(uda1380_exit);
855
848MODULE_AUTHOR("Giorgio Padrin"); 856MODULE_AUTHOR("Giorgio Padrin");
849MODULE_DESCRIPTION("Audio support for codec Philips UDA1380"); 857MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
850MODULE_LICENSE("GPL"); 858MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
new file mode 100644
index 000000000000..e3989d406f54
--- /dev/null
+++ b/sound/soc/codecs/wm8350.c
@@ -0,0 +1,1583 @@
1/*
2 * wm8350.c -- WM8350 ALSA SoC audio driver
3 *
4 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/mfd/wm8350/audio.h>
20#include <linux/mfd/wm8350/core.h>
21#include <linux/regulator/consumer.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
30#include "wm8350.h"
31
32#define WM8350_OUTn_0dB 0x39
33
34#define WM8350_RAMP_NONE 0
35#define WM8350_RAMP_UP 1
36#define WM8350_RAMP_DOWN 2
37
38/* We only include the analogue supplies here; the digital supplies
39 * need to be available well before this driver can be probed.
40 */
41static const char *supply_names[] = {
42 "AVDD",
43 "HPVDD",
44};
45
46struct wm8350_output {
47 u16 active;
48 u16 left_vol;
49 u16 right_vol;
50 u16 ramp;
51 u16 mute;
52};
53
54struct wm8350_data {
55 struct snd_soc_codec codec;
56 struct wm8350_output out1;
57 struct wm8350_output out2;
58 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
59};
60
61static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 struct wm8350 *wm8350 = codec->control_data;
65 return wm8350->reg_cache[reg];
66}
67
68static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
69 unsigned int reg)
70{
71 struct wm8350 *wm8350 = codec->control_data;
72 return wm8350_reg_read(wm8350, reg);
73}
74
75static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
76 unsigned int value)
77{
78 struct wm8350 *wm8350 = codec->control_data;
79 return wm8350_reg_write(wm8350, reg, value);
80}
81
82/*
83 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
84 */
85static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
86{
87 struct wm8350_data *wm8350_data = codec->private_data;
88 struct wm8350_output *out1 = &wm8350_data->out1;
89 struct wm8350 *wm8350 = codec->control_data;
90 int left_complete = 0, right_complete = 0;
91 u16 reg, val;
92
93 /* left channel */
94 reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
95 val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
96
97 if (out1->ramp == WM8350_RAMP_UP) {
98 /* ramp step up */
99 if (val < out1->left_vol) {
100 val++;
101 reg &= ~WM8350_OUT1L_VOL_MASK;
102 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
103 reg | (val << WM8350_OUT1L_VOL_SHIFT));
104 } else
105 left_complete = 1;
106 } else if (out1->ramp == WM8350_RAMP_DOWN) {
107 /* ramp step down */
108 if (val > 0) {
109 val--;
110 reg &= ~WM8350_OUT1L_VOL_MASK;
111 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
112 reg | (val << WM8350_OUT1L_VOL_SHIFT));
113 } else
114 left_complete = 1;
115 } else
116 return 1;
117
118 /* right channel */
119 reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
120 val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
121 if (out1->ramp == WM8350_RAMP_UP) {
122 /* ramp step up */
123 if (val < out1->right_vol) {
124 val++;
125 reg &= ~WM8350_OUT1R_VOL_MASK;
126 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
127 reg | (val << WM8350_OUT1R_VOL_SHIFT));
128 } else
129 right_complete = 1;
130 } else if (out1->ramp == WM8350_RAMP_DOWN) {
131 /* ramp step down */
132 if (val > 0) {
133 val--;
134 reg &= ~WM8350_OUT1R_VOL_MASK;
135 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
136 reg | (val << WM8350_OUT1R_VOL_SHIFT));
137 } else
138 right_complete = 1;
139 }
140
141 /* only hit the update bit if either volume has changed this step */
142 if (!left_complete || !right_complete)
143 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
144
145 return left_complete & right_complete;
146}
147
148/*
149 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
150 */
151static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
152{
153 struct wm8350_data *wm8350_data = codec->private_data;
154 struct wm8350_output *out2 = &wm8350_data->out2;
155 struct wm8350 *wm8350 = codec->control_data;
156 int left_complete = 0, right_complete = 0;
157 u16 reg, val;
158
159 /* left channel */
160 reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
161 val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
162 if (out2->ramp == WM8350_RAMP_UP) {
163 /* ramp step up */
164 if (val < out2->left_vol) {
165 val++;
166 reg &= ~WM8350_OUT2L_VOL_MASK;
167 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
168 reg | (val << WM8350_OUT1L_VOL_SHIFT));
169 } else
170 left_complete = 1;
171 } else if (out2->ramp == WM8350_RAMP_DOWN) {
172 /* ramp step down */
173 if (val > 0) {
174 val--;
175 reg &= ~WM8350_OUT2L_VOL_MASK;
176 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
177 reg | (val << WM8350_OUT1L_VOL_SHIFT));
178 } else
179 left_complete = 1;
180 } else
181 return 1;
182
183 /* right channel */
184 reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
185 val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
186 if (out2->ramp == WM8350_RAMP_UP) {
187 /* ramp step up */
188 if (val < out2->right_vol) {
189 val++;
190 reg &= ~WM8350_OUT2R_VOL_MASK;
191 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
192 reg | (val << WM8350_OUT1R_VOL_SHIFT));
193 } else
194 right_complete = 1;
195 } else if (out2->ramp == WM8350_RAMP_DOWN) {
196 /* ramp step down */
197 if (val > 0) {
198 val--;
199 reg &= ~WM8350_OUT2R_VOL_MASK;
200 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
201 reg | (val << WM8350_OUT1R_VOL_SHIFT));
202 } else
203 right_complete = 1;
204 }
205
206 /* only hit the update bit if either volume has changed this step */
207 if (!left_complete || !right_complete)
208 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
209
210 return left_complete & right_complete;
211}
212
213/*
214 * This work ramps both output PGAs at stream start/stop time to
215 * minimise pop associated with DAPM power switching.
216 * It's best to enable Zero Cross when ramping occurs to minimise any
217 * zipper noises.
218 */
219static void wm8350_pga_work(struct work_struct *work)
220{
221 struct snd_soc_codec *codec =
222 container_of(work, struct snd_soc_codec, delayed_work.work);
223 struct wm8350_data *wm8350_data = codec->private_data;
224 struct wm8350_output *out1 = &wm8350_data->out1,
225 *out2 = &wm8350_data->out2;
226 int i, out1_complete, out2_complete;
227
228 /* do we need to ramp at all ? */
229 if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
230 return;
231
232 /* PGA volumes have 6 bits of resolution to ramp */
233 for (i = 0; i <= 63; i++) {
234 out1_complete = 1, out2_complete = 1;
235 if (out1->ramp != WM8350_RAMP_NONE)
236 out1_complete = wm8350_out1_ramp_step(codec);
237 if (out2->ramp != WM8350_RAMP_NONE)
238 out2_complete = wm8350_out2_ramp_step(codec);
239
240 /* ramp finished ? */
241 if (out1_complete && out2_complete)
242 break;
243
244 /* we need to delay longer on the up ramp */
245 if (out1->ramp == WM8350_RAMP_UP ||
246 out2->ramp == WM8350_RAMP_UP) {
247 /* delay is longer over 0dB as increases are larger */
248 if (i >= WM8350_OUTn_0dB)
249 schedule_timeout_interruptible(msecs_to_jiffies
250 (2));
251 else
252 schedule_timeout_interruptible(msecs_to_jiffies
253 (1));
254 } else
255 udelay(50); /* doesn't matter if we delay longer */
256 }
257
258 out1->ramp = WM8350_RAMP_NONE;
259 out2->ramp = WM8350_RAMP_NONE;
260}
261
262/*
263 * WM8350 Controls
264 */
265
266static int pga_event(struct snd_soc_dapm_widget *w,
267 struct snd_kcontrol *kcontrol, int event)
268{
269 struct snd_soc_codec *codec = w->codec;
270 struct wm8350_data *wm8350_data = codec->private_data;
271 struct wm8350_output *out;
272
273 switch (w->shift) {
274 case 0:
275 case 1:
276 out = &wm8350_data->out1;
277 break;
278 case 2:
279 case 3:
280 out = &wm8350_data->out2;
281 break;
282
283 default:
284 BUG();
285 return -1;
286 }
287
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 out->ramp = WM8350_RAMP_UP;
291 out->active = 1;
292
293 if (!delayed_work_pending(&codec->delayed_work))
294 schedule_delayed_work(&codec->delayed_work,
295 msecs_to_jiffies(1));
296 break;
297
298 case SND_SOC_DAPM_PRE_PMD:
299 out->ramp = WM8350_RAMP_DOWN;
300 out->active = 0;
301
302 if (!delayed_work_pending(&codec->delayed_work))
303 schedule_delayed_work(&codec->delayed_work,
304 msecs_to_jiffies(1));
305 break;
306 }
307
308 return 0;
309}
310
311static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
313{
314 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct wm8350_data *wm8350_priv = codec->private_data;
316 struct wm8350_output *out = NULL;
317 struct soc_mixer_control *mc =
318 (struct soc_mixer_control *)kcontrol->private_value;
319 int ret;
320 unsigned int reg = mc->reg;
321 u16 val;
322
323 /* For OUT1 and OUT2 we shadow the values and only actually write
324 * them out when active in order to ensure the amplifier comes on
325 * as quietly as possible. */
326 switch (reg) {
327 case WM8350_LOUT1_VOLUME:
328 out = &wm8350_priv->out1;
329 break;
330 case WM8350_LOUT2_VOLUME:
331 out = &wm8350_priv->out2;
332 break;
333 default:
334 break;
335 }
336
337 if (out) {
338 out->left_vol = ucontrol->value.integer.value[0];
339 out->right_vol = ucontrol->value.integer.value[1];
340 if (!out->active)
341 return 1;
342 }
343
344 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
345 if (ret < 0)
346 return ret;
347
348 /* now hit the volume update bits (always bit 8) */
349 val = wm8350_codec_read(codec, reg);
350 wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
351 return 1;
352}
353
354static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct wm8350_data *wm8350_priv = codec->private_data;
359 struct wm8350_output *out1 = &wm8350_priv->out1;
360 struct wm8350_output *out2 = &wm8350_priv->out2;
361 struct soc_mixer_control *mc =
362 (struct soc_mixer_control *)kcontrol->private_value;
363 unsigned int reg = mc->reg;
364
365 /* If these are cached registers use the cache */
366 switch (reg) {
367 case WM8350_LOUT1_VOLUME:
368 ucontrol->value.integer.value[0] = out1->left_vol;
369 ucontrol->value.integer.value[1] = out1->right_vol;
370 return 0;
371
372 case WM8350_LOUT2_VOLUME:
373 ucontrol->value.integer.value[0] = out2->left_vol;
374 ucontrol->value.integer.value[1] = out2->right_vol;
375 return 0;
376
377 default:
378 break;
379 }
380
381 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
382}
383
384/* double control with volume update */
385#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
386 xinvert, tlv_array) \
387{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
388 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
389 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
390 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
391 .tlv.p = (tlv_array), \
392 .info = snd_soc_info_volsw_2r, \
393 .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
394 .private_value = (unsigned long)&(struct soc_mixer_control) \
395 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
396 .rshift = xshift, .max = xmax, .invert = xinvert}, }
397
398static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
399static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
400static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
401static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
402static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
403static const char *wm8350_adcfilter[] = { "None", "High Pass" };
404static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
405static const char *wm8350_lr[] = { "Left", "Right" };
406
407static const struct soc_enum wm8350_enum[] = {
408 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
409 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
410 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
411 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
412 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
413 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
414 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
415 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
416 SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
417};
418
419static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525);
420static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600);
421static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
422static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
423static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
424
425static const unsigned int capture_sd_tlv[] = {
426 TLV_DB_RANGE_HEAD(2),
427 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
428 13, 15, TLV_DB_SCALE_ITEM(0, 0, 0),
429};
430
431static const struct snd_kcontrol_new wm8350_snd_controls[] = {
432 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
433 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
434 SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume",
435 WM8350_DAC_DIGITAL_VOLUME_L,
436 WM8350_DAC_DIGITAL_VOLUME_R,
437 0, 255, 0, dac_pcm_tlv),
438 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
439 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
440 SOC_ENUM("Playback PCM Filter", wm8350_enum[4]),
441 SOC_ENUM("Capture PCM Filter", wm8350_enum[5]),
442 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]),
443 SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
444 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
445 WM8350_ADC_DIGITAL_VOLUME_L,
446 WM8350_ADC_DIGITAL_VOLUME_R,
447 0, 255, 0, adc_pcm_tlv),
448 SOC_DOUBLE_TLV("Capture Sidetone Volume",
449 WM8350_ADC_DIVIDER,
450 8, 4, 15, 1, capture_sd_tlv),
451 SOC_WM8350_DOUBLE_R_TLV("Capture Volume",
452 WM8350_LEFT_INPUT_VOLUME,
453 WM8350_RIGHT_INPUT_VOLUME,
454 2, 63, 0, pre_amp_tlv),
455 SOC_DOUBLE_R("Capture ZC Switch",
456 WM8350_LEFT_INPUT_VOLUME,
457 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
458 SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
459 WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
460 SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
461 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
462 5, 7, 0, out_mix_tlv),
463 SOC_SINGLE_TLV("Left Input Bypass Volume",
464 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
465 9, 7, 0, out_mix_tlv),
466 SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
467 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
468 1, 7, 0, out_mix_tlv),
469 SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
470 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
471 5, 7, 0, out_mix_tlv),
472 SOC_SINGLE_TLV("Right Input Bypass Volume",
473 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
474 13, 7, 0, out_mix_tlv),
475 SOC_SINGLE("Left Input Mixer +20dB Switch",
476 WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
477 SOC_SINGLE("Right Input Mixer +20dB Switch",
478 WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
479 SOC_SINGLE_TLV("Out4 Capture Volume",
480 WM8350_INPUT_MIXER_VOLUME,
481 1, 7, 0, out_mix_tlv),
482 SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume",
483 WM8350_LOUT1_VOLUME,
484 WM8350_ROUT1_VOLUME,
485 2, 63, 0, out_pga_tlv),
486 SOC_DOUBLE_R("Out1 Playback ZC Switch",
487 WM8350_LOUT1_VOLUME,
488 WM8350_ROUT1_VOLUME, 13, 1, 0),
489 SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume",
490 WM8350_LOUT2_VOLUME,
491 WM8350_ROUT2_VOLUME,
492 2, 63, 0, out_pga_tlv),
493 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
494 WM8350_ROUT2_VOLUME, 13, 1, 0),
495 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
496 SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
497 5, 7, 0, out_mix_tlv),
498
499 SOC_DOUBLE_R("Out1 Playback Switch",
500 WM8350_LOUT1_VOLUME,
501 WM8350_ROUT1_VOLUME,
502 14, 1, 1),
503 SOC_DOUBLE_R("Out2 Playback Switch",
504 WM8350_LOUT2_VOLUME,
505 WM8350_ROUT2_VOLUME,
506 14, 1, 1),
507};
508
509/*
510 * DAPM Controls
511 */
512
513/* Left Playback Mixer */
514static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
515 SOC_DAPM_SINGLE("Playback Switch",
516 WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
517 SOC_DAPM_SINGLE("Left Bypass Switch",
518 WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
519 SOC_DAPM_SINGLE("Right Playback Switch",
520 WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
521 SOC_DAPM_SINGLE("Left Sidetone Switch",
522 WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
523 SOC_DAPM_SINGLE("Right Sidetone Switch",
524 WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
525};
526
527/* Right Playback Mixer */
528static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
529 SOC_DAPM_SINGLE("Playback Switch",
530 WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
531 SOC_DAPM_SINGLE("Right Bypass Switch",
532 WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
533 SOC_DAPM_SINGLE("Left Playback Switch",
534 WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
535 SOC_DAPM_SINGLE("Left Sidetone Switch",
536 WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
537 SOC_DAPM_SINGLE("Right Sidetone Switch",
538 WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
539};
540
541/* Out4 Mixer */
542static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
543 SOC_DAPM_SINGLE("Right Playback Switch",
544 WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
545 SOC_DAPM_SINGLE("Left Playback Switch",
546 WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
547 SOC_DAPM_SINGLE("Right Capture Switch",
548 WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
549 SOC_DAPM_SINGLE("Out3 Playback Switch",
550 WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
551 SOC_DAPM_SINGLE("Right Mixer Switch",
552 WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
553 SOC_DAPM_SINGLE("Left Mixer Switch",
554 WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
555};
556
557/* Out3 Mixer */
558static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
559 SOC_DAPM_SINGLE("Left Playback Switch",
560 WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
561 SOC_DAPM_SINGLE("Left Capture Switch",
562 WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
563 SOC_DAPM_SINGLE("Out4 Playback Switch",
564 WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
565 SOC_DAPM_SINGLE("Left Mixer Switch",
566 WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
567};
568
569/* Left Input Mixer */
570static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
571 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
572 WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
573 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
574 WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
575 SOC_DAPM_SINGLE("PGA Capture Switch",
576 WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
577};
578
579/* Right Input Mixer */
580static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
581 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
582 WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
583 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
584 WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
585 SOC_DAPM_SINGLE("PGA Capture Switch",
586 WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
587};
588
589/* Left Mic Mixer */
590static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
591 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
592 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
593 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
594};
595
596/* Right Mic Mixer */
597static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
598 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
599 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
600 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
601};
602
603/* Beep Switch */
604static const struct snd_kcontrol_new wm8350_beep_switch_controls =
605SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
606
607/* Out4 Capture Mux */
608static const struct snd_kcontrol_new wm8350_out4_capture_controls =
609SOC_DAPM_ENUM("Route", wm8350_enum[8]);
610
611static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
612
613 SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
614 SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
615 SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
616 0, pga_event,
617 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
618 SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
619 pga_event,
620 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
621 SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
622 0, pga_event,
623 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
624 SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
625 pga_event,
626 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
627
628 SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
629 7, 0, &wm8350_right_capt_mixer_controls[0],
630 ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
631
632 SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
633 6, 0, &wm8350_left_capt_mixer_controls[0],
634 ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
635
636 SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
637 &wm8350_out4_mixer_controls[0],
638 ARRAY_SIZE(wm8350_out4_mixer_controls)),
639
640 SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
641 &wm8350_out3_mixer_controls[0],
642 ARRAY_SIZE(wm8350_out3_mixer_controls)),
643
644 SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
645 &wm8350_right_play_mixer_controls[0],
646 ARRAY_SIZE(wm8350_right_play_mixer_controls)),
647
648 SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
649 &wm8350_left_play_mixer_controls[0],
650 ARRAY_SIZE(wm8350_left_play_mixer_controls)),
651
652 SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
653 &wm8350_left_mic_mixer_controls[0],
654 ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
655
656 SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
657 &wm8350_right_mic_mixer_controls[0],
658 ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
659
660 /* virtual mixer for Beep and Out2R */
661 SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
662
663 SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
664 &wm8350_beep_switch_controls),
665
666 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
667 WM8350_POWER_MGMT_4, 3, 0),
668 SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
669 WM8350_POWER_MGMT_4, 2, 0),
670 SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
671 WM8350_POWER_MGMT_4, 5, 0),
672 SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
673 WM8350_POWER_MGMT_4, 4, 0),
674
675 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
676
677 SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
678 &wm8350_out4_capture_controls),
679
680 SND_SOC_DAPM_OUTPUT("OUT1R"),
681 SND_SOC_DAPM_OUTPUT("OUT1L"),
682 SND_SOC_DAPM_OUTPUT("OUT2R"),
683 SND_SOC_DAPM_OUTPUT("OUT2L"),
684 SND_SOC_DAPM_OUTPUT("OUT3"),
685 SND_SOC_DAPM_OUTPUT("OUT4"),
686
687 SND_SOC_DAPM_INPUT("IN1RN"),
688 SND_SOC_DAPM_INPUT("IN1RP"),
689 SND_SOC_DAPM_INPUT("IN2R"),
690 SND_SOC_DAPM_INPUT("IN1LP"),
691 SND_SOC_DAPM_INPUT("IN1LN"),
692 SND_SOC_DAPM_INPUT("IN2L"),
693 SND_SOC_DAPM_INPUT("IN3R"),
694 SND_SOC_DAPM_INPUT("IN3L"),
695};
696
697static const struct snd_soc_dapm_route audio_map[] = {
698
699 /* left playback mixer */
700 {"Left Playback Mixer", "Playback Switch", "Left DAC"},
701 {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
702 {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
703 {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
704 {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
705
706 /* right playback mixer */
707 {"Right Playback Mixer", "Playback Switch", "Right DAC"},
708 {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
709 {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
710 {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
711 {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
712
713 /* out4 playback mixer */
714 {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
715 {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
716 {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
717 {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
718 {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
719 {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
720 {"OUT4", NULL, "Out4 Mixer"},
721
722 /* out3 playback mixer */
723 {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
724 {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
725 {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
726 {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
727 {"OUT3", NULL, "Out3 Mixer"},
728
729 /* out2 */
730 {"Right Out2 PGA", NULL, "Right Playback Mixer"},
731 {"Left Out2 PGA", NULL, "Left Playback Mixer"},
732 {"OUT2L", NULL, "Left Out2 PGA"},
733 {"OUT2R", NULL, "Right Out2 PGA"},
734
735 /* out1 */
736 {"Right Out1 PGA", NULL, "Right Playback Mixer"},
737 {"Left Out1 PGA", NULL, "Left Playback Mixer"},
738 {"OUT1L", NULL, "Left Out1 PGA"},
739 {"OUT1R", NULL, "Right Out1 PGA"},
740
741 /* ADCs */
742 {"Left ADC", NULL, "Left Capture Mixer"},
743 {"Right ADC", NULL, "Right Capture Mixer"},
744
745 /* Left capture mixer */
746 {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
747 {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
748 {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
749 {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
750
751 /* Right capture mixer */
752 {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
753 {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
754 {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
755 {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
756
757 /* L3 Inputs */
758 {"IN3L PGA", NULL, "IN3L"},
759 {"IN3R PGA", NULL, "IN3R"},
760
761 /* Left Mic mixer */
762 {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
763 {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
764 {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
765
766 /* Right Mic mixer */
767 {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
768 {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
769 {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
770
771 /* out 4 capture */
772 {"Out4 Capture Channel", NULL, "Out4 Mixer"},
773
774 /* Beep */
775 {"Beep", NULL, "IN3R PGA"},
776};
777
778static int wm8350_add_controls(struct snd_soc_codec *codec)
779{
780 int err, i;
781
782 for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) {
783 err = snd_ctl_add(codec->card,
784 snd_soc_cnew(&wm8350_snd_controls[i],
785 codec, NULL));
786 if (err < 0)
787 return err;
788 }
789
790 return 0;
791}
792
793static int wm8350_add_widgets(struct snd_soc_codec *codec)
794{
795 int ret;
796
797 ret = snd_soc_dapm_new_controls(codec,
798 wm8350_dapm_widgets,
799 ARRAY_SIZE(wm8350_dapm_widgets));
800 if (ret != 0) {
801 dev_err(codec->dev, "dapm control register failed\n");
802 return ret;
803 }
804
805 /* set up audio paths */
806 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
807 if (ret != 0) {
808 dev_err(codec->dev, "DAPM route register failed\n");
809 return ret;
810 }
811
812 return snd_soc_dapm_new_widgets(codec);
813}
814
815static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
816 int clk_id, unsigned int freq, int dir)
817{
818 struct snd_soc_codec *codec = codec_dai->codec;
819 struct wm8350 *wm8350 = codec->control_data;
820 u16 fll_4;
821
822 switch (clk_id) {
823 case WM8350_MCLK_SEL_MCLK:
824 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
825 WM8350_MCLK_SEL);
826 break;
827 case WM8350_MCLK_SEL_PLL_MCLK:
828 case WM8350_MCLK_SEL_PLL_DAC:
829 case WM8350_MCLK_SEL_PLL_ADC:
830 case WM8350_MCLK_SEL_PLL_32K:
831 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
832 WM8350_MCLK_SEL);
833 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
834 ~WM8350_FLL_CLK_SRC_MASK;
835 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
836 break;
837 }
838
839 /* MCLK direction */
840 if (dir == WM8350_MCLK_DIR_OUT)
841 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
842 WM8350_MCLK_DIR);
843 else
844 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
845 WM8350_MCLK_DIR);
846
847 return 0;
848}
849
850static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
851{
852 struct snd_soc_codec *codec = codec_dai->codec;
853 u16 val;
854
855 switch (div_id) {
856 case WM8350_ADC_CLKDIV:
857 val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) &
858 ~WM8350_ADC_CLKDIV_MASK;
859 wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div);
860 break;
861 case WM8350_DAC_CLKDIV:
862 val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) &
863 ~WM8350_DAC_CLKDIV_MASK;
864 wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
865 break;
866 case WM8350_BCLK_CLKDIV:
867 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
868 ~WM8350_BCLK_DIV_MASK;
869 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
870 break;
871 case WM8350_OPCLK_CLKDIV:
872 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
873 ~WM8350_OPCLK_DIV_MASK;
874 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
875 break;
876 case WM8350_SYS_CLKDIV:
877 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
878 ~WM8350_MCLK_DIV_MASK;
879 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
880 break;
881 case WM8350_DACLR_CLKDIV:
882 val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
883 ~WM8350_DACLRC_RATE_MASK;
884 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div);
885 break;
886 case WM8350_ADCLR_CLKDIV:
887 val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
888 ~WM8350_ADCLRC_RATE_MASK;
889 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div);
890 break;
891 default:
892 return -EINVAL;
893 }
894
895 return 0;
896}
897
898static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
899{
900 struct snd_soc_codec *codec = codec_dai->codec;
901 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
902 ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
903 u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) &
904 ~WM8350_BCLK_MSTR;
905 u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
906 ~WM8350_DACLRC_ENA;
907 u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
908 ~WM8350_ADCLRC_ENA;
909
910 /* set master/slave audio interface */
911 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
912 case SND_SOC_DAIFMT_CBM_CFM:
913 master |= WM8350_BCLK_MSTR;
914 dac_lrc |= WM8350_DACLRC_ENA;
915 adc_lrc |= WM8350_ADCLRC_ENA;
916 break;
917 case SND_SOC_DAIFMT_CBS_CFS:
918 break;
919 default:
920 return -EINVAL;
921 }
922
923 /* interface format */
924 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
925 case SND_SOC_DAIFMT_I2S:
926 iface |= 0x2 << 8;
927 break;
928 case SND_SOC_DAIFMT_RIGHT_J:
929 break;
930 case SND_SOC_DAIFMT_LEFT_J:
931 iface |= 0x1 << 8;
932 break;
933 case SND_SOC_DAIFMT_DSP_A:
934 iface |= 0x3 << 8;
935 break;
936 case SND_SOC_DAIFMT_DSP_B:
937 iface |= 0x3 << 8; /* lg not sure which mode */
938 break;
939 default:
940 return -EINVAL;
941 }
942
943 /* clock inversion */
944 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
945 case SND_SOC_DAIFMT_NB_NF:
946 break;
947 case SND_SOC_DAIFMT_IB_IF:
948 iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
949 break;
950 case SND_SOC_DAIFMT_IB_NF:
951 iface |= WM8350_AIF_BCLK_INV;
952 break;
953 case SND_SOC_DAIFMT_NB_IF:
954 iface |= WM8350_AIF_LRCLK_INV;
955 break;
956 default:
957 return -EINVAL;
958 }
959
960 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
961 wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master);
962 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
963 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
964 return 0;
965}
966
967static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
968 int cmd, struct snd_soc_dai *codec_dai)
969{
970 struct snd_soc_codec *codec = codec_dai->codec;
971 int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
972 WM8350_BCLK_MSTR;
973 int enabled = 0;
974
975 /* Check that the DACs or ADCs are enabled since they are
976 * required for LRC in master mode. The DACs or ADCs need a
977 * valid audio path i.e. pin -> ADC or DAC -> pin before
978 * the LRC will be enabled in master mode. */
979 if (!master && cmd != SNDRV_PCM_TRIGGER_START)
980 return 0;
981
982 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
983 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
984 (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
985 } else {
986 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
987 (WM8350_DACR_ENA | WM8350_DACL_ENA);
988 }
989
990 if (!enabled) {
991 dev_err(codec->dev,
992 "%s: invalid audio path - no clocks available\n",
993 __func__);
994 return -EINVAL;
995 }
996 return 0;
997}
998
999static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1000 struct snd_pcm_hw_params *params,
1001 struct snd_soc_dai *codec_dai)
1002{
1003 struct snd_soc_codec *codec = codec_dai->codec;
1004 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
1005 ~WM8350_AIF_WL_MASK;
1006
1007 /* bit size */
1008 switch (params_format(params)) {
1009 case SNDRV_PCM_FORMAT_S16_LE:
1010 break;
1011 case SNDRV_PCM_FORMAT_S20_3LE:
1012 iface |= 0x1 << 10;
1013 break;
1014 case SNDRV_PCM_FORMAT_S24_LE:
1015 iface |= 0x2 << 10;
1016 break;
1017 case SNDRV_PCM_FORMAT_S32_LE:
1018 iface |= 0x3 << 10;
1019 break;
1020 }
1021
1022 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
1023 return 0;
1024}
1025
1026static int wm8350_mute(struct snd_soc_dai *dai, int mute)
1027{
1028 struct snd_soc_codec *codec = dai->codec;
1029 struct wm8350 *wm8350 = codec->control_data;
1030
1031 if (mute)
1032 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1033 else
1034 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1035 return 0;
1036}
1037
1038/* FLL divisors */
1039struct _fll_div {
1040 int div; /* FLL_OUTDIV */
1041 int n;
1042 int k;
1043 int ratio; /* FLL_FRATIO */
1044};
1045
1046/* The size in bits of the fll divide multiplied by 10
1047 * to allow rounding later */
1048#define FIXED_FLL_SIZE ((1 << 16) * 10)
1049
1050static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1051 unsigned int output)
1052{
1053 u64 Kpart;
1054 unsigned int t1, t2, K, Nmod;
1055
1056 if (output >= 2815250 && output <= 3125000)
1057 fll_div->div = 0x4;
1058 else if (output >= 5625000 && output <= 6250000)
1059 fll_div->div = 0x3;
1060 else if (output >= 11250000 && output <= 12500000)
1061 fll_div->div = 0x2;
1062 else if (output >= 22500000 && output <= 25000000)
1063 fll_div->div = 0x1;
1064 else {
1065 printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
1066 return -EINVAL;
1067 }
1068
1069 if (input > 48000)
1070 fll_div->ratio = 1;
1071 else
1072 fll_div->ratio = 8;
1073
1074 t1 = output * (1 << (fll_div->div + 1));
1075 t2 = input * fll_div->ratio;
1076
1077 fll_div->n = t1 / t2;
1078 Nmod = t1 % t2;
1079
1080 if (Nmod) {
1081 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1082 do_div(Kpart, t2);
1083 K = Kpart & 0xFFFFFFFF;
1084
1085 /* Check if we need to round */
1086 if ((K % 10) >= 5)
1087 K += 5;
1088
1089 /* Move down to proper range now rounding is done */
1090 K /= 10;
1091 fll_div->k = K;
1092 } else
1093 fll_div->k = 0;
1094
1095 return 0;
1096}
1097
1098static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1099 int pll_id, unsigned int freq_in,
1100 unsigned int freq_out)
1101{
1102 struct snd_soc_codec *codec = codec_dai->codec;
1103 struct wm8350 *wm8350 = codec->control_data;
1104 struct _fll_div fll_div;
1105 int ret = 0;
1106 u16 fll_1, fll_4;
1107
1108 /* power down FLL - we need to do this for reconfiguration */
1109 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1110 WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
1111
1112 if (freq_out == 0 || freq_in == 0)
1113 return ret;
1114
1115 ret = fll_factors(&fll_div, freq_in, freq_out);
1116 if (ret < 0)
1117 return ret;
1118 dev_dbg(wm8350->dev,
1119 "FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
1120 freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
1121 fll_div.ratio);
1122
1123 /* set up N.K & dividers */
1124 fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) &
1125 ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
1126 wm8350_codec_write(codec, WM8350_FLL_CONTROL_1,
1127 fll_1 | (fll_div.div << 8) | 0x50);
1128 wm8350_codec_write(codec, WM8350_FLL_CONTROL_2,
1129 (fll_div.ratio << 11) | (fll_div.
1130 n & WM8350_FLL_N_MASK));
1131 wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
1132 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
1133 ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
1134 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4,
1135 fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
1136 (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
1137
1138 /* power FLL on */
1139 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
1140 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
1141
1142 return 0;
1143}
1144
1145static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1146 enum snd_soc_bias_level level)
1147{
1148 struct wm8350 *wm8350 = codec->control_data;
1149 struct wm8350_data *priv = codec->private_data;
1150 struct wm8350_audio_platform_data *platform =
1151 wm8350->codec.platform_data;
1152 u16 pm1;
1153 int ret;
1154
1155 switch (level) {
1156 case SND_SOC_BIAS_ON:
1157 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1158 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1159 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1160 pm1 | WM8350_VMID_50K |
1161 platform->codec_current_on << 14);
1162 break;
1163
1164 case SND_SOC_BIAS_PREPARE:
1165 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
1166 pm1 &= ~WM8350_VMID_MASK;
1167 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1168 pm1 | WM8350_VMID_50K);
1169 break;
1170
1171 case SND_SOC_BIAS_STANDBY:
1172 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1173 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1174 priv->supplies);
1175 if (ret != 0)
1176 return ret;
1177
1178 /* Enable the system clock */
1179 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
1180 WM8350_SYSCLK_ENA);
1181
1182 /* mute DAC & outputs */
1183 wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
1184 WM8350_DAC_MUTE_ENA);
1185
1186 /* discharge cap memory */
1187 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1188 platform->dis_out1 |
1189 (platform->dis_out2 << 2) |
1190 (platform->dis_out3 << 4) |
1191 (platform->dis_out4 << 6));
1192
1193 /* wait for discharge */
1194 schedule_timeout_interruptible(msecs_to_jiffies
1195 (platform->
1196 cap_discharge_msecs));
1197
1198 /* enable antipop */
1199 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1200 (platform->vmid_s_curve << 8));
1201
1202 /* ramp up vmid */
1203 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1204 (platform->
1205 codec_current_charge << 14) |
1206 WM8350_VMID_5K | WM8350_VMIDEN |
1207 WM8350_VBUFEN);
1208
1209 /* wait for vmid */
1210 schedule_timeout_interruptible(msecs_to_jiffies
1211 (platform->
1212 vmid_charge_msecs));
1213
1214 /* turn on vmid 300k */
1215 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1216 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1217 pm1 |= WM8350_VMID_300K |
1218 (platform->codec_current_standby << 14);
1219 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1220 pm1);
1221
1222
1223 /* enable analogue bias */
1224 pm1 |= WM8350_BIASEN;
1225 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1226
1227 /* disable antipop */
1228 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1229
1230 } else {
1231 /* turn on vmid 300k and reduce current */
1232 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1233 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1234 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1235 pm1 | WM8350_VMID_300K |
1236 (platform->
1237 codec_current_standby << 14));
1238
1239 }
1240 break;
1241
1242 case SND_SOC_BIAS_OFF:
1243
1244 /* mute DAC & enable outputs */
1245 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1246
1247 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
1248 WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
1249 WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
1250
1251 /* enable anti pop S curve */
1252 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1253 (platform->vmid_s_curve << 8));
1254
1255 /* turn off vmid */
1256 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1257 ~WM8350_VMIDEN;
1258 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1259
1260 /* wait */
1261 schedule_timeout_interruptible(msecs_to_jiffies
1262 (platform->
1263 vmid_discharge_msecs));
1264
1265 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1266 (platform->vmid_s_curve << 8) |
1267 platform->dis_out1 |
1268 (platform->dis_out2 << 2) |
1269 (platform->dis_out3 << 4) |
1270 (platform->dis_out4 << 6));
1271
1272 /* turn off VBuf and drain */
1273 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1274 ~(WM8350_VBUFEN | WM8350_VMID_MASK);
1275 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1276 pm1 | WM8350_OUTPUT_DRAIN_EN);
1277
1278 /* wait */
1279 schedule_timeout_interruptible(msecs_to_jiffies
1280 (platform->drain_msecs));
1281
1282 pm1 &= ~WM8350_BIASEN;
1283 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1284
1285 /* disable anti-pop */
1286 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1287
1288 wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
1289 WM8350_OUT1L_ENA);
1290 wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
1291 WM8350_OUT1R_ENA);
1292 wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
1293 WM8350_OUT2L_ENA);
1294 wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
1295 WM8350_OUT2R_ENA);
1296
1297 /* disable clock gen */
1298 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1299 WM8350_SYSCLK_ENA);
1300
1301 regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
1302 priv->supplies);
1303 break;
1304 }
1305 codec->bias_level = level;
1306 return 0;
1307}
1308
1309static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
1310{
1311 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1312 struct snd_soc_codec *codec = socdev->codec;
1313
1314 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1315 return 0;
1316}
1317
1318static int wm8350_resume(struct platform_device *pdev)
1319{
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->codec;
1322
1323 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1324
1325 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1326 wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
1327
1328 return 0;
1329}
1330
1331static struct snd_soc_codec *wm8350_codec;
1332
1333static int wm8350_probe(struct platform_device *pdev)
1334{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec;
1337 struct wm8350 *wm8350;
1338 struct wm8350_data *priv;
1339 int ret;
1340 struct wm8350_output *out1;
1341 struct wm8350_output *out2;
1342
1343 BUG_ON(!wm8350_codec);
1344
1345 socdev->codec = wm8350_codec;
1346 codec = socdev->codec;
1347 wm8350 = codec->control_data;
1348 priv = codec->private_data;
1349
1350 /* Enable the codec */
1351 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1352
1353 /* Enable robust clocking mode in ADC */
1354 wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
1355 wm8350_codec_write(codec, 0xde, 0x13);
1356 wm8350_codec_write(codec, WM8350_SECURITY, 0);
1357
1358 /* read OUT1 & OUT2 volumes */
1359 out1 = &priv->out1;
1360 out2 = &priv->out2;
1361 out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
1362 WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1363 out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
1364 WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1365 out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
1366 WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1367 out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
1368 WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1369 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
1370 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
1371 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
1372 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
1373
1374 /* Latch VU bits & mute */
1375 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
1376 WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
1377 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
1378 WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
1379 wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
1380 WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
1381 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1382 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1383
1384 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1385 if (ret < 0) {
1386 dev_err(&pdev->dev, "failed to create pcms\n");
1387 return ret;
1388 }
1389
1390 wm8350_add_controls(codec);
1391 wm8350_add_widgets(codec);
1392
1393 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1394
1395 ret = snd_soc_init_card(socdev);
1396 if (ret < 0) {
1397 dev_err(&pdev->dev, "failed to register card\n");
1398 goto card_err;
1399 }
1400
1401 return 0;
1402
1403card_err:
1404 snd_soc_free_pcms(socdev);
1405 snd_soc_dapm_free(socdev);
1406 return ret;
1407}
1408
1409static int wm8350_remove(struct platform_device *pdev)
1410{
1411 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1412 struct snd_soc_codec *codec = socdev->codec;
1413 struct wm8350 *wm8350 = codec->control_data;
1414 int ret;
1415
1416 /* cancel any work waiting to be queued. */
1417 ret = cancel_delayed_work(&codec->delayed_work);
1418
1419 /* if there was any work waiting then we run it now and
1420 * wait for its completion */
1421 if (ret) {
1422 schedule_delayed_work(&codec->delayed_work, 0);
1423 flush_scheduled_work();
1424 }
1425
1426 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1427
1428 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1429
1430 return 0;
1431}
1432
1433#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1434
1435#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1436 SNDRV_PCM_FMTBIT_S20_3LE |\
1437 SNDRV_PCM_FMTBIT_S24_LE)
1438
1439struct snd_soc_dai wm8350_dai = {
1440 .name = "WM8350",
1441 .playback = {
1442 .stream_name = "Playback",
1443 .channels_min = 1,
1444 .channels_max = 2,
1445 .rates = WM8350_RATES,
1446 .formats = WM8350_FORMATS,
1447 },
1448 .capture = {
1449 .stream_name = "Capture",
1450 .channels_min = 1,
1451 .channels_max = 2,
1452 .rates = WM8350_RATES,
1453 .formats = WM8350_FORMATS,
1454 },
1455 .ops = {
1456 .hw_params = wm8350_pcm_hw_params,
1457 .digital_mute = wm8350_mute,
1458 .trigger = wm8350_pcm_trigger,
1459 .set_fmt = wm8350_set_dai_fmt,
1460 .set_sysclk = wm8350_set_dai_sysclk,
1461 .set_pll = wm8350_set_fll,
1462 .set_clkdiv = wm8350_set_clkdiv,
1463 },
1464};
1465EXPORT_SYMBOL_GPL(wm8350_dai);
1466
1467struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1468 .probe = wm8350_probe,
1469 .remove = wm8350_remove,
1470 .suspend = wm8350_suspend,
1471 .resume = wm8350_resume,
1472};
1473EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1474
1475static int wm8350_codec_probe(struct platform_device *pdev)
1476{
1477 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1478 struct wm8350_data *priv;
1479 struct snd_soc_codec *codec;
1480 int ret, i;
1481
1482 if (wm8350->codec.platform_data == NULL) {
1483 dev_err(&pdev->dev, "No audio platform data supplied\n");
1484 return -EINVAL;
1485 }
1486
1487 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1488 if (priv == NULL)
1489 return -ENOMEM;
1490
1491 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1492 priv->supplies[i].supply = supply_names[i];
1493
1494 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1495 priv->supplies);
1496 if (ret != 0)
1497 goto err_priv;
1498
1499 codec = &priv->codec;
1500 wm8350->codec.codec = codec;
1501
1502 wm8350_dai.dev = &pdev->dev;
1503
1504 mutex_init(&codec->mutex);
1505 INIT_LIST_HEAD(&codec->dapm_widgets);
1506 INIT_LIST_HEAD(&codec->dapm_paths);
1507 codec->dev = &pdev->dev;
1508 codec->name = "WM8350";
1509 codec->owner = THIS_MODULE;
1510 codec->read = wm8350_codec_read;
1511 codec->write = wm8350_codec_write;
1512 codec->bias_level = SND_SOC_BIAS_OFF;
1513 codec->set_bias_level = wm8350_set_bias_level;
1514 codec->dai = &wm8350_dai;
1515 codec->num_dai = 1;
1516 codec->reg_cache_size = WM8350_MAX_REGISTER;
1517 codec->private_data = priv;
1518 codec->control_data = wm8350;
1519
1520 /* Put the codec into reset if it wasn't already */
1521 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1522
1523 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1524 ret = snd_soc_register_codec(codec);
1525 if (ret != 0)
1526 goto err_supply;
1527
1528 wm8350_codec = codec;
1529
1530 ret = snd_soc_register_dai(&wm8350_dai);
1531 if (ret != 0)
1532 goto err_codec;
1533 return 0;
1534
1535err_codec:
1536 snd_soc_unregister_codec(codec);
1537err_supply:
1538 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1539err_priv:
1540 kfree(priv);
1541 wm8350_codec = NULL;
1542 return ret;
1543}
1544
1545static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1546{
1547 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1548 struct snd_soc_codec *codec = wm8350->codec.codec;
1549 struct wm8350_data *priv = codec->private_data;
1550
1551 snd_soc_unregister_dai(&wm8350_dai);
1552 snd_soc_unregister_codec(codec);
1553 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1554 kfree(priv);
1555 wm8350_codec = NULL;
1556 return 0;
1557}
1558
1559static struct platform_driver wm8350_codec_driver = {
1560 .driver = {
1561 .name = "wm8350-codec",
1562 .owner = THIS_MODULE,
1563 },
1564 .probe = wm8350_codec_probe,
1565 .remove = __devexit_p(wm8350_codec_remove),
1566};
1567
1568static __init int wm8350_init(void)
1569{
1570 return platform_driver_register(&wm8350_codec_driver);
1571}
1572module_init(wm8350_init);
1573
1574static __exit void wm8350_exit(void)
1575{
1576 platform_driver_unregister(&wm8350_codec_driver);
1577}
1578module_exit(wm8350_exit);
1579
1580MODULE_DESCRIPTION("ASoC WM8350 driver");
1581MODULE_AUTHOR("Liam Girdwood");
1582MODULE_LICENSE("GPL");
1583MODULE_ALIAS("platform:wm8350-codec");
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
new file mode 100644
index 000000000000..cc2887aa6c38
--- /dev/null
+++ b/sound/soc/codecs/wm8350.h
@@ -0,0 +1,20 @@
1/*
2 * wm8350.h - WM8903 audio codec interface
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef _WM8350_H
13#define _WM8350_H
14
15#include <sound/soc.h>
16
17extern struct snd_soc_dai wm8350_dai;
18extern struct snd_soc_codec_device soc_codec_dev_wm8350;
19
20#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 9a37c8d95ed2..40f8238df717 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License version 2 as
@@ -18,6 +18,7 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/spi/spi.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
@@ -27,7 +28,6 @@
27 28
28#include "wm8510.h" 29#include "wm8510.h"
29 30
30#define AUDIO_NAME "wm8510"
31#define WM8510_VERSION "0.6" 31#define WM8510_VERSION "0.6"
32 32
33struct snd_soc_codec_device soc_codec_dev_wm8510; 33struct snd_soc_codec_device soc_codec_dev_wm8510;
@@ -55,6 +55,9 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
55 0x0001, 55 0x0001,
56}; 56};
57 57
58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10
60
58/* 61/*
59 * read wm8510 register cache 62 * read wm8510 register cache
60 */ 63 */
@@ -224,9 +227,9 @@ SND_SOC_DAPM_PGA("SpkN Out", WM8510_POWER3, 5, 0, NULL, 0),
224SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0), 227SND_SOC_DAPM_PGA("SpkP Out", WM8510_POWER3, 6, 0, NULL, 0),
225SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0), 228SND_SOC_DAPM_PGA("Mono Out", WM8510_POWER3, 7, 0, NULL, 0),
226 229
227SND_SOC_DAPM_PGA("Mic PGA", WM8510_POWER2, 2, 0, 230SND_SOC_DAPM_MIXER("Mic PGA", WM8510_POWER2, 2, 0,
228 &wm8510_micpga_controls[0], 231 &wm8510_micpga_controls[0],
229 ARRAY_SIZE(wm8510_micpga_controls)), 232 ARRAY_SIZE(wm8510_micpga_controls)),
230SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0, 233SND_SOC_DAPM_MIXER("Boost Mixer", WM8510_POWER2, 4, 0,
231 &wm8510_boost_controls[0], 234 &wm8510_boost_controls[0],
232 ARRAY_SIZE(wm8510_boost_controls)), 235 ARRAY_SIZE(wm8510_boost_controls)),
@@ -460,7 +463,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
460} 463}
461 464
462static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, 465static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
463 struct snd_pcm_hw_params *params) 466 struct snd_pcm_hw_params *params,
467 struct snd_soc_dai *dai)
464{ 468{
465 struct snd_soc_pcm_runtime *rtd = substream->private_data; 469 struct snd_soc_pcm_runtime *rtd = substream->private_data;
466 struct snd_soc_device *socdev = rtd->socdev; 470 struct snd_soc_device *socdev = rtd->socdev;
@@ -526,23 +530,35 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
526static int wm8510_set_bias_level(struct snd_soc_codec *codec, 530static int wm8510_set_bias_level(struct snd_soc_codec *codec,
527 enum snd_soc_bias_level level) 531 enum snd_soc_bias_level level)
528{ 532{
533 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3;
529 534
530 switch (level) { 535 switch (level) {
531 case SND_SOC_BIAS_ON: 536 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_PREPARE:
538 power1 |= 0x1; /* VMID 50k */
539 wm8510_write(codec, WM8510_POWER1, power1);
540 break;
541
537 case SND_SOC_BIAS_STANDBY: 542 case SND_SOC_BIAS_STANDBY:
543 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
544
545 if (codec->bias_level == SND_SOC_BIAS_OFF) {
546 /* Initial cap charge at VMID 5k */
547 wm8510_write(codec, WM8510_POWER1, power1 | 0x3);
548 mdelay(100);
549 }
550
551 power1 |= 0x2; /* VMID 500k */
552 wm8510_write(codec, WM8510_POWER1, power1);
538 break; 553 break;
554
539 case SND_SOC_BIAS_OFF: 555 case SND_SOC_BIAS_OFF:
540 /* everything off, dac mute, inactive */ 556 wm8510_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER1, 0x0); 557 wm8510_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER2, 0x0); 558 wm8510_write(codec, WM8510_POWER3, 0);
543 wm8510_write(codec, WM8510_POWER3, 0x0);
544 break; 559 break;
545 } 560 }
561
546 codec->bias_level = level; 562 codec->bias_level = level;
547 return 0; 563 return 0;
548} 564}
@@ -570,8 +586,6 @@ struct snd_soc_dai wm8510_dai = {
570 .formats = WM8510_FORMATS,}, 586 .formats = WM8510_FORMATS,},
571 .ops = { 587 .ops = {
572 .hw_params = wm8510_pcm_hw_params, 588 .hw_params = wm8510_pcm_hw_params,
573 },
574 .dai_ops = {
575 .digital_mute = wm8510_mute, 589 .digital_mute = wm8510_mute,
576 .set_fmt = wm8510_set_dai_fmt, 590 .set_fmt = wm8510_set_dai_fmt,
577 .set_clkdiv = wm8510_set_dai_clkdiv, 591 .set_clkdiv = wm8510_set_dai_clkdiv,
@@ -640,10 +654,11 @@ static int wm8510_init(struct snd_soc_device *socdev)
640 } 654 }
641 655
642 /* power on device */ 656 /* power on device */
657 codec->bias_level = SND_SOC_BIAS_OFF;
643 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 658 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
644 wm8510_add_controls(codec); 659 wm8510_add_controls(codec);
645 wm8510_add_widgets(codec); 660 wm8510_add_widgets(codec);
646 ret = snd_soc_register_card(socdev); 661 ret = snd_soc_init_card(socdev);
647 if (ret < 0) { 662 if (ret < 0) {
648 printk(KERN_ERR "wm8510: failed to register card\n"); 663 printk(KERN_ERR "wm8510: failed to register card\n");
649 goto card_err; 664 goto card_err;
@@ -747,6 +762,62 @@ err_driver:
747} 762}
748#endif 763#endif
749 764
765#if defined(CONFIG_SPI_MASTER)
766static int __devinit wm8510_spi_probe(struct spi_device *spi)
767{
768 struct snd_soc_device *socdev = wm8510_socdev;
769 struct snd_soc_codec *codec = socdev->codec;
770 int ret;
771
772 codec->control_data = spi;
773
774 ret = wm8510_init(socdev);
775 if (ret < 0)
776 dev_err(&spi->dev, "failed to initialise WM8510\n");
777
778 return ret;
779}
780
781static int __devexit wm8510_spi_remove(struct spi_device *spi)
782{
783 return 0;
784}
785
786static struct spi_driver wm8510_spi_driver = {
787 .driver = {
788 .name = "wm8510",
789 .bus = &spi_bus_type,
790 .owner = THIS_MODULE,
791 },
792 .probe = wm8510_spi_probe,
793 .remove = __devexit_p(wm8510_spi_remove),
794};
795
796static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
797{
798 struct spi_transfer t;
799 struct spi_message m;
800 u8 msg[2];
801
802 if (len <= 0)
803 return 0;
804
805 msg[0] = data[0];
806 msg[1] = data[1];
807
808 spi_message_init(&m);
809 memset(&t, 0, (sizeof t));
810
811 t.tx_buf = &msg[0];
812 t.len = len;
813
814 spi_message_add_tail(&t, &m);
815 spi_sync(spi, &m);
816
817 return len;
818}
819#endif /* CONFIG_SPI_MASTER */
820
750static int wm8510_probe(struct platform_device *pdev) 821static int wm8510_probe(struct platform_device *pdev)
751{ 822{
752 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 823 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -772,8 +843,14 @@ static int wm8510_probe(struct platform_device *pdev)
772 codec->hw_write = (hw_write_t)i2c_master_send; 843 codec->hw_write = (hw_write_t)i2c_master_send;
773 ret = wm8510_add_i2c_device(pdev, setup); 844 ret = wm8510_add_i2c_device(pdev, setup);
774 } 845 }
775#else 846#endif
776 /* Add other interfaces here */ 847#if defined(CONFIG_SPI_MASTER)
848 if (setup->spi) {
849 codec->hw_write = (hw_write_t)wm8510_spi_write;
850 ret = spi_register_driver(&wm8510_spi_driver);
851 if (ret != 0)
852 printk(KERN_ERR "can't add spi driver");
853 }
777#endif 854#endif
778 855
779 if (ret != 0) 856 if (ret != 0)
@@ -796,6 +873,9 @@ static int wm8510_remove(struct platform_device *pdev)
796 i2c_unregister_device(codec->control_data); 873 i2c_unregister_device(codec->control_data);
797 i2c_del_driver(&wm8510_i2c_driver); 874 i2c_del_driver(&wm8510_i2c_driver);
798#endif 875#endif
876#if defined(CONFIG_SPI_MASTER)
877 spi_unregister_driver(&wm8510_spi_driver);
878#endif
799 kfree(codec); 879 kfree(codec);
800 880
801 return 0; 881 return 0;
@@ -809,6 +889,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8510 = {
809}; 889};
810EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510); 890EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
811 891
892static int __init wm8510_modinit(void)
893{
894 return snd_soc_register_dai(&wm8510_dai);
895}
896module_init(wm8510_modinit);
897
898static void __exit wm8510_exit(void)
899{
900 snd_soc_unregister_dai(&wm8510_dai);
901}
902module_exit(wm8510_exit);
903
812MODULE_DESCRIPTION("ASoC WM8510 driver"); 904MODULE_DESCRIPTION("ASoC WM8510 driver");
813MODULE_AUTHOR("Liam Girdwood"); 905MODULE_AUTHOR("Liam Girdwood");
814MODULE_LICENSE("GPL"); 906MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8510.h b/sound/soc/codecs/wm8510.h
index c53683960456..bdefcf5c69ff 100644
--- a/sound/soc/codecs/wm8510.h
+++ b/sound/soc/codecs/wm8510.h
@@ -94,6 +94,7 @@
94#define WM8510_MCLKDIV_12 (7 << 5) 94#define WM8510_MCLKDIV_12 (7 << 5)
95 95
96struct wm8510_setup_data { 96struct wm8510_setup_data {
97 int spi;
97 int i2c_bus; 98 int i2c_bus;
98 unsigned short i2c_address; 99 unsigned short i2c_address;
99}; 100};
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index df1ffbe305bf..d004e5845298 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -36,7 +35,6 @@
36 35
37#include "wm8580.h" 36#include "wm8580.h"
38 37
39#define AUDIO_NAME "wm8580"
40#define WM8580_VERSION "0.1" 38#define WM8580_VERSION "0.1"
41 39
42struct pll_state { 40struct pll_state {
@@ -550,13 +548,13 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
550 * Set PCM DAI bit size and sample rate. 548 * Set PCM DAI bit size and sample rate.
551 */ 549 */
552static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, 550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
553 struct snd_pcm_hw_params *params) 551 struct snd_pcm_hw_params *params,
552 struct snd_soc_dai *dai)
554{ 553{
555 struct snd_soc_pcm_runtime *rtd = substream->private_data; 554 struct snd_soc_pcm_runtime *rtd = substream->private_data;
556 struct snd_soc_dai_link *dai = rtd->dai;
557 struct snd_soc_device *socdev = rtd->socdev; 555 struct snd_soc_device *socdev = rtd->socdev;
558 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
559 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id); 557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
560 558
561 paifb &= ~WM8580_AIF_LENGTH_MASK; 559 paifb &= ~WM8580_AIF_LENGTH_MASK;
562 /* bit size */ 560 /* bit size */
@@ -576,7 +574,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
576 return -EINVAL; 574 return -EINVAL;
577 } 575 }
578 576
579 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb); 577 wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
580 return 0; 578 return 0;
581} 579}
582 580
@@ -800,8 +798,6 @@ struct snd_soc_dai wm8580_dai[] = {
800 }, 798 },
801 .ops = { 799 .ops = {
802 .hw_params = wm8580_paif_hw_params, 800 .hw_params = wm8580_paif_hw_params,
803 },
804 .dai_ops = {
805 .set_fmt = wm8580_set_paif_dai_fmt, 801 .set_fmt = wm8580_set_paif_dai_fmt,
806 .set_clkdiv = wm8580_set_dai_clkdiv, 802 .set_clkdiv = wm8580_set_dai_clkdiv,
807 .set_pll = wm8580_set_dai_pll, 803 .set_pll = wm8580_set_dai_pll,
@@ -820,8 +816,6 @@ struct snd_soc_dai wm8580_dai[] = {
820 }, 816 },
821 .ops = { 817 .ops = {
822 .hw_params = wm8580_paif_hw_params, 818 .hw_params = wm8580_paif_hw_params,
823 },
824 .dai_ops = {
825 .set_fmt = wm8580_set_paif_dai_fmt, 819 .set_fmt = wm8580_set_paif_dai_fmt,
826 .set_clkdiv = wm8580_set_dai_clkdiv, 820 .set_clkdiv = wm8580_set_dai_clkdiv,
827 .set_pll = wm8580_set_dai_pll, 821 .set_pll = wm8580_set_dai_pll,
@@ -875,7 +869,7 @@ static int wm8580_init(struct snd_soc_device *socdev)
875 wm8580_add_controls(codec); 869 wm8580_add_controls(codec);
876 wm8580_add_widgets(codec); 870 wm8580_add_widgets(codec);
877 871
878 ret = snd_soc_register_card(socdev); 872 ret = snd_soc_init_card(socdev);
879 if (ret < 0) { 873 if (ret < 0) {
880 printk(KERN_ERR "wm8580: failed to register card\n"); 874 printk(KERN_ERR "wm8580: failed to register card\n");
881 goto card_err; 875 goto card_err;
@@ -902,85 +896,85 @@ static struct snd_soc_device *wm8580_socdev;
902 * low = 0x1a 896 * low = 0x1a
903 * high = 0x1b 897 * high = 0x1b
904 */ 898 */
905static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
906
907/* Magic definition of all other variables and things */
908I2C_CLIENT_INSMOD;
909 899
910static struct i2c_driver wm8580_i2c_driver; 900static int wm8580_i2c_probe(struct i2c_client *i2c,
911static struct i2c_client client_template; 901 const struct i2c_device_id *id)
912
913static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
914{ 902{
915 struct snd_soc_device *socdev = wm8580_socdev; 903 struct snd_soc_device *socdev = wm8580_socdev;
916 struct wm8580_setup_data *setup = socdev->codec_data;
917 struct snd_soc_codec *codec = socdev->codec; 904 struct snd_soc_codec *codec = socdev->codec;
918 struct i2c_client *i2c;
919 int ret; 905 int ret;
920 906
921 if (addr != setup->i2c_address)
922 return -ENODEV;
923
924 client_template.adapter = adap;
925 client_template.addr = addr;
926
927 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
928 if (i2c == NULL) {
929 kfree(codec);
930 return -ENOMEM;
931 }
932 i2c_set_clientdata(i2c, codec); 907 i2c_set_clientdata(i2c, codec);
933 codec->control_data = i2c; 908 codec->control_data = i2c;
934 909
935 ret = i2c_attach_client(i2c);
936 if (ret < 0) {
937 dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
938 goto err;
939 }
940
941 ret = wm8580_init(socdev); 910 ret = wm8580_init(socdev);
942 if (ret < 0) { 911 if (ret < 0)
943 dev_err(&i2c->dev, "failed to initialise WM8580\n"); 912 dev_err(&i2c->dev, "failed to initialise WM8580\n");
944 goto err;
945 }
946
947 return ret;
948
949err:
950 kfree(codec);
951 kfree(i2c);
952 return ret; 913 return ret;
953} 914}
954 915
955static int wm8580_i2c_detach(struct i2c_client *client) 916static int wm8580_i2c_remove(struct i2c_client *client)
956{ 917{
957 struct snd_soc_codec *codec = i2c_get_clientdata(client); 918 struct snd_soc_codec *codec = i2c_get_clientdata(client);
958 i2c_detach_client(client);
959 kfree(codec->reg_cache); 919 kfree(codec->reg_cache);
960 kfree(client);
961 return 0; 920 return 0;
962} 921}
963 922
964static int wm8580_i2c_attach(struct i2c_adapter *adap) 923static const struct i2c_device_id wm8580_i2c_id[] = {
965{ 924 { "wm8580", 0 },
966 return i2c_probe(adap, &addr_data, wm8580_codec_probe); 925 { }
967} 926};
927MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
968 928
969/* corgi i2c codec control layer */
970static struct i2c_driver wm8580_i2c_driver = { 929static struct i2c_driver wm8580_i2c_driver = {
971 .driver = { 930 .driver = {
972 .name = "WM8580 I2C Codec", 931 .name = "WM8580 I2C Codec",
973 .owner = THIS_MODULE, 932 .owner = THIS_MODULE,
974 }, 933 },
975 .attach_adapter = wm8580_i2c_attach, 934 .probe = wm8580_i2c_probe,
976 .detach_client = wm8580_i2c_detach, 935 .remove = wm8580_i2c_remove,
977 .command = NULL, 936 .id_table = wm8580_i2c_id,
978}; 937};
979 938
980static struct i2c_client client_template = { 939static int wm8580_add_i2c_device(struct platform_device *pdev,
981 .name = "WM8580", 940 const struct wm8580_setup_data *setup)
982 .driver = &wm8580_i2c_driver, 941{
983}; 942 struct i2c_board_info info;
943 struct i2c_adapter *adapter;
944 struct i2c_client *client;
945 int ret;
946
947 ret = i2c_add_driver(&wm8580_i2c_driver);
948 if (ret != 0) {
949 dev_err(&pdev->dev, "can't add i2c driver\n");
950 return ret;
951 }
952
953 memset(&info, 0, sizeof(struct i2c_board_info));
954 info.addr = setup->i2c_address;
955 strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
956
957 adapter = i2c_get_adapter(setup->i2c_bus);
958 if (!adapter) {
959 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
960 setup->i2c_bus);
961 goto err_driver;
962 }
963
964 client = i2c_new_device(adapter, &info);
965 i2c_put_adapter(adapter);
966 if (!client) {
967 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
968 (unsigned int)info.addr);
969 goto err_driver;
970 }
971
972 return 0;
973
974err_driver:
975 i2c_del_driver(&wm8580_i2c_driver);
976 return -ENODEV;
977}
984#endif 978#endif
985 979
986static int wm8580_probe(struct platform_device *pdev) 980static int wm8580_probe(struct platform_device *pdev)
@@ -1013,11 +1007,8 @@ static int wm8580_probe(struct platform_device *pdev)
1013 1007
1014#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1008#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1015 if (setup->i2c_address) { 1009 if (setup->i2c_address) {
1016 normal_i2c[0] = setup->i2c_address;
1017 codec->hw_write = (hw_write_t)i2c_master_send; 1010 codec->hw_write = (hw_write_t)i2c_master_send;
1018 ret = i2c_add_driver(&wm8580_i2c_driver); 1011 ret = wm8580_add_i2c_device(pdev, setup);
1019 if (ret != 0)
1020 printk(KERN_ERR "can't add i2c driver");
1021 } 1012 }
1022#else 1013#else
1023 /* Add other interfaces here */ 1014 /* Add other interfaces here */
@@ -1036,6 +1027,7 @@ static int wm8580_remove(struct platform_device *pdev)
1036 snd_soc_free_pcms(socdev); 1027 snd_soc_free_pcms(socdev);
1037 snd_soc_dapm_free(socdev); 1028 snd_soc_dapm_free(socdev);
1038#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1029#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1030 i2c_unregister_device(codec->control_data);
1039 i2c_del_driver(&wm8580_i2c_driver); 1031 i2c_del_driver(&wm8580_i2c_driver);
1040#endif 1032#endif
1041 kfree(codec->private_data); 1033 kfree(codec->private_data);
@@ -1050,6 +1042,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1050}; 1042};
1051EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); 1043EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1052 1044
1045static int __init wm8580_modinit(void)
1046{
1047 return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1048}
1049module_init(wm8580_modinit);
1050
1051static void __exit wm8580_exit(void)
1052{
1053 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1054}
1055module_exit(wm8580_exit);
1056
1053MODULE_DESCRIPTION("ASoC WM8580 driver"); 1057MODULE_DESCRIPTION("ASoC WM8580 driver");
1054MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1058MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1055MODULE_LICENSE("GPL"); 1059MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 589ddaba21d7..09e4422f6f2f 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -29,6 +29,7 @@
29#define WM8580_CLKSRC_NONE 5 29#define WM8580_CLKSRC_NONE 5
30 30
31struct wm8580_setup_data { 31struct wm8580_setup_data {
32 int i2c_bus;
32 unsigned short i2c_address; 33 unsigned short i2c_address;
33}; 34};
34 35
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
new file mode 100644
index 000000000000..80b11983e137
--- /dev/null
+++ b/sound/soc/codecs/wm8728.c
@@ -0,0 +1,585 @@
1/*
2 * wm8728.c -- WM8728 ALSA SoC Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/spi/spi.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#include <sound/tlv.h>
28
29#include "wm8728.h"
30
31struct snd_soc_codec_device soc_codec_dev_wm8728;
32
33/*
34 * We can't read the WM8728 register space so we cache them instead.
35 * Note that the defaults here aren't the physical defaults, we latch
36 * the volume update bits, mute the output and enable infinite zero
37 * detect.
38 */
39static const u16 wm8728_reg_defaults[] = {
40 0x1ff,
41 0x1ff,
42 0x001,
43 0x100,
44};
45
46static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 u16 *cache = codec->reg_cache;
50 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
51 return cache[reg];
52}
53
54static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
55 u16 reg, unsigned int value)
56{
57 u16 *cache = codec->reg_cache;
58 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
59 cache[reg] = value;
60}
61
62/*
63 * write to the WM8728 register space
64 */
65static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
66 unsigned int value)
67{
68 u8 data[2];
69
70 /* data is
71 * D15..D9 WM8728 register offset
72 * D8...D0 register data
73 */
74 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
75 data[1] = value & 0x00ff;
76
77 wm8728_write_reg_cache(codec, reg, value);
78
79 if (codec->hw_write(codec->control_data, data, 2) == 2)
80 return 0;
81 else
82 return -EIO;
83}
84
85static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
86
87static const struct snd_kcontrol_new wm8728_snd_controls[] = {
88
89SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
90 0, 255, 0, wm8728_tlv),
91
92SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
93};
94
95static int wm8728_add_controls(struct snd_soc_codec *codec)
96{
97 int err, i;
98
99 for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) {
100 err = snd_ctl_add(codec->card,
101 snd_soc_cnew(&wm8728_snd_controls[i],
102 codec, NULL));
103 if (err < 0)
104 return err;
105 }
106
107 return 0;
108}
109
110/*
111 * DAPM controls.
112 */
113static const struct snd_soc_dapm_widget wm8728_dapm_widgets[] = {
114SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
115SND_SOC_DAPM_OUTPUT("VOUTL"),
116SND_SOC_DAPM_OUTPUT("VOUTR"),
117};
118
119static const struct snd_soc_dapm_route intercon[] = {
120 {"VOUTL", NULL, "DAC"},
121 {"VOUTR", NULL, "DAC"},
122};
123
124static int wm8728_add_widgets(struct snd_soc_codec *codec)
125{
126 snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
127 ARRAY_SIZE(wm8728_dapm_widgets));
128
129 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
130
131 snd_soc_dapm_new_widgets(codec);
132
133 return 0;
134}
135
136static int wm8728_mute(struct snd_soc_dai *dai, int mute)
137{
138 struct snd_soc_codec *codec = dai->codec;
139 u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
140
141 if (mute)
142 wm8728_write(codec, WM8728_DACCTL, mute_reg | 1);
143 else
144 wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1);
145
146 return 0;
147}
148
149static int wm8728_hw_params(struct snd_pcm_substream *substream,
150 struct snd_pcm_hw_params *params,
151 struct snd_soc_dai *dai)
152{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_device *socdev = rtd->socdev;
155 struct snd_soc_codec *codec = socdev->codec;
156 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
157
158 dac &= ~0x18;
159
160 switch (params_format(params)) {
161 case SNDRV_PCM_FORMAT_S16_LE:
162 break;
163 case SNDRV_PCM_FORMAT_S20_3LE:
164 dac |= 0x10;
165 break;
166 case SNDRV_PCM_FORMAT_S24_LE:
167 dac |= 0x08;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 wm8728_write(codec, WM8728_DACCTL, dac);
174
175 return 0;
176}
177
178static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
179 unsigned int fmt)
180{
181 struct snd_soc_codec *codec = codec_dai->codec;
182 u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL);
183
184 /* Currently only I2S is supported by the driver, though the
185 * hardware is more flexible.
186 */
187 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
188 case SND_SOC_DAIFMT_I2S:
189 iface |= 1;
190 break;
191 default:
192 return -EINVAL;
193 }
194
195 /* The hardware only support full slave mode */
196 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
197 case SND_SOC_DAIFMT_CBS_CFS:
198 break;
199 default:
200 return -EINVAL;
201 }
202
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 iface &= ~0x22;
206 break;
207 case SND_SOC_DAIFMT_IB_NF:
208 iface |= 0x20;
209 iface &= ~0x02;
210 break;
211 case SND_SOC_DAIFMT_NB_IF:
212 iface |= 0x02;
213 iface &= ~0x20;
214 break;
215 case SND_SOC_DAIFMT_IB_IF:
216 iface |= 0x22;
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 wm8728_write(codec, WM8728_IFCTL, iface);
223 return 0;
224}
225
226static int wm8728_set_bias_level(struct snd_soc_codec *codec,
227 enum snd_soc_bias_level level)
228{
229 u16 reg;
230 int i;
231
232 switch (level) {
233 case SND_SOC_BIAS_ON:
234 case SND_SOC_BIAS_PREPARE:
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->bias_level == SND_SOC_BIAS_OFF) {
237 /* Power everything up... */
238 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
239 wm8728_write(codec, WM8728_DACCTL, reg & ~0x4);
240
241 /* ..then sync in the register cache. */
242 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
243 wm8728_write(codec, i,
244 wm8728_read_reg_cache(codec, i));
245 }
246 break;
247
248 case SND_SOC_BIAS_OFF:
249 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
250 wm8728_write(codec, WM8728_DACCTL, reg | 0x4);
251 break;
252 }
253 codec->bias_level = level;
254 return 0;
255}
256
257#define WM8728_RATES (SNDRV_PCM_RATE_8000_192000)
258
259#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
260 SNDRV_PCM_FMTBIT_S24_LE)
261
262struct snd_soc_dai wm8728_dai = {
263 .name = "WM8728",
264 .playback = {
265 .stream_name = "Playback",
266 .channels_min = 2,
267 .channels_max = 2,
268 .rates = WM8728_RATES,
269 .formats = WM8728_FORMATS,
270 },
271 .ops = {
272 .hw_params = wm8728_hw_params,
273 .digital_mute = wm8728_mute,
274 .set_fmt = wm8728_set_dai_fmt,
275 }
276};
277EXPORT_SYMBOL_GPL(wm8728_dai);
278
279static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
280{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->codec;
283
284 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
285
286 return 0;
287}
288
289static int wm8728_resume(struct platform_device *pdev)
290{
291 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
292 struct snd_soc_codec *codec = socdev->codec;
293
294 wm8728_set_bias_level(codec, codec->suspend_bias_level);
295
296 return 0;
297}
298
299/*
300 * initialise the WM8728 driver
301 * register the mixer and dsp interfaces with the kernel
302 */
303static int wm8728_init(struct snd_soc_device *socdev)
304{
305 struct snd_soc_codec *codec = socdev->codec;
306 int ret = 0;
307
308 codec->name = "WM8728";
309 codec->owner = THIS_MODULE;
310 codec->read = wm8728_read_reg_cache;
311 codec->write = wm8728_write;
312 codec->set_bias_level = wm8728_set_bias_level;
313 codec->dai = &wm8728_dai;
314 codec->num_dai = 1;
315 codec->bias_level = SND_SOC_BIAS_OFF;
316 codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
317 codec->reg_cache = kmemdup(wm8728_reg_defaults,
318 sizeof(wm8728_reg_defaults),
319 GFP_KERNEL);
320 if (codec->reg_cache == NULL)
321 return -ENOMEM;
322
323 /* register pcms */
324 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
325 if (ret < 0) {
326 printk(KERN_ERR "wm8728: failed to create pcms\n");
327 goto pcm_err;
328 }
329
330 /* power on device */
331 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
332
333 wm8728_add_controls(codec);
334 wm8728_add_widgets(codec);
335 ret = snd_soc_init_card(socdev);
336 if (ret < 0) {
337 printk(KERN_ERR "wm8728: failed to register card\n");
338 goto card_err;
339 }
340
341 return ret;
342
343card_err:
344 snd_soc_free_pcms(socdev);
345 snd_soc_dapm_free(socdev);
346pcm_err:
347 kfree(codec->reg_cache);
348 return ret;
349}
350
351static struct snd_soc_device *wm8728_socdev;
352
353#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
354
355/*
356 * WM8728 2 wire address is determined by GPIO5
357 * state during powerup.
358 * low = 0x1a
359 * high = 0x1b
360 */
361
362static int wm8728_i2c_probe(struct i2c_client *i2c,
363 const struct i2c_device_id *id)
364{
365 struct snd_soc_device *socdev = wm8728_socdev;
366 struct snd_soc_codec *codec = socdev->codec;
367 int ret;
368
369 i2c_set_clientdata(i2c, codec);
370 codec->control_data = i2c;
371
372 ret = wm8728_init(socdev);
373 if (ret < 0)
374 pr_err("failed to initialise WM8728\n");
375
376 return ret;
377}
378
379static int wm8728_i2c_remove(struct i2c_client *client)
380{
381 struct snd_soc_codec *codec = i2c_get_clientdata(client);
382 kfree(codec->reg_cache);
383 return 0;
384}
385
386static const struct i2c_device_id wm8728_i2c_id[] = {
387 { "wm8728", 0 },
388 { }
389};
390MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
391
392static struct i2c_driver wm8728_i2c_driver = {
393 .driver = {
394 .name = "WM8728 I2C Codec",
395 .owner = THIS_MODULE,
396 },
397 .probe = wm8728_i2c_probe,
398 .remove = wm8728_i2c_remove,
399 .id_table = wm8728_i2c_id,
400};
401
402static int wm8728_add_i2c_device(struct platform_device *pdev,
403 const struct wm8728_setup_data *setup)
404{
405 struct i2c_board_info info;
406 struct i2c_adapter *adapter;
407 struct i2c_client *client;
408 int ret;
409
410 ret = i2c_add_driver(&wm8728_i2c_driver);
411 if (ret != 0) {
412 dev_err(&pdev->dev, "can't add i2c driver\n");
413 return ret;
414 }
415
416 memset(&info, 0, sizeof(struct i2c_board_info));
417 info.addr = setup->i2c_address;
418 strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
419
420 adapter = i2c_get_adapter(setup->i2c_bus);
421 if (!adapter) {
422 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
423 setup->i2c_bus);
424 goto err_driver;
425 }
426
427 client = i2c_new_device(adapter, &info);
428 i2c_put_adapter(adapter);
429 if (!client) {
430 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
431 (unsigned int)info.addr);
432 goto err_driver;
433 }
434
435 return 0;
436
437err_driver:
438 i2c_del_driver(&wm8728_i2c_driver);
439 return -ENODEV;
440}
441#endif
442
443#if defined(CONFIG_SPI_MASTER)
444static int __devinit wm8728_spi_probe(struct spi_device *spi)
445{
446 struct snd_soc_device *socdev = wm8728_socdev;
447 struct snd_soc_codec *codec = socdev->codec;
448 int ret;
449
450 codec->control_data = spi;
451
452 ret = wm8728_init(socdev);
453 if (ret < 0)
454 dev_err(&spi->dev, "failed to initialise WM8728\n");
455
456 return ret;
457}
458
459static int __devexit wm8728_spi_remove(struct spi_device *spi)
460{
461 return 0;
462}
463
464static struct spi_driver wm8728_spi_driver = {
465 .driver = {
466 .name = "wm8728",
467 .bus = &spi_bus_type,
468 .owner = THIS_MODULE,
469 },
470 .probe = wm8728_spi_probe,
471 .remove = __devexit_p(wm8728_spi_remove),
472};
473
474static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
475{
476 struct spi_transfer t;
477 struct spi_message m;
478 u8 msg[2];
479
480 if (len <= 0)
481 return 0;
482
483 msg[0] = data[0];
484 msg[1] = data[1];
485
486 spi_message_init(&m);
487 memset(&t, 0, (sizeof t));
488
489 t.tx_buf = &msg[0];
490 t.len = len;
491
492 spi_message_add_tail(&t, &m);
493 spi_sync(spi, &m);
494
495 return len;
496}
497#endif /* CONFIG_SPI_MASTER */
498
499static int wm8728_probe(struct platform_device *pdev)
500{
501 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
502 struct wm8728_setup_data *setup;
503 struct snd_soc_codec *codec;
504 int ret = 0;
505
506 setup = socdev->codec_data;
507 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
508 if (codec == NULL)
509 return -ENOMEM;
510
511 socdev->codec = codec;
512 mutex_init(&codec->mutex);
513 INIT_LIST_HEAD(&codec->dapm_widgets);
514 INIT_LIST_HEAD(&codec->dapm_paths);
515
516 wm8728_socdev = socdev;
517 ret = -ENODEV;
518
519#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
520 if (setup->i2c_address) {
521 codec->hw_write = (hw_write_t)i2c_master_send;
522 ret = wm8728_add_i2c_device(pdev, setup);
523 }
524#endif
525#if defined(CONFIG_SPI_MASTER)
526 if (setup->spi) {
527 codec->hw_write = (hw_write_t)wm8728_spi_write;
528 ret = spi_register_driver(&wm8728_spi_driver);
529 if (ret != 0)
530 printk(KERN_ERR "can't add spi driver");
531 }
532#endif
533
534 if (ret != 0)
535 kfree(codec);
536
537 return ret;
538}
539
540/* power down chip */
541static int wm8728_remove(struct platform_device *pdev)
542{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 struct snd_soc_codec *codec = socdev->codec;
545
546 if (codec->control_data)
547 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
548
549 snd_soc_free_pcms(socdev);
550 snd_soc_dapm_free(socdev);
551#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
552 i2c_unregister_device(codec->control_data);
553 i2c_del_driver(&wm8728_i2c_driver);
554#endif
555#if defined(CONFIG_SPI_MASTER)
556 spi_unregister_driver(&wm8728_spi_driver);
557#endif
558 kfree(codec);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_wm8728 = {
564 .probe = wm8728_probe,
565 .remove = wm8728_remove,
566 .suspend = wm8728_suspend,
567 .resume = wm8728_resume,
568};
569EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
570
571static int __init wm8728_modinit(void)
572{
573 return snd_soc_register_dai(&wm8728_dai);
574}
575module_init(wm8728_modinit);
576
577static void __exit wm8728_exit(void)
578{
579 snd_soc_unregister_dai(&wm8728_dai);
580}
581module_exit(wm8728_exit);
582
583MODULE_DESCRIPTION("ASoC WM8728 driver");
584MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
585MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
new file mode 100644
index 000000000000..d269c132474b
--- /dev/null
+++ b/sound/soc/codecs/wm8728.h
@@ -0,0 +1,30 @@
1/*
2 * wm8728.h -- WM8728 ASoC codec driver
3 *
4 * Copyright 2008 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM8728_H
14#define _WM8728_H
15
16#define WM8728_DACLVOL 0x00
17#define WM8728_DACRVOL 0x01
18#define WM8728_DACCTL 0x02
19#define WM8728_IFCTL 0x03
20
21struct wm8728_setup_data {
22 int spi;
23 int i2c_bus;
24 unsigned short i2c_address;
25};
26
27extern struct snd_soc_dai wm8728_dai;
28extern struct snd_soc_codec_device soc_codec_dev_wm8728;
29
30#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7b64d9a7ff76..c444b9f2701e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8731.h" 30#include "wm8731.h"
31 31
32#define AUDIO_NAME "wm8731"
33#define WM8731_VERSION "0.13" 32#define WM8731_VERSION "0.13"
34 33
35struct snd_soc_codec_device soc_codec_dev_wm8731; 34struct snd_soc_codec_device soc_codec_dev_wm8731;
@@ -265,7 +264,8 @@ static inline int get_coeff(int mclk, int rate)
265} 264}
266 265
267static int wm8731_hw_params(struct snd_pcm_substream *substream, 266static int wm8731_hw_params(struct snd_pcm_substream *substream,
268 struct snd_pcm_hw_params *params) 267 struct snd_pcm_hw_params *params,
268 struct snd_soc_dai *dai)
269{ 269{
270 struct snd_soc_pcm_runtime *rtd = substream->private_data; 270 struct snd_soc_pcm_runtime *rtd = substream->private_data;
271 struct snd_soc_device *socdev = rtd->socdev; 271 struct snd_soc_device *socdev = rtd->socdev;
@@ -294,7 +294,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
294 return 0; 294 return 0;
295} 295}
296 296
297static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) 297static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
298 struct snd_soc_dai *dai)
298{ 299{
299 struct snd_soc_pcm_runtime *rtd = substream->private_data; 300 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct snd_soc_device *socdev = rtd->socdev; 301 struct snd_soc_device *socdev = rtd->socdev;
@@ -306,7 +307,8 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
306 return 0; 307 return 0;
307} 308}
308 309
309static void wm8731_shutdown(struct snd_pcm_substream *substream) 310static void wm8731_shutdown(struct snd_pcm_substream *substream,
311 struct snd_soc_dai *dai)
310{ 312{
311 struct snd_soc_pcm_runtime *rtd = substream->private_data; 313 struct snd_soc_pcm_runtime *rtd = substream->private_data;
312 struct snd_soc_device *socdev = rtd->socdev; 314 struct snd_soc_device *socdev = rtd->socdev;
@@ -462,8 +464,6 @@ struct snd_soc_dai wm8731_dai = {
462 .prepare = wm8731_pcm_prepare, 464 .prepare = wm8731_pcm_prepare,
463 .hw_params = wm8731_hw_params, 465 .hw_params = wm8731_hw_params,
464 .shutdown = wm8731_shutdown, 466 .shutdown = wm8731_shutdown,
465 },
466 .dai_ops = {
467 .digital_mute = wm8731_mute, 467 .digital_mute = wm8731_mute,
468 .set_sysclk = wm8731_set_dai_sysclk, 468 .set_sysclk = wm8731_set_dai_sysclk,
469 .set_fmt = wm8731_set_dai_fmt, 469 .set_fmt = wm8731_set_dai_fmt,
@@ -545,7 +545,7 @@ static int wm8731_init(struct snd_soc_device *socdev)
545 545
546 wm8731_add_controls(codec); 546 wm8731_add_controls(codec);
547 wm8731_add_widgets(codec); 547 wm8731_add_widgets(codec);
548 ret = snd_soc_register_card(socdev); 548 ret = snd_soc_init_card(socdev);
549 if (ret < 0) { 549 if (ret < 0) {
550 printk(KERN_ERR "wm8731: failed to register card\n"); 550 printk(KERN_ERR "wm8731: failed to register card\n");
551 goto card_err; 551 goto card_err;
@@ -793,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
793}; 793};
794EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 794EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
795 795
796static int __init wm8731_modinit(void)
797{
798 return snd_soc_register_dai(&wm8731_dai);
799}
800module_init(wm8731_modinit);
801
802static void __exit wm8731_exit(void)
803{
804 snd_soc_unregister_dai(&wm8731_dai);
805}
806module_exit(wm8731_exit);
807
796MODULE_DESCRIPTION("ASoC WM8731 driver"); 808MODULE_DESCRIPTION("ASoC WM8731 driver");
797MODULE_AUTHOR("Richard Purdie"); 809MODULE_AUTHOR("Richard Purdie");
798MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4892e398a598..5997fa68e0d5 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8750.h" 30#include "wm8750.h"
31 31
32#define AUDIO_NAME "WM8750"
33#define WM8750_VERSION "0.12" 32#define WM8750_VERSION "0.12"
34 33
35/* codec private data */ 34/* codec private data */
@@ -615,7 +614,8 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
615} 614}
616 615
617static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, 616static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
618 struct snd_pcm_hw_params *params) 617 struct snd_pcm_hw_params *params,
618 struct snd_soc_dai *dai)
619{ 619{
620 struct snd_soc_pcm_runtime *rtd = substream->private_data; 620 struct snd_soc_pcm_runtime *rtd = substream->private_data;
621 struct snd_soc_device *socdev = rtd->socdev; 621 struct snd_soc_device *socdev = rtd->socdev;
@@ -710,8 +710,6 @@ struct snd_soc_dai wm8750_dai = {
710 .formats = WM8750_FORMATS,}, 710 .formats = WM8750_FORMATS,},
711 .ops = { 711 .ops = {
712 .hw_params = wm8750_pcm_hw_params, 712 .hw_params = wm8750_pcm_hw_params,
713 },
714 .dai_ops = {
715 .digital_mute = wm8750_mute, 713 .digital_mute = wm8750_mute,
716 .set_fmt = wm8750_set_dai_fmt, 714 .set_fmt = wm8750_set_dai_fmt,
717 .set_sysclk = wm8750_set_dai_sysclk, 715 .set_sysclk = wm8750_set_dai_sysclk,
@@ -820,7 +818,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
820 818
821 wm8750_add_controls(codec); 819 wm8750_add_controls(codec);
822 wm8750_add_widgets(codec); 820 wm8750_add_widgets(codec);
823 ret = snd_soc_register_card(socdev); 821 ret = snd_soc_init_card(socdev);
824 if (ret < 0) { 822 if (ret < 0) {
825 printk(KERN_ERR "wm8750: failed to register card\n"); 823 printk(KERN_ERR "wm8750: failed to register card\n");
826 goto card_err; 824 goto card_err;
@@ -1087,6 +1085,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1087}; 1085};
1088EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 1086EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1089 1087
1088static int __init wm8750_modinit(void)
1089{
1090 return snd_soc_register_dai(&wm8750_dai);
1091}
1092module_init(wm8750_modinit);
1093
1094static void __exit wm8750_exit(void)
1095{
1096 snd_soc_unregister_dai(&wm8750_dai);
1097}
1098module_exit(wm8750_exit);
1099
1090MODULE_DESCRIPTION("ASoC WM8750 driver"); 1100MODULE_DESCRIPTION("ASoC WM8750 driver");
1091MODULE_AUTHOR("Liam Girdwood"); 1101MODULE_AUTHOR("Liam Girdwood");
1092MODULE_LICENSE("GPL"); 1102MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 8c4df44f3345..6c21b50c9375 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -2,8 +2,7 @@
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -40,6 +39,7 @@
40#include <linux/pm.h> 39#include <linux/pm.h>
41#include <linux/i2c.h> 40#include <linux/i2c.h>
42#include <linux/platform_device.h> 41#include <linux/platform_device.h>
42#include <linux/spi/spi.h>
43#include <sound/core.h> 43#include <sound/core.h>
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
@@ -51,7 +51,6 @@
51 51
52#include "wm8753.h" 52#include "wm8753.h"
53 53
54#define AUDIO_NAME "wm8753"
55#define WM8753_VERSION "0.16" 54#define WM8753_VERSION "0.16"
56 55
57static int caps_charge = 2000; 56static int caps_charge = 2000;
@@ -923,7 +922,8 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
923 * Set PCM DAI bit size and sample rate. 922 * Set PCM DAI bit size and sample rate.
924 */ 923 */
925static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, 924static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
926 struct snd_pcm_hw_params *params) 925 struct snd_pcm_hw_params *params,
926 struct snd_soc_dai *dai)
927{ 927{
928 struct snd_soc_pcm_runtime *rtd = substream->private_data; 928 struct snd_soc_pcm_runtime *rtd = substream->private_data;
929 struct snd_soc_device *socdev = rtd->socdev; 929 struct snd_soc_device *socdev = rtd->socdev;
@@ -1156,7 +1156,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1156 * Set PCM DAI bit size and sample rate. 1156 * Set PCM DAI bit size and sample rate.
1157 */ 1157 */
1158static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, 1158static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1159 struct snd_pcm_hw_params *params) 1159 struct snd_pcm_hw_params *params,
1160 struct snd_soc_dai *dai)
1160{ 1161{
1161 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1162 struct snd_soc_device *socdev = rtd->socdev; 1163 struct snd_soc_device *socdev = rtd->socdev;
@@ -1324,16 +1325,15 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1324 .channels_min = 1, 1325 .channels_min = 1,
1325 .channels_max = 2, 1326 .channels_max = 2,
1326 .rates = WM8753_RATES, 1327 .rates = WM8753_RATES,
1327 .formats = WM8753_FORMATS,}, 1328 .formats = WM8753_FORMATS},
1328 .capture = { /* dummy for fast DAI switching */ 1329 .capture = { /* dummy for fast DAI switching */
1329 .stream_name = "Capture", 1330 .stream_name = "Capture",
1330 .channels_min = 1, 1331 .channels_min = 1,
1331 .channels_max = 2, 1332 .channels_max = 2,
1332 .rates = WM8753_RATES, 1333 .rates = WM8753_RATES,
1333 .formats = WM8753_FORMATS,}, 1334 .formats = WM8753_FORMATS},
1334 .ops = { 1335 .ops = {
1335 .hw_params = wm8753_i2s_hw_params,}, 1336 .hw_params = wm8753_i2s_hw_params,
1336 .dai_ops = {
1337 .digital_mute = wm8753_mute, 1337 .digital_mute = wm8753_mute,
1338 .set_fmt = wm8753_mode1h_set_dai_fmt, 1338 .set_fmt = wm8753_mode1h_set_dai_fmt,
1339 .set_clkdiv = wm8753_set_dai_clkdiv, 1339 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1357,8 +1357,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1357 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1358 .formats = WM8753_FORMATS,}, 1358 .formats = WM8753_FORMATS,},
1359 .ops = { 1359 .ops = {
1360 .hw_params = wm8753_pcm_hw_params,}, 1360 .hw_params = wm8753_pcm_hw_params,
1361 .dai_ops = {
1362 .digital_mute = wm8753_mute, 1361 .digital_mute = wm8753_mute,
1363 .set_fmt = wm8753_mode1v_set_dai_fmt, 1362 .set_fmt = wm8753_mode1v_set_dai_fmt,
1364 .set_clkdiv = wm8753_set_dai_clkdiv, 1363 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1386,8 +1385,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1386 .rates = WM8753_RATES, 1385 .rates = WM8753_RATES,
1387 .formats = WM8753_FORMATS,}, 1386 .formats = WM8753_FORMATS,},
1388 .ops = { 1387 .ops = {
1389 .hw_params = wm8753_pcm_hw_params,}, 1388 .hw_params = wm8753_pcm_hw_params,
1390 .dai_ops = {
1391 .digital_mute = wm8753_mute, 1389 .digital_mute = wm8753_mute,
1392 .set_fmt = wm8753_mode2_set_dai_fmt, 1390 .set_fmt = wm8753_mode2_set_dai_fmt,
1393 .set_clkdiv = wm8753_set_dai_clkdiv, 1391 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1411,8 +1409,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1411 .rates = WM8753_RATES, 1409 .rates = WM8753_RATES,
1412 .formats = WM8753_FORMATS,}, 1410 .formats = WM8753_FORMATS,},
1413 .ops = { 1411 .ops = {
1414 .hw_params = wm8753_i2s_hw_params,}, 1412 .hw_params = wm8753_i2s_hw_params,
1415 .dai_ops = {
1416 .digital_mute = wm8753_mute, 1413 .digital_mute = wm8753_mute,
1417 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1414 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1418 .set_clkdiv = wm8753_set_dai_clkdiv, 1415 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1440,8 +1437,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1440 .rates = WM8753_RATES, 1437 .rates = WM8753_RATES,
1441 .formats = WM8753_FORMATS,}, 1438 .formats = WM8753_FORMATS,},
1442 .ops = { 1439 .ops = {
1443 .hw_params = wm8753_i2s_hw_params,}, 1440 .hw_params = wm8753_i2s_hw_params,
1444 .dai_ops = {
1445 .digital_mute = wm8753_mute, 1441 .digital_mute = wm8753_mute,
1446 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1442 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1447 .set_clkdiv = wm8753_set_dai_clkdiv, 1443 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1609,7 +1605,7 @@ static int wm8753_init(struct snd_soc_device *socdev)
1609 1605
1610 wm8753_add_controls(codec); 1606 wm8753_add_controls(codec);
1611 wm8753_add_widgets(codec); 1607 wm8753_add_widgets(codec);
1612 ret = snd_soc_register_card(socdev); 1608 ret = snd_soc_init_card(socdev);
1613 if (ret < 0) { 1609 if (ret < 0) {
1614 printk(KERN_ERR "wm8753: failed to register card\n"); 1610 printk(KERN_ERR "wm8753: failed to register card\n");
1615 goto card_err; 1611 goto card_err;
@@ -1719,6 +1715,63 @@ err_driver:
1719} 1715}
1720#endif 1716#endif
1721 1717
1718#if defined(CONFIG_SPI_MASTER)
1719static int __devinit wm8753_spi_probe(struct spi_device *spi)
1720{
1721 struct snd_soc_device *socdev = wm8753_socdev;
1722 struct snd_soc_codec *codec = socdev->codec;
1723 int ret;
1724
1725 codec->control_data = spi;
1726
1727 ret = wm8753_init(socdev);
1728 if (ret < 0)
1729 dev_err(&spi->dev, "failed to initialise WM8753\n");
1730
1731 return ret;
1732}
1733
1734static int __devexit wm8753_spi_remove(struct spi_device *spi)
1735{
1736 return 0;
1737}
1738
1739static struct spi_driver wm8753_spi_driver = {
1740 .driver = {
1741 .name = "wm8753",
1742 .bus = &spi_bus_type,
1743 .owner = THIS_MODULE,
1744 },
1745 .probe = wm8753_spi_probe,
1746 .remove = __devexit_p(wm8753_spi_remove),
1747};
1748
1749static int wm8753_spi_write(struct spi_device *spi, const char *data, int len)
1750{
1751 struct spi_transfer t;
1752 struct spi_message m;
1753 u8 msg[2];
1754
1755 if (len <= 0)
1756 return 0;
1757
1758 msg[0] = data[0];
1759 msg[1] = data[1];
1760
1761 spi_message_init(&m);
1762 memset(&t, 0, (sizeof t));
1763
1764 t.tx_buf = &msg[0];
1765 t.len = len;
1766
1767 spi_message_add_tail(&t, &m);
1768 spi_sync(spi, &m);
1769
1770 return len;
1771}
1772#endif
1773
1774
1722static int wm8753_probe(struct platform_device *pdev) 1775static int wm8753_probe(struct platform_device *pdev)
1723{ 1776{
1724 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1777 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
@@ -1753,8 +1806,14 @@ static int wm8753_probe(struct platform_device *pdev)
1753 codec->hw_write = (hw_write_t)i2c_master_send; 1806 codec->hw_write = (hw_write_t)i2c_master_send;
1754 ret = wm8753_add_i2c_device(pdev, setup); 1807 ret = wm8753_add_i2c_device(pdev, setup);
1755 } 1808 }
1756#else 1809#endif
1757 /* Add other interfaces here */ 1810#if defined(CONFIG_SPI_MASTER)
1811 if (setup->spi) {
1812 codec->hw_write = (hw_write_t)wm8753_spi_write;
1813 ret = spi_register_driver(&wm8753_spi_driver);
1814 if (ret != 0)
1815 printk(KERN_ERR "can't add spi driver");
1816 }
1758#endif 1817#endif
1759 1818
1760 if (ret != 0) { 1819 if (ret != 0) {
@@ -1798,6 +1857,9 @@ static int wm8753_remove(struct platform_device *pdev)
1798 i2c_unregister_device(codec->control_data); 1857 i2c_unregister_device(codec->control_data);
1799 i2c_del_driver(&wm8753_i2c_driver); 1858 i2c_del_driver(&wm8753_i2c_driver);
1800#endif 1859#endif
1860#if defined(CONFIG_SPI_MASTER)
1861 spi_unregister_driver(&wm8753_spi_driver);
1862#endif
1801 kfree(codec->private_data); 1863 kfree(codec->private_data);
1802 kfree(codec); 1864 kfree(codec);
1803 1865
@@ -1812,6 +1874,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1812}; 1874};
1813EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); 1875EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1814 1876
1877static int __init wm8753_modinit(void)
1878{
1879 return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1880}
1881module_init(wm8753_modinit);
1882
1883static void __exit wm8753_exit(void)
1884{
1885 snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1886}
1887module_exit(wm8753_exit);
1888
1815MODULE_DESCRIPTION("ASoC WM8753 driver"); 1889MODULE_DESCRIPTION("ASoC WM8753 driver");
1816MODULE_AUTHOR("Liam Girdwood"); 1890MODULE_AUTHOR("Liam Girdwood");
1817MODULE_LICENSE("GPL"); 1891MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.h b/sound/soc/codecs/wm8753.h
index 7defde069f1d..f55704ce931b 100644
--- a/sound/soc/codecs/wm8753.h
+++ b/sound/soc/codecs/wm8753.h
@@ -2,8 +2,7 @@
2 * wm8753.h -- audio driver for WM8753 2 * wm8753.h -- audio driver for WM8753
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -79,6 +78,7 @@
79#define WM8753_ADCTL2 0x3f 78#define WM8753_ADCTL2 0x3f
80 79
81struct wm8753_setup_data { 80struct wm8753_setup_data {
81 int spi;
82 int i2c_bus; 82 int i2c_bus;
83 unsigned short i2c_address; 83 unsigned short i2c_address;
84}; 84};
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 0b8c6d38b48f..6767de10ded0 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/moduleparam.h> 20#include <linux/moduleparam.h>
21#include <linux/version.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/init.h> 22#include <linux/init.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
@@ -139,6 +138,10 @@
139struct snd_soc_codec_device soc_codec_dev_wm8900; 138struct snd_soc_codec_device soc_codec_dev_wm8900;
140 139
141struct wm8900_priv { 140struct wm8900_priv {
141 struct snd_soc_codec codec;
142
143 u16 reg_cache[WM8900_MAXREG];
144
142 u32 fll_in; /* FLL input frequency */ 145 u32 fll_in; /* FLL input frequency */
143 u32 fll_out; /* FLL output frequency */ 146 u32 fll_out; /* FLL output frequency */
144}; 147};
@@ -728,7 +731,8 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
728} 731}
729 732
730static int wm8900_hw_params(struct snd_pcm_substream *substream, 733static int wm8900_hw_params(struct snd_pcm_substream *substream,
731 struct snd_pcm_hw_params *params) 734 struct snd_pcm_hw_params *params,
735 struct snd_soc_dai *dai)
732{ 736{
733 struct snd_soc_pcm_runtime *rtd = substream->private_data; 737 struct snd_soc_pcm_runtime *rtd = substream->private_data;
734 struct snd_soc_device *socdev = rtd->socdev; 738 struct snd_soc_device *socdev = rtd->socdev;
@@ -1118,8 +1122,6 @@ struct snd_soc_dai wm8900_dai = {
1118 }, 1122 },
1119 .ops = { 1123 .ops = {
1120 .hw_params = wm8900_hw_params, 1124 .hw_params = wm8900_hw_params,
1121 },
1122 .dai_ops = {
1123 .set_clkdiv = wm8900_set_dai_clkdiv, 1125 .set_clkdiv = wm8900_set_dai_clkdiv,
1124 .set_pll = wm8900_set_dai_pll, 1126 .set_pll = wm8900_set_dai_pll,
1125 .set_fmt = wm8900_set_dai_fmt, 1127 .set_fmt = wm8900_set_dai_fmt,
@@ -1284,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
1284 return 0; 1286 return 0;
1285} 1287}
1286 1288
1287/* 1289static struct snd_soc_codec *wm8900_codec;
1288 * initialise the WM8900 driver 1290
1289 * register the mixer and dsp interfaces with the kernel 1291static int wm8900_i2c_probe(struct i2c_client *i2c,
1290 */ 1292 const struct i2c_device_id *id)
1291static int wm8900_init(struct snd_soc_device *socdev)
1292{ 1293{
1293 struct snd_soc_codec *codec = socdev->codec; 1294 struct wm8900_priv *wm8900;
1294 int ret = 0; 1295 struct snd_soc_codec *codec;
1295 unsigned int reg; 1296 unsigned int reg;
1296 struct i2c_client *i2c_client = socdev->codec->control_data; 1297 int ret;
1298
1299 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1300 if (wm8900 == NULL)
1301 return -ENOMEM;
1302
1303 codec = &wm8900->codec;
1304 codec->private_data = wm8900;
1305 codec->reg_cache = &wm8900->reg_cache[0];
1306 codec->reg_cache_size = WM8900_MAXREG;
1307
1308 mutex_init(&codec->mutex);
1309 INIT_LIST_HEAD(&codec->dapm_widgets);
1310 INIT_LIST_HEAD(&codec->dapm_paths);
1297 1311
1298 codec->name = "WM8900"; 1312 codec->name = "WM8900";
1299 codec->owner = THIS_MODULE; 1313 codec->owner = THIS_MODULE;
@@ -1301,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
1301 codec->write = wm8900_write; 1315 codec->write = wm8900_write;
1302 codec->dai = &wm8900_dai; 1316 codec->dai = &wm8900_dai;
1303 codec->num_dai = 1; 1317 codec->num_dai = 1;
1304 codec->reg_cache_size = WM8900_MAXREG; 1318 codec->hw_write = (hw_write_t)i2c_master_send;
1305 codec->reg_cache = kmemdup(wm8900_reg_defaults, 1319 codec->control_data = i2c;
1306 sizeof(wm8900_reg_defaults), GFP_KERNEL); 1320 codec->set_bias_level = wm8900_set_bias_level;
1307 1321 codec->dev = &i2c->dev;
1308 if (codec->reg_cache == NULL)
1309 return -ENOMEM;
1310 1322
1311 reg = wm8900_read(codec, WM8900_REG_ID); 1323 reg = wm8900_read(codec, WM8900_REG_ID);
1312 if (reg != 0x8900) { 1324 if (reg != 0x8900) {
1313 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n", 1325 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1314 reg); 1326 ret = -ENODEV;
1315 return -ENODEV; 1327 goto err;
1316 }
1317
1318 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1319 if (codec->private_data == NULL) {
1320 ret = -ENOMEM;
1321 goto priv_err;
1322 } 1328 }
1323 1329
1324 /* Read back from the chip */ 1330 /* Read back from the chip */
1325 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1331 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1326 reg = (reg >> 12) & 0xf; 1332 reg = (reg >> 12) & 0xf;
1327 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg); 1333 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1328 1334
1329 wm8900_reset(codec); 1335 wm8900_reset(codec);
1330 1336
1337 /* Turn the chip on */
1338 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339
1331 /* Latch the volume update bits */ 1340 /* Latch the volume update bits */
1332 wm8900_write(codec, WM8900_REG_LINVOL, 1341 wm8900_write(codec, WM8900_REG_LINVOL,
1333 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1342 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1353,160 +1362,98 @@ static int wm8900_init(struct snd_soc_device *socdev)
1353 /* Set the DAC and mixer output bias */ 1362 /* Set the DAC and mixer output bias */
1354 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1363 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1355 1364
1356 /* Register pcms */ 1365 wm8900_dai.dev = &i2c->dev;
1357 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1358 if (ret < 0) {
1359 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1360 goto pcm_err;
1361 }
1362
1363 /* Turn the chip on */
1364 codec->bias_level = SND_SOC_BIAS_OFF;
1365 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1366
1367 wm8900_add_controls(codec);
1368 wm8900_add_widgets(codec);
1369
1370 ret = snd_soc_register_card(socdev);
1371 if (ret < 0) {
1372 dev_err(&i2c_client->dev, "Failed to register card\n");
1373 goto card_err;
1374 }
1375 return ret;
1376
1377card_err:
1378 snd_soc_free_pcms(socdev);
1379 snd_soc_dapm_free(socdev);
1380pcm_err:
1381 kfree(codec->reg_cache);
1382priv_err:
1383 kfree(codec->private_data);
1384 return ret;
1385}
1386 1366
1387static struct snd_soc_device *wm8900_socdev; 1367 wm8900_codec = codec;
1388 1368
1389#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1369 ret = snd_soc_register_codec(codec);
1390 1370 if (ret != 0) {
1391static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 1371 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1392
1393/* Magic definition of all other variables and things */
1394I2C_CLIENT_INSMOD;
1395
1396static struct i2c_driver wm8900_i2c_driver;
1397static struct i2c_client client_template;
1398
1399/* If the i2c layer weren't so broken, we could pass this kind of data
1400 around */
1401static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1402{
1403 struct snd_soc_device *socdev = wm8900_socdev;
1404 struct wm8900_setup_data *setup = socdev->codec_data;
1405 struct snd_soc_codec *codec = socdev->codec;
1406 struct i2c_client *i2c;
1407 int ret;
1408
1409 if (addr != setup->i2c_address)
1410 return -ENODEV;
1411
1412 dev_err(&adap->dev, "Probe on %x\n", addr);
1413
1414 client_template.adapter = adap;
1415 client_template.addr = addr;
1416
1417 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1418 if (i2c == NULL) {
1419 kfree(codec);
1420 return -ENOMEM;
1421 }
1422 i2c_set_clientdata(i2c, codec);
1423 codec->control_data = i2c;
1424
1425 ret = i2c_attach_client(i2c);
1426 if (ret < 0) {
1427 dev_err(&adap->dev,
1428 "failed to attach codec at addr %x\n", addr);
1429 goto err; 1372 goto err;
1430 } 1373 }
1431 1374
1432 ret = wm8900_init(socdev); 1375 ret = snd_soc_register_dai(&wm8900_dai);
1433 if (ret < 0) { 1376 if (ret != 0) {
1434 dev_err(&adap->dev, "failed to initialise WM8900\n"); 1377 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1435 goto err; 1378 goto err_codec;
1436 } 1379 }
1380
1437 return ret; 1381 return ret;
1438 1382
1383err_codec:
1384 snd_soc_unregister_codec(codec);
1439err: 1385err:
1440 kfree(codec); 1386 kfree(wm8900);
1441 kfree(i2c); 1387 wm8900_codec = NULL;
1442 return ret; 1388 return ret;
1443} 1389}
1444 1390
1445static int wm8900_i2c_detach(struct i2c_client *client) 1391static int wm8900_i2c_remove(struct i2c_client *client)
1446{ 1392{
1447 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1393 snd_soc_unregister_dai(&wm8900_dai);
1448 i2c_detach_client(client); 1394 snd_soc_unregister_codec(wm8900_codec);
1449 kfree(codec->reg_cache); 1395
1450 kfree(client); 1396 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1397
1398 wm8900_dai.dev = NULL;
1399 kfree(wm8900_codec->private_data);
1400 wm8900_codec = NULL;
1401
1451 return 0; 1402 return 0;
1452} 1403}
1453 1404
1454static int wm8900_i2c_attach(struct i2c_adapter *adap) 1405static const struct i2c_device_id wm8900_i2c_id[] = {
1455{ 1406 { "wm8900", 0 },
1456 return i2c_probe(adap, &addr_data, wm8900_codec_probe); 1407 { }
1457} 1408};
1409MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1458 1410
1459/* corgi i2c codec control layer */
1460static struct i2c_driver wm8900_i2c_driver = { 1411static struct i2c_driver wm8900_i2c_driver = {
1461 .driver = { 1412 .driver = {
1462 .name = "WM8900 I2C codec", 1413 .name = "WM8900",
1463 .owner = THIS_MODULE, 1414 .owner = THIS_MODULE,
1464 }, 1415 },
1465 .attach_adapter = wm8900_i2c_attach, 1416 .probe = wm8900_i2c_probe,
1466 .detach_client = wm8900_i2c_detach, 1417 .remove = wm8900_i2c_remove,
1467 .command = NULL, 1418 .id_table = wm8900_i2c_id,
1468};
1469
1470static struct i2c_client client_template = {
1471 .name = "WM8900",
1472 .driver = &wm8900_i2c_driver,
1473}; 1419};
1474#endif
1475 1420
1476static int wm8900_probe(struct platform_device *pdev) 1421static int wm8900_probe(struct platform_device *pdev)
1477{ 1422{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct wm8900_setup_data *setup;
1480 struct snd_soc_codec *codec; 1424 struct snd_soc_codec *codec;
1481 int ret = 0; 1425 int ret = 0;
1482 1426
1483 dev_info(&pdev->dev, "WM8900 Audio Codec\n"); 1427 if (!wm8900_codec) {
1484 1428 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1485 setup = socdev->codec_data; 1429 return -ENODEV;
1486 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1430 }
1487 if (codec == NULL)
1488 return -ENOMEM;
1489
1490 mutex_init(&codec->mutex);
1491 INIT_LIST_HEAD(&codec->dapm_widgets);
1492 INIT_LIST_HEAD(&codec->dapm_paths);
1493 1431
1432 codec = wm8900_codec;
1494 socdev->codec = codec; 1433 socdev->codec = codec;
1495 1434
1496 codec->set_bias_level = wm8900_set_bias_level; 1435 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1439 goto pcm_err;
1440 }
1497 1441
1498 wm8900_socdev = socdev; 1442 wm8900_add_controls(codec);
1499#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1443 wm8900_add_widgets(codec);
1500 if (setup->i2c_address) { 1444
1501 normal_i2c[0] = setup->i2c_address; 1445 ret = snd_soc_init_card(socdev);
1502 codec->hw_write = (hw_write_t)i2c_master_send; 1446 if (ret < 0) {
1503 ret = i2c_add_driver(&wm8900_i2c_driver); 1447 dev_err(&pdev->dev, "Failed to register card\n");
1504 if (ret != 0) 1448 goto card_err;
1505 printk(KERN_ERR "can't add i2c driver");
1506 } 1449 }
1507#else 1450
1508#error Non-I2C interfaces not yet supported 1451 return ret;
1509#endif 1452
1453card_err:
1454 snd_soc_free_pcms(socdev);
1455 snd_soc_dapm_free(socdev);
1456pcm_err:
1510 return ret; 1457 return ret;
1511} 1458}
1512 1459
@@ -1514,17 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
1514static int wm8900_remove(struct platform_device *pdev) 1461static int wm8900_remove(struct platform_device *pdev)
1515{ 1462{
1516 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1517 struct snd_soc_codec *codec = socdev->codec;
1518
1519 if (codec->control_data)
1520 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1521 1464
1522 snd_soc_free_pcms(socdev); 1465 snd_soc_free_pcms(socdev);
1523 snd_soc_dapm_free(socdev); 1466 snd_soc_dapm_free(socdev);
1524#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1525 i2c_del_driver(&wm8900_i2c_driver);
1526#endif
1527 kfree(codec);
1528 1467
1529 return 0; 1468 return 0;
1530} 1469}
@@ -1537,6 +1476,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1537}; 1476};
1538EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900); 1477EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1539 1478
1479static int __init wm8900_modinit(void)
1480{
1481 return i2c_add_driver(&wm8900_i2c_driver);
1482}
1483module_init(wm8900_modinit);
1484
1485static void __exit wm8900_exit(void)
1486{
1487 i2c_del_driver(&wm8900_i2c_driver);
1488}
1489module_exit(wm8900_exit);
1490
1540MODULE_DESCRIPTION("ASoC WM8900 driver"); 1491MODULE_DESCRIPTION("ASoC WM8900 driver");
1541MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 1492MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1542MODULE_LICENSE("GPL"); 1493MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index ba450d99e902..fd15007d10c7 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,12 +52,6 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai; 55extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900; 56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63 57
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index a3f54ec4226e..bde74546db4a 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -33,19 +33,6 @@
33 33
34#include "wm8903.h" 34#include "wm8903.h"
35 35
36struct wm8903_priv {
37 int sysclk;
38
39 /* Reference counts */
40 int charge_pump_users;
41 int class_w_users;
42 int playback_active;
43 int capture_active;
44
45 struct snd_pcm_substream *master_substream;
46 struct snd_pcm_substream *slave_substream;
47};
48
49/* Register defaults at reset */ 36/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = { 37static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */ 38 0x8903, /* R0 - SW Reset and ID */
@@ -223,6 +210,23 @@ static u16 wm8903_reg_defaults[] = {
223 0x0000, /* R172 - Analogue Output Bias 0 */ 210 0x0000, /* R172 - Analogue Output Bias 0 */
224}; 211};
225 212
213struct wm8903_priv {
214 struct snd_soc_codec codec;
215 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
216
217 int sysclk;
218
219 /* Reference counts */
220 int charge_pump_users;
221 int class_w_users;
222 int playback_active;
223 int capture_active;
224
225 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream;
227};
228
229
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec, 230static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg) 231 unsigned int reg)
228{ 232{
@@ -360,6 +364,8 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
360static void wm8903_reset(struct snd_soc_codec *codec) 364static void wm8903_reset(struct snd_soc_codec *codec)
361{ 365{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0); 366 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
367 memcpy(codec->reg_cache, wm8903_reg_defaults,
368 sizeof(wm8903_reg_defaults));
363} 369}
364 370
365#define WM8903_OUTPUT_SHORT 0x8 371#define WM8903_OUTPUT_SHORT 0x8
@@ -392,6 +398,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
392 break; 398 break;
393 default: 399 default:
394 BUG(); 400 BUG();
401 return -EINVAL; /* Spurious warning from some compilers */
395 } 402 }
396 403
397 switch (w->shift) { 404 switch (w->shift) {
@@ -403,6 +410,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
403 break; 410 break;
404 default: 411 default:
405 BUG(); 412 BUG();
413 return -EINVAL; /* Spurious warning from some compilers */
406 } 414 }
407 415
408 if (event & SND_SOC_DAPM_PRE_PMU) { 416 if (event & SND_SOC_DAPM_PRE_PMU) {
@@ -653,14 +661,14 @@ static const struct snd_kcontrol_new wm8903_snd_controls[] = {
653 661
654/* Input PGAs - No TLV since the scale depends on PGA mode */ 662/* Input PGAs - No TLV since the scale depends on PGA mode */
655SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0, 663SOC_SINGLE("Left Input PGA Switch", WM8903_ANALOGUE_LEFT_INPUT_0,
656 7, 1, 0), 664 7, 1, 1),
657SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0, 665SOC_SINGLE("Left Input PGA Volume", WM8903_ANALOGUE_LEFT_INPUT_0,
658 0, 31, 0), 666 0, 31, 0),
659SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1, 667SOC_SINGLE("Left Input PGA Common Mode Switch", WM8903_ANALOGUE_LEFT_INPUT_1,
660 6, 1, 0), 668 6, 1, 0),
661 669
662SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0, 670SOC_SINGLE("Right Input PGA Switch", WM8903_ANALOGUE_RIGHT_INPUT_0,
663 7, 1, 0), 671 7, 1, 1),
664SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0, 672SOC_SINGLE("Right Input PGA Volume", WM8903_ANALOGUE_RIGHT_INPUT_0,
665 0, 31, 0), 673 0, 31, 0),
666SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, 674SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
@@ -773,14 +781,14 @@ static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 781SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
774SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 782SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
775SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), 783SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
776SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), 784SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0),
777}; 785};
778 786
779static const struct snd_kcontrol_new right_output_mixer[] = { 787static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0), 788SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
781SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0), 789SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
782SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0), 790SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
783SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0), 791SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 0, 1, 0),
784}; 792};
785 793
786static const struct snd_kcontrol_new left_speaker_mixer[] = { 794static const struct snd_kcontrol_new left_speaker_mixer[] = {
@@ -788,7 +796,7 @@ SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
788SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0), 796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
789SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0), 797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
790SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 798SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0), 799 0, 1, 0),
792}; 800};
793 801
794static const struct snd_kcontrol_new right_speaker_mixer[] = { 802static const struct snd_kcontrol_new right_speaker_mixer[] = {
@@ -797,7 +805,7 @@ SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 805SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0), 806 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 807SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0), 808 0, 1, 0),
801}; 809};
802 810
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = { 811static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
@@ -989,6 +997,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
989 997
990 case SND_SOC_BIAS_STANDBY: 998 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) { 999 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1000 wm8903_write(codec, WM8903_CLOCK_RATES_2,
1001 WM8903_CLK_SYS_ENA);
1002
992 wm8903_run_sequence(codec, 0); 1003 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache); 1004 wm8903_sync_reg_cache(codec, codec->reg_cache);
994 1005
@@ -1019,6 +1030,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1019 1030
1020 case SND_SOC_BIAS_OFF: 1031 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32); 1032 wm8903_run_sequence(codec, 32);
1033 reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
1034 reg &= ~WM8903_CLK_SYS_ENA;
1035 wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
1022 break; 1036 break;
1023 } 1037 }
1024 1038
@@ -1257,7 +1271,8 @@ static struct {
1257 { 0, 0 }, 1271 { 0, 0 },
1258}; 1272};
1259 1273
1260static int wm8903_startup(struct snd_pcm_substream *substream) 1274static int wm8903_startup(struct snd_pcm_substream *substream,
1275 struct snd_soc_dai *dai)
1261{ 1276{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev; 1278 struct snd_soc_device *socdev = rtd->socdev;
@@ -1298,7 +1313,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream)
1298 return 0; 1313 return 0;
1299} 1314}
1300 1315
1301static void wm8903_shutdown(struct snd_pcm_substream *substream) 1316static void wm8903_shutdown(struct snd_pcm_substream *substream,
1317 struct snd_soc_dai *dai)
1302{ 1318{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1319 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev; 1320 struct snd_soc_device *socdev = rtd->socdev;
@@ -1317,7 +1333,8 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream)
1317} 1333}
1318 1334
1319static int wm8903_hw_params(struct snd_pcm_substream *substream, 1335static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params) 1336 struct snd_pcm_hw_params *params,
1337 struct snd_soc_dai *dai)
1321{ 1338{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1339 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev; 1340 struct snd_soc_device *socdev = rtd->socdev;
@@ -1515,8 +1532,6 @@ struct snd_soc_dai wm8903_dai = {
1515 .startup = wm8903_startup, 1532 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown, 1533 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params, 1534 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute, 1535 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt, 1536 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk 1537 .set_sysclk = wm8903_set_dai_sysclk
@@ -1560,39 +1575,48 @@ static int wm8903_resume(struct platform_device *pdev)
1560 return 0; 1575 return 0;
1561} 1576}
1562 1577
1563/* 1578static struct snd_soc_codec *wm8903_codec;
1564 * initialise the WM8903 driver 1579
1565 * register the mixer and dsp interfaces with the kernel 1580static int wm8903_i2c_probe(struct i2c_client *i2c,
1566 */ 1581 const struct i2c_device_id *id)
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{ 1582{
1569 struct snd_soc_codec *codec = socdev->codec; 1583 struct wm8903_priv *wm8903;
1570 struct i2c_client *i2c = codec->control_data; 1584 struct snd_soc_codec *codec;
1571 int ret = 0; 1585 int ret;
1572 u16 val; 1586 u16 val;
1573 1587
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID); 1588 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1589 if (wm8903 == NULL)
1576 dev_err(&i2c->dev, 1590 return -ENOMEM;
1577 "Device with ID register %x is not a WM8903\n", val); 1591
1578 return -ENODEV; 1592 codec = &wm8903->codec;
1579 }
1580 1593
1594 mutex_init(&codec->mutex);
1595 INIT_LIST_HEAD(&codec->dapm_widgets);
1596 INIT_LIST_HEAD(&codec->dapm_paths);
1597
1598 codec->dev = &i2c->dev;
1581 codec->name = "WM8903"; 1599 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE; 1600 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read; 1601 codec->read = wm8903_read;
1584 codec->write = wm8903_write; 1602 codec->write = wm8903_write;
1603 codec->hw_write = (hw_write_t)i2c_master_send;
1585 codec->bias_level = SND_SOC_BIAS_OFF; 1604 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level; 1605 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai; 1606 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1; 1607 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults); 1608 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults, 1609 codec->reg_cache = &wm8903->reg_cache[0];
1591 sizeof(wm8903_reg_defaults), 1610 codec->private_data = wm8903;
1592 GFP_KERNEL); 1611
1593 if (codec->reg_cache == NULL) { 1612 i2c_set_clientdata(i2c, codec);
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n"); 1613 codec->control_data = i2c;
1595 return -ENOMEM; 1614
1615 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1616 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1617 dev_err(&i2c->dev,
1618 "Device with ID register %x is not a WM8903\n", val);
1619 return -ENODEV;
1596 } 1620 }
1597 1621
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER); 1622 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
@@ -1601,16 +1625,6 @@ static int wm8903_init(struct snd_soc_device *socdev)
1601 1625
1602 wm8903_reset(codec); 1626 wm8903_reset(codec);
1603 1627
1604 /* register pcms */
1605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1606 if (ret < 0) {
1607 dev_err(&i2c->dev, "failed to create pcms\n");
1608 goto pcm_err;
1609 }
1610
1611 /* SYSCLK is required for pretty much anything */
1612 wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
1613
1614 /* power on device */ 1628 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1629 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616 1630
@@ -1645,47 +1659,45 @@ static int wm8903_init(struct snd_soc_device *socdev)
1645 val |= WM8903_DAC_MUTEMODE; 1659 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val); 1660 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647 1661
1648 wm8903_add_controls(codec); 1662 wm8903_dai.dev = &i2c->dev;
1649 wm8903_add_widgets(codec); 1663 wm8903_codec = codec;
1650 ret = snd_soc_register_card(socdev); 1664
1651 if (ret < 0) { 1665 ret = snd_soc_register_codec(codec);
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n"); 1666 if (ret != 0) {
1653 goto card_err; 1667 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1668 goto err;
1669 }
1670
1671 ret = snd_soc_register_dai(&wm8903_dai);
1672 if (ret != 0) {
1673 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1674 goto err_codec;
1654 } 1675 }
1655 1676
1656 return ret; 1677 return ret;
1657 1678
1658card_err: 1679err_codec:
1659 snd_soc_free_pcms(socdev); 1680 snd_soc_unregister_codec(codec);
1660 snd_soc_dapm_free(socdev); 1681err:
1661pcm_err: 1682 wm8903_codec = NULL;
1662 kfree(codec->reg_cache); 1683 kfree(wm8903);
1663 return ret; 1684 return ret;
1664} 1685}
1665 1686
1666static struct snd_soc_device *wm8903_socdev; 1687static int wm8903_i2c_remove(struct i2c_client *client)
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{ 1688{
1671 struct snd_soc_device *socdev = wm8903_socdev; 1689 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674 1690
1675 i2c_set_clientdata(i2c, codec); 1691 snd_soc_unregister_dai(&wm8903_dai);
1676 codec->control_data = i2c; 1692 snd_soc_unregister_codec(codec);
1677 1693
1678 ret = wm8903_init(socdev); 1694 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681 1695
1682 return ret; 1696 kfree(codec->private_data);
1683} 1697
1698 wm8903_codec = NULL;
1699 wm8903_dai.dev = NULL;
1684 1700
1685static int wm8903_i2c_remove(struct i2c_client *client)
1686{
1687 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1688 kfree(codec->reg_cache);
1689 return 0; 1701 return 0;
1690} 1702}
1691 1703
@@ -1709,75 +1721,37 @@ static struct i2c_driver wm8903_i2c_driver = {
1709static int wm8903_probe(struct platform_device *pdev) 1721static int wm8903_probe(struct platform_device *pdev)
1710{ 1722{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1723 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1712 struct wm8903_setup_data *setup;
1713 struct snd_soc_codec *codec;
1714 struct wm8903_priv *wm8903;
1715 struct i2c_board_info board_info;
1716 struct i2c_adapter *adapter;
1717 struct i2c_client *i2c_client;
1718 int ret = 0; 1724 int ret = 0;
1719 1725
1720 setup = socdev->codec_data; 1726 if (!wm8903_codec) {
1721 1727 dev_err(&pdev->dev, "I2C device not yet probed\n");
1722 if (!setup->i2c_address) { 1728 goto err;
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 } 1729 }
1726 1730
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1731 socdev->codec = wm8903_codec;
1728 if (codec == NULL)
1729 return -ENOMEM;
1730 1732
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1733 /* register pcms */
1732 if (wm8903 == NULL) { 1734 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1733 ret = -ENOMEM; 1735 if (ret < 0) {
1734 goto err_codec; 1736 dev_err(&pdev->dev, "failed to create pcms\n");
1737 goto err;
1735 } 1738 }
1736 1739
1737 codec->private_data = wm8903; 1740 wm8903_add_controls(socdev->codec);
1738 socdev->codec = codec; 1741 wm8903_add_widgets(socdev->codec);
1739 mutex_init(&codec->mutex);
1740 INIT_LIST_HEAD(&codec->dapm_widgets);
1741 INIT_LIST_HEAD(&codec->dapm_paths);
1742
1743 wm8903_socdev = socdev;
1744 1742
1745 codec->hw_write = (hw_write_t)i2c_master_send; 1743 ret = snd_soc_init_card(socdev);
1746 ret = i2c_add_driver(&wm8903_i2c_driver); 1744 if (ret < 0) {
1747 if (ret != 0) { 1745 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1748 dev_err(&pdev->dev, "can't add i2c driver\n"); 1746 goto card_err;
1749 goto err_priv;
1750 } else {
1751 memset(&board_info, 0, sizeof(board_info));
1752 strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
1753 board_info.addr = setup->i2c_address;
1754
1755 adapter = i2c_get_adapter(setup->i2c_bus);
1756 if (!adapter) {
1757 dev_err(&pdev->dev, "Can't get I2C bus %d\n",
1758 setup->i2c_bus);
1759 ret = -ENODEV;
1760 goto err_adapter;
1761 }
1762
1763 i2c_client = i2c_new_device(adapter, &board_info);
1764 i2c_put_adapter(adapter);
1765 if (i2c_client == NULL) {
1766 dev_err(&pdev->dev,
1767 "I2C driver registration failed\n");
1768 ret = -ENODEV;
1769 goto err_adapter;
1770 }
1771 } 1747 }
1772 1748
1773 return ret; 1749 return ret;
1774 1750
1775err_adapter: 1751card_err:
1776 i2c_del_driver(&wm8903_i2c_driver); 1752 snd_soc_free_pcms(socdev);
1777err_priv: 1753 snd_soc_dapm_free(socdev);
1778 kfree(codec->private_data); 1754err:
1779err_codec:
1780 kfree(codec);
1781 return ret; 1755 return ret;
1782} 1756}
1783 1757
@@ -1792,10 +1766,6 @@ static int wm8903_remove(struct platform_device *pdev)
1792 1766
1793 snd_soc_free_pcms(socdev); 1767 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev); 1768 snd_soc_dapm_free(socdev);
1795 i2c_unregister_device(socdev->codec->control_data);
1796 i2c_del_driver(&wm8903_i2c_driver);
1797 kfree(codec->private_data);
1798 kfree(codec);
1799 1769
1800 return 0; 1770 return 0;
1801} 1771}
@@ -1808,6 +1778,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1808}; 1778};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903); 1779EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810 1780
1781static int __init wm8903_modinit(void)
1782{
1783 return i2c_add_driver(&wm8903_i2c_driver);
1784}
1785module_init(wm8903_modinit);
1786
1787static void __exit wm8903_exit(void)
1788{
1789 i2c_del_driver(&wm8903_i2c_driver);
1790}
1791module_exit(wm8903_exit);
1792
1811MODULE_DESCRIPTION("ASoC WM8903 driver"); 1793MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); 1794MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL"); 1795MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index cec622f2f660..0ea27e2b9963 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,11 +18,6 @@
18extern struct snd_soc_dai wm8903_dai; 18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903; 19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20 20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1 21#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2 22#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3 23#define WM8903_BCLK 3
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 974a4cd0f3fd..88ead7f8dd98 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -29,7 +29,6 @@
29 29
30#include "wm8971.h" 30#include "wm8971.h"
31 31
32#define AUDIO_NAME "wm8971"
33#define WM8971_VERSION "0.9" 32#define WM8971_VERSION "0.9"
34 33
35#define WM8971_REG_COUNT 43 34#define WM8971_REG_COUNT 43
@@ -542,7 +541,8 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
542} 541}
543 542
544static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream, 543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
545 struct snd_pcm_hw_params *params) 544 struct snd_pcm_hw_params *params,
545 struct snd_soc_dai *dai)
546{ 546{
547 struct snd_soc_pcm_runtime *rtd = substream->private_data; 547 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_device *socdev = rtd->socdev; 548 struct snd_soc_device *socdev = rtd->socdev;
@@ -635,8 +635,6 @@ struct snd_soc_dai wm8971_dai = {
635 .formats = WM8971_FORMATS,}, 635 .formats = WM8971_FORMATS,},
636 .ops = { 636 .ops = {
637 .hw_params = wm8971_pcm_hw_params, 637 .hw_params = wm8971_pcm_hw_params,
638 },
639 .dai_ops = {
640 .digital_mute = wm8971_mute, 638 .digital_mute = wm8971_mute,
641 .set_fmt = wm8971_set_dai_fmt, 639 .set_fmt = wm8971_set_dai_fmt,
642 .set_sysclk = wm8971_set_dai_sysclk, 640 .set_sysclk = wm8971_set_dai_sysclk,
@@ -749,7 +747,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
749 747
750 wm8971_add_controls(codec); 748 wm8971_add_controls(codec);
751 wm8971_add_widgets(codec); 749 wm8971_add_widgets(codec);
752 ret = snd_soc_register_card(socdev); 750 ret = snd_soc_init_card(socdev);
753 if (ret < 0) { 751 if (ret < 0) {
754 printk(KERN_ERR "wm8971: failed to register card\n"); 752 printk(KERN_ERR "wm8971: failed to register card\n");
755 goto card_err; 753 goto card_err;
@@ -937,6 +935,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8971 = {
937 935
938EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971); 936EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
939 937
938static int __init wm8971_modinit(void)
939{
940 return snd_soc_register_dai(&wm8971_dai);
941}
942module_init(wm8971_modinit);
943
944static void __exit wm8971_exit(void)
945{
946 snd_soc_unregister_dai(&wm8971_dai);
947}
948module_exit(wm8971_exit);
949
940MODULE_DESCRIPTION("ASoC WM8971 driver"); 950MODULE_DESCRIPTION("ASoC WM8971 driver");
941MODULE_AUTHOR("Lab126"); 951MODULE_AUTHOR("Lab126");
942MODULE_LICENSE("GPL"); 952MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 63410d7b5efb..5b5afc144478 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -30,7 +30,6 @@
30 30
31#include "wm8990.h" 31#include "wm8990.h"
32 32
33#define AUDIO_NAME "wm8990"
34#define WM8990_VERSION "0.2" 33#define WM8990_VERSION "0.2"
35 34
36/* codec private data */ 35/* codec private data */
@@ -107,6 +106,7 @@ static const u16 wm8990_reg[] = {
107 0x0008, /* R60 - PLL1 */ 106 0x0008, /* R60 - PLL1 */
108 0x0031, /* R61 - PLL2 */ 107 0x0031, /* R61 - PLL2 */
109 0x0026, /* R62 - PLL3 */ 108 0x0026, /* R62 - PLL3 */
109 0x0000, /* R63 - Driver internal */
110}; 110};
111 111
112/* 112/*
@@ -127,10 +127,9 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
127 unsigned int reg, unsigned int value) 127 unsigned int reg, unsigned int value)
128{ 128{
129 u16 *cache = codec->reg_cache; 129 u16 *cache = codec->reg_cache;
130 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
131 130
132 /* Reset register is uncached */ 131 /* Reset register and reserved registers are uncached */
133 if (reg == 0) 132 if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1)
134 return; 133 return;
135 134
136 cache[reg] = value; 135 cache[reg] = value;
@@ -1173,7 +1172,8 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1173 * Set PCM DAI bit size and sample rate. 1172 * Set PCM DAI bit size and sample rate.
1174 */ 1173 */
1175static int wm8990_hw_params(struct snd_pcm_substream *substream, 1174static int wm8990_hw_params(struct snd_pcm_substream *substream,
1176 struct snd_pcm_hw_params *params) 1175 struct snd_pcm_hw_params *params,
1176 struct snd_soc_dai *dai)
1177{ 1177{
1178 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1179 struct snd_soc_device *socdev = rtd->socdev; 1179 struct snd_soc_device *socdev = rtd->socdev;
@@ -1223,8 +1223,14 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1223 switch (level) { 1223 switch (level) {
1224 case SND_SOC_BIAS_ON: 1224 case SND_SOC_BIAS_ON:
1225 break; 1225 break;
1226
1226 case SND_SOC_BIAS_PREPARE: 1227 case SND_SOC_BIAS_PREPARE:
1228 /* VMID=2*50k */
1229 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1230 ~WM8990_VMID_MODE_MASK;
1231 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1227 break; 1232 break;
1233
1228 case SND_SOC_BIAS_STANDBY: 1234 case SND_SOC_BIAS_STANDBY:
1229 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1235 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1230 /* Enable all output discharge bits */ 1236 /* Enable all output discharge bits */
@@ -1273,10 +1279,17 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1273 1279
1274 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1280 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1275 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN); 1281 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1276 } else {
1277 /* ON -> standby */
1278 1282
1283 /* Enable workaround for ADC clocking issue. */
1284 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
1285 wm8990_write(codec, WM8990_EXT_CTL1, 0xa003);
1286 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0);
1279 } 1287 }
1288
1289 /* VMID=2*250k */
1290 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1291 ~WM8990_VMID_MODE_MASK;
1292 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1280 break; 1293 break;
1281 1294
1282 case SND_SOC_BIAS_OFF: 1295 case SND_SOC_BIAS_OFF:
@@ -1350,8 +1363,7 @@ struct snd_soc_dai wm8990_dai = {
1350 .rates = WM8990_RATES, 1363 .rates = WM8990_RATES,
1351 .formats = WM8990_FORMATS,}, 1364 .formats = WM8990_FORMATS,},
1352 .ops = { 1365 .ops = {
1353 .hw_params = wm8990_hw_params,}, 1366 .hw_params = wm8990_hw_params,
1354 .dai_ops = {
1355 .digital_mute = wm8990_mute, 1367 .digital_mute = wm8990_mute,
1356 .set_fmt = wm8990_set_dai_fmt, 1368 .set_fmt = wm8990_set_dai_fmt,
1357 .set_clkdiv = wm8990_set_dai_clkdiv, 1369 .set_clkdiv = wm8990_set_dai_clkdiv,
@@ -1450,7 +1462,7 @@ static int wm8990_init(struct snd_soc_device *socdev)
1450 1462
1451 wm8990_add_controls(codec); 1463 wm8990_add_controls(codec);
1452 wm8990_add_widgets(codec); 1464 wm8990_add_widgets(codec);
1453 ret = snd_soc_register_card(socdev); 1465 ret = snd_soc_init_card(socdev);
1454 if (ret < 0) { 1466 if (ret < 0) {
1455 printk(KERN_ERR "wm8990: failed to register card\n"); 1467 printk(KERN_ERR "wm8990: failed to register card\n");
1456 goto card_err; 1468 goto card_err;
@@ -1631,6 +1643,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1631}; 1643};
1632EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990); 1644EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1633 1645
1646static int __init wm8990_modinit(void)
1647{
1648 return snd_soc_register_dai(&wm8990_dai);
1649}
1650module_init(wm8990_modinit);
1651
1652static void __exit wm8990_exit(void)
1653{
1654 snd_soc_unregister_dai(&wm8990_dai);
1655}
1656module_exit(wm8990_exit);
1657
1634MODULE_DESCRIPTION("ASoC WM8990 driver"); 1658MODULE_DESCRIPTION("ASoC WM8990 driver");
1635MODULE_AUTHOR("Liam Girdwood"); 1659MODULE_AUTHOR("Liam Girdwood");
1636MODULE_LICENSE("GPL"); 1660MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0e192f3b0788..7114ddc88b4b 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -80,8 +80,8 @@
80#define WM8990_PLL3 0x3E 80#define WM8990_PLL3 0x3E
81#define WM8990_INTDRIVBITS 0x3F 81#define WM8990_INTDRIVBITS 0x3F
82 82
83#define WM8990_REGISTER_COUNT 60 83#define WM8990_EXT_ACCESS_ENA 0x75
84#define WM8990_MAX_REGISTER 0x3F 84#define WM8990_EXT_CTL1 0x7a
85 85
86/* 86/*
87 * Field Definitions. 87 * Field Definitions.
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 2f1c91b1d556..af83d629078a 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -2,8 +2,7 @@
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -488,7 +487,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
488 return 0; 487 return 0;
489} 488}
490 489
491static int ac97_prepare(struct snd_pcm_substream *substream) 490static int ac97_prepare(struct snd_pcm_substream *substream,
491 struct snd_soc_dai *dai)
492{ 492{
493 struct snd_pcm_runtime *runtime = substream->runtime; 493 struct snd_pcm_runtime *runtime = substream->runtime;
494 struct snd_soc_pcm_runtime *rtd = substream->private_data; 494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -508,7 +508,8 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
508 return ac97_write(codec, reg, runtime->rate); 508 return ac97_write(codec, reg, runtime->rate);
509} 509}
510 510
511static int ac97_aux_prepare(struct snd_pcm_substream *substream) 511static int ac97_aux_prepare(struct snd_pcm_substream *substream,
512 struct snd_soc_dai *dai)
512{ 513{
513 struct snd_pcm_runtime *runtime = substream->runtime; 514 struct snd_pcm_runtime *runtime = substream->runtime;
514 struct snd_soc_pcm_runtime *rtd = substream->private_data; 515 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -534,7 +535,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
534struct snd_soc_dai wm9712_dai[] = { 535struct snd_soc_dai wm9712_dai[] = {
535{ 536{
536 .name = "AC97 HiFi", 537 .name = "AC97 HiFi",
537 .type = SND_SOC_DAI_AC97_BUS, 538 .ac97_control = 1,
538 .playback = { 539 .playback = {
539 .stream_name = "HiFi Playback", 540 .stream_name = "HiFi Playback",
540 .channels_min = 1, 541 .channels_min = 1,
@@ -689,7 +690,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
689 690
690 ret = wm9712_reset(codec, 0); 691 ret = wm9712_reset(codec, 0);
691 if (ret < 0) { 692 if (ret < 0) {
692 printk(KERN_ERR "AC97 link error\n"); 693 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
693 goto reset_err; 694 goto reset_err;
694 } 695 }
695 696
@@ -699,7 +700,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
699 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 700 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
700 wm9712_add_controls(codec); 701 wm9712_add_controls(codec);
701 wm9712_add_widgets(codec); 702 wm9712_add_widgets(codec);
702 ret = snd_soc_register_card(socdev); 703 ret = snd_soc_init_card(socdev);
703 if (ret < 0) { 704 if (ret < 0) {
704 printk(KERN_ERR "wm9712: failed to register card\n"); 705 printk(KERN_ERR "wm9712: failed to register card\n");
705 goto reset_err; 706 goto reset_err;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 441d0580db1f..f3ca8aaf0139 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -2,8 +2,7 @@
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -141,7 +140,7 @@ SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
141 140
142SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0), 141SOC_SINGLE("ALC Target Volume", AC97_CODEC_CLASS_REV, 12, 15, 0),
143SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0), 142SOC_SINGLE("ALC Hold Time", AC97_CODEC_CLASS_REV, 8, 15, 0),
144SOC_SINGLE("ALC Decay Time ", AC97_CODEC_CLASS_REV, 4, 15, 0), 143SOC_SINGLE("ALC Decay Time", AC97_CODEC_CLASS_REV, 4, 15, 0),
145SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0), 144SOC_SINGLE("ALC Attack Time", AC97_CODEC_CLASS_REV, 0, 15, 0),
146SOC_ENUM("ALC Function", wm9713_enum[6]), 145SOC_ENUM("ALC Function", wm9713_enum[6]),
147SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0), 146SOC_SINGLE("ALC Max Volume", AC97_PCI_SVID, 11, 7, 0),
@@ -929,11 +928,10 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
929} 928}
930 929
931static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, 930static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
932 struct snd_pcm_hw_params *params) 931 struct snd_pcm_hw_params *params,
932 struct snd_soc_dai *dai)
933{ 933{
934 struct snd_soc_pcm_runtime *rtd = substream->private_data; 934 struct snd_soc_codec *codec = dai->codec;
935 struct snd_soc_device *socdev = rtd->socdev;
936 struct snd_soc_codec *codec = socdev->codec;
937 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3; 935 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
938 936
939 switch (params_format(params)) { 937 switch (params_format(params)) {
@@ -955,11 +953,10 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
955 return 0; 953 return 0;
956} 954}
957 955
958static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 956static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
957 struct snd_soc_dai *dai)
959{ 958{
960 struct snd_soc_pcm_runtime *rtd = substream->private_data; 959 struct snd_soc_codec *codec = dai->codec;
961 struct snd_soc_device *socdev = rtd->socdev;
962 struct snd_soc_codec *codec = socdev->codec;
963 u16 status; 960 u16 status;
964 961
965 /* Gracefully shut down the voice interface. */ 962 /* Gracefully shut down the voice interface. */
@@ -970,12 +967,11 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
970 ac97_write(codec, AC97_EXTENDED_MID, status); 967 ac97_write(codec, AC97_EXTENDED_MID, status);
971} 968}
972 969
973static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 970static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
971 struct snd_soc_dai *dai)
974{ 972{
973 struct snd_soc_codec *codec = dai->codec;
975 struct snd_pcm_runtime *runtime = substream->runtime; 974 struct snd_pcm_runtime *runtime = substream->runtime;
976 struct snd_soc_pcm_runtime *rtd = substream->private_data;
977 struct snd_soc_device *socdev = rtd->socdev;
978 struct snd_soc_codec *codec = socdev->codec;
979 int reg; 975 int reg;
980 u16 vra; 976 u16 vra;
981 977
@@ -990,12 +986,11 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
990 return ac97_write(codec, reg, runtime->rate); 986 return ac97_write(codec, reg, runtime->rate);
991} 987}
992 988
993static int ac97_aux_prepare(struct snd_pcm_substream *substream) 989static int ac97_aux_prepare(struct snd_pcm_substream *substream,
990 struct snd_soc_dai *dai)
994{ 991{
992 struct snd_soc_codec *codec = dai->codec;
995 struct snd_pcm_runtime *runtime = substream->runtime; 993 struct snd_pcm_runtime *runtime = substream->runtime;
996 struct snd_soc_pcm_runtime *rtd = substream->private_data;
997 struct snd_soc_device *socdev = rtd->socdev;
998 struct snd_soc_codec *codec = socdev->codec;
999 u16 vra, xsle; 994 u16 vra, xsle;
1000 995
1001 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 996 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -1029,7 +1024,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
1029struct snd_soc_dai wm9713_dai[] = { 1024struct snd_soc_dai wm9713_dai[] = {
1030{ 1025{
1031 .name = "AC97 HiFi", 1026 .name = "AC97 HiFi",
1032 .type = SND_SOC_DAI_AC97_BUS, 1027 .ac97_control = 1,
1033 .playback = { 1028 .playback = {
1034 .stream_name = "HiFi Playback", 1029 .stream_name = "HiFi Playback",
1035 .channels_min = 1, 1030 .channels_min = 1,
@@ -1043,8 +1038,7 @@ struct snd_soc_dai wm9713_dai[] = {
1043 .rates = WM9713_RATES, 1038 .rates = WM9713_RATES,
1044 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1039 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1045 .ops = { 1040 .ops = {
1046 .prepare = ac97_hifi_prepare,}, 1041 .prepare = ac97_hifi_prepare,
1047 .dai_ops = {
1048 .set_clkdiv = wm9713_set_dai_clkdiv, 1042 .set_clkdiv = wm9713_set_dai_clkdiv,
1049 .set_pll = wm9713_set_dai_pll,}, 1043 .set_pll = wm9713_set_dai_pll,},
1050 }, 1044 },
@@ -1057,8 +1051,7 @@ struct snd_soc_dai wm9713_dai[] = {
1057 .rates = WM9713_RATES, 1051 .rates = WM9713_RATES,
1058 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1052 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1059 .ops = { 1053 .ops = {
1060 .prepare = ac97_aux_prepare,}, 1054 .prepare = ac97_aux_prepare,
1061 .dai_ops = {
1062 .set_clkdiv = wm9713_set_dai_clkdiv, 1055 .set_clkdiv = wm9713_set_dai_clkdiv,
1063 .set_pll = wm9713_set_dai_pll,}, 1056 .set_pll = wm9713_set_dai_pll,},
1064 }, 1057 },
@@ -1078,8 +1071,7 @@ struct snd_soc_dai wm9713_dai[] = {
1078 .formats = WM9713_PCM_FORMATS,}, 1071 .formats = WM9713_PCM_FORMATS,},
1079 .ops = { 1072 .ops = {
1080 .hw_params = wm9713_pcm_hw_params, 1073 .hw_params = wm9713_pcm_hw_params,
1081 .shutdown = wm9713_voiceshutdown,}, 1074 .shutdown = wm9713_voiceshutdown,
1082 .dai_ops = {
1083 .set_clkdiv = wm9713_set_dai_clkdiv, 1075 .set_clkdiv = wm9713_set_dai_clkdiv,
1084 .set_pll = wm9713_set_dai_pll, 1076 .set_pll = wm9713_set_dai_pll,
1085 .set_fmt = wm9713_set_dai_fmt, 1077 .set_fmt = wm9713_set_dai_fmt,
@@ -1098,6 +1090,8 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1098 } 1090 }
1099 1091
1100 soc_ac97_ops.reset(codec->ac97); 1092 soc_ac97_ops.reset(codec->ac97);
1093 if (soc_ac97_ops.warm_reset)
1094 soc_ac97_ops.warm_reset(codec->ac97);
1101 if (ac97_read(codec, 0) != wm9713_reg[0]) 1095 if (ac97_read(codec, 0) != wm9713_reg[0])
1102 return -EIO; 1096 return -EIO;
1103 return 0; 1097 return 0;
@@ -1241,7 +1235,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1241 wm9713_reset(codec, 0); 1235 wm9713_reset(codec, 0);
1242 ret = wm9713_reset(codec, 1); 1236 ret = wm9713_reset(codec, 1);
1243 if (ret < 0) { 1237 if (ret < 0) {
1244 printk(KERN_ERR "AC97 link error\n"); 1238 printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n");
1245 goto reset_err; 1239 goto reset_err;
1246 } 1240 }
1247 1241
@@ -1253,7 +1247,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1253 1247
1254 wm9713_add_controls(codec); 1248 wm9713_add_controls(codec);
1255 wm9713_add_widgets(codec); 1249 wm9713_add_widgets(codec);
1256 ret = snd_soc_register_card(socdev); 1250 ret = snd_soc_init_card(socdev);
1257 if (ret < 0) 1251 if (ret < 0)
1258 goto reset_err; 1252 goto reset_err;
1259 return 0; 1253 return 0;
@@ -1289,7 +1283,6 @@ static int wm9713_soc_remove(struct platform_device *pdev)
1289 snd_soc_free_ac97_codec(codec); 1283 snd_soc_free_ac97_codec(codec);
1290 kfree(codec->private_data); 1284 kfree(codec->private_data);
1291 kfree(codec->reg_cache); 1285 kfree(codec->reg_cache);
1292 kfree(codec->dai);
1293 kfree(codec); 1286 kfree(codec);
1294 return 0; 1287 return 0;
1295} 1288}
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 8f7e33834902..b502741692d6 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -17,3 +17,13 @@ config SND_DAVINCI_SOC_EVM
17 help 17 help
18 Say Y if you want to add support for SoC audio on TI 18 Say Y if you want to add support for SoC audio on TI
19 DaVinci EVM platform. 19 DaVinci EVM platform.
20
21config SND_DAVINCI_SOC_SFFSDR
22 tristate "SoC Audio support for SFFSDR"
23 depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR
24 select SND_DAVINCI_SOC_I2S
25 select SND_SOC_PCM3008
26 select SFFSDR_FPGA
27 help
28 Say Y if you want to add support for SoC audio on
29 Lyrtech SFFSDR board.
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca772e5b4637..ca8bae1fc3f6 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
7 7
8# DAVINCI Machine Support 8# DAVINCI Machine Support
9snd-soc-evm-objs := davinci-evm.o 9snd-soc-evm-objs := davinci-evm.o
10snd-soc-sffsdr-objs := davinci-sffsdr.o
10 11
11obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 12obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 9e6062cd6b59..54851f318568 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -26,8 +26,9 @@
26#include "davinci-pcm.h" 26#include "davinci-pcm.h"
27#include "davinci-i2s.h" 27#include "davinci-i2s.h"
28 28
29#define EVM_CODEC_CLOCK 22579200
30 29
30#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
31 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
31static int evm_hw_params(struct snd_pcm_substream *substream, 32static int evm_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 33 struct snd_pcm_hw_params *params)
33{ 34{
@@ -35,22 +36,34 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 36 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
36 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 37 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
37 int ret = 0; 38 int ret = 0;
39 unsigned sysclk;
40
41 /* ASP1 on DM355 EVM is clocked by an external oscillator */
42 if (machine_is_davinci_dm355_evm())
43 sysclk = 27000000;
44
45 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
46 * board-dm644x-evm.c using GPIOs from U18. There are six
47 * options; here we "know" we use a 48 KHz sample rate.
48 */
49 else if (machine_is_davinci_evm())
50 sysclk = 12288000;
51
52 else
53 return -EINVAL;
38 54
39 /* set codec DAI configuration */ 55 /* set codec DAI configuration */
40 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 56 ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
41 SND_SOC_DAIFMT_CBM_CFM);
42 if (ret < 0) 57 if (ret < 0)
43 return ret; 58 return ret;
44 59
45 /* set cpu DAI configuration */ 60 /* set cpu DAI configuration */
46 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | 61 ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
47 SND_SOC_DAIFMT_IB_NF);
48 if (ret < 0) 62 if (ret < 0)
49 return ret; 63 return ret;
50 64
51 /* set the codec system clock */ 65 /* set the codec system clock */
52 ret = snd_soc_dai_set_sysclk(codec_dai, 0, EVM_CODEC_CLOCK, 66 ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
53 SND_SOC_CLOCK_OUT);
54 if (ret < 0) 67 if (ret < 0)
55 return ret; 68 return ret;
56 69
@@ -128,8 +141,9 @@ static struct snd_soc_dai_link evm_dai = {
128}; 141};
129 142
130/* davinci-evm audio machine driver */ 143/* davinci-evm audio machine driver */
131static struct snd_soc_machine snd_soc_machine_evm = { 144static struct snd_soc_card snd_soc_card_evm = {
132 .name = "DaVinci EVM", 145 .name = "DaVinci EVM",
146 .platform = &davinci_soc_platform,
133 .dai_link = &evm_dai, 147 .dai_link = &evm_dai,
134 .num_links = 1, 148 .num_links = 1,
135}; 149};
@@ -142,8 +156,7 @@ static struct aic3x_setup_data evm_aic3x_setup = {
142 156
143/* evm audio subsystem */ 157/* evm audio subsystem */
144static struct snd_soc_device evm_snd_devdata = { 158static struct snd_soc_device evm_snd_devdata = {
145 .machine = &snd_soc_machine_evm, 159 .card = &snd_soc_card_evm,
146 .platform = &davinci_soc_platform,
147 .codec_dev = &soc_codec_dev_aic3x, 160 .codec_dev = &soc_codec_dev_aic3x,
148 .codec_data = &evm_aic3x_setup, 161 .codec_data = &evm_aic3x_setup,
149}; 162};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index abb5fedb0b1e..0fee779e3c76 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -59,6 +59,7 @@
59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1) 59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1)
60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2) 60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2)
61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3) 61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3)
62#define DAVINCI_MCBSP_PCR_SCLKME (1 << 7)
62#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8) 63#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8)
63#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9) 64#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9)
64#define DAVINCI_MCBSP_PCR_FSRM (1 << 10) 65#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
@@ -110,16 +111,59 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
110{ 111{
111 struct snd_soc_pcm_runtime *rtd = substream->private_data; 112 struct snd_soc_pcm_runtime *rtd = substream->private_data;
112 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; 113 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
114 struct snd_soc_device *socdev = rtd->socdev;
115 struct snd_soc_platform *platform = socdev->card->platform;
113 u32 w; 116 u32 w;
117 int ret;
114 118
115 /* Start the sample generator and enable transmitter/receiver */ 119 /* Start the sample generator and enable transmitter/receiver */
116 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 120 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
117 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1); 121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1);
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
123
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
125 /* Stop the DMA to avoid data loss */
126 /* while the transmitter is out of reset to handle XSYNCERR */
127 if (platform->pcm_ops->trigger) {
128 ret = platform->pcm_ops->trigger(substream,
129 SNDRV_PCM_TRIGGER_STOP);
130 if (ret < 0)
131 printk(KERN_DEBUG "Playback DMA stop failed\n");
132 }
133
134 /* Enable the transmitter */
135 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
119 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1); 136 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
120 else 137 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
138
139 /* wait for any unexpected frame sync error to occur */
140 udelay(100);
141
142 /* Disable the transmitter to clear any outstanding XSYNCERR */
143 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
144 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0);
145 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
146
147 /* Restart the DMA */
148 if (platform->pcm_ops->trigger) {
149 ret = platform->pcm_ops->trigger(substream,
150 SNDRV_PCM_TRIGGER_START);
151 if (ret < 0)
152 printk(KERN_DEBUG "Playback DMA start failed\n");
153 }
154 /* Enable the transmitter */
155 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
156 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
157 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
158
159 } else {
160
161 /* Enable the reciever */
162 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1); 163 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 164 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
165 }
166
123 167
124 /* Start frame sync */ 168 /* Start frame sync */
125 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 169 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -144,7 +188,8 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
144 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 188 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
145} 189}
146 190
147static int davinci_i2s_startup(struct snd_pcm_substream *substream) 191static int davinci_i2s_startup(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai)
148{ 193{
149 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
150 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -155,61 +200,138 @@ static int davinci_i2s_startup(struct snd_pcm_substream *substream)
155 return 0; 200 return 0;
156} 201}
157 202
203#define DEFAULT_BITPERSAMPLE 16
204
158static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 205static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
159 unsigned int fmt) 206 unsigned int fmt)
160{ 207{
161 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 208 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
162 u32 w; 209 unsigned int pcr;
210 unsigned int srgr;
211 unsigned int rcr;
212 unsigned int xcr;
213 srgr = DAVINCI_MCBSP_SRGR_FSGM |
214 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
215 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
163 216
164 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 217 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
165 case SND_SOC_DAIFMT_CBS_CFS: 218 case SND_SOC_DAIFMT_CBS_CFS:
166 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 219 /* cpu is master */
167 DAVINCI_MCBSP_PCR_FSXM | 220 pcr = DAVINCI_MCBSP_PCR_FSXM |
168 DAVINCI_MCBSP_PCR_FSRM | 221 DAVINCI_MCBSP_PCR_FSRM |
169 DAVINCI_MCBSP_PCR_CLKXM | 222 DAVINCI_MCBSP_PCR_CLKXM |
170 DAVINCI_MCBSP_PCR_CLKRM); 223 DAVINCI_MCBSP_PCR_CLKRM;
171 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, 224 break;
172 DAVINCI_MCBSP_SRGR_FSGM); 225 case SND_SOC_DAIFMT_CBM_CFS:
226 /* McBSP CLKR pin is the input for the Sample Rate Generator.
227 * McBSP FSR and FSX are driven by the Sample Rate Generator. */
228 pcr = DAVINCI_MCBSP_PCR_SCLKME |
229 DAVINCI_MCBSP_PCR_FSXM |
230 DAVINCI_MCBSP_PCR_FSRM;
173 break; 231 break;
174 case SND_SOC_DAIFMT_CBM_CFM: 232 case SND_SOC_DAIFMT_CBM_CFM:
175 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 0); 233 /* codec is master */
234 pcr = 0;
176 break; 235 break;
177 default: 236 default:
237 printk(KERN_ERR "%s:bad master\n", __func__);
178 return -EINVAL; 238 return -EINVAL;
179 } 239 }
180 240
181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 241 rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1);
182 case SND_SOC_DAIFMT_IB_NF: 242 xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1);
183 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 243 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
184 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 244 case SND_SOC_DAIFMT_DSP_B:
185 DAVINCI_MCBSP_PCR_CLKRP, 1);
186 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w);
187 break; 245 break;
188 case SND_SOC_DAIFMT_NB_IF: 246 case SND_SOC_DAIFMT_I2S:
189 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 247 /* Davinci doesn't support TRUE I2S, but some codecs will have
190 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_FSXP | 248 * the left and right channels contiguous. This allows
191 DAVINCI_MCBSP_PCR_FSRP, 1); 249 * dsp_a mode to be used with an inverted normal frame clk.
192 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 250 * If your codec is master and does not have contiguous
251 * channels, then you will have sound on only one channel.
252 * Try using a different mode, or codec as slave.
253 *
254 * The TLV320AIC33 is an example of a codec where this works.
255 * It has a variable bit clock frequency allowing it to have
256 * valid data on every bit clock.
257 *
258 * The TLV320AIC23 is an example of a codec where this does not
259 * work. It has a fixed bit clock frequency with progressively
260 * more empty bit clock slots between channels as the sample
261 * rate is lowered.
262 */
263 fmt ^= SND_SOC_DAIFMT_NB_IF;
264 case SND_SOC_DAIFMT_DSP_A:
265 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
266 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
267 break;
268 default:
269 printk(KERN_ERR "%s:bad format\n", __func__);
270 return -EINVAL;
271 }
272
273 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
274 case SND_SOC_DAIFMT_NB_NF:
275 /* CLKRP Receive clock polarity,
276 * 1 - sampled on rising edge of CLKR
277 * valid on rising edge
278 * CLKXP Transmit clock polarity,
279 * 1 - clocked on falling edge of CLKX
280 * valid on rising edge
281 * FSRP Receive frame sync pol, 0 - active high
282 * FSXP Transmit frame sync pol, 0 - active high
283 */
284 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
193 break; 285 break;
194 case SND_SOC_DAIFMT_IB_IF: 286 case SND_SOC_DAIFMT_IB_IF:
195 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 287 /* CLKRP Receive clock polarity,
196 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 288 * 0 - sampled on falling edge of CLKR
197 DAVINCI_MCBSP_PCR_CLKRP | 289 * valid on falling edge
198 DAVINCI_MCBSP_PCR_FSXP | 290 * CLKXP Transmit clock polarity,
199 DAVINCI_MCBSP_PCR_FSRP, 1); 291 * 0 - clocked on rising edge of CLKX
200 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 292 * valid on falling edge
293 * FSRP Receive frame sync pol, 1 - active low
294 * FSXP Transmit frame sync pol, 1 - active low
295 */
296 pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
201 break; 297 break;
202 case SND_SOC_DAIFMT_NB_NF: 298 case SND_SOC_DAIFMT_NB_IF:
299 /* CLKRP Receive clock polarity,
300 * 1 - sampled on rising edge of CLKR
301 * valid on rising edge
302 * CLKXP Transmit clock polarity,
303 * 1 - clocked on falling edge of CLKX
304 * valid on rising edge
305 * FSRP Receive frame sync pol, 1 - active low
306 * FSXP Transmit frame sync pol, 1 - active low
307 */
308 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
309 DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
310 break;
311 case SND_SOC_DAIFMT_IB_NF:
312 /* CLKRP Receive clock polarity,
313 * 0 - sampled on falling edge of CLKR
314 * valid on falling edge
315 * CLKXP Transmit clock polarity,
316 * 0 - clocked on rising edge of CLKX
317 * valid on falling edge
318 * FSRP Receive frame sync pol, 0 - active high
319 * FSXP Transmit frame sync pol, 0 - active high
320 */
203 break; 321 break;
204 default: 322 default:
205 return -EINVAL; 323 return -EINVAL;
206 } 324 }
207 325 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
326 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
327 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
328 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
208 return 0; 329 return 0;
209} 330}
210 331
211static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, 332static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
212 struct snd_pcm_hw_params *params) 333 struct snd_pcm_hw_params *params,
334 struct snd_soc_dai *dai)
213{ 335{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 336 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 337 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
@@ -219,25 +341,20 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
219 u32 w; 341 u32 w;
220 342
221 /* general line settings */ 343 /* general line settings */
222 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, 344 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
223 DAVINCI_MCBSP_SPCR_RINTM(3) | 345 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
224 DAVINCI_MCBSP_SPCR_XINTM(3) | 346 w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
225 DAVINCI_MCBSP_SPCR_FREE); 347 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
226 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, 348 } else {
227 DAVINCI_MCBSP_RCR_RFRLEN1(1) | 349 w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
228 DAVINCI_MCBSP_RCR_RDATDLY(1)); 350 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
229 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, 351 }
230 DAVINCI_MCBSP_XCR_XFRLEN1(1) |
231 DAVINCI_MCBSP_XCR_XDATDLY(1) |
232 DAVINCI_MCBSP_XCR_XFIG);
233 352
234 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 353 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
235 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG); 354 w = DAVINCI_MCBSP_SRGR_FSGM;
236 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1); 355 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1);
237 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
238 356
239 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 357 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
240 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG);
241 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1); 358 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1);
242 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w); 359 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
243 360
@@ -260,20 +377,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
260 return -EINVAL; 377 return -EINVAL;
261 } 378 }
262 379
263 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); 380 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
264 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 381 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG);
265 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1); 382 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
266 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w); 383 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
384 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
267 385
268 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); 386 } else {
269 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | 387 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG);
270 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1); 388 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
271 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w); 389 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1);
390 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
272 391
392 }
273 return 0; 393 return 0;
274} 394}
275 395
276static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 396static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
397 struct snd_soc_dai *dai)
277{ 398{
278 int ret = 0; 399 int ret = 0;
279 400
@@ -299,8 +420,8 @@ static int davinci_i2s_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai) 420 struct snd_soc_dai *dai)
300{ 421{
301 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
302 struct snd_soc_machine *machine = socdev->machine; 423 struct snd_soc_card *card = socdev->card;
303 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 424 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
304 struct davinci_mcbsp_dev *dev; 425 struct davinci_mcbsp_dev *dev;
305 struct resource *mem, *ioarea; 426 struct resource *mem, *ioarea;
306 struct evm_snd_platform_data *pdata; 427 struct evm_snd_platform_data *pdata;
@@ -361,8 +482,8 @@ static void davinci_i2s_remove(struct platform_device *pdev,
361 struct snd_soc_dai *dai) 482 struct snd_soc_dai *dai)
362{ 483{
363 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 484 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
364 struct snd_soc_machine *machine = socdev->machine; 485 struct snd_soc_card *card = socdev->card;
365 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 486 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
366 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 487 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
367 struct resource *mem; 488 struct resource *mem;
368 489
@@ -381,7 +502,6 @@ static void davinci_i2s_remove(struct platform_device *pdev,
381struct snd_soc_dai davinci_i2s_dai = { 502struct snd_soc_dai davinci_i2s_dai = {
382 .name = "davinci-i2s", 503 .name = "davinci-i2s",
383 .id = 0, 504 .id = 0,
384 .type = SND_SOC_DAI_I2S,
385 .probe = davinci_i2s_probe, 505 .probe = davinci_i2s_probe,
386 .remove = davinci_i2s_remove, 506 .remove = davinci_i2s_remove,
387 .playback = { 507 .playback = {
@@ -397,13 +517,24 @@ struct snd_soc_dai davinci_i2s_dai = {
397 .ops = { 517 .ops = {
398 .startup = davinci_i2s_startup, 518 .startup = davinci_i2s_startup,
399 .trigger = davinci_i2s_trigger, 519 .trigger = davinci_i2s_trigger,
400 .hw_params = davinci_i2s_hw_params,}, 520 .hw_params = davinci_i2s_hw_params,
401 .dai_ops = {
402 .set_fmt = davinci_i2s_set_dai_fmt, 521 .set_fmt = davinci_i2s_set_dai_fmt,
403 }, 522 },
404}; 523};
405EXPORT_SYMBOL_GPL(davinci_i2s_dai); 524EXPORT_SYMBOL_GPL(davinci_i2s_dai);
406 525
526static int __init davinci_i2s_init(void)
527{
528 return snd_soc_register_dai(&davinci_i2s_dai);
529}
530module_init(davinci_i2s_init);
531
532static void __exit davinci_i2s_exit(void)
533{
534 snd_soc_unregister_dai(&davinci_i2s_dai);
535}
536module_exit(davinci_i2s_exit);
537
407MODULE_AUTHOR("Vladimir Barinov"); 538MODULE_AUTHOR("Vladimir Barinov");
408MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface"); 539MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
409MODULE_LICENSE("GPL"); 540MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 76feaa657375..366049d8578c 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/kernel.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
@@ -24,13 +25,6 @@
24 25
25#include "davinci-pcm.h" 26#include "davinci-pcm.h"
26 27
27#define DAVINCI_PCM_DEBUG 0
28#if DAVINCI_PCM_DEBUG
29#define DPRINTK(x...) printk(KERN_DEBUG x)
30#else
31#define DPRINTK(x...)
32#endif
33
34static struct snd_pcm_hardware davinci_pcm_hardware = { 28static struct snd_pcm_hardware davinci_pcm_hardware = {
35 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
@@ -78,8 +72,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
78 dma_offset = prtd->period * period_size; 72 dma_offset = prtd->period * period_size;
79 dma_pos = runtime->dma_addr + dma_offset; 73 dma_pos = runtime->dma_addr + dma_offset;
80 74
81 DPRINTK("audio_set_dma_params_play channel = %d dma_ptr = %x " 75 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
82 "period_size=%x\n", lch, dma_pos, period_size); 76 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size);
83 77
84 data_type = prtd->params->data_type; 78 data_type = prtd->params->data_type;
85 count = period_size / data_type; 79 count = period_size / data_type;
@@ -112,7 +106,7 @@ static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
112 struct snd_pcm_substream *substream = data; 106 struct snd_pcm_substream *substream = data;
113 struct davinci_runtime_data *prtd = substream->runtime->private_data; 107 struct davinci_runtime_data *prtd = substream->runtime->private_data;
114 108
115 DPRINTK("lch=%d, status=0x%x\n", lch, ch_status); 109 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status);
116 110
117 if (unlikely(ch_status != DMA_COMPLETE)) 111 if (unlikely(ch_status != DMA_COMPLETE))
118 return; 112 return;
@@ -218,7 +212,7 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
218 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
219 count = src - runtime->dma_addr; 213 count = src - runtime->dma_addr;
220 else 214 else
221 count = dst - runtime->dma_addr;; 215 count = dst - runtime->dma_addr;
222 216
223 spin_unlock(&prtd->lock); 217 spin_unlock(&prtd->lock);
224 218
@@ -316,8 +310,8 @@ static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316 buf->area = dma_alloc_writecombine(pcm->card->dev, size, 310 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
317 &buf->addr, GFP_KERNEL); 311 &buf->addr, GFP_KERNEL);
318 312
319 DPRINTK("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", 313 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
320 (void *) buf->area, (void *) buf->addr, size); 314 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
321 315
322 if (!buf->area) 316 if (!buf->area)
323 return -ENOMEM; 317 return -ENOMEM;
@@ -384,6 +378,18 @@ struct snd_soc_platform davinci_soc_platform = {
384}; 378};
385EXPORT_SYMBOL_GPL(davinci_soc_platform); 379EXPORT_SYMBOL_GPL(davinci_soc_platform);
386 380
381static int __init davinci_soc_platform_init(void)
382{
383 return snd_soc_register_platform(&davinci_soc_platform);
384}
385module_init(davinci_soc_platform_init);
386
387static void __exit davinci_soc_platform_exit(void)
388{
389 snd_soc_unregister_platform(&davinci_soc_platform);
390}
391module_exit(davinci_soc_platform_exit);
392
387MODULE_AUTHOR("Vladimir Barinov"); 393MODULE_AUTHOR("Vladimir Barinov");
388MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); 394MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
389MODULE_LICENSE("GPL"); 395MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
new file mode 100644
index 000000000000..4935d1bcbd8d
--- /dev/null
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -0,0 +1,161 @@
1/*
2 * ASoC driver for Lyrtech SFFSDR board.
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
8 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
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/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include <asm/dma.h>
27#include <asm/mach-types.h>
28#include <asm/plat-sffsdr/sffsdr-fpga.h>
29
30#include <mach/mcbsp.h>
31#include <mach/edma.h>
32
33#include "../codecs/pcm3008.h"
34#include "davinci-pcm.h"
35#include "davinci-i2s.h"
36
37static int sffsdr_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params,
39 struct snd_soc_dai *dai)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
43 int fs;
44 int ret = 0;
45
46 /* Set cpu DAI configuration:
47 * CLKX and CLKR are the inputs for the Sample Rate Generator.
48 * FSX and FSR are outputs, driven by the sample Rate Generator. */
49 ret = snd_soc_dai_set_fmt(cpu_dai,
50 SND_SOC_DAIFMT_RIGHT_J |
51 SND_SOC_DAIFMT_CBM_CFS |
52 SND_SOC_DAIFMT_IB_NF);
53 if (ret < 0)
54 return ret;
55
56 /* Fsref can be 32000, 44100 or 48000. */
57 fs = params_rate(params);
58
59 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
60
61 return sffsdr_fpga_set_codec_fs(fs);
62}
63
64static struct snd_soc_ops sffsdr_ops = {
65 .hw_params = sffsdr_hw_params,
66};
67
68/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
69static struct snd_soc_dai_link sffsdr_dai = {
70 .name = "PCM3008", /* Codec name */
71 .stream_name = "PCM3008 HiFi",
72 .cpu_dai = &davinci_i2s_dai,
73 .codec_dai = &pcm3008_dai,
74 .ops = &sffsdr_ops,
75};
76
77/* davinci-sffsdr audio machine driver */
78static struct snd_soc_card snd_soc_sffsdr = {
79 .name = "DaVinci SFFSDR",
80 .platform = &davinci_soc_platform,
81 .dai_link = &sffsdr_dai,
82 .num_links = 1,
83};
84
85/* sffsdr audio private data */
86static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
87 .dem0_pin = GPIO(45),
88 .dem1_pin = GPIO(46),
89 .pdad_pin = GPIO(47),
90 .pdda_pin = GPIO(38),
91};
92
93/* sffsdr audio subsystem */
94static struct snd_soc_device sffsdr_snd_devdata = {
95 .card = &snd_soc_sffsdr,
96 .codec_dev = &soc_codec_dev_pcm3008,
97 .codec_data = &sffsdr_pcm3008_setup,
98};
99
100static struct resource sffsdr_snd_resources[] = {
101 {
102 .start = DAVINCI_MCBSP_BASE,
103 .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
104 .flags = IORESOURCE_MEM,
105 },
106};
107
108static struct evm_snd_platform_data sffsdr_snd_data = {
109 .tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
110 .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
111};
112
113static struct platform_device *sffsdr_snd_device;
114
115static int __init sffsdr_init(void)
116{
117 int ret;
118
119 if (!machine_is_sffsdr())
120 return -EINVAL;
121
122 sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
123 if (!sffsdr_snd_device) {
124 printk(KERN_ERR "platform device allocation failed\n");
125 return -ENOMEM;
126 }
127
128 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata);
129 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
130 sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data;
131
132 ret = platform_device_add_resources(sffsdr_snd_device,
133 sffsdr_snd_resources,
134 ARRAY_SIZE(sffsdr_snd_resources));
135 if (ret) {
136 printk(KERN_ERR "platform device add ressources failed\n");
137 goto error;
138 }
139
140 ret = platform_device_add(sffsdr_snd_device);
141 if (ret)
142 goto error;
143
144 return ret;
145
146error:
147 platform_device_put(sffsdr_snd_device);
148 return ret;
149}
150
151static void __exit sffsdr_exit(void)
152{
153 platform_device_unregister(sffsdr_snd_device);
154}
155
156module_init(sffsdr_init);
157module_exit(sffsdr_exit);
158
159MODULE_AUTHOR("Hugo Villeneuve");
160MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
161MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index bba9546ba5f5..95c12b26fe37 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -20,7 +20,8 @@ config SND_SOC_MPC8610_HPCD
20 20
21config SND_SOC_MPC5200_I2S 21config SND_SOC_MPC5200_I2S
22 tristate "Freescale MPC5200 PSC in I2S mode driver" 22 tristate "Freescale MPC5200 PSC in I2S mode driver"
23 depends on PPC_MPC52xx && PPC_BESTCOMM
23 select SND_SOC_OF_SIMPLE 24 select SND_SOC_OF_SIMPLE
24 depends on SND_SOC && PPC_MPC52xx 25 select PPC_BESTCOMM_GEN_BD
25 help 26 help
26 Say Y here to support the MPC5200 PSCs in I2S mode. 27 Say Y here to support the MPC5200 PSCs in I2S mode.
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index d2d3da9729f2..64993eda5679 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -284,7 +284,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
284 * fsl_dma_new: initialize this PCM driver. 284 * fsl_dma_new: initialize this PCM driver.
285 * 285 *
286 * This function is called when the codec driver calls snd_soc_new_pcms(), 286 * This function is called when the codec driver calls snd_soc_new_pcms(),
287 * once for each .dai_link in the machine driver's snd_soc_machine 287 * once for each .dai_link in the machine driver's snd_soc_card
288 * structure. 288 * structure.
289 */ 289 */
290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, 290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
@@ -853,6 +853,18 @@ int fsl_dma_configure(struct fsl_dma_info *dma_info)
853} 853}
854EXPORT_SYMBOL_GPL(fsl_dma_configure); 854EXPORT_SYMBOL_GPL(fsl_dma_configure);
855 855
856static int __init fsl_soc_platform_init(void)
857{
858 return snd_soc_register_platform(&fsl_soc_platform);
859}
860module_init(fsl_soc_platform_init);
861
862static void __exit fsl_soc_platform_exit(void)
863{
864 snd_soc_unregister_platform(&fsl_soc_platform);
865}
866module_exit(fsl_soc_platform_exit);
867
856MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 868MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
857MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module"); 869MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module");
858MODULE_LICENSE("GPL"); 870MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 157a7895ffa1..c6d6eb71dc1d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -266,7 +266,8 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
266 * If this is the first stream open, then grab the IRQ and program most of 266 * If this is the first stream open, then grab the IRQ and program most of
267 * the SSI registers. 267 * the SSI registers.
268 */ 268 */
269static int fsl_ssi_startup(struct snd_pcm_substream *substream) 269static int fsl_ssi_startup(struct snd_pcm_substream *substream,
270 struct snd_soc_dai *dai)
270{ 271{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data; 272 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 273 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -411,7 +412,8 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream)
411 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the 412 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
412 * clock master. 413 * clock master.
413 */ 414 */
414static int fsl_ssi_prepare(struct snd_pcm_substream *substream) 415static int fsl_ssi_prepare(struct snd_pcm_substream *substream,
416 struct snd_soc_dai *dai)
415{ 417{
416 struct snd_pcm_runtime *runtime = substream->runtime; 418 struct snd_pcm_runtime *runtime = substream->runtime;
417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 419 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -441,7 +443,8 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
441 * The DMA channel is in external master start and pause mode, which 443 * The DMA channel is in external master start and pause mode, which
442 * means the SSI completely controls the flow of data. 444 * means the SSI completely controls the flow of data.
443 */ 445 */
444static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) 446static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
447 struct snd_soc_dai *dai)
445{ 448{
446 struct snd_soc_pcm_runtime *rtd = substream->private_data; 449 struct snd_soc_pcm_runtime *rtd = substream->private_data;
447 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 450 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -490,7 +493,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
490 * 493 *
491 * Shutdown the SSI if there are no other substreams open. 494 * Shutdown the SSI if there are no other substreams open.
492 */ 495 */
493static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) 496static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
497 struct snd_soc_dai *dai)
494{ 498{
495 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
496 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 500 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -578,8 +582,6 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
578 .prepare = fsl_ssi_prepare, 582 .prepare = fsl_ssi_prepare,
579 .shutdown = fsl_ssi_shutdown, 583 .shutdown = fsl_ssi_shutdown,
580 .trigger = fsl_ssi_trigger, 584 .trigger = fsl_ssi_trigger,
581 },
582 .dai_ops = {
583 .set_sysclk = fsl_ssi_set_sysclk, 585 .set_sysclk = fsl_ssi_set_sysclk,
584 .set_fmt = fsl_ssi_set_fmt, 586 .set_fmt = fsl_ssi_set_fmt,
585 }, 587 },
@@ -671,6 +673,14 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
671 fsl_ssi_dai->private_data = ssi_private; 673 fsl_ssi_dai->private_data = ssi_private;
672 fsl_ssi_dai->name = ssi_private->name; 674 fsl_ssi_dai->name = ssi_private->name;
673 fsl_ssi_dai->id = ssi_info->id; 675 fsl_ssi_dai->id = ssi_info->id;
676 fsl_ssi_dai->dev = ssi_info->dev;
677
678 ret = snd_soc_register_dai(fsl_ssi_dai);
679 if (ret != 0) {
680 dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
681 kfree(fsl_ssi_dai);
682 return NULL;
683 }
674 684
675 return fsl_ssi_dai; 685 return fsl_ssi_dai;
676} 686}
@@ -688,6 +698,8 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
688 698
689 device_remove_file(ssi_private->dev, &ssi_private->dev_attr); 699 device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
690 700
701 snd_soc_unregister_dai(&ssi_private->cpu_dai);
702
691 kfree(ssi_private); 703 kfree(ssi_private);
692} 704}
693EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 705EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 86923299bc10..9eb1ce185bd0 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -187,7 +187,8 @@ static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
187 * If this is the first stream open, then grab the IRQ and program most of 187 * If this is the first stream open, then grab the IRQ and program most of
188 * the PSC registers. 188 * the PSC registers.
189 */ 189 */
190static int psc_i2s_startup(struct snd_pcm_substream *substream) 190static int psc_i2s_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
191{ 192{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 194 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -220,7 +221,8 @@ static int psc_i2s_startup(struct snd_pcm_substream *substream)
220} 221}
221 222
222static int psc_i2s_hw_params(struct snd_pcm_substream *substream, 223static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
223 struct snd_pcm_hw_params *params) 224 struct snd_pcm_hw_params *params,
225 struct snd_soc_dai *dai)
224{ 226{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 227 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 228 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -256,7 +258,8 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
256 return 0; 258 return 0;
257} 259}
258 260
259static int psc_i2s_hw_free(struct snd_pcm_substream *substream) 261static int psc_i2s_hw_free(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
260{ 263{
261 snd_pcm_set_runtime_buffer(substream, NULL); 264 snd_pcm_set_runtime_buffer(substream, NULL);
262 return 0; 265 return 0;
@@ -268,7 +271,8 @@ static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
268 * This function is called by ALSA to start, stop, pause, and resume the DMA 271 * This function is called by ALSA to start, stop, pause, and resume the DMA
269 * transfer of data. 272 * transfer of data.
270 */ 273 */
271static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 274static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
275 struct snd_soc_dai *dai)
272{ 276{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 278 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -277,7 +281,7 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
277 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs; 281 struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs;
278 u16 imr; 282 u16 imr;
279 u8 psc_cmd; 283 u8 psc_cmd;
280 long flags; 284 unsigned long flags;
281 285
282 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) 286 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
283 s = &psc_i2s->capture; 287 s = &psc_i2s->capture;
@@ -383,7 +387,8 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
383 * 387 *
384 * Shutdown the PSC if there are no other substreams open. 388 * Shutdown the PSC if there are no other substreams open.
385 */ 389 */
386static void psc_i2s_shutdown(struct snd_pcm_substream *substream) 390static void psc_i2s_shutdown(struct snd_pcm_substream *substream,
391 struct snd_soc_dai *dai)
387{ 392{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 393 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 394 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -464,7 +469,6 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
464 * psc_i2s_dai_template: template CPU Digital Audio Interface 469 * psc_i2s_dai_template: template CPU Digital Audio Interface
465 */ 470 */
466static struct snd_soc_dai psc_i2s_dai_template = { 471static struct snd_soc_dai psc_i2s_dai_template = {
467 .type = SND_SOC_DAI_I2S,
468 .playback = { 472 .playback = {
469 .channels_min = 2, 473 .channels_min = 2,
470 .channels_max = 2, 474 .channels_max = 2,
@@ -483,8 +487,6 @@ static struct snd_soc_dai psc_i2s_dai_template = {
483 .hw_free = psc_i2s_hw_free, 487 .hw_free = psc_i2s_hw_free,
484 .shutdown = psc_i2s_shutdown, 488 .shutdown = psc_i2s_shutdown,
485 .trigger = psc_i2s_trigger, 489 .trigger = psc_i2s_trigger,
486 },
487 .dai_ops = {
488 .set_sysclk = psc_i2s_set_sysclk, 490 .set_sysclk = psc_i2s_set_sysclk,
489 .set_fmt = psc_i2s_set_fmt, 491 .set_fmt = psc_i2s_set_fmt,
490 }, 492 },
@@ -699,9 +701,11 @@ static ssize_t psc_i2s_stat_store(struct device *dev,
699 return count; 701 return count;
700} 702}
701 703
702DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); 704static DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL);
703DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); 705static DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show,
704DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, psc_i2s_stat_store); 706 psc_i2s_stat_store);
707static DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show,
708 psc_i2s_stat_store);
705 709
706/* --------------------------------------------------------------------- 710/* ---------------------------------------------------------------------
707 * OF platform bus binding code: 711 * OF platform bus binding code:
@@ -819,11 +823,13 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
819 823
820 /* Register the SYSFS files */ 824 /* Register the SYSFS files */
821 rc = device_create_file(psc_i2s->dev, &dev_attr_status); 825 rc = device_create_file(psc_i2s->dev, &dev_attr_status);
822 rc = device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); 826 rc |= device_create_file(psc_i2s->dev, &dev_attr_capture_overrun);
823 rc = device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); 827 rc |= device_create_file(psc_i2s->dev, &dev_attr_playback_underrun);
824 if (rc) 828 if (rc)
825 dev_info(psc_i2s->dev, "error creating sysfs files\n"); 829 dev_info(psc_i2s->dev, "error creating sysfs files\n");
826 830
831 snd_soc_register_platform(&psc_i2s_pcm_soc_platform);
832
827 /* Tell the ASoC OF helpers about it */ 833 /* Tell the ASoC OF helpers about it */
828 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node, 834 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
829 &psc_i2s->dai); 835 &psc_i2s->dai);
@@ -837,6 +843,8 @@ static int __devexit psc_i2s_of_remove(struct of_device *op)
837 843
838 dev_dbg(&op->dev, "psc_i2s_remove()\n"); 844 dev_dbg(&op->dev, "psc_i2s_remove()\n");
839 845
846 snd_soc_unregister_platform(&psc_i2s_pcm_soc_platform);
847
840 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task); 848 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
841 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task); 849 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
842 850
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 94f89debde1f..bcec3f60bad9 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -29,7 +29,7 @@
29struct mpc8610_hpcd_data { 29struct mpc8610_hpcd_data {
30 struct snd_soc_device sound_devdata; 30 struct snd_soc_device sound_devdata;
31 struct snd_soc_dai_link dai; 31 struct snd_soc_dai_link dai;
32 struct snd_soc_machine machine; 32 struct snd_soc_card machine;
33 unsigned int dai_format; 33 unsigned int dai_format;
34 unsigned int codec_clk_direction; 34 unsigned int codec_clk_direction;
35 unsigned int cpu_clk_direction; 35 unsigned int cpu_clk_direction;
@@ -185,7 +185,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
185/** 185/**
186 * mpc8610_hpcd_machine: ASoC machine data 186 * mpc8610_hpcd_machine: ASoC machine data
187 */ 187 */
188static struct snd_soc_machine mpc8610_hpcd_machine = { 188static struct snd_soc_card mpc8610_hpcd_machine = {
189 .probe = mpc8610_hpcd_machine_probe, 189 .probe = mpc8610_hpcd_machine_probe,
190 .remove = mpc8610_hpcd_machine_remove, 190 .remove = mpc8610_hpcd_machine_remove,
191 .name = "MPC8610 HPCD", 191 .name = "MPC8610 HPCD",
@@ -465,9 +465,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
465 goto error; 465 goto error;
466 } 466 }
467 467
468 machine_data->sound_devdata.machine = &mpc8610_hpcd_machine; 468 machine_data->sound_devdata.card = &mpc8610_hpcd_machine;
469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270; 469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270;
470 machine_data->sound_devdata.platform = &fsl_soc_platform; 470 machine_data->machine.platform = &fsl_soc_platform;
471 471
472 sound_device->dev.platform_data = machine_data; 472 sound_device->dev.platform_data = machine_data;
473 473
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
index 0382fdac51cd..8bc5cd9e972f 100644
--- a/sound/soc/fsl/soc-of-simple.c
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -31,7 +31,7 @@ struct of_snd_soc_device {
31 int id; 31 int id;
32 struct list_head list; 32 struct list_head list;
33 struct snd_soc_device device; 33 struct snd_soc_device device;
34 struct snd_soc_machine machine; 34 struct snd_soc_card card;
35 struct snd_soc_dai_link dai_link; 35 struct snd_soc_dai_link dai_link;
36 struct platform_device *pdev; 36 struct platform_device *pdev;
37 struct device_node *platform_node; 37 struct device_node *platform_node;
@@ -58,9 +58,9 @@ of_snd_soc_get_device(struct device_node *codec_node)
58 /* Initialize the structure and add it to the global list */ 58 /* Initialize the structure and add it to the global list */
59 of_soc->codec_node = codec_node; 59 of_soc->codec_node = codec_node;
60 of_soc->id = of_snd_soc_next_index++; 60 of_soc->id = of_snd_soc_next_index++;
61 of_soc->machine.dai_link = &of_soc->dai_link; 61 of_soc->card.dai_link = &of_soc->dai_link;
62 of_soc->machine.num_links = 1; 62 of_soc->card.num_links = 1;
63 of_soc->device.machine = &of_soc->machine; 63 of_soc->device.card = &of_soc->card;
64 of_soc->dai_link.ops = &of_snd_soc_ops; 64 of_soc->dai_link.ops = &of_snd_soc_ops;
65 list_add(&of_soc->list, &of_snd_soc_device_list); 65 list_add(&of_soc->list, &of_snd_soc_device_list);
66 66
@@ -158,8 +158,8 @@ int of_snd_soc_register_platform(struct snd_soc_platform *platform,
158 158
159 of_soc->platform_node = node; 159 of_soc->platform_node = node;
160 of_soc->dai_link.cpu_dai = cpu_dai; 160 of_soc->dai_link.cpu_dai = cpu_dai;
161 of_soc->device.platform = platform; 161 of_soc->card.platform = platform;
162 of_soc->machine.name = of_soc->dai_link.cpu_dai->name; 162 of_soc->card.name = of_soc->dai_link.cpu_dai->name;
163 163
164 /* Now try to register the SoC device */ 164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc); 165 of_snd_soc_register_device(of_soc);
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index aea27e70043c..4f7f04014585 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,6 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
3 depends on ARCH_OMAP && SND_SOC 3 depends on ARCH_OMAP
4 4
5config SND_OMAP_SOC_MCBSP 5config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
@@ -10,6 +10,48 @@ config SND_OMAP_SOC_N810
10 tristate "SoC Audio support for Nokia N810" 10 tristate "SoC Audio support for Nokia N810"
11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 11 depends on SND_OMAP_SOC && MACH_NOKIA_N810
12 select SND_OMAP_SOC_MCBSP 12 select SND_OMAP_SOC_MCBSP
13 select OMAP_MUX
13 select SND_SOC_TLV320AIC3X 14 select SND_SOC_TLV320AIC3X
14 help 15 help
15 Say Y if you want to add support for SoC audio on Nokia N810. 16 Say Y if you want to add support for SoC audio on Nokia N810.
17
18config SND_OMAP_SOC_OSK5912
19 tristate "SoC Audio support for omap osk5912"
20 depends on SND_OMAP_SOC && MACH_OMAP_OSK
21 select SND_OMAP_SOC_MCBSP
22 select SND_SOC_TLV320AIC23
23 help
24 Say Y if you want to add support for SoC audio on osk5912.
25
26config SND_OMAP_SOC_OVERO
27 tristate "SoC Audio support for Gumstix Overo"
28 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO
29 select SND_OMAP_SOC_MCBSP
30 select SND_SOC_TWL4030
31 help
32 Say Y if you want to add support for SoC audio on the Gumstix Overo.
33
34config SND_OMAP_SOC_OMAP2EVM
35 tristate "SoC Audio support for OMAP2EVM board"
36 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM
37 select SND_OMAP_SOC_MCBSP
38 select SND_SOC_TWL4030
39 help
40 Say Y if you want to add support for SoC audio on the omap2evm board.
41
42config SND_OMAP_SOC_SDP3430
43 tristate "SoC Audio support for Texas Instruments SDP3430"
44 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
45 select SND_OMAP_SOC_MCBSP
46 select SND_SOC_TWL4030
47 help
48 Say Y if you want to add support for SoC audio on Texas Instruments
49 SDP3430.
50
51config SND_OMAP_SOC_OMAP3_PANDORA
52 tristate "SoC Audio support for OMAP3 Pandora"
53 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
54 select SND_OMAP_SOC_MCBSP
55 select SND_SOC_TWL4030
56 help
57 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index d8d8d58075e3..76fedd96e365 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -7,5 +7,15 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
7 7
8# OMAP Machine Support 8# OMAP Machine Support
9snd-soc-n810-objs := n810.o 9snd-soc-n810-objs := n810.o
10snd-soc-osk5912-objs := osk5912.o
11snd-soc-overo-objs := overo.o
12snd-soc-omap2evm-objs := omap2evm.o
13snd-soc-sdp3430-objs := sdp3430.o
14snd-soc-omap3pandora-objs := omap3pandora.o
10 15
11obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 16obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
17obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
18obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
19obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
20obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
21obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index d166b6b2a60d..25593fee9121 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -70,9 +70,13 @@ static void n810_ext_control(struct snd_soc_codec *codec)
70 70
71static int n810_startup(struct snd_pcm_substream *substream) 71static int n810_startup(struct snd_pcm_substream *substream)
72{ 72{
73 struct snd_pcm_runtime *runtime = substream->runtime;
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_codec *codec = rtd->socdev->codec; 75 struct snd_soc_codec *codec = rtd->socdev->codec;
75 76
77 snd_pcm_hw_constraint_minmax(runtime,
78 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
79
76 n810_ext_control(codec); 80 n810_ext_control(codec);
77 return clk_enable(sys_clkout2); 81 return clk_enable(sys_clkout2);
78} 82}
@@ -247,9 +251,9 @@ static int n810_aic33_init(struct snd_soc_codec *codec)
247 int i, err; 251 int i, err;
248 252
249 /* Not connected */ 253 /* Not connected */
250 snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); 254 snd_soc_dapm_nc_pin(codec, "MONO_LOUT");
251 snd_soc_dapm_disable_pin(codec, "HPLCOM"); 255 snd_soc_dapm_nc_pin(codec, "HPLCOM");
252 snd_soc_dapm_disable_pin(codec, "HPRCOM"); 256 snd_soc_dapm_nc_pin(codec, "HPRCOM");
253 257
254 /* Add N810 specific controls */ 258 /* Add N810 specific controls */
255 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) { 259 for (i = 0; i < ARRAY_SIZE(aic33_n810_controls); i++) {
@@ -282,8 +286,9 @@ static struct snd_soc_dai_link n810_dai = {
282}; 286};
283 287
284/* Audio machine driver */ 288/* Audio machine driver */
285static struct snd_soc_machine snd_soc_machine_n810 = { 289static struct snd_soc_card snd_soc_n810 = {
286 .name = "N810", 290 .name = "N810",
291 .platform = &omap_soc_platform,
287 .dai_link = &n810_dai, 292 .dai_link = &n810_dai,
288 .num_links = 1, 293 .num_links = 1,
289}; 294};
@@ -298,8 +303,7 @@ static struct aic3x_setup_data n810_aic33_setup = {
298 303
299/* Audio subsystem */ 304/* Audio subsystem */
300static struct snd_soc_device n810_snd_devdata = { 305static struct snd_soc_device n810_snd_devdata = {
301 .machine = &snd_soc_machine_n810, 306 .card = &snd_soc_n810,
302 .platform = &omap_soc_platform,
303 .codec_dev = &soc_codec_dev_aic3x, 307 .codec_dev = &soc_codec_dev_aic3x,
304 .codec_data = &n810_aic33_setup, 308 .codec_data = &n810_aic33_setup,
305}; 309};
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 35310e16d7f3..ec5e18a78758 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -36,13 +36,12 @@
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38 38
39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_44100 | \ 39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
40 SNDRV_PCM_RATE_48000 | \
41 SNDRV_PCM_RATE_KNOT)
42 40
43struct omap_mcbsp_data { 41struct omap_mcbsp_data {
44 unsigned int bus_id; 42 unsigned int bus_id;
45 struct omap_mcbsp_reg_cfg regs; 43 struct omap_mcbsp_reg_cfg regs;
44 unsigned int fmt;
46 /* 45 /*
47 * Flags indicating is the bus already activated and configured by 46 * Flags indicating is the bus already activated and configured by
48 * another substream 47 * another substream
@@ -59,12 +58,7 @@ static struct omap_mcbsp_data mcbsp_data[NUM_LINKS];
59 * Stream DMA parameters. DMA request line and port address are set runtime 58 * Stream DMA parameters. DMA request line and port address are set runtime
60 * since they are different between OMAP1 and later OMAPs 59 * since they are different between OMAP1 and later OMAPs
61 */ 60 */
62static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2] = { 61static struct omap_pcm_dma_data omap_mcbsp_dai_dma_params[NUM_LINKS][2];
63{
64 { .name = "I2S PCM Stereo out", },
65 { .name = "I2S PCM Stereo in", },
66},
67};
68 62
69#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX) 63#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
70static const int omap1_dma_reqs[][2] = { 64static const int omap1_dma_reqs[][2] = {
@@ -84,11 +78,22 @@ static const unsigned long omap1_mcbsp_port[][2] = {
84static const int omap1_dma_reqs[][2] = {}; 78static const int omap1_dma_reqs[][2] = {};
85static const unsigned long omap1_mcbsp_port[][2] = {}; 79static const unsigned long omap1_mcbsp_port[][2] = {};
86#endif 80#endif
87#if defined(CONFIG_ARCH_OMAP2420) 81
88static const int omap2420_dma_reqs[][2] = { 82#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
83static const int omap24xx_dma_reqs[][2] = {
89 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX }, 84 { OMAP24XX_DMA_MCBSP1_TX, OMAP24XX_DMA_MCBSP1_RX },
90 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX }, 85 { OMAP24XX_DMA_MCBSP2_TX, OMAP24XX_DMA_MCBSP2_RX },
86#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
87 { OMAP24XX_DMA_MCBSP3_TX, OMAP24XX_DMA_MCBSP3_RX },
88 { OMAP24XX_DMA_MCBSP4_TX, OMAP24XX_DMA_MCBSP4_RX },
89 { OMAP24XX_DMA_MCBSP5_TX, OMAP24XX_DMA_MCBSP5_RX },
90#endif
91}; 91};
92#else
93static const int omap24xx_dma_reqs[][2] = {};
94#endif
95
96#if defined(CONFIG_ARCH_OMAP2420)
92static const unsigned long omap2420_mcbsp_port[][2] = { 97static const unsigned long omap2420_mcbsp_port[][2] = {
93 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, 98 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1,
94 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 }, 99 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR1 },
@@ -96,11 +101,45 @@ static const unsigned long omap2420_mcbsp_port[][2] = {
96 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 }, 101 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR1 },
97}; 102};
98#else 103#else
99static const int omap2420_dma_reqs[][2] = {};
100static const unsigned long omap2420_mcbsp_port[][2] = {}; 104static const unsigned long omap2420_mcbsp_port[][2] = {};
101#endif 105#endif
102 106
103static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 107#if defined(CONFIG_ARCH_OMAP2430)
108static const unsigned long omap2430_mcbsp_port[][2] = {
109 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
110 OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
111 { OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
112 OMAP24XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
113 { OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
114 OMAP2430_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
115 { OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
116 OMAP2430_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
117 { OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
118 OMAP2430_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
119};
120#else
121static const unsigned long omap2430_mcbsp_port[][2] = {};
122#endif
123
124#if defined(CONFIG_ARCH_OMAP34XX)
125static const unsigned long omap34xx_mcbsp_port[][2] = {
126 { OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
127 OMAP34XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
128 { OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
129 OMAP34XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
130 { OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
131 OMAP34XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
132 { OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
133 OMAP34XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
134 { OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DXR,
135 OMAP34XX_MCBSP5_BASE + OMAP_MCBSP_REG_DRR },
136};
137#else
138static const unsigned long omap34xx_mcbsp_port[][2] = {};
139#endif
140
141static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
142 struct snd_soc_dai *dai)
104{ 143{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -113,7 +152,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
113 return err; 152 return err;
114} 153}
115 154
116static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) 155static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
156 struct snd_soc_dai *dai)
117{ 157{
118 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -125,7 +165,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
125 } 165 }
126} 166}
127 167
128static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) 168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
169 struct snd_soc_dai *dai)
129{ 170{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 172 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -154,27 +195,34 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
154} 195}
155 196
156static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 197static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
157 struct snd_pcm_hw_params *params) 198 struct snd_pcm_hw_params *params,
199 struct snd_soc_dai *dai)
158{ 200{
159 struct snd_soc_pcm_runtime *rtd = substream->private_data; 201 struct snd_soc_pcm_runtime *rtd = substream->private_data;
160 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 202 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
161 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 203 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
162 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 204 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
163 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 205 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
206 int wlen, channels;
164 unsigned long port; 207 unsigned long port;
165 208
166 if (cpu_class_is_omap1()) { 209 if (cpu_class_is_omap1()) {
167 dma = omap1_dma_reqs[bus_id][substream->stream]; 210 dma = omap1_dma_reqs[bus_id][substream->stream];
168 port = omap1_mcbsp_port[bus_id][substream->stream]; 211 port = omap1_mcbsp_port[bus_id][substream->stream];
169 } else if (cpu_is_omap2420()) { 212 } else if (cpu_is_omap2420()) {
170 dma = omap2420_dma_reqs[bus_id][substream->stream]; 213 dma = omap24xx_dma_reqs[bus_id][substream->stream];
171 port = omap2420_mcbsp_port[bus_id][substream->stream]; 214 port = omap2420_mcbsp_port[bus_id][substream->stream];
215 } else if (cpu_is_omap2430()) {
216 dma = omap24xx_dma_reqs[bus_id][substream->stream];
217 port = omap2430_mcbsp_port[bus_id][substream->stream];
218 } else if (cpu_is_omap343x()) {
219 dma = omap24xx_dma_reqs[bus_id][substream->stream];
220 port = omap34xx_mcbsp_port[bus_id][substream->stream];
172 } else { 221 } else {
173 /*
174 * TODO: Add support for 2430 and 3430
175 */
176 return -ENODEV; 222 return -ENODEV;
177 } 223 }
224 omap_mcbsp_dai_dma_params[id][substream->stream].name =
225 substream->stream ? "Audio Capture" : "Audio Playback";
178 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 226 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
179 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 227 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
180 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 228 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
@@ -184,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
184 return 0; 232 return 0;
185 } 233 }
186 234
187 switch (params_channels(params)) { 235 channels = params_channels(params);
236 switch (channels) {
188 case 2: 237 case 2:
189 /* Set 1 word per (McBPSP) frame and use dual-phase frames */ 238 /* Use dual-phase frames */
190 regs->rcr2 |= RFRLEN2(1 - 1) | RPHASE; 239 regs->rcr2 |= RPHASE;
240 regs->xcr2 |= XPHASE;
241 case 1:
242 /* Set 1 word per (McBSP) frame */
243 regs->rcr2 |= RFRLEN2(1 - 1);
191 regs->rcr1 |= RFRLEN1(1 - 1); 244 regs->rcr1 |= RFRLEN1(1 - 1);
192 regs->xcr2 |= XFRLEN2(1 - 1) | XPHASE; 245 regs->xcr2 |= XFRLEN2(1 - 1);
193 regs->xcr1 |= XFRLEN1(1 - 1); 246 regs->xcr1 |= XFRLEN1(1 - 1);
194 break; 247 break;
195 default: 248 default:
@@ -200,19 +253,29 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
200 switch (params_format(params)) { 253 switch (params_format(params)) {
201 case SNDRV_PCM_FORMAT_S16_LE: 254 case SNDRV_PCM_FORMAT_S16_LE:
202 /* Set word lengths */ 255 /* Set word lengths */
256 wlen = 16;
203 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16); 257 regs->rcr2 |= RWDLEN2(OMAP_MCBSP_WORD_16);
204 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16); 258 regs->rcr1 |= RWDLEN1(OMAP_MCBSP_WORD_16);
205 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16); 259 regs->xcr2 |= XWDLEN2(OMAP_MCBSP_WORD_16);
206 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16); 260 regs->xcr1 |= XWDLEN1(OMAP_MCBSP_WORD_16);
207 /* Set FS period and length in terms of bit clock periods */
208 regs->srgr2 |= FPER(16 * 2 - 1);
209 regs->srgr1 |= FWID(16 - 1);
210 break; 261 break;
211 default: 262 default:
212 /* Unsupported PCM format */ 263 /* Unsupported PCM format */
213 return -EINVAL; 264 return -EINVAL;
214 } 265 }
215 266
267 /* Set FS period and length in terms of bit clock periods */
268 switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
269 case SND_SOC_DAIFMT_I2S:
270 regs->srgr2 |= FPER(wlen * 2 - 1);
271 regs->srgr1 |= FWID(wlen - 1);
272 break;
273 case SND_SOC_DAIFMT_DSP_B:
274 regs->srgr2 |= FPER(wlen * channels - 1);
275 regs->srgr1 |= FWID(wlen * channels - 2);
276 break;
277 }
278
216 omap_mcbsp_config(bus_id, &mcbsp_data->regs); 279 omap_mcbsp_config(bus_id, &mcbsp_data->regs);
217 mcbsp_data->configured = 1; 280 mcbsp_data->configured = 1;
218 281
@@ -232,6 +295,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
232 if (mcbsp_data->configured) 295 if (mcbsp_data->configured)
233 return 0; 296 return 0;
234 297
298 mcbsp_data->fmt = fmt;
235 memset(regs, 0, sizeof(*regs)); 299 memset(regs, 0, sizeof(*regs));
236 /* Generic McBSP register settings */ 300 /* Generic McBSP register settings */
237 regs->spcr2 |= XINTM(3) | FREE; 301 regs->spcr2 |= XINTM(3) | FREE;
@@ -245,6 +309,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
245 regs->rcr2 |= RDATDLY(1); 309 regs->rcr2 |= RDATDLY(1);
246 regs->xcr2 |= XDATDLY(1); 310 regs->xcr2 |= XDATDLY(1);
247 break; 311 break;
312 case SND_SOC_DAIFMT_DSP_B:
313 /* 0-bit data delay */
314 regs->rcr2 |= RDATDLY(0);
315 regs->xcr2 |= XDATDLY(0);
316 break;
248 default: 317 default:
249 /* Unsupported data format */ 318 /* Unsupported data format */
250 return -EINVAL; 319 return -EINVAL;
@@ -310,7 +379,7 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
310 int clk_id) 379 int clk_id)
311{ 380{
312 int sel_bit; 381 int sel_bit;
313 u16 reg; 382 u16 reg, reg_devconf1 = OMAP243X_CONTROL_DEVCONF1;
314 383
315 if (cpu_class_is_omap1()) { 384 if (cpu_class_is_omap1()) {
316 /* OMAP1's can use only external source clock */ 385 /* OMAP1's can use only external source clock */
@@ -320,6 +389,12 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
320 return 0; 389 return 0;
321 } 390 }
322 391
392 if (cpu_is_omap2420() && mcbsp_data->bus_id > 1)
393 return -EINVAL;
394
395 if (cpu_is_omap343x())
396 reg_devconf1 = OMAP343X_CONTROL_DEVCONF1;
397
323 switch (mcbsp_data->bus_id) { 398 switch (mcbsp_data->bus_id) {
324 case 0: 399 case 0:
325 reg = OMAP2_CONTROL_DEVCONF0; 400 reg = OMAP2_CONTROL_DEVCONF0;
@@ -329,20 +404,26 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
329 reg = OMAP2_CONTROL_DEVCONF0; 404 reg = OMAP2_CONTROL_DEVCONF0;
330 sel_bit = 6; 405 sel_bit = 6;
331 break; 406 break;
332 /* TODO: Support for ports 3 - 5 in OMAP2430 and OMAP34xx */ 407 case 2:
408 reg = reg_devconf1;
409 sel_bit = 0;
410 break;
411 case 3:
412 reg = reg_devconf1;
413 sel_bit = 2;
414 break;
415 case 4:
416 reg = reg_devconf1;
417 sel_bit = 4;
418 break;
333 default: 419 default:
334 return -EINVAL; 420 return -EINVAL;
335 } 421 }
336 422
337 if (cpu_class_is_omap2()) { 423 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK)
338 if (clk_id == OMAP_MCBSP_SYSCLK_CLKS_FCLK) { 424 omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg);
339 omap_ctrl_writel(omap_ctrl_readl(reg) & 425 else
340 ~(1 << sel_bit), reg); 426 omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg);
341 } else {
342 omap_ctrl_writel(omap_ctrl_readl(reg) |
343 (1 << sel_bit), reg);
344 }
345 }
346 427
347 return 0; 428 return 0;
348} 429}
@@ -376,39 +457,61 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
376 return err; 457 return err;
377} 458}
378 459
379struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS] = { 460#define OMAP_MCBSP_DAI_BUILDER(link_id) \
380{ 461{ \
381 .name = "omap-mcbsp-dai", 462 .name = "omap-mcbsp-dai-"#link_id, \
382 .id = 0, 463 .id = (link_id), \
383 .type = SND_SOC_DAI_I2S, 464 .playback = { \
384 .playback = { 465 .channels_min = 1, \
385 .channels_min = 2, 466 .channels_max = 2, \
386 .channels_max = 2, 467 .rates = OMAP_MCBSP_RATES, \
387 .rates = OMAP_MCBSP_RATES, 468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
388 .formats = SNDRV_PCM_FMTBIT_S16_LE, 469 }, \
389 }, 470 .capture = { \
390 .capture = { 471 .channels_min = 1, \
391 .channels_min = 2, 472 .channels_max = 2, \
392 .channels_max = 2, 473 .rates = OMAP_MCBSP_RATES, \
393 .rates = OMAP_MCBSP_RATES, 474 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, 475 }, \
395 }, 476 .ops = { \
396 .ops = { 477 .startup = omap_mcbsp_dai_startup, \
397 .startup = omap_mcbsp_dai_startup, 478 .shutdown = omap_mcbsp_dai_shutdown, \
398 .shutdown = omap_mcbsp_dai_shutdown, 479 .trigger = omap_mcbsp_dai_trigger, \
399 .trigger = omap_mcbsp_dai_trigger, 480 .hw_params = omap_mcbsp_dai_hw_params, \
400 .hw_params = omap_mcbsp_dai_hw_params, 481 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
401 }, 482 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
402 .dai_ops = { 483 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
403 .set_fmt = omap_mcbsp_dai_set_dai_fmt, 484 }, \
404 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, 485 .private_data = &mcbsp_data[(link_id)].bus_id, \
405 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, 486}
406 }, 487
407 .private_data = &mcbsp_data[0].bus_id, 488struct snd_soc_dai omap_mcbsp_dai[] = {
408}, 489 OMAP_MCBSP_DAI_BUILDER(0),
490 OMAP_MCBSP_DAI_BUILDER(1),
491#if NUM_LINKS >= 3
492 OMAP_MCBSP_DAI_BUILDER(2),
493#endif
494#if NUM_LINKS == 5
495 OMAP_MCBSP_DAI_BUILDER(3),
496 OMAP_MCBSP_DAI_BUILDER(4),
497#endif
409}; 498};
499
410EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 500EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
411 501
502static int __init snd_omap_mcbsp_init(void)
503{
504 return snd_soc_register_dais(omap_mcbsp_dai,
505 ARRAY_SIZE(omap_mcbsp_dai));
506}
507module_init(snd_omap_mcbsp_init);
508
509static void __exit snd_omap_mcbsp_exit(void)
510{
511 snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai));
512}
513module_exit(snd_omap_mcbsp_exit);
514
412MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 515MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
413MODULE_DESCRIPTION("OMAP I2S SoC Interface"); 516MODULE_DESCRIPTION("OMAP I2S SoC Interface");
414MODULE_LICENSE("GPL"); 517MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index ed8afb550671..df7ad13ba73d 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -38,11 +38,17 @@ enum omap_mcbsp_div {
38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ 38 OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
39}; 39};
40 40
41/* 41#if defined(CONFIG_ARCH_OMAP2420)
42 * REVISIT: Preparation for the ASoC v2. Let the number of available links to 42#define NUM_LINKS 2
43 * be same than number of McBSP ports found in OMAP(s) we are compiling for. 43#endif
44 */ 44#if defined(CONFIG_ARCH_OMAP15XX) || defined(CONFIG_ARCH_OMAP16XX)
45#define NUM_LINKS 1 45#undef NUM_LINKS
46#define NUM_LINKS 3
47#endif
48#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX)
49#undef NUM_LINKS
50#define NUM_LINKS 5
51#endif
46 52
47extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS]; 53extern struct snd_soc_dai omap_mcbsp_dai[NUM_LINKS];
48 54
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 690bfeaec4a0..b0362dfd5b71 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -97,7 +97,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
97 prtd->dma_data = dma_data; 97 prtd->dma_data = dma_data;
98 err = omap_request_dma(dma_data->dma_req, dma_data->name, 98 err = omap_request_dma(dma_data->dma_req, dma_data->name,
99 omap_pcm_dma_irq, substream, &prtd->dma_ch); 99 omap_pcm_dma_irq, substream, &prtd->dma_ch);
100 if (!cpu_is_omap1510()) { 100 if (!err && !cpu_is_omap1510()) {
101 /* 101 /*
102 * Link channel with itself so DMA doesn't need any 102 * Link channel with itself so DMA doesn't need any
103 * reprogramming while looping the buffer 103 * reprogramming while looping the buffer
@@ -147,12 +147,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; 147 dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC;
148 dma_params.src_start = runtime->dma_addr; 148 dma_params.src_start = runtime->dma_addr;
149 dma_params.dst_start = dma_data->port_addr; 149 dma_params.dst_start = dma_data->port_addr;
150 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
150 } else { 151 } else {
151 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 152 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
152 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 153 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
153 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; 154 dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
154 dma_params.src_start = dma_data->port_addr; 155 dma_params.src_start = dma_data->port_addr;
155 dma_params.dst_start = runtime->dma_addr; 156 dma_params.dst_start = runtime->dma_addr;
157 dma_params.src_port = OMAP_DMA_PORT_MPUI;
156 } 158 }
157 /* 159 /*
158 * Set DMA transfer frame size equal to ALSA period size and frame 160 * Set DMA transfer frame size equal to ALSA period size and frame
@@ -231,7 +233,7 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
231 if (ret < 0) 233 if (ret < 0)
232 goto out; 234 goto out;
233 235
234 prtd = kzalloc(sizeof(prtd), GFP_KERNEL); 236 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
235 if (prtd == NULL) { 237 if (prtd == NULL) {
236 ret = -ENOMEM; 238 ret = -ENOMEM;
237 goto out; 239 goto out;
@@ -352,6 +354,18 @@ struct snd_soc_platform omap_soc_platform = {
352}; 354};
353EXPORT_SYMBOL_GPL(omap_soc_platform); 355EXPORT_SYMBOL_GPL(omap_soc_platform);
354 356
357static int __init omap_soc_platform_init(void)
358{
359 return snd_soc_register_platform(&omap_soc_platform);
360}
361module_init(omap_soc_platform_init);
362
363static void __exit omap_soc_platform_exit(void)
364{
365 snd_soc_unregister_platform(&omap_soc_platform);
366}
367module_exit(omap_soc_platform_exit);
368
355MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 369MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
356MODULE_DESCRIPTION("OMAP PCM DMA module"); 370MODULE_DESCRIPTION("OMAP PCM DMA module");
357MODULE_LICENSE("GPL"); 371MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
new file mode 100644
index 000000000000..0c2322dcf02a
--- /dev/null
+++ b/sound/soc/omap/omap2evm.c
@@ -0,0 +1,151 @@
1/*
2 * omap2evm.c -- SoC audio machine driver for omap2evm board
3 *
4 * Author: Arun KS <arunks@mistralsolutions.com>
5 *
6 * Based on sound/soc/omap/overo.c by Steve Sakoman
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * 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., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/clk.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <mach/hardware.h>
33#include <mach/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/twl4030.h"
39
40static int omap2evm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params,
42 struct snd_soc_dai *dai)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops omap2evm_ops = {
81 .hw_params = omap2evm_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link omap2evm_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &omap2evm_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_card snd_soc_omap2evm = {
95 .name = "omap2evm",
96 .platform = &omap_soc_platform,
97 .dai_link = &omap2evm_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device omap2evm_snd_devdata = {
103 .card = &snd_soc_omap2evm,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *omap2evm_snd_device;
108
109static int __init omap2evm_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap2evm()) {
114 pr_debug("Not omap2evm!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "omap2evm SoC init\n");
118
119 omap2evm_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!omap2evm_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(omap2evm_snd_device, &omap2evm_snd_devdata);
126 omap2evm_snd_devdata.dev = &omap2evm_snd_device->dev;
127 *(unsigned int *)omap2evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(omap2evm_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(omap2evm_snd_device);
138
139 return ret;
140}
141module_init(omap2evm_soc_init);
142
143static void __exit omap2evm_soc_exit(void)
144{
145 platform_device_unregister(omap2evm_snd_device);
146}
147module_exit(omap2evm_soc_exit);
148
149MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
150MODULE_DESCRIPTION("ALSA SoC omap2evm");
151MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
new file mode 100644
index 000000000000..fd24a4acd2f5
--- /dev/null
+++ b/sound/soc/omap/omap3beagle.c
@@ -0,0 +1,149 @@
1/*
2 * omap3beagle.c -- SoC audio for OMAP3 Beagle
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops omap3beagle_ops = {
78 .hw_params = omap3beagle_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link omap3beagle_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &omap3beagle_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_omap3beagle = {
92 .name = "omap3beagle",
93 .platform = &omap_soc_platform,
94 .dai_link = &omap3beagle_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device omap3beagle_snd_devdata = {
100 .card = &snd_soc_omap3beagle,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *omap3beagle_snd_device;
105
106static int __init omap3beagle_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_omap3_beagle()) {
111 pr_debug("Not OMAP3 Beagle!\n");
112 return -ENODEV;
113 }
114 pr_info("OMAP3 Beagle SoC init\n");
115
116 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!omap3beagle_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata);
123 omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
124 *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(omap3beagle_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(omap3beagle_snd_device);
135
136 return ret;
137}
138
139static void __exit omap3beagle_soc_exit(void)
140{
141 platform_device_unregister(omap3beagle_snd_device);
142}
143
144module_init(omap3beagle_soc_init);
145module_exit(omap3beagle_soc_exit);
146
147MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
148MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
149MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
new file mode 100644
index 000000000000..fcc2f5d9a878
--- /dev/null
+++ b/sound/soc/omap/omap3pandora.c
@@ -0,0 +1,324 @@
1/*
2 * omap3pandora.c -- SoC audio for Pandora Handheld Console
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <linux/gpio.h>
25#include <linux/delay.h>
26
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
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38#define OMAP3_PANDORA_DAC_POWER_GPIO 118
39#define OMAP3_PANDORA_AMP_POWER_GPIO 14
40
41#define PREFIX "ASoC omap3pandora: "
42
43static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
44 struct snd_soc_dai *cpu_dai, unsigned int fmt)
45{
46 int ret;
47
48 /* Set codec DAI configuration */
49 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
50 if (ret < 0) {
51 pr_err(PREFIX "can't set codec DAI configuration\n");
52 return ret;
53 }
54
55 /* Set cpu DAI configuration */
56 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
57 if (ret < 0) {
58 pr_err(PREFIX "can't set cpu DAI configuration\n");
59 return ret;
60 }
61
62 /* Set the codec system clock for DAC and ADC */
63 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
64 SND_SOC_CLOCK_IN);
65 if (ret < 0) {
66 pr_err(PREFIX "can't set codec system clock\n");
67 return ret;
68 }
69
70 /* Set McBSP clock to external */
71 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0,
72 SND_SOC_CLOCK_IN);
73 if (ret < 0) {
74 pr_err(PREFIX "can't set cpu system clock\n");
75 return ret;
76 }
77
78 ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 8);
79 if (ret < 0) {
80 pr_err(PREFIX "can't set SRG clock divider\n");
81 return ret;
82 }
83
84 return 0;
85}
86
87static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params)
89{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data;
91 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
92 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
93
94 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
95 SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBS_CFS);
98}
99
100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params)
102{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
104 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
105 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
106
107 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
108 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111}
112
113static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *k, int event)
115{
116 if (SND_SOC_DAPM_EVENT_ON(event)) {
117 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
118 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
119 } else {
120 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
121 mdelay(1);
122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
123 }
124
125 return 0;
126}
127
128/*
129 * Audio paths on Pandora board:
130 *
131 * |O| ---> PCM DAC +-> AMP -> Headphone Jack
132 * |M| A +--------> Line Out
133 * |A| <~~clk~~+
134 * |P| <--- TWL4030 <--------- Line In and MICs
135 */
136static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
137 SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
138 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
139 0, 0, NULL, 0, omap3pandora_hp_event,
140 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
141 SND_SOC_DAPM_HP("Headphone Jack", NULL),
142 SND_SOC_DAPM_LINE("Line Out", NULL),
143};
144
145static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
146 SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
147 SND_SOC_DAPM_MIC("Mic (external)", NULL),
148 SND_SOC_DAPM_LINE("Line In", NULL),
149};
150
151static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
152 {"Headphone Amplifier", NULL, "PCM DAC"},
153 {"Line Out", NULL, "PCM DAC"},
154 {"Headphone Jack", NULL, "Headphone Amplifier"},
155};
156
157static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
158 {"INL", NULL, "Line In"},
159 {"INR", NULL, "Line In"},
160 {"INL", NULL, "Mic (Internal)"},
161 {"INR", NULL, "Mic (external)"},
162};
163
164static int omap3pandora_out_init(struct snd_soc_codec *codec)
165{
166 int ret;
167
168 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
169 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
170 if (ret < 0)
171 return ret;
172
173 snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
174 ARRAY_SIZE(omap3pandora_out_map));
175
176 return snd_soc_dapm_sync(codec);
177}
178
179static int omap3pandora_in_init(struct snd_soc_codec *codec)
180{
181 int ret;
182
183 /* All TWL4030 output pins are floating */
184 snd_soc_dapm_nc_pin(codec, "OUTL"),
185 snd_soc_dapm_nc_pin(codec, "OUTR"),
186 snd_soc_dapm_nc_pin(codec, "EARPIECE"),
187 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"),
188 snd_soc_dapm_nc_pin(codec, "PREDRIVER"),
189 snd_soc_dapm_nc_pin(codec, "HSOL"),
190 snd_soc_dapm_nc_pin(codec, "HSOR"),
191 snd_soc_dapm_nc_pin(codec, "CARKITL"),
192 snd_soc_dapm_nc_pin(codec, "CARKITR"),
193 snd_soc_dapm_nc_pin(codec, "HFL"),
194 snd_soc_dapm_nc_pin(codec, "HFR"),
195
196 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
197 ARRAY_SIZE(omap3pandora_in_dapm_widgets));
198 if (ret < 0)
199 return ret;
200
201 snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
202 ARRAY_SIZE(omap3pandora_in_map));
203
204 return snd_soc_dapm_sync(codec);
205}
206
207static struct snd_soc_ops omap3pandora_out_ops = {
208 .hw_params = omap3pandora_out_hw_params,
209};
210
211static struct snd_soc_ops omap3pandora_in_ops = {
212 .hw_params = omap3pandora_in_hw_params,
213};
214
215/* Digital audio interface glue - connects codec <--> CPU */
216static struct snd_soc_dai_link omap3pandora_dai[] = {
217 {
218 .name = "PCM1773",
219 .stream_name = "HiFi Out",
220 .cpu_dai = &omap_mcbsp_dai[0],
221 .codec_dai = &twl4030_dai,
222 .ops = &omap3pandora_out_ops,
223 .init = omap3pandora_out_init,
224 }, {
225 .name = "TWL4030",
226 .stream_name = "Line/Mic In",
227 .cpu_dai = &omap_mcbsp_dai[1],
228 .codec_dai = &twl4030_dai,
229 .ops = &omap3pandora_in_ops,
230 .init = omap3pandora_in_init,
231 }
232};
233
234/* SoC card */
235static struct snd_soc_card snd_soc_card_omap3pandora = {
236 .name = "omap3pandora",
237 .platform = &omap_soc_platform,
238 .dai_link = omap3pandora_dai,
239 .num_links = ARRAY_SIZE(omap3pandora_dai),
240};
241
242/* Audio subsystem */
243static struct snd_soc_device omap3pandora_snd_data = {
244 .card = &snd_soc_card_omap3pandora,
245 .codec_dev = &soc_codec_dev_twl4030,
246};
247
248static struct platform_device *omap3pandora_snd_device;
249
250static int __init omap3pandora_soc_init(void)
251{
252 int ret;
253
254 if (!machine_is_omap3_pandora()) {
255 pr_debug(PREFIX "Not OMAP3 Pandora\n");
256 return -ENODEV;
257 }
258 pr_info("OMAP3 Pandora SoC init\n");
259
260 ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
261 if (ret) {
262 pr_err(PREFIX "Failed to get DAC power GPIO\n");
263 return ret;
264 }
265
266 ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
267 if (ret) {
268 pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
269 goto fail0;
270 }
271
272 ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
273 if (ret) {
274 pr_err(PREFIX "Failed to get amp power GPIO\n");
275 goto fail0;
276 }
277
278 ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
279 if (ret) {
280 pr_err(PREFIX "Failed to set amp power GPIO direction\n");
281 goto fail1;
282 }
283
284 omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
285 if (omap3pandora_snd_device == NULL) {
286 pr_err(PREFIX "Platform device allocation failed\n");
287 ret = -ENOMEM;
288 goto fail1;
289 }
290
291 platform_set_drvdata(omap3pandora_snd_device, &omap3pandora_snd_data);
292 omap3pandora_snd_data.dev = &omap3pandora_snd_device->dev;
293 *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */
294 *(unsigned int *)omap_mcbsp_dai[1].private_data = 3; /* McBSP4 */
295
296 ret = platform_device_add(omap3pandora_snd_device);
297 if (ret) {
298 pr_err(PREFIX "Unable to add platform device\n");
299 goto fail2;
300 }
301
302 return 0;
303
304fail2:
305 platform_device_put(omap3pandora_snd_device);
306fail1:
307 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
308fail0:
309 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
310 return ret;
311}
312module_init(omap3pandora_soc_init);
313
314static void __exit omap3pandora_soc_exit(void)
315{
316 platform_device_unregister(omap3pandora_snd_device);
317 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
318 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
319}
320module_exit(omap3pandora_soc_exit);
321
322MODULE_AUTHOR("Grazvydas Ignotas <notasas@gmail.com>");
323MODULE_DESCRIPTION("ALSA SoC OMAP3 Pandora");
324MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
new file mode 100644
index 000000000000..cd41a948df7b
--- /dev/null
+++ b/sound/soc/omap/osk5912.c
@@ -0,0 +1,232 @@
1/*
2 * osk5912.c -- SoC audio for OSK 5912
3 *
4 * Copyright (C) 2008 Mistral Solutions
5 *
6 * Contact: Arun KS <arunks@mistralsolutions.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * 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., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include <linux/clk.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <mach/hardware.h>
33#include <linux/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/tlv320aic23.h"
39
40#define CODEC_CLOCK 12000000
41
42static struct clk *tlv320aic23_mclk;
43
44static int osk_startup(struct snd_pcm_substream *substream)
45{
46 return clk_enable(tlv320aic23_mclk);
47}
48
49static void osk_shutdown(struct snd_pcm_substream *substream)
50{
51 clk_disable(tlv320aic23_mclk);
52}
53
54static int osk_hw_params(struct snd_pcm_substream *substream,
55 struct snd_pcm_hw_params *params)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
59 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
60 int err;
61
62 /* Set codec DAI configuration */
63 err = snd_soc_dai_set_fmt(codec_dai,
64 SND_SOC_DAIFMT_DSP_B |
65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) {
68 printk(KERN_ERR "can't set codec DAI configuration\n");
69 return err;
70 }
71
72 /* Set cpu DAI configuration */
73 err = snd_soc_dai_set_fmt(cpu_dai,
74 SND_SOC_DAIFMT_DSP_B |
75 SND_SOC_DAIFMT_NB_IF |
76 SND_SOC_DAIFMT_CBM_CFM);
77 if (err < 0) {
78 printk(KERN_ERR "can't set cpu DAI configuration\n");
79 return err;
80 }
81
82 /* Set the codec system clock for DAC and ADC */
83 err =
84 snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN);
85
86 if (err < 0) {
87 printk(KERN_ERR "can't set codec system clock\n");
88 return err;
89 }
90
91 return err;
92}
93
94static struct snd_soc_ops osk_ops = {
95 .startup = osk_startup,
96 .hw_params = osk_hw_params,
97 .shutdown = osk_shutdown,
98};
99
100static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
101 SND_SOC_DAPM_HP("Headphone Jack", NULL),
102 SND_SOC_DAPM_LINE("Line In", NULL),
103 SND_SOC_DAPM_MIC("Mic Jack", NULL),
104};
105
106static const struct snd_soc_dapm_route audio_map[] = {
107 {"Headphone Jack", NULL, "LHPOUT"},
108 {"Headphone Jack", NULL, "RHPOUT"},
109
110 {"LLINEIN", NULL, "Line In"},
111 {"RLINEIN", NULL, "Line In"},
112
113 {"MICIN", NULL, "Mic Jack"},
114};
115
116static int osk_tlv320aic23_init(struct snd_soc_codec *codec)
117{
118
119 /* Add osk5912 specific widgets */
120 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
121 ARRAY_SIZE(tlv320aic23_dapm_widgets));
122
123 /* Set up osk5912 specific audio path audio_map */
124 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
125
126 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
127 snd_soc_dapm_enable_pin(codec, "Line In");
128 snd_soc_dapm_enable_pin(codec, "Mic Jack");
129
130 snd_soc_dapm_sync(codec);
131
132 return 0;
133}
134
135/* Digital audio interface glue - connects codec <--> CPU */
136static struct snd_soc_dai_link osk_dai = {
137 .name = "TLV320AIC23",
138 .stream_name = "AIC23",
139 .cpu_dai = &omap_mcbsp_dai[0],
140 .codec_dai = &tlv320aic23_dai,
141 .init = osk_tlv320aic23_init,
142 .ops = &osk_ops,
143};
144
145/* Audio machine driver */
146static struct snd_soc_card snd_soc_card_osk = {
147 .name = "OSK5912",
148 .platform = &omap_soc_platform,
149 .dai_link = &osk_dai,
150 .num_links = 1,
151};
152
153/* Audio subsystem */
154static struct snd_soc_device osk_snd_devdata = {
155 .card = &snd_soc_card_osk,
156 .codec_dev = &soc_codec_dev_tlv320aic23,
157};
158
159static struct platform_device *osk_snd_device;
160
161static int __init osk_soc_init(void)
162{
163 int err;
164 u32 curRate;
165 struct device *dev;
166
167 if (!(machine_is_omap_osk()))
168 return -ENODEV;
169
170 osk_snd_device = platform_device_alloc("soc-audio", -1);
171 if (!osk_snd_device)
172 return -ENOMEM;
173
174 platform_set_drvdata(osk_snd_device, &osk_snd_devdata);
175 osk_snd_devdata.dev = &osk_snd_device->dev;
176 *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */
177 err = platform_device_add(osk_snd_device);
178 if (err)
179 goto err1;
180
181 dev = &osk_snd_device->dev;
182
183 tlv320aic23_mclk = clk_get(dev, "mclk");
184 if (IS_ERR(tlv320aic23_mclk)) {
185 printk(KERN_ERR "Could not get mclk clock\n");
186 return -ENODEV;
187 }
188
189 if (clk_get_usecount(tlv320aic23_mclk) > 0) {
190 /* MCLK is already in use */
191 printk(KERN_WARNING
192 "MCLK in use at %d Hz. We change it to %d Hz\n",
193 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK);
194 }
195
196 /*
197 * Configure 12 MHz output on MCLK.
198 */
199 curRate = (uint) clk_get_rate(tlv320aic23_mclk);
200 if (curRate != CODEC_CLOCK) {
201 if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) {
202 printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n");
203 err = -ECANCELED;
204 goto err1;
205 }
206 }
207
208 printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n",
209 (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK,
210 clk_get_usecount(tlv320aic23_mclk));
211
212 return 0;
213err1:
214 clk_put(tlv320aic23_mclk);
215 platform_device_del(osk_snd_device);
216 platform_device_put(osk_snd_device);
217
218 return err;
219
220}
221
222static void __exit osk_soc_exit(void)
223{
224 platform_device_unregister(osk_snd_device);
225}
226
227module_init(osk_soc_init);
228module_exit(osk_soc_exit);
229
230MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
231MODULE_DESCRIPTION("ALSA SoC OSK 5912");
232MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
new file mode 100644
index 000000000000..a72dc4e159e5
--- /dev/null
+++ b/sound/soc/omap/overo.c
@@ -0,0 +1,148 @@
1/*
2 * overo.c -- SoC audio for Gumstix Overo
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int overo_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops overo_ops = {
78 .hw_params = overo_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link overo_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &overo_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_overo = {
92 .name = "overo",
93 .platform = &omap_soc_platform,
94 .dai_link = &overo_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device overo_snd_devdata = {
100 .card = &snd_soc_card_overo,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *overo_snd_device;
105
106static int __init overo_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_overo()) {
111 pr_debug("Not Overo!\n");
112 return -ENODEV;
113 }
114 printk(KERN_INFO "overo SoC init\n");
115
116 overo_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!overo_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(overo_snd_device, &overo_snd_devdata);
123 overo_snd_devdata.dev = &overo_snd_device->dev;
124 *(unsigned int *)overo_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(overo_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(overo_snd_device);
135
136 return ret;
137}
138module_init(overo_soc_init);
139
140static void __exit overo_soc_exit(void)
141{
142 platform_device_unregister(overo_snd_device);
143}
144module_exit(overo_soc_exit);
145
146MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
147MODULE_DESCRIPTION("ALSA SoC overo");
148MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
new file mode 100644
index 000000000000..ad97836818b1
--- /dev/null
+++ b/sound/soc/omap/sdp3430.c
@@ -0,0 +1,152 @@
1/*
2 * sdp3430.c -- SoC audio for TI OMAP3430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * Based on:
7 * Author: Steve Sakoman <steve@sakoman.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * 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., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/clk.h>
26#include <linux/platform_device.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 <mach/hardware.h>
34#include <mach/gpio.h>
35#include <mach/mcbsp.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39#include "../codecs/twl4030.h"
40
41static int sdp3430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops sdp3430_ops = {
81 .hw_params = sdp3430_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link sdp3430_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &sdp3430_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_machine snd_soc_machine_sdp3430 = {
95 .name = "SDP3430",
96 .platform = &omap_soc_platform,
97 .dai_link = &sdp3430_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device sdp3430_snd_devdata = {
103 .machine = &snd_soc_machine_sdp3430,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *sdp3430_snd_device;
108
109static int __init sdp3430_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap_3430sdp()) {
114 pr_debug("Not SDP3430!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "SDP3430 SoC init\n");
118
119 sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!sdp3430_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata);
126 sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
127 *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(sdp3430_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(sdp3430_snd_device);
138
139 return ret;
140}
141module_init(sdp3430_soc_init);
142
143static void __exit sdp3430_soc_exit(void)
144{
145 platform_device_unregister(sdp3430_snd_device);
146}
147module_exit(sdp3430_soc_exit);
148
149MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
150MODULE_DESCRIPTION("ALSA SoC SDP3430");
151MODULE_LICENSE("GPL");
152
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f8c1cdd940ac..f82e10699471 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -21,6 +21,9 @@ config SND_PXA2XX_SOC_AC97
21config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
22 tristate 22 tristate
23 23
24config SND_PXA_SOC_SSP
25 tristate
26
24config SND_PXA2XX_SOC_CORGI 27config SND_PXA2XX_SOC_CORGI
25 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 28 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
26 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx 29 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -75,3 +78,22 @@ config SND_PXA2XX_SOC_EM_X270
75 help 78 help
76 Say Y if you want to add support for SoC audio on 79 Say Y if you want to add support for SoC audio on
77 CompuLab EM-x270. 80 CompuLab EM-x270.
81
82config SND_PXA2XX_SOC_PALM27X
83 bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
84 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
85 select SND_PXA2XX_SOC_AC97
86 select SND_SOC_WM9712
87 help
88 Say Y if you want to add support for SoC audio on
89 Palm T|X, T5 or LifeDrive handheld computer.
90
91config SND_SOC_ZYLONITE
92 tristate "SoC Audio support for Marvell Zylonite"
93 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
94 select SND_PXA2XX_SOC_AC97
95 select SND_PXA_SOC_SSP
96 select SND_SOC_WM9713
97 help
98 Say Y if you want to add support for SoC audio on the
99 Marvell Zylonite reference platform.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 5bc8edf9dca9..08a9f2797729 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -2,10 +2,12 @@
2snd-soc-pxa2xx-objs := pxa2xx-pcm.o 2snd-soc-pxa2xx-objs := pxa2xx-pcm.o
3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o 3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o 4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
5snd-soc-pxa-ssp-objs := pxa-ssp.o
5 6
6obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o 7obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
7obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o 8obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
8obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o 9obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
10obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
9 11
10# PXA Machine Support 12# PXA Machine Support
11snd-soc-corgi-objs := corgi.o 13snd-soc-corgi-objs := corgi.o
@@ -14,6 +16,8 @@ snd-soc-tosa-objs := tosa.o
14snd-soc-e800-objs := e800_wm9712.o 16snd-soc-e800-objs := e800_wm9712.o
15snd-soc-spitz-objs := spitz.o 17snd-soc-spitz-objs := spitz.o
16snd-soc-em-x270-objs := em-x270.o 18snd-soc-em-x270-objs := em-x270.o
19snd-soc-palm27x-objs := palm27x.o
20snd-soc-zylonite-objs := zylonite.o
17 21
18obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 22obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
19obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 23obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -21,3 +25,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
21obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o 25obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
22obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 26obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
23obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 27obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
28obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
29obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 72b7a5140bf8..1ba25a559524 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -18,13 +18,13 @@
18#include <linux/timer.h> 18#include <linux/timer.h>
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/gpio.h>
21#include <sound/core.h> 22#include <sound/core.h>
22#include <sound/pcm.h> 23#include <sound/pcm.h>
23#include <sound/soc.h> 24#include <sound/soc.h>
24#include <sound/soc-dapm.h> 25#include <sound/soc-dapm.h>
25 26
26#include <asm/mach-types.h> 27#include <asm/mach-types.h>
27#include <asm/hardware/scoop.h>
28#include <mach/pxa-regs.h> 28#include <mach/pxa-regs.h>
29#include <mach/hardware.h> 29#include <mach/hardware.h>
30#include <mach/corgi.h> 30#include <mach/corgi.h>
@@ -54,8 +54,8 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
54 switch (corgi_jack_func) { 54 switch (corgi_jack_func) {
55 case CORGI_HP: 55 case CORGI_HP:
56 /* set = unmute headphone */ 56 /* set = unmute headphone */
57 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 57 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
58 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 58 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
59 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 59 snd_soc_dapm_disable_pin(codec, "Mic Jack");
60 snd_soc_dapm_disable_pin(codec, "Line Jack"); 60 snd_soc_dapm_disable_pin(codec, "Line Jack");
61 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 61 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
@@ -63,24 +63,24 @@ static void corgi_ext_control(struct snd_soc_codec *codec)
63 break; 63 break;
64 case CORGI_MIC: 64 case CORGI_MIC:
65 /* reset = mute headphone */ 65 /* reset = mute headphone */
66 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 66 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
67 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 67 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
68 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 68 snd_soc_dapm_enable_pin(codec, "Mic Jack");
69 snd_soc_dapm_disable_pin(codec, "Line Jack"); 69 snd_soc_dapm_disable_pin(codec, "Line Jack");
70 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 70 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
71 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
72 break; 72 break;
73 case CORGI_LINE: 73 case CORGI_LINE:
74 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 74 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
75 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 75 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
76 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 76 snd_soc_dapm_disable_pin(codec, "Mic Jack");
77 snd_soc_dapm_enable_pin(codec, "Line Jack"); 77 snd_soc_dapm_enable_pin(codec, "Line Jack");
78 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 78 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
79 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 79 snd_soc_dapm_disable_pin(codec, "Headset Jack");
80 break; 80 break;
81 case CORGI_HEADSET: 81 case CORGI_HEADSET:
82 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 82 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
83 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 83 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
84 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 84 snd_soc_dapm_enable_pin(codec, "Mic Jack");
85 snd_soc_dapm_disable_pin(codec, "Line Jack"); 85 snd_soc_dapm_disable_pin(codec, "Line Jack");
86 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 86 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
@@ -108,15 +108,11 @@ static int corgi_startup(struct snd_pcm_substream *substream)
108} 108}
109 109
110/* we need to unmute the HP at shutdown as the mute burns power on corgi */ 110/* we need to unmute the HP at shutdown as the mute burns power on corgi */
111static int corgi_shutdown(struct snd_pcm_substream *substream) 111static void corgi_shutdown(struct snd_pcm_substream *substream)
112{ 112{
113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
114 struct snd_soc_codec *codec = rtd->socdev->codec;
115
116 /* set = unmute headphone */ 113 /* set = unmute headphone */
117 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_L); 114 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
118 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MUTE_R); 115 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
119 return 0;
120} 116}
121 117
122static int corgi_hw_params(struct snd_pcm_substream *substream, 118static int corgi_hw_params(struct snd_pcm_substream *substream,
@@ -218,22 +214,14 @@ static int corgi_set_spk(struct snd_kcontrol *kcontrol,
218static int corgi_amp_event(struct snd_soc_dapm_widget *w, 214static int corgi_amp_event(struct snd_soc_dapm_widget *w,
219 struct snd_kcontrol *k, int event) 215 struct snd_kcontrol *k, int event)
220{ 216{
221 if (SND_SOC_DAPM_EVENT_ON(event)) 217 gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
222 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
223 else
224 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_APM_ON);
225
226 return 0; 218 return 0;
227} 219}
228 220
229static int corgi_mic_event(struct snd_soc_dapm_widget *w, 221static int corgi_mic_event(struct snd_soc_dapm_widget *w,
230 struct snd_kcontrol *k, int event) 222 struct snd_kcontrol *k, int event)
231{ 223{
232 if (SND_SOC_DAPM_EVENT_ON(event)) 224 gpio_set_value(CORGI_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
233 set_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
234 else
235 reset_scoop_gpio(&corgiscoop_device.dev, CORGI_SCP_MIC_BIAS);
236
237 return 0; 225 return 0;
238} 226}
239 227
@@ -289,8 +277,8 @@ static int corgi_wm8731_init(struct snd_soc_codec *codec)
289{ 277{
290 int i, err; 278 int i, err;
291 279
292 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 280 snd_soc_dapm_nc_pin(codec, "LLINEIN");
293 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 281 snd_soc_dapm_nc_pin(codec, "RLINEIN");
294 282
295 /* Add corgi specific controls */ 283 /* Add corgi specific controls */
296 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) { 284 for (i = 0; i < ARRAY_SIZE(wm8731_corgi_controls); i++) {
@@ -322,8 +310,9 @@ static struct snd_soc_dai_link corgi_dai = {
322}; 310};
323 311
324/* corgi audio machine driver */ 312/* corgi audio machine driver */
325static struct snd_soc_machine snd_soc_machine_corgi = { 313static struct snd_soc_card snd_soc_corgi = {
326 .name = "Corgi", 314 .name = "Corgi",
315 .platform = &pxa2xx_soc_platform,
327 .dai_link = &corgi_dai, 316 .dai_link = &corgi_dai,
328 .num_links = 1, 317 .num_links = 1,
329}; 318};
@@ -336,8 +325,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
336 325
337/* corgi audio subsystem */ 326/* corgi audio subsystem */
338static struct snd_soc_device corgi_snd_devdata = { 327static struct snd_soc_device corgi_snd_devdata = {
339 .machine = &snd_soc_machine_corgi, 328 .card = &snd_soc_corgi,
340 .platform = &pxa2xx_soc_platform,
341 .codec_dev = &soc_codec_dev_wm8731, 329 .codec_dev = &soc_codec_dev_wm8731,
342 .codec_data = &corgi_wm8731_setup, 330 .codec_data = &corgi_wm8731_setup,
343}; 331};
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 6781c5be242f..2e3386dfa0f0 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -29,7 +29,7 @@
29#include "pxa2xx-pcm.h" 29#include "pxa2xx-pcm.h"
30#include "pxa2xx-ac97.h" 30#include "pxa2xx-ac97.h"
31 31
32static struct snd_soc_machine e800; 32static struct snd_soc_card e800;
33 33
34static struct snd_soc_dai_link e800_dai[] = { 34static struct snd_soc_dai_link e800_dai[] = {
35{ 35{
@@ -40,15 +40,15 @@ static struct snd_soc_dai_link e800_dai[] = {
40}, 40},
41}; 41};
42 42
43static struct snd_soc_machine e800 = { 43static struct snd_soc_card e800 = {
44 .name = "Toshiba e800", 44 .name = "Toshiba e800",
45 .platform = &pxa2xx_soc_platform,
45 .dai_link = e800_dai, 46 .dai_link = e800_dai,
46 .num_links = ARRAY_SIZE(e800_dai), 47 .num_links = ARRAY_SIZE(e800_dai),
47}; 48};
48 49
49static struct snd_soc_device e800_snd_devdata = { 50static struct snd_soc_device e800_snd_devdata = {
50 .machine = &e800, 51 .card = &e800,
51 .platform = &pxa2xx_soc_platform,
52 .codec_dev = &soc_codec_dev_wm9712, 52 .codec_dev = &soc_codec_dev_wm9712,
53}; 53};
54 54
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index d9c3f7b28be2..fe4a729ea648 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -9,7 +9,7 @@
9 * Copyright 2005 Wolfson Microelectronics PLC. 9 * Copyright 2005 Wolfson Microelectronics PLC.
10 * Copyright 2005 Openedhand Ltd. 10 * Copyright 2005 Openedhand Ltd.
11 * 11 *
12 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 12 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
13 * Richard Purdie <richard@openedhand.com> 13 * Richard Purdie <richard@openedhand.com>
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify it 15 * This program is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/device.h> 24#include <linux/device.h>
25 25
26#include <sound/driver.h>
27#include <sound/core.h> 26#include <sound/core.h>
28#include <sound/pcm.h> 27#include <sound/pcm.h>
29#include <sound/soc.h> 28#include <sound/soc.h>
@@ -53,15 +52,15 @@ static struct snd_soc_dai_link em_x270_dai[] = {
53 }, 52 },
54}; 53};
55 54
56static struct snd_soc_machine em_x270 = { 55static struct snd_soc_card em_x270 = {
57 .name = "EM-X270", 56 .name = "EM-X270",
57 .platform = &pxa2xx_soc_platform,
58 .dai_link = em_x270_dai, 58 .dai_link = em_x270_dai,
59 .num_links = ARRAY_SIZE(em_x270_dai), 59 .num_links = ARRAY_SIZE(em_x270_dai),
60}; 60};
61 61
62static struct snd_soc_device em_x270_snd_devdata = { 62static struct snd_soc_device em_x270_snd_devdata = {
63 .machine = &em_x270, 63 .card = &em_x270,
64 .platform = &pxa2xx_soc_platform,
65 .codec_dev = &soc_codec_dev_wm9712, 64 .codec_dev = &soc_codec_dev_wm9712,
66}; 65};
67 66
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
new file mode 100644
index 000000000000..4a9cf3083af0
--- /dev/null
+++ b/sound/soc/pxa/palm27x.c
@@ -0,0 +1,269 @@
1/*
2 * linux/sound/soc/pxa/palm27x.c
3 *
4 * SoC Audio driver for Palm T|X, T5 and LifeDrive
5 *
6 * based on tosa.c
7 *
8 * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
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
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/device.h>
19#include <linux/gpio.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27
28#include <asm/mach-types.h>
29#include <mach/audio.h>
30#include <mach/palmasoc.h>
31
32#include "../codecs/wm9712.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-ac97.h"
35
36static int palm27x_jack_func = 1;
37static int palm27x_spk_func = 1;
38static int palm27x_ep_gpio = -1;
39
40static void palm27x_ext_control(struct snd_soc_codec *codec)
41{
42 if (!palm27x_spk_func)
43 snd_soc_dapm_enable_pin(codec, "Speaker");
44 else
45 snd_soc_dapm_disable_pin(codec, "Speaker");
46
47 if (!palm27x_jack_func)
48 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
49 else
50 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
51
52 snd_soc_dapm_sync(codec);
53}
54
55static int palm27x_startup(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_codec *codec = rtd->socdev->codec;
59
60 /* check the jack status at stream startup */
61 palm27x_ext_control(codec);
62 return 0;
63}
64
65static struct snd_soc_ops palm27x_ops = {
66 .startup = palm27x_startup,
67};
68
69static irqreturn_t palm27x_interrupt(int irq, void *v)
70{
71 palm27x_spk_func = gpio_get_value(palm27x_ep_gpio);
72 palm27x_jack_func = !palm27x_spk_func;
73 return IRQ_HANDLED;
74}
75
76static int palm27x_get_jack(struct snd_kcontrol *kcontrol,
77 struct snd_ctl_elem_value *ucontrol)
78{
79 ucontrol->value.integer.value[0] = palm27x_jack_func;
80 return 0;
81}
82
83static int palm27x_set_jack(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
87
88 if (palm27x_jack_func == ucontrol->value.integer.value[0])
89 return 0;
90
91 palm27x_jack_func = ucontrol->value.integer.value[0];
92 palm27x_ext_control(codec);
93 return 1;
94}
95
96static int palm27x_get_spk(struct snd_kcontrol *kcontrol,
97 struct snd_ctl_elem_value *ucontrol)
98{
99 ucontrol->value.integer.value[0] = palm27x_spk_func;
100 return 0;
101}
102
103static int palm27x_set_spk(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
107
108 if (palm27x_spk_func == ucontrol->value.integer.value[0])
109 return 0;
110
111 palm27x_spk_func = ucontrol->value.integer.value[0];
112 palm27x_ext_control(codec);
113 return 1;
114}
115
116/* PalmTX machine dapm widgets */
117static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", NULL),
119 SND_SOC_DAPM_SPK("Speaker", NULL),
120};
121
122/* PalmTX audio map */
123static const struct snd_soc_dapm_route audio_map[] = {
124 /* headphone connected to HPOUTL, HPOUTR */
125 {"Headphone Jack", NULL, "HPOUTL"},
126 {"Headphone Jack", NULL, "HPOUTR"},
127
128 /* ext speaker connected to ROUT2, LOUT2 */
129 {"Speaker", NULL, "LOUT2"},
130 {"Speaker", NULL, "ROUT2"},
131};
132
133static const char *jack_function[] = {"Headphone", "Off"};
134static const char *spk_function[] = {"On", "Off"};
135static const struct soc_enum palm27x_enum[] = {
136 SOC_ENUM_SINGLE_EXT(2, jack_function),
137 SOC_ENUM_SINGLE_EXT(2, spk_function),
138};
139
140static const struct snd_kcontrol_new palm27x_controls[] = {
141 SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack,
142 palm27x_set_jack),
143 SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk,
144 palm27x_set_spk),
145};
146
147static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{
149 int i, err;
150
151 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT");
153
154 /* add palm27x specific controls */
155 for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) {
156 err = snd_ctl_add(codec->card,
157 snd_soc_cnew(&palm27x_controls[i],
158 codec, NULL));
159 if (err < 0)
160 return err;
161 }
162
163 /* add palm27x specific widgets */
164 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
165 ARRAY_SIZE(palm27x_dapm_widgets));
166
167 /* set up palm27x specific audio path audio_map */
168 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
169
170 snd_soc_dapm_sync(codec);
171 return 0;
172}
173
174static struct snd_soc_dai_link palm27x_dai[] = {
175{
176 .name = "AC97 HiFi",
177 .stream_name = "AC97 HiFi",
178 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
179 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
180 .init = palm27x_ac97_init,
181 .ops = &palm27x_ops,
182},
183{
184 .name = "AC97 Aux",
185 .stream_name = "AC97 Aux",
186 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
187 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
188 .ops = &palm27x_ops,
189},
190};
191
192static struct snd_soc_card palm27x_asoc = {
193 .name = "Palm/PXA27x",
194 .platform = &pxa2xx_soc_platform,
195 .dai_link = palm27x_dai,
196 .num_links = ARRAY_SIZE(palm27x_dai),
197};
198
199static struct snd_soc_device palm27x_snd_devdata = {
200 .card = &palm27x_asoc,
201 .codec_dev = &soc_codec_dev_wm9712,
202};
203
204static struct platform_device *palm27x_snd_device;
205
206static int __init palm27x_asoc_init(void)
207{
208 int ret;
209
210 if (!(machine_is_palmtx() || machine_is_palmt5() ||
211 machine_is_palmld()))
212 return -ENODEV;
213
214 ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
215 if (ret)
216 return ret;
217 ret = gpio_direction_input(palm27x_ep_gpio);
218 if (ret)
219 goto err_alloc;
220
221 if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt,
222 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
223 "Headphone jack", NULL))
224 goto err_alloc;
225
226 palm27x_snd_device = platform_device_alloc("soc-audio", -1);
227 if (!palm27x_snd_device) {
228 ret = -ENOMEM;
229 goto err_dev;
230 }
231
232 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
233 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
234 ret = platform_device_add(palm27x_snd_device);
235
236 if (ret != 0)
237 goto put_device;
238
239 return 0;
240
241put_device:
242 platform_device_put(palm27x_snd_device);
243err_dev:
244 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
245err_alloc:
246 gpio_free(palm27x_ep_gpio);
247
248 return ret;
249}
250
251static void __exit palm27x_asoc_exit(void)
252{
253 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
254 gpio_free(palm27x_ep_gpio);
255 platform_device_unregister(palm27x_snd_device);
256}
257
258void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data)
259{
260 palm27x_ep_gpio = data->jack_gpio;
261}
262
263module_init(palm27x_asoc_init);
264module_exit(palm27x_asoc_exit);
265
266/* Module information */
267MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
268MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
269MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index f84f7d8db09a..6e9827189fff 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -242,8 +242,8 @@ static int poodle_wm8731_init(struct snd_soc_codec *codec)
242{ 242{
243 int i, err; 243 int i, err;
244 244
245 snd_soc_dapm_disable_pin(codec, "LLINEIN"); 245 snd_soc_dapm_nc_pin(codec, "LLINEIN");
246 snd_soc_dapm_disable_pin(codec, "RLINEIN"); 246 snd_soc_dapm_nc_pin(codec, "RLINEIN");
247 snd_soc_dapm_enable_pin(codec, "MICIN"); 247 snd_soc_dapm_enable_pin(codec, "MICIN");
248 248
249 /* Add poodle specific controls */ 249 /* Add poodle specific controls */
@@ -276,8 +276,9 @@ static struct snd_soc_dai_link poodle_dai = {
276}; 276};
277 277
278/* poodle audio machine driver */ 278/* poodle audio machine driver */
279static struct snd_soc_machine snd_soc_machine_poodle = { 279static struct snd_soc_card snd_soc_poodle = {
280 .name = "Poodle", 280 .name = "Poodle",
281 .platform = &pxa2xx_soc_platform,
281 .dai_link = &poodle_dai, 282 .dai_link = &poodle_dai,
282 .num_links = 1, 283 .num_links = 1,
283}; 284};
@@ -290,8 +291,7 @@ static struct wm8731_setup_data poodle_wm8731_setup = {
290 291
291/* poodle audio subsystem */ 292/* poodle audio subsystem */
292static struct snd_soc_device poodle_snd_devdata = { 293static struct snd_soc_device poodle_snd_devdata = {
293 .machine = &snd_soc_machine_poodle, 294 .card = &snd_soc_poodle,
294 .platform = &pxa2xx_soc_platform,
295 .codec_dev = &soc_codec_dev_wm8731, 295 .codec_dev = &soc_codec_dev_wm8731,
296 .codec_data = &poodle_wm8731_setup, 296 .codec_data = &poodle_wm8731_setup,
297}; 297};
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
new file mode 100644
index 000000000000..73cb6b4c2f2d
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -0,0 +1,931 @@
1#define DEBUG
2/*
3 * pxa-ssp.c -- ALSA Soc Audio Layer
4 *
5 * Copyright 2005,2008 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * Mark Brown <broonie@opensource.wolfsonmicro.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 * TODO:
15 * o Test network mode for > 16bit sample size
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/initval.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/pxa2xx-lib.h>
30
31#include <mach/hardware.h>
32#include <mach/pxa-regs.h>
33#include <mach/regs-ssp.h>
34#include <mach/audio.h>
35#include <mach/ssp.h>
36
37#include "pxa2xx-pcm.h"
38#include "pxa-ssp.h"
39
40/*
41 * SSP audio private data
42 */
43struct ssp_priv {
44 struct ssp_dev dev;
45 unsigned int sysclk;
46 int dai_fmt;
47#ifdef CONFIG_PM
48 struct ssp_state state;
49#endif
50};
51
52#define PXA2xx_SSP1_BASE 0x41000000
53#define PXA27x_SSP2_BASE 0x41700000
54#define PXA27x_SSP3_BASE 0x41900000
55#define PXA3xx_SSP4_BASE 0x41a00000
56
57static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
58 .name = "SSP1 PCM Mono out",
59 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
60 .drcmr = &DRCMR(14),
61 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
62 DCMD_BURST16 | DCMD_WIDTH2,
63};
64
65static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
66 .name = "SSP1 PCM Mono in",
67 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
68 .drcmr = &DRCMR(13),
69 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
70 DCMD_BURST16 | DCMD_WIDTH2,
71};
72
73static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
74 .name = "SSP1 PCM Stereo out",
75 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
76 .drcmr = &DRCMR(14),
77 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
78 DCMD_BURST16 | DCMD_WIDTH4,
79};
80
81static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
82 .name = "SSP1 PCM Stereo in",
83 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
84 .drcmr = &DRCMR(13),
85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
86 DCMD_BURST16 | DCMD_WIDTH4,
87};
88
89static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
90 .name = "SSP2 PCM Mono out",
91 .dev_addr = PXA27x_SSP2_BASE + SSDR,
92 .drcmr = &DRCMR(16),
93 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
94 DCMD_BURST16 | DCMD_WIDTH2,
95};
96
97static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
98 .name = "SSP2 PCM Mono in",
99 .dev_addr = PXA27x_SSP2_BASE + SSDR,
100 .drcmr = &DRCMR(15),
101 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
102 DCMD_BURST16 | DCMD_WIDTH2,
103};
104
105static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
106 .name = "SSP2 PCM Stereo out",
107 .dev_addr = PXA27x_SSP2_BASE + SSDR,
108 .drcmr = &DRCMR(16),
109 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
110 DCMD_BURST16 | DCMD_WIDTH4,
111};
112
113static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
114 .name = "SSP2 PCM Stereo in",
115 .dev_addr = PXA27x_SSP2_BASE + SSDR,
116 .drcmr = &DRCMR(15),
117 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
118 DCMD_BURST16 | DCMD_WIDTH4,
119};
120
121static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
122 .name = "SSP3 PCM Mono out",
123 .dev_addr = PXA27x_SSP3_BASE + SSDR,
124 .drcmr = &DRCMR(67),
125 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
126 DCMD_BURST16 | DCMD_WIDTH2,
127};
128
129static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
130 .name = "SSP3 PCM Mono in",
131 .dev_addr = PXA27x_SSP3_BASE + SSDR,
132 .drcmr = &DRCMR(66),
133 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
134 DCMD_BURST16 | DCMD_WIDTH2,
135};
136
137static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
138 .name = "SSP3 PCM Stereo out",
139 .dev_addr = PXA27x_SSP3_BASE + SSDR,
140 .drcmr = &DRCMR(67),
141 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
142 DCMD_BURST16 | DCMD_WIDTH4,
143};
144
145static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
146 .name = "SSP3 PCM Stereo in",
147 .dev_addr = PXA27x_SSP3_BASE + SSDR,
148 .drcmr = &DRCMR(66),
149 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
150 DCMD_BURST16 | DCMD_WIDTH4,
151};
152
153static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
154 .name = "SSP4 PCM Mono out",
155 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
156 .drcmr = &DRCMR(67),
157 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
158 DCMD_BURST16 | DCMD_WIDTH2,
159};
160
161static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
162 .name = "SSP4 PCM Mono in",
163 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
164 .drcmr = &DRCMR(66),
165 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
166 DCMD_BURST16 | DCMD_WIDTH2,
167};
168
169static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
170 .name = "SSP4 PCM Stereo out",
171 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
172 .drcmr = &DRCMR(67),
173 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
174 DCMD_BURST16 | DCMD_WIDTH4,
175};
176
177static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
178 .name = "SSP4 PCM Stereo in",
179 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
180 .drcmr = &DRCMR(66),
181 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
182 DCMD_BURST16 | DCMD_WIDTH4,
183};
184
185static void dump_registers(struct ssp_device *ssp)
186{
187 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
188 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
189 ssp_read_reg(ssp, SSTO));
190
191 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
192 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
193 ssp_read_reg(ssp, SSACD));
194}
195
196static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = {
197 {
198 &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in,
199 &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
200 },
201 {
202 &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
203 &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
204 },
205 {
206 &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
207 &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
208 },
209 {
210 &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
211 &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
212 },
213};
214
215static int pxa_ssp_startup(struct snd_pcm_substream *substream,
216 struct snd_soc_dai *dai)
217{
218 struct snd_soc_pcm_runtime *rtd = substream->private_data;
219 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
220 struct ssp_priv *priv = cpu_dai->private_data;
221 int ret = 0;
222
223 if (!cpu_dai->active) {
224 ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ);
225 if (ret < 0)
226 return ret;
227 ssp_disable(&priv->dev);
228 }
229 return ret;
230}
231
232static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
233 struct snd_soc_dai *dai)
234{
235 struct snd_soc_pcm_runtime *rtd = substream->private_data;
236 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
237 struct ssp_priv *priv = cpu_dai->private_data;
238
239 if (!cpu_dai->active) {
240 ssp_disable(&priv->dev);
241 ssp_exit(&priv->dev);
242 }
243}
244
245#ifdef CONFIG_PM
246
247static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
248{
249 struct ssp_priv *priv = cpu_dai->private_data;
250
251 if (!cpu_dai->active)
252 return 0;
253
254 ssp_save_state(&priv->dev, &priv->state);
255 clk_disable(priv->dev.ssp->clk);
256 return 0;
257}
258
259static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
260{
261 struct ssp_priv *priv = cpu_dai->private_data;
262
263 if (!cpu_dai->active)
264 return 0;
265
266 clk_enable(priv->dev.ssp->clk);
267 ssp_restore_state(&priv->dev, &priv->state);
268 ssp_enable(&priv->dev);
269
270 return 0;
271}
272
273#else
274#define pxa_ssp_suspend NULL
275#define pxa_ssp_resume NULL
276#endif
277
278/**
279 * ssp_set_clkdiv - set SSP clock divider
280 * @div: serial clock rate divider
281 */
282static void ssp_set_scr(struct ssp_dev *dev, u32 div)
283{
284 struct ssp_device *ssp = dev->ssp;
285 u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR;
286
287 ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div)));
288}
289
290/*
291 * Set the SSP ports SYSCLK.
292 */
293static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct ssp_priv *priv = cpu_dai->private_data;
297 struct ssp_device *ssp = priv->dev.ssp;
298 int val;
299
300 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
301 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
302
303 dev_dbg(&ssp->pdev->dev,
304 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n",
305 cpu_dai->id, clk_id, freq);
306
307 switch (clk_id) {
308 case PXA_SSP_CLK_NET_PLL:
309 sscr0 |= SSCR0_MOD;
310 break;
311 case PXA_SSP_CLK_PLL:
312 /* Internal PLL is fixed */
313 if (cpu_is_pxa25x())
314 priv->sysclk = 1843200;
315 else
316 priv->sysclk = 13000000;
317 break;
318 case PXA_SSP_CLK_EXT:
319 priv->sysclk = freq;
320 sscr0 |= SSCR0_ECS;
321 break;
322 case PXA_SSP_CLK_NET:
323 priv->sysclk = freq;
324 sscr0 |= SSCR0_NCS | SSCR0_MOD;
325 break;
326 case PXA_SSP_CLK_AUDIO:
327 priv->sysclk = 0;
328 ssp_set_scr(&priv->dev, 1);
329 sscr0 |= SSCR0_ADC;
330 break;
331 default:
332 return -ENODEV;
333 }
334
335 /* The SSP clock must be disabled when changing SSP clock mode
336 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
337 if (!cpu_is_pxa3xx())
338 clk_disable(priv->dev.ssp->clk);
339 val = ssp_read_reg(ssp, SSCR0) | sscr0;
340 ssp_write_reg(ssp, SSCR0, val);
341 if (!cpu_is_pxa3xx())
342 clk_enable(priv->dev.ssp->clk);
343
344 return 0;
345}
346
347/*
348 * Set the SSP clock dividers.
349 */
350static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
351 int div_id, int div)
352{
353 struct ssp_priv *priv = cpu_dai->private_data;
354 struct ssp_device *ssp = priv->dev.ssp;
355 int val;
356
357 switch (div_id) {
358 case PXA_SSP_AUDIO_DIV_ACDS:
359 val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
360 ssp_write_reg(ssp, SSACD, val);
361 break;
362 case PXA_SSP_AUDIO_DIV_SCDB:
363 val = ssp_read_reg(ssp, SSACD);
364 val &= ~SSACD_SCDB;
365#if defined(CONFIG_PXA3xx)
366 if (cpu_is_pxa3xx())
367 val &= ~SSACD_SCDX8;
368#endif
369 switch (div) {
370 case PXA_SSP_CLK_SCDB_1:
371 val |= SSACD_SCDB;
372 break;
373 case PXA_SSP_CLK_SCDB_4:
374 break;
375#if defined(CONFIG_PXA3xx)
376 case PXA_SSP_CLK_SCDB_8:
377 if (cpu_is_pxa3xx())
378 val |= SSACD_SCDX8;
379 else
380 return -EINVAL;
381 break;
382#endif
383 default:
384 return -EINVAL;
385 }
386 ssp_write_reg(ssp, SSACD, val);
387 break;
388 case PXA_SSP_DIV_SCR:
389 ssp_set_scr(&priv->dev, div);
390 break;
391 default:
392 return -ENODEV;
393 }
394
395 return 0;
396}
397
398/*
399 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
400 */
401static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
402 int pll_id, unsigned int freq_in, unsigned int freq_out)
403{
404 struct ssp_priv *priv = cpu_dai->private_data;
405 struct ssp_device *ssp = priv->dev.ssp;
406 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
407
408#if defined(CONFIG_PXA3xx)
409 if (cpu_is_pxa3xx())
410 ssp_write_reg(ssp, SSACDD, 0);
411#endif
412
413 switch (freq_out) {
414 case 5622000:
415 break;
416 case 11345000:
417 ssacd |= (0x1 << 4);
418 break;
419 case 12235000:
420 ssacd |= (0x2 << 4);
421 break;
422 case 14857000:
423 ssacd |= (0x3 << 4);
424 break;
425 case 32842000:
426 ssacd |= (0x4 << 4);
427 break;
428 case 48000000:
429 ssacd |= (0x5 << 4);
430 break;
431 case 0:
432 /* Disable */
433 break;
434
435 default:
436#ifdef CONFIG_PXA3xx
437 /* PXA3xx has a clock ditherer which can be used to generate
438 * a wider range of frequencies - calculate a value for it.
439 */
440 if (cpu_is_pxa3xx()) {
441 u32 val;
442 u64 tmp = 19968;
443 tmp *= 1000000;
444 do_div(tmp, freq_out);
445 val = tmp;
446
447 val = (val << 16) | 64;;
448 ssp_write_reg(ssp, SSACDD, val);
449
450 ssacd |= (0x6 << 4);
451
452 dev_dbg(&ssp->pdev->dev,
453 "Using SSACDD %x to supply %dHz\n",
454 val, freq_out);
455 break;
456 }
457#endif
458
459 return -EINVAL;
460 }
461
462 ssp_write_reg(ssp, SSACD, ssacd);
463
464 return 0;
465}
466
467/*
468 * Set the active slots in TDM/Network mode
469 */
470static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
471 unsigned int mask, int slots)
472{
473 struct ssp_priv *priv = cpu_dai->private_data;
474 struct ssp_device *ssp = priv->dev.ssp;
475 u32 sscr0;
476
477 sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7);
478
479 /* set number of active slots */
480 sscr0 |= SSCR0_SlotsPerFrm(slots);
481 ssp_write_reg(ssp, SSCR0, sscr0);
482
483 /* set active slot mask */
484 ssp_write_reg(ssp, SSTSA, mask);
485 ssp_write_reg(ssp, SSRSA, mask);
486 return 0;
487}
488
489/*
490 * Tristate the SSP DAI lines
491 */
492static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
493 int tristate)
494{
495 struct ssp_priv *priv = cpu_dai->private_data;
496 struct ssp_device *ssp = priv->dev.ssp;
497 u32 sscr1;
498
499 sscr1 = ssp_read_reg(ssp, SSCR1);
500 if (tristate)
501 sscr1 &= ~SSCR1_TTE;
502 else
503 sscr1 |= SSCR1_TTE;
504 ssp_write_reg(ssp, SSCR1, sscr1);
505
506 return 0;
507}
508
509/*
510 * Set up the SSP DAI format.
511 * The SSP Port must be inactive before calling this function as the
512 * physical interface format is changed.
513 */
514static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
515 unsigned int fmt)
516{
517 struct ssp_priv *priv = cpu_dai->private_data;
518 struct ssp_device *ssp = priv->dev.ssp;
519 u32 sscr0;
520 u32 sscr1;
521 u32 sspsp;
522
523 /* reset port settings */
524 sscr0 = ssp_read_reg(ssp, SSCR0) &
525 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
526 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
527 sspsp = 0;
528
529 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
530 case SND_SOC_DAIFMT_CBM_CFM:
531 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
532 break;
533 case SND_SOC_DAIFMT_CBM_CFS:
534 sscr1 |= SSCR1_SCLKDIR;
535 break;
536 case SND_SOC_DAIFMT_CBS_CFS:
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 ssp_write_reg(ssp, SSCR0, sscr0);
543 ssp_write_reg(ssp, SSCR1, sscr1);
544 ssp_write_reg(ssp, SSPSP, sspsp);
545
546 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
547 case SND_SOC_DAIFMT_I2S:
548 sscr0 |= SSCR0_MOD | SSCR0_PSP;
549 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
550
551 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
552 case SND_SOC_DAIFMT_NB_NF:
553 sspsp |= SSPSP_FSRT;
554 break;
555 case SND_SOC_DAIFMT_NB_IF:
556 sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
557 break;
558 case SND_SOC_DAIFMT_IB_IF:
559 sspsp |= SSPSP_SFRMP;
560 break;
561 default:
562 return -EINVAL;
563 }
564 break;
565
566 case SND_SOC_DAIFMT_DSP_A:
567 sspsp |= SSPSP_FSRT;
568 case SND_SOC_DAIFMT_DSP_B:
569 sscr0 |= SSCR0_MOD | SSCR0_PSP;
570 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
571
572 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
573 case SND_SOC_DAIFMT_NB_NF:
574 sspsp |= SSPSP_SFRMP;
575 break;
576 case SND_SOC_DAIFMT_IB_IF:
577 break;
578 default:
579 return -EINVAL;
580 }
581 break;
582
583 default:
584 return -EINVAL;
585 }
586
587 ssp_write_reg(ssp, SSCR0, sscr0);
588 ssp_write_reg(ssp, SSCR1, sscr1);
589 ssp_write_reg(ssp, SSPSP, sspsp);
590
591 dump_registers(ssp);
592
593 /* Since we are configuring the timings for the format by hand
594 * we have to defer some things until hw_params() where we
595 * know parameters like the sample size.
596 */
597 priv->dai_fmt = fmt;
598
599 return 0;
600}
601
602/*
603 * Set the SSP audio DMA parameters and sample size.
604 * Can be called multiple times by oss emulation.
605 */
606static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
607 struct snd_pcm_hw_params *params,
608 struct snd_soc_dai *dai)
609{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
612 struct ssp_priv *priv = cpu_dai->private_data;
613 struct ssp_device *ssp = priv->dev.ssp;
614 int dma = 0, chn = params_channels(params);
615 u32 sscr0;
616 u32 sspsp;
617 int width = snd_pcm_format_physical_width(params_format(params));
618
619 /* select correct DMA params */
620 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
621 dma = 1; /* capture DMA offset is 1,3 */
622 if (chn == 2)
623 dma += 2; /* stereo DMA offset is 2, mono is 0 */
624 cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
625
626 dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
627
628 /* we can only change the settings if the port is not in use */
629 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
630 return 0;
631
632 /* clear selected SSP bits */
633 sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
634 ssp_write_reg(ssp, SSCR0, sscr0);
635
636 /* bit size */
637 sscr0 = ssp_read_reg(ssp, SSCR0);
638 switch (params_format(params)) {
639 case SNDRV_PCM_FORMAT_S16_LE:
640#ifdef CONFIG_PXA3xx
641 if (cpu_is_pxa3xx())
642 sscr0 |= SSCR0_FPCKE;
643#endif
644 sscr0 |= SSCR0_DataSize(16);
645 if (params_channels(params) > 1)
646 sscr0 |= SSCR0_EDSS;
647 break;
648 case SNDRV_PCM_FORMAT_S24_LE:
649 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
650 /* we must be in network mode (2 slots) for 24 bit stereo */
651 break;
652 case SNDRV_PCM_FORMAT_S32_LE:
653 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
654 /* we must be in network mode (2 slots) for 32 bit stereo */
655 break;
656 }
657 ssp_write_reg(ssp, SSCR0, sscr0);
658
659 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
660 case SND_SOC_DAIFMT_I2S:
661 /* Cleared when the DAI format is set */
662 sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width);
663 ssp_write_reg(ssp, SSPSP, sspsp);
664 break;
665 default:
666 break;
667 }
668
669 /* We always use a network mode so we always require TDM slots
670 * - complain loudly and fail if they've not been set up yet.
671 */
672 if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) {
673 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
674 return -EINVAL;
675 }
676
677 dump_registers(ssp);
678
679 return 0;
680}
681
682static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
683 struct snd_soc_dai *dai)
684{
685 struct snd_soc_pcm_runtime *rtd = substream->private_data;
686 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
687 int ret = 0;
688 struct ssp_priv *priv = cpu_dai->private_data;
689 struct ssp_device *ssp = priv->dev.ssp;
690 int val;
691
692 switch (cmd) {
693 case SNDRV_PCM_TRIGGER_RESUME:
694 ssp_enable(&priv->dev);
695 break;
696 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
697 val = ssp_read_reg(ssp, SSCR1);
698 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
699 val |= SSCR1_TSRE;
700 else
701 val |= SSCR1_RSRE;
702 ssp_write_reg(ssp, SSCR1, val);
703 val = ssp_read_reg(ssp, SSSR);
704 ssp_write_reg(ssp, SSSR, val);
705 break;
706 case SNDRV_PCM_TRIGGER_START:
707 val = ssp_read_reg(ssp, SSCR1);
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 val |= SSCR1_TSRE;
710 else
711 val |= SSCR1_RSRE;
712 ssp_write_reg(ssp, SSCR1, val);
713 ssp_enable(&priv->dev);
714 break;
715 case SNDRV_PCM_TRIGGER_STOP:
716 val = ssp_read_reg(ssp, SSCR1);
717 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 val &= ~SSCR1_TSRE;
719 else
720 val &= ~SSCR1_RSRE;
721 ssp_write_reg(ssp, SSCR1, val);
722 break;
723 case SNDRV_PCM_TRIGGER_SUSPEND:
724 ssp_disable(&priv->dev);
725 break;
726 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
727 val = ssp_read_reg(ssp, SSCR1);
728 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
729 val &= ~SSCR1_TSRE;
730 else
731 val &= ~SSCR1_RSRE;
732 ssp_write_reg(ssp, SSCR1, val);
733 break;
734
735 default:
736 ret = -EINVAL;
737 }
738
739 dump_registers(ssp);
740
741 return ret;
742}
743
744static int pxa_ssp_probe(struct platform_device *pdev,
745 struct snd_soc_dai *dai)
746{
747 struct ssp_priv *priv;
748 int ret;
749
750 priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
751 if (!priv)
752 return -ENOMEM;
753
754 priv->dev.ssp = ssp_request(dai->id, "SoC audio");
755 if (priv->dev.ssp == NULL) {
756 ret = -ENODEV;
757 goto err_priv;
758 }
759
760 dai->private_data = priv;
761
762 return 0;
763
764err_priv:
765 kfree(priv);
766 return ret;
767}
768
769static void pxa_ssp_remove(struct platform_device *pdev,
770 struct snd_soc_dai *dai)
771{
772 struct ssp_priv *priv = dai->private_data;
773 ssp_free(priv->dev.ssp);
774}
775
776#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
777 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
778 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
779 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
780
781#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
782 SNDRV_PCM_FMTBIT_S24_LE | \
783 SNDRV_PCM_FMTBIT_S32_LE)
784
785struct snd_soc_dai pxa_ssp_dai[] = {
786 {
787 .name = "pxa2xx-ssp1",
788 .id = 0,
789 .probe = pxa_ssp_probe,
790 .remove = pxa_ssp_remove,
791 .suspend = pxa_ssp_suspend,
792 .resume = pxa_ssp_resume,
793 .playback = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = PXA_SSP_RATES,
797 .formats = PXA_SSP_FORMATS,
798 },
799 .capture = {
800 .channels_min = 1,
801 .channels_max = 2,
802 .rates = PXA_SSP_RATES,
803 .formats = PXA_SSP_FORMATS,
804 },
805 .ops = {
806 .startup = pxa_ssp_startup,
807 .shutdown = pxa_ssp_shutdown,
808 .trigger = pxa_ssp_trigger,
809 .hw_params = pxa_ssp_hw_params,
810 .set_sysclk = pxa_ssp_set_dai_sysclk,
811 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
812 .set_pll = pxa_ssp_set_dai_pll,
813 .set_fmt = pxa_ssp_set_dai_fmt,
814 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
815 .set_tristate = pxa_ssp_set_dai_tristate,
816 },
817 },
818 { .name = "pxa2xx-ssp2",
819 .id = 1,
820 .probe = pxa_ssp_probe,
821 .remove = pxa_ssp_remove,
822 .suspend = pxa_ssp_suspend,
823 .resume = pxa_ssp_resume,
824 .playback = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = PXA_SSP_RATES,
828 .formats = PXA_SSP_FORMATS,
829 },
830 .capture = {
831 .channels_min = 1,
832 .channels_max = 2,
833 .rates = PXA_SSP_RATES,
834 .formats = PXA_SSP_FORMATS,
835 },
836 .ops = {
837 .startup = pxa_ssp_startup,
838 .shutdown = pxa_ssp_shutdown,
839 .trigger = pxa_ssp_trigger,
840 .hw_params = pxa_ssp_hw_params,
841 .set_sysclk = pxa_ssp_set_dai_sysclk,
842 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
843 .set_pll = pxa_ssp_set_dai_pll,
844 .set_fmt = pxa_ssp_set_dai_fmt,
845 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
846 .set_tristate = pxa_ssp_set_dai_tristate,
847 },
848 },
849 {
850 .name = "pxa2xx-ssp3",
851 .id = 2,
852 .probe = pxa_ssp_probe,
853 .remove = pxa_ssp_remove,
854 .suspend = pxa_ssp_suspend,
855 .resume = pxa_ssp_resume,
856 .playback = {
857 .channels_min = 1,
858 .channels_max = 2,
859 .rates = PXA_SSP_RATES,
860 .formats = PXA_SSP_FORMATS,
861 },
862 .capture = {
863 .channels_min = 1,
864 .channels_max = 2,
865 .rates = PXA_SSP_RATES,
866 .formats = PXA_SSP_FORMATS,
867 },
868 .ops = {
869 .startup = pxa_ssp_startup,
870 .shutdown = pxa_ssp_shutdown,
871 .trigger = pxa_ssp_trigger,
872 .hw_params = pxa_ssp_hw_params,
873 .set_sysclk = pxa_ssp_set_dai_sysclk,
874 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
875 .set_pll = pxa_ssp_set_dai_pll,
876 .set_fmt = pxa_ssp_set_dai_fmt,
877 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
878 .set_tristate = pxa_ssp_set_dai_tristate,
879 },
880 },
881 {
882 .name = "pxa2xx-ssp4",
883 .id = 3,
884 .probe = pxa_ssp_probe,
885 .remove = pxa_ssp_remove,
886 .suspend = pxa_ssp_suspend,
887 .resume = pxa_ssp_resume,
888 .playback = {
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = PXA_SSP_RATES,
892 .formats = PXA_SSP_FORMATS,
893 },
894 .capture = {
895 .channels_min = 1,
896 .channels_max = 2,
897 .rates = PXA_SSP_RATES,
898 .formats = PXA_SSP_FORMATS,
899 },
900 .ops = {
901 .startup = pxa_ssp_startup,
902 .shutdown = pxa_ssp_shutdown,
903 .trigger = pxa_ssp_trigger,
904 .hw_params = pxa_ssp_hw_params,
905 .set_sysclk = pxa_ssp_set_dai_sysclk,
906 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
907 .set_pll = pxa_ssp_set_dai_pll,
908 .set_fmt = pxa_ssp_set_dai_fmt,
909 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
910 .set_tristate = pxa_ssp_set_dai_tristate,
911 },
912 },
913};
914EXPORT_SYMBOL_GPL(pxa_ssp_dai);
915
916static int __init pxa_ssp_init(void)
917{
918 return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
919}
920module_init(pxa_ssp_init);
921
922static void __exit pxa_ssp_exit(void)
923{
924 snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
925}
926module_exit(pxa_ssp_exit);
927
928/* Module information */
929MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
930MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
931MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
new file mode 100644
index 000000000000..91deadd55675
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -0,0 +1,47 @@
1/*
2 * ASoC PXA SSP port support
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 _PXA_SSP_H
10#define _PXA_SSP_H
11
12/* pxa DAI SSP IDs */
13#define PXA_DAI_SSP1 0
14#define PXA_DAI_SSP2 1
15#define PXA_DAI_SSP3 2
16#define PXA_DAI_SSP4 3
17
18/* SSP clock sources */
19#define PXA_SSP_CLK_PLL 0
20#define PXA_SSP_CLK_EXT 1
21#define PXA_SSP_CLK_NET 2
22#define PXA_SSP_CLK_AUDIO 3
23#define PXA_SSP_CLK_NET_PLL 4
24
25/* SSP audio dividers */
26#define PXA_SSP_AUDIO_DIV_ACDS 0
27#define PXA_SSP_AUDIO_DIV_SCDB 1
28#define PXA_SSP_DIV_SCR 2
29
30/* SSP ACDS audio dividers values */
31#define PXA_SSP_CLK_AUDIO_DIV_1 0
32#define PXA_SSP_CLK_AUDIO_DIV_2 1
33#define PXA_SSP_CLK_AUDIO_DIV_4 2
34#define PXA_SSP_CLK_AUDIO_DIV_8 3
35#define PXA_SSP_CLK_AUDIO_DIV_16 4
36#define PXA_SSP_CLK_AUDIO_DIV_32 5
37
38/* SSP divider bypass */
39#define PXA_SSP_CLK_SCDB_4 0
40#define PXA_SSP_CLK_SCDB_1 1
41#define PXA_SSP_CLK_SCDB_8 2
42
43#define PXA_SSP_PLL_OUT 0
44
45extern struct snd_soc_dai pxa_ssp_dai[4];
46
47#endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index a80ae074b090..812c2b4d3e07 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -21,6 +21,7 @@
21 21
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <mach/pxa-regs.h> 23#include <mach/pxa-regs.h>
24#include <mach/regs-ac97.h>
24 25
25#include "pxa2xx-pcm.h" 26#include "pxa2xx-pcm.h"
26#include "pxa2xx-ac97.h" 27#include "pxa2xx-ac97.h"
@@ -49,7 +50,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
49static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = { 50static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
50 .name = "AC97 PCM Stereo out", 51 .name = "AC97 PCM Stereo out",
51 .dev_addr = __PREG(PCDR), 52 .dev_addr = __PREG(PCDR),
52 .drcmr = &DRCMRTXPCDR, 53 .drcmr = &DRCMR(12),
53 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 54 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
54 DCMD_BURST32 | DCMD_WIDTH4, 55 DCMD_BURST32 | DCMD_WIDTH4,
55}; 56};
@@ -57,7 +58,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_out = {
57static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = { 58static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
58 .name = "AC97 PCM Stereo in", 59 .name = "AC97 PCM Stereo in",
59 .dev_addr = __PREG(PCDR), 60 .dev_addr = __PREG(PCDR),
60 .drcmr = &DRCMRRXPCDR, 61 .drcmr = &DRCMR(11),
61 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 62 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
62 DCMD_BURST32 | DCMD_WIDTH4, 63 DCMD_BURST32 | DCMD_WIDTH4,
63}; 64};
@@ -65,7 +66,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_stereo_in = {
65static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = { 66static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
66 .name = "AC97 Aux PCM (Slot 5) Mono out", 67 .name = "AC97 Aux PCM (Slot 5) Mono out",
67 .dev_addr = __PREG(MODR), 68 .dev_addr = __PREG(MODR),
68 .drcmr = &DRCMRTXMODR, 69 .drcmr = &DRCMR(10),
69 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 70 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
70 DCMD_BURST16 | DCMD_WIDTH2, 71 DCMD_BURST16 | DCMD_WIDTH2,
71}; 72};
@@ -73,7 +74,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_out = {
73static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = { 74static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
74 .name = "AC97 Aux PCM (Slot 5) Mono in", 75 .name = "AC97 Aux PCM (Slot 5) Mono in",
75 .dev_addr = __PREG(MODR), 76 .dev_addr = __PREG(MODR),
76 .drcmr = &DRCMRRXMODR, 77 .drcmr = &DRCMR(9),
77 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 78 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
78 DCMD_BURST16 | DCMD_WIDTH2, 79 DCMD_BURST16 | DCMD_WIDTH2,
79}; 80};
@@ -81,20 +82,18 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_aux_mono_in = {
81static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = { 82static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
82 .name = "AC97 Mic PCM (Slot 6) Mono in", 83 .name = "AC97 Mic PCM (Slot 6) Mono in",
83 .dev_addr = __PREG(MCDR), 84 .dev_addr = __PREG(MCDR),
84 .drcmr = &DRCMRRXMCDR, 85 .drcmr = &DRCMR(8),
85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 86 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
86 DCMD_BURST16 | DCMD_WIDTH2, 87 DCMD_BURST16 | DCMD_WIDTH2,
87}; 88};
88 89
89#ifdef CONFIG_PM 90#ifdef CONFIG_PM
90static int pxa2xx_ac97_suspend(struct platform_device *pdev, 91static int pxa2xx_ac97_suspend(struct snd_soc_dai *dai)
91 struct snd_soc_dai *dai)
92{ 92{
93 return pxa2xx_ac97_hw_suspend(); 93 return pxa2xx_ac97_hw_suspend();
94} 94}
95 95
96static int pxa2xx_ac97_resume(struct platform_device *pdev, 96static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
97 struct snd_soc_dai *dai)
98{ 97{
99 return pxa2xx_ac97_hw_resume(); 98 return pxa2xx_ac97_hw_resume();
100} 99}
@@ -117,7 +116,8 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev,
117} 116}
118 117
119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 118static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params) 119 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai)
121{ 121{
122 struct snd_soc_pcm_runtime *rtd = substream->private_data; 122 struct snd_soc_pcm_runtime *rtd = substream->private_data;
123 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 123 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -131,7 +131,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
131} 131}
132 132
133static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 133static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *params) 134 struct snd_pcm_hw_params *params,
135 struct snd_soc_dai *dai)
135{ 136{
136 struct snd_soc_pcm_runtime *rtd = substream->private_data; 137 struct snd_soc_pcm_runtime *rtd = substream->private_data;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 138 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -145,7 +146,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
145} 146}
146 147
147static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 148static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params) 149 struct snd_pcm_hw_params *params,
150 struct snd_soc_dai *dai)
149{ 151{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data; 152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 153 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -170,7 +172,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
170{ 172{
171 .name = "pxa2xx-ac97", 173 .name = "pxa2xx-ac97",
172 .id = 0, 174 .id = 0,
173 .type = SND_SOC_DAI_AC97, 175 .ac97_control = 1,
174 .probe = pxa2xx_ac97_probe, 176 .probe = pxa2xx_ac97_probe,
175 .remove = pxa2xx_ac97_remove, 177 .remove = pxa2xx_ac97_remove,
176 .suspend = pxa2xx_ac97_suspend, 178 .suspend = pxa2xx_ac97_suspend,
@@ -193,7 +195,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
193{ 195{
194 .name = "pxa2xx-ac97-aux", 196 .name = "pxa2xx-ac97-aux",
195 .id = 1, 197 .id = 1,
196 .type = SND_SOC_DAI_AC97, 198 .ac97_control = 1,
197 .playback = { 199 .playback = {
198 .stream_name = "AC97 Aux Playback", 200 .stream_name = "AC97 Aux Playback",
199 .channels_min = 1, 201 .channels_min = 1,
@@ -212,7 +214,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
212{ 214{
213 .name = "pxa2xx-ac97-mic", 215 .name = "pxa2xx-ac97-mic",
214 .id = 2, 216 .id = 2,
215 .type = SND_SOC_DAI_AC97, 217 .ac97_control = 1,
216 .capture = { 218 .capture = {
217 .stream_name = "AC97 Mic Capture", 219 .stream_name = "AC97 Mic Capture",
218 .channels_min = 1, 220 .channels_min = 1,
@@ -227,6 +229,18 @@ struct snd_soc_dai pxa_ac97_dai[] = {
227EXPORT_SYMBOL_GPL(pxa_ac97_dai); 229EXPORT_SYMBOL_GPL(pxa_ac97_dai);
228EXPORT_SYMBOL_GPL(soc_ac97_ops); 230EXPORT_SYMBOL_GPL(soc_ac97_ops);
229 231
232static int __init pxa_ac97_init(void)
233{
234 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
235}
236module_init(pxa_ac97_init);
237
238static void __exit pxa_ac97_exit(void)
239{
240 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
241}
242module_exit(pxa_ac97_exit);
243
230MODULE_AUTHOR("Nicolas Pitre"); 244MODULE_AUTHOR("Nicolas Pitre");
231MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); 245MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
232MODULE_LICENSE("GPL"); 246MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index 39d19212f6d3..517991fb1099 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com 6 * lrg@slimlogic.co.uk
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 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 9 * under the terms of the GNU General Public License as published by the
@@ -39,6 +39,45 @@ struct pxa2xx_gpio {
39 u32 frm; 39 u32 frm;
40}; 40};
41 41
42/*
43 * I2S Controller Register and Bit Definitions
44 */
45#define SACR0 __REG(0x40400000) /* Global Control Register */
46#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
47#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
48#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
49#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
50#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
51#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
52
53#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
54#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */
55#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
56#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
57#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
58#define SACR0_BCKD (1 << 2) /* Bit Clock Direction */
59#define SACR0_ENB (1 << 0) /* Enable I2S Link */
60#define SACR1_ENLBF (1 << 5) /* Enable Loopback */
61#define SACR1_DRPL (1 << 4) /* Disable Replaying Function */
62#define SACR1_DREC (1 << 3) /* Disable Recording Function */
63#define SACR1_AMSL (1 << 0) /* Specify Alternate Mode */
64
65#define SASR0_I2SOFF (1 << 7) /* Controller Status */
66#define SASR0_ROR (1 << 6) /* Rx FIFO Overrun */
67#define SASR0_TUR (1 << 5) /* Tx FIFO Underrun */
68#define SASR0_RFS (1 << 4) /* Rx FIFO Service Request */
69#define SASR0_TFS (1 << 3) /* Tx FIFO Service Request */
70#define SASR0_BSY (1 << 2) /* I2S Busy */
71#define SASR0_RNE (1 << 1) /* Rx FIFO Not Empty */
72#define SASR0_TNF (1 << 0) /* Tx FIFO Not Empty */
73
74#define SAICR_ROR (1 << 6) /* Clear Rx FIFO Overrun Interrupt */
75#define SAICR_TUR (1 << 5) /* Clear Tx FIFO Underrun Interrupt */
76
77#define SAIMR_ROR (1 << 6) /* Enable Rx FIFO Overrun Condition Interrupt */
78#define SAIMR_TUR (1 << 5) /* Enable Tx FIFO Underrun Condition Interrupt */
79#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */
80#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */
42 81
43struct pxa_i2s_port { 82struct pxa_i2s_port {
44 u32 sadiv; 83 u32 sadiv;
@@ -54,7 +93,7 @@ static struct clk *clk_i2s;
54static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = { 93static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
55 .name = "I2S PCM Stereo out", 94 .name = "I2S PCM Stereo out",
56 .dev_addr = __PREG(SADR), 95 .dev_addr = __PREG(SADR),
57 .drcmr = &DRCMRTXSADR, 96 .drcmr = &DRCMR(3),
58 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG | 97 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
59 DCMD_BURST32 | DCMD_WIDTH4, 98 DCMD_BURST32 | DCMD_WIDTH4,
60}; 99};
@@ -62,7 +101,7 @@ static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_out = {
62static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = { 101static struct pxa2xx_pcm_dma_params pxa2xx_i2s_pcm_stereo_in = {
63 .name = "I2S PCM Stereo in", 102 .name = "I2S PCM Stereo in",
64 .dev_addr = __PREG(SADR), 103 .dev_addr = __PREG(SADR),
65 .drcmr = &DRCMRRXSADR, 104 .drcmr = &DRCMR(2),
66 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC | 105 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
67 DCMD_BURST32 | DCMD_WIDTH4, 106 DCMD_BURST32 | DCMD_WIDTH4,
68}; 107};
@@ -82,7 +121,8 @@ static struct pxa2xx_gpio gpio_bus[] = {
82 }, 121 },
83}; 122};
84 123
85static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) 124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
125 struct snd_soc_dai *dai)
86{ 126{
87 struct snd_soc_pcm_runtime *rtd = substream->private_data; 127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
88 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 128 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -148,7 +188,8 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
148} 188}
149 189
150static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, 190static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
151 struct snd_pcm_hw_params *params) 191 struct snd_pcm_hw_params *params,
192 struct snd_soc_dai *dai)
152{ 193{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -209,7 +250,8 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
209 return 0; 250 return 0;
210} 251}
211 252
212static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 253static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
254 struct snd_soc_dai *dai)
213{ 255{
214 int ret = 0; 256 int ret = 0;
215 257
@@ -230,7 +272,8 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
230 return ret; 272 return ret;
231} 273}
232 274
233static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) 275static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
276 struct snd_soc_dai *dai)
234{ 277{
235 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
236 SACR1 |= SACR1_DRPL; 279 SACR1 |= SACR1_DRPL;
@@ -250,8 +293,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
250} 293}
251 294
252#ifdef CONFIG_PM 295#ifdef CONFIG_PM
253static int pxa2xx_i2s_suspend(struct platform_device *dev, 296static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
254 struct snd_soc_dai *dai)
255{ 297{
256 if (!dai->active) 298 if (!dai->active)
257 return 0; 299 return 0;
@@ -268,8 +310,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev,
268 return 0; 310 return 0;
269} 311}
270 312
271static int pxa2xx_i2s_resume(struct platform_device *pdev, 313static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
272 struct snd_soc_dai *dai)
273{ 314{
274 if (!dai->active) 315 if (!dai->active)
275 return 0; 316 return 0;
@@ -297,7 +338,6 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev,
297struct snd_soc_dai pxa_i2s_dai = { 338struct snd_soc_dai pxa_i2s_dai = {
298 .name = "pxa2xx-i2s", 339 .name = "pxa2xx-i2s",
299 .id = 0, 340 .id = 0,
300 .type = SND_SOC_DAI_I2S,
301 .suspend = pxa2xx_i2s_suspend, 341 .suspend = pxa2xx_i2s_suspend,
302 .resume = pxa2xx_i2s_resume, 342 .resume = pxa2xx_i2s_resume,
303 .playback = { 343 .playback = {
@@ -314,8 +354,7 @@ struct snd_soc_dai pxa_i2s_dai = {
314 .startup = pxa2xx_i2s_startup, 354 .startup = pxa2xx_i2s_startup,
315 .shutdown = pxa2xx_i2s_shutdown, 355 .shutdown = pxa2xx_i2s_shutdown,
316 .trigger = pxa2xx_i2s_trigger, 356 .trigger = pxa2xx_i2s_trigger,
317 .hw_params = pxa2xx_i2s_hw_params,}, 357 .hw_params = pxa2xx_i2s_hw_params,
318 .dai_ops = {
319 .set_fmt = pxa2xx_i2s_set_dai_fmt, 358 .set_fmt = pxa2xx_i2s_set_dai_fmt,
320 .set_sysclk = pxa2xx_i2s_set_dai_sysclk, 359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
321 }, 360 },
@@ -325,12 +364,23 @@ EXPORT_SYMBOL_GPL(pxa_i2s_dai);
325 364
326static int pxa2xx_i2s_probe(struct platform_device *dev) 365static int pxa2xx_i2s_probe(struct platform_device *dev)
327{ 366{
367 int ret;
368
328 clk_i2s = clk_get(&dev->dev, "I2SCLK"); 369 clk_i2s = clk_get(&dev->dev, "I2SCLK");
329 return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0; 370 if (IS_ERR(clk_i2s))
371 return PTR_ERR(clk_i2s);
372
373 pxa_i2s_dai.dev = &dev->dev;
374 ret = snd_soc_register_dai(&pxa_i2s_dai);
375 if (ret != 0)
376 clk_put(clk_i2s);
377
378 return ret;
330} 379}
331 380
332static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) 381static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
333{ 382{
383 snd_soc_unregister_dai(&pxa_i2s_dai);
334 clk_put(clk_i2s); 384 clk_put(clk_i2s);
335 clk_i2s = ERR_PTR(-ENOENT); 385 clk_i2s = ERR_PTR(-ENOENT);
336 return 0; 386 return 0;
@@ -366,6 +416,6 @@ module_init(pxa2xx_i2s_init);
366module_exit(pxa2xx_i2s_exit); 416module_exit(pxa2xx_i2s_exit);
367 417
368/* Module information */ 418/* Module information */
369MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 419MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
370MODULE_DESCRIPTION("pxa2xx I2S SoC Interface"); 420MODULE_DESCRIPTION("pxa2xx I2S SoC Interface");
371MODULE_LICENSE("GPL"); 421MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index afcd892cd2fa..53b9fb127a6d 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -61,15 +61,15 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
61 61
62 __pxa2xx_pcm_hw_free(substream); 62 __pxa2xx_pcm_hw_free(substream);
63 63
64 if (prtd->dma_ch) { 64 if (prtd->dma_ch >= 0) {
65 pxa_free_dma(prtd->dma_ch); 65 pxa_free_dma(prtd->dma_ch);
66 prtd->dma_ch = 0; 66 prtd->dma_ch = -1;
67 } 67 }
68 68
69 return 0; 69 return 0;
70} 70}
71 71
72struct snd_pcm_ops pxa2xx_pcm_ops = { 72static struct snd_pcm_ops pxa2xx_pcm_ops = {
73 .open = __pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
74 .close = __pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
75 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
@@ -118,6 +118,18 @@ struct snd_soc_platform pxa2xx_soc_platform = {
118}; 118};
119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
120 120
121static int __init pxa2xx_soc_platform_init(void)
122{
123 return snd_soc_register_platform(&pxa2xx_soc_platform);
124}
125module_init(pxa2xx_soc_platform_init);
126
127static void __exit pxa2xx_soc_platform_exit(void)
128{
129 snd_soc_unregister_platform(&pxa2xx_soc_platform);
130}
131module_exit(pxa2xx_soc_platform_exit);
132
121MODULE_AUTHOR("Nicolas Pitre"); 133MODULE_AUTHOR("Nicolas Pitre");
122MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); 134MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
123MODULE_LICENSE("GPL"); 135MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 3d4738c06e7e..a3b9e6bdf979 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -19,16 +19,15 @@
19#include <linux/timer.h> 19#include <linux/timer.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/gpio.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/soc.h> 25#include <sound/soc.h>
25#include <sound/soc-dapm.h> 26#include <sound/soc-dapm.h>
26 27
27#include <asm/mach-types.h> 28#include <asm/mach-types.h>
28#include <asm/hardware/scoop.h>
29#include <mach/pxa-regs.h> 29#include <mach/pxa-regs.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/akita.h>
32#include <mach/spitz.h> 31#include <mach/spitz.h>
33#include "../codecs/wm8750.h" 32#include "../codecs/wm8750.h"
34#include "pxa2xx-pcm.h" 33#include "pxa2xx-pcm.h"
@@ -63,8 +62,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
63 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 62 snd_soc_dapm_disable_pin(codec, "Mic Jack");
64 snd_soc_dapm_disable_pin(codec, "Line Jack"); 63 snd_soc_dapm_disable_pin(codec, "Line Jack");
65 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 64 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
66 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 65 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
67 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 66 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
68 break; 67 break;
69 case SPITZ_MIC: 68 case SPITZ_MIC:
70 /* enable mic jack and bias, mute hp */ 69 /* enable mic jack and bias, mute hp */
@@ -72,8 +71,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
72 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 71 snd_soc_dapm_disable_pin(codec, "Headset Jack");
73 snd_soc_dapm_disable_pin(codec, "Line Jack"); 72 snd_soc_dapm_disable_pin(codec, "Line Jack");
74 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 73 snd_soc_dapm_enable_pin(codec, "Mic Jack");
75 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 74 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
76 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 75 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
77 break; 76 break;
78 case SPITZ_LINE: 77 case SPITZ_LINE:
79 /* enable line jack, disable mic bias and mute hp */ 78 /* enable line jack, disable mic bias and mute hp */
@@ -81,8 +80,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
81 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 80 snd_soc_dapm_disable_pin(codec, "Headset Jack");
82 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 81 snd_soc_dapm_disable_pin(codec, "Mic Jack");
83 snd_soc_dapm_enable_pin(codec, "Line Jack"); 82 snd_soc_dapm_enable_pin(codec, "Line Jack");
84 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 83 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
85 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 84 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
86 break; 85 break;
87 case SPITZ_HEADSET: 86 case SPITZ_HEADSET:
88 /* enable and unmute headset jack enable mic bias, mute L hp */ 87 /* enable and unmute headset jack enable mic bias, mute L hp */
@@ -90,8 +89,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
90 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 89 snd_soc_dapm_enable_pin(codec, "Mic Jack");
91 snd_soc_dapm_disable_pin(codec, "Line Jack"); 90 snd_soc_dapm_disable_pin(codec, "Line Jack");
92 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 91 snd_soc_dapm_enable_pin(codec, "Headset Jack");
93 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 92 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
94 set_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 93 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
95 break; 94 break;
96 case SPITZ_HP_OFF: 95 case SPITZ_HP_OFF:
97 96
@@ -100,8 +99,8 @@ static void spitz_ext_control(struct snd_soc_codec *codec)
100 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 99 snd_soc_dapm_disable_pin(codec, "Headset Jack");
101 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 100 snd_soc_dapm_disable_pin(codec, "Mic Jack");
102 snd_soc_dapm_disable_pin(codec, "Line Jack"); 101 snd_soc_dapm_disable_pin(codec, "Line Jack");
103 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_L); 102 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
104 reset_scoop_gpio(&spitzscoop_device.dev, SPITZ_SCP_MUTE_R); 103 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
105 break; 104 break;
106 } 105 }
107 snd_soc_dapm_sync(codec); 106 snd_soc_dapm_sync(codec);
@@ -215,23 +214,14 @@ static int spitz_set_spk(struct snd_kcontrol *kcontrol,
215static int spitz_mic_bias(struct snd_soc_dapm_widget *w, 214static int spitz_mic_bias(struct snd_soc_dapm_widget *w,
216 struct snd_kcontrol *k, int event) 215 struct snd_kcontrol *k, int event)
217{ 216{
218 if (machine_is_borzoi() || machine_is_spitz()) { 217 if (machine_is_borzoi() || machine_is_spitz())
219 if (SND_SOC_DAPM_EVENT_ON(event)) 218 gpio_set_value(SPITZ_GPIO_MIC_BIAS,
220 set_scoop_gpio(&spitzscoop2_device.dev, 219 SND_SOC_DAPM_EVENT_ON(event));
221 SPITZ_SCP2_MIC_BIAS); 220
222 else 221 if (machine_is_akita())
223 reset_scoop_gpio(&spitzscoop2_device.dev, 222 gpio_set_value(AKITA_GPIO_MIC_BIAS,
224 SPITZ_SCP2_MIC_BIAS); 223 SND_SOC_DAPM_EVENT_ON(event));
225 }
226 224
227 if (machine_is_akita()) {
228 if (SND_SOC_DAPM_EVENT_ON(event))
229 akita_set_ioexp(&akitaioexp_device.dev,
230 AKITA_IOEXP_MIC_BIAS);
231 else
232 akita_reset_ioexp(&akitaioexp_device.dev,
233 AKITA_IOEXP_MIC_BIAS);
234 }
235 return 0; 225 return 0;
236} 226}
237 227
@@ -291,13 +281,13 @@ static int spitz_wm8750_init(struct snd_soc_codec *codec)
291 int i, err; 281 int i, err;
292 282
293 /* NC codec pins */ 283 /* NC codec pins */
294 snd_soc_dapm_disable_pin(codec, "RINPUT1"); 284 snd_soc_dapm_nc_pin(codec, "RINPUT1");
295 snd_soc_dapm_disable_pin(codec, "LINPUT2"); 285 snd_soc_dapm_nc_pin(codec, "LINPUT2");
296 snd_soc_dapm_disable_pin(codec, "RINPUT2"); 286 snd_soc_dapm_nc_pin(codec, "RINPUT2");
297 snd_soc_dapm_disable_pin(codec, "LINPUT3"); 287 snd_soc_dapm_nc_pin(codec, "LINPUT3");
298 snd_soc_dapm_disable_pin(codec, "RINPUT3"); 288 snd_soc_dapm_nc_pin(codec, "RINPUT3");
299 snd_soc_dapm_disable_pin(codec, "OUT3"); 289 snd_soc_dapm_nc_pin(codec, "OUT3");
300 snd_soc_dapm_disable_pin(codec, "MONO1"); 290 snd_soc_dapm_nc_pin(codec, "MONO1");
301 291
302 /* Add spitz specific controls */ 292 /* Add spitz specific controls */
303 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) { 293 for (i = 0; i < ARRAY_SIZE(wm8750_spitz_controls); i++) {
@@ -329,8 +319,9 @@ static struct snd_soc_dai_link spitz_dai = {
329}; 319};
330 320
331/* spitz audio machine driver */ 321/* spitz audio machine driver */
332static struct snd_soc_machine snd_soc_machine_spitz = { 322static struct snd_soc_card snd_soc_spitz = {
333 .name = "Spitz", 323 .name = "Spitz",
324 .platform = &pxa2xx_soc_platform,
334 .dai_link = &spitz_dai, 325 .dai_link = &spitz_dai,
335 .num_links = 1, 326 .num_links = 1,
336}; 327};
@@ -343,8 +334,7 @@ static struct wm8750_setup_data spitz_wm8750_setup = {
343 334
344/* spitz audio subsystem */ 335/* spitz audio subsystem */
345static struct snd_soc_device spitz_snd_devdata = { 336static struct snd_soc_device spitz_snd_devdata = {
346 .machine = &snd_soc_machine_spitz, 337 .card = &snd_soc_spitz,
347 .platform = &pxa2xx_soc_platform,
348 .codec_dev = &soc_codec_dev_wm8750, 338 .codec_dev = &soc_codec_dev_wm8750,
349 .codec_data = &spitz_wm8750_setup, 339 .codec_data = &spitz_wm8750_setup,
350}; 340};
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 2baaa750f123..c77194f74c9b 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -4,7 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Authors: Liam Girdwood <liam.girdwood@wolfsonmicro.com> 7 * Authors: Liam Girdwood <lrg@slimlogic.co.uk>
8 * Richard Purdie <richard@openedhand.com> 8 * Richard Purdie <richard@openedhand.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
38#include "pxa2xx-pcm.h" 38#include "pxa2xx-pcm.h"
39#include "pxa2xx-ac97.h" 39#include "pxa2xx-ac97.h"
40 40
41static struct snd_soc_machine tosa; 41static struct snd_soc_card tosa;
42 42
43#define TOSA_HP 0 43#define TOSA_HP 0
44#define TOSA_MIC_INT 1 44#define TOSA_MIC_INT 1
@@ -190,8 +190,8 @@ static int tosa_ac97_init(struct snd_soc_codec *codec)
190{ 190{
191 int i, err; 191 int i, err;
192 192
193 snd_soc_dapm_disable_pin(codec, "OUT3"); 193 snd_soc_dapm_nc_pin(codec, "OUT3");
194 snd_soc_dapm_disable_pin(codec, "MONOOUT"); 194 snd_soc_dapm_nc_pin(codec, "MONOOUT");
195 195
196 /* add tosa specific controls */ 196 /* add tosa specific controls */
197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) { 197 for (i = 0; i < ARRAY_SIZE(tosa_controls); i++) {
@@ -230,15 +230,37 @@ static struct snd_soc_dai_link tosa_dai[] = {
230}, 230},
231}; 231};
232 232
233static struct snd_soc_machine tosa = { 233static int tosa_probe(struct platform_device *dev)
234{
235 int ret;
236
237 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
238 if (ret)
239 return ret;
240 ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
241 if (ret)
242 gpio_free(TOSA_GPIO_L_MUTE);
243
244 return ret;
245}
246
247static int tosa_remove(struct platform_device *dev)
248{
249 gpio_free(TOSA_GPIO_L_MUTE);
250 return 0;
251}
252
253static struct snd_soc_card tosa = {
234 .name = "Tosa", 254 .name = "Tosa",
255 .platform = &pxa2xx_soc_platform,
235 .dai_link = tosa_dai, 256 .dai_link = tosa_dai,
236 .num_links = ARRAY_SIZE(tosa_dai), 257 .num_links = ARRAY_SIZE(tosa_dai),
258 .probe = tosa_probe,
259 .remove = tosa_remove,
237}; 260};
238 261
239static struct snd_soc_device tosa_snd_devdata = { 262static struct snd_soc_device tosa_snd_devdata = {
240 .machine = &tosa, 263 .card = &tosa,
241 .platform = &pxa2xx_soc_platform,
242 .codec_dev = &soc_codec_dev_wm9712, 264 .codec_dev = &soc_codec_dev_wm9712,
243}; 265};
244 266
@@ -251,11 +273,6 @@ static int __init tosa_init(void)
251 if (!machine_is_tosa()) 273 if (!machine_is_tosa())
252 return -ENODEV; 274 return -ENODEV;
253 275
254 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
255 if (ret)
256 return ret;
257 gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
258
259 tosa_snd_device = platform_device_alloc("soc-audio", -1); 276 tosa_snd_device = platform_device_alloc("soc-audio", -1);
260 if (!tosa_snd_device) { 277 if (!tosa_snd_device) {
261 ret = -ENOMEM; 278 ret = -ENOMEM;
@@ -272,15 +289,12 @@ static int __init tosa_init(void)
272 platform_device_put(tosa_snd_device); 289 platform_device_put(tosa_snd_device);
273 290
274err_alloc: 291err_alloc:
275 gpio_free(TOSA_GPIO_L_MUTE);
276
277 return ret; 292 return ret;
278} 293}
279 294
280static void __exit tosa_exit(void) 295static void __exit tosa_exit(void)
281{ 296{
282 platform_device_unregister(tosa_snd_device); 297 platform_device_unregister(tosa_snd_device);
283 gpio_free(TOSA_GPIO_L_MUTE);
284} 298}
285 299
286module_init(tosa_init); 300module_init(tosa_init);
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
new file mode 100644
index 000000000000..f8e9ecd589d3
--- /dev/null
+++ b/sound/soc/pxa/zylonite.c
@@ -0,0 +1,219 @@
1/*
2 * zylonite.c -- SoC audio for Zylonite
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/device.h>
17#include <linux/i2c.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm9713.h"
25#include "pxa2xx-pcm.h"
26#include "pxa2xx-ac97.h"
27#include "pxa-ssp.h"
28
29static struct snd_soc_card zylonite;
30
31static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
32 SND_SOC_DAPM_HP("Headphone", NULL),
33 SND_SOC_DAPM_MIC("Headset Microphone", NULL),
34 SND_SOC_DAPM_MIC("Handset Microphone", NULL),
35 SND_SOC_DAPM_SPK("Multiactor", NULL),
36 SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
37};
38
39/* Currently supported audio map */
40static const struct snd_soc_dapm_route audio_map[] = {
41
42 /* Headphone output connected to HPL/HPR */
43 { "Headphone", NULL, "HPL" },
44 { "Headphone", NULL, "HPR" },
45
46 /* On-board earpiece */
47 { "Headset Earpiece", NULL, "OUT3" },
48
49 /* Headphone mic */
50 { "MIC2A", NULL, "Mic Bias" },
51 { "Mic Bias", NULL, "Headset Microphone" },
52
53 /* On-board mic */
54 { "MIC1", NULL, "Mic Bias" },
55 { "Mic Bias", NULL, "Handset Microphone" },
56
57 /* Multiactor differentially connected over SPKL/SPKR */
58 { "Multiactor", NULL, "SPKL" },
59 { "Multiactor", NULL, "SPKR" },
60};
61
62static int zylonite_wm9713_init(struct snd_soc_codec *codec)
63{
64 /* Currently we only support use of the AC97 clock here. If
65 * CLK_POUT is selected by SW15 then the clock API will need
66 * to be used to request and enable it here.
67 */
68
69 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
70 ARRAY_SIZE(zylonite_dapm_widgets));
71
72 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
73
74 /* Static setup for now */
75 snd_soc_dapm_enable_pin(codec, "Headphone");
76 snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
77
78 snd_soc_dapm_sync(codec);
79 return 0;
80}
81
82static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
83 struct snd_pcm_hw_params *params)
84{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
87 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
88 unsigned int pll_out = 0;
89 unsigned int acds = 0;
90 unsigned int wm9713_div = 0;
91 int ret = 0;
92
93 switch (params_rate(params)) {
94 case 8000:
95 wm9713_div = 12;
96 pll_out = 2048000;
97 break;
98 case 16000:
99 wm9713_div = 6;
100 pll_out = 4096000;
101 break;
102 case 48000:
103 default:
104 wm9713_div = 2;
105 pll_out = 12288000;
106 acds = 1;
107 break;
108 }
109
110 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
111 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
112 if (ret < 0)
113 return ret;
114
115 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
116 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
117 if (ret < 0)
118 return ret;
119
120 ret = snd_soc_dai_set_tdm_slot(cpu_dai,
121 params_channels(params),
122 params_channels(params));
123 if (ret < 0)
124 return ret;
125
126 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out);
127 if (ret < 0)
128 return ret;
129
130 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
131 if (ret < 0)
132 return ret;
133
134 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
135 if (ret < 0)
136 return ret;
137
138 /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs
139 * to be set instead.
140 */
141 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
142 WM9713_PCMDIV(wm9713_div));
143 if (ret < 0)
144 return ret;
145
146 return 0;
147}
148
149static struct snd_soc_ops zylonite_voice_ops = {
150 .hw_params = zylonite_voice_hw_params,
151};
152
153static struct snd_soc_dai_link zylonite_dai[] = {
154{
155 .name = "AC97",
156 .stream_name = "AC97 HiFi",
157 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
158 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
159 .init = zylonite_wm9713_init,
160},
161{
162 .name = "AC97 Aux",
163 .stream_name = "AC97 Aux",
164 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
165 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
166},
167{
168 .name = "WM9713 Voice",
169 .stream_name = "WM9713 Voice",
170 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
171 .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
172 .ops = &zylonite_voice_ops,
173},
174};
175
176static struct snd_soc_card zylonite = {
177 .name = "Zylonite",
178 .platform = &pxa2xx_soc_platform,
179 .dai_link = zylonite_dai,
180 .num_links = ARRAY_SIZE(zylonite_dai),
181};
182
183static struct snd_soc_device zylonite_snd_ac97_devdata = {
184 .card = &zylonite,
185 .codec_dev = &soc_codec_dev_wm9713,
186};
187
188static struct platform_device *zylonite_snd_ac97_device;
189
190static int __init zylonite_init(void)
191{
192 int ret;
193
194 zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
195 if (!zylonite_snd_ac97_device)
196 return -ENOMEM;
197
198 platform_set_drvdata(zylonite_snd_ac97_device,
199 &zylonite_snd_ac97_devdata);
200 zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
201
202 ret = platform_device_add(zylonite_snd_ac97_device);
203 if (ret != 0)
204 platform_device_put(zylonite_snd_ac97_device);
205
206 return ret;
207}
208
209static void __exit zylonite_exit(void)
210{
211 platform_device_unregister(zylonite_snd_ac97_device);
212}
213
214module_init(zylonite_init);
215module_exit(zylonite_exit);
216
217MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
218MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
219MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b9f2353effeb..fcd03acf10f6 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -44,3 +44,8 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
44 Say Y if you want to add support for SoC audio on ln2440sbc 44 Say Y if you want to add support for SoC audio on ln2440sbc
45 with the ALC650. 45 with the ALC650.
46 46
47config SND_S3C24XX_SOC_S3C24XX_UDA134X
48 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
49 depends on SND_S3C24XX_SOC
50 select SND_S3C24XX_SOC_I2S
51 select SND_SOC_UDA134X
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 0aa5fb0b9700..96b3f3f617d4 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -13,7 +13,9 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
16snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
16 17
17obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 18obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
18obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 19obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
19obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 20obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
21obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 4eab2c19c454..12c71482d258 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -27,7 +27,7 @@
27#include "s3c24xx-pcm.h" 27#include "s3c24xx-pcm.h"
28#include "s3c24xx-ac97.h" 28#include "s3c24xx-ac97.h"
29 29
30static struct snd_soc_machine ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
32static struct snd_soc_dai_link ln2440sbc_dai[] = { 32static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
38}, 38},
39}; 39};
40 40
41static struct snd_soc_machine ln2440sbc = { 41static struct snd_soc_card ln2440sbc = {
42 .name = "LN2440SBC", 42 .name = "LN2440SBC",
43 .platform = &s3c24xx_soc_platform,
43 .dai_link = ln2440sbc_dai, 44 .dai_link = ln2440sbc_dai,
44 .num_links = ARRAY_SIZE(ln2440sbc_dai), 45 .num_links = ARRAY_SIZE(ln2440sbc_dai),
45}; 46};
46 47
47static struct snd_soc_device ln2440sbc_snd_ac97_devdata = { 48static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
48 .machine = &ln2440sbc, 49 .card = &ln2440sbc,
49 .platform = &s3c24xx_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 73a50e93a9a2..45bb12e8ea44 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -59,7 +59,7 @@
59#define NEO_CAPTURE_HEADSET 7 59#define NEO_CAPTURE_HEADSET 7
60#define NEO_CAPTURE_BLUETOOTH 8 60#define NEO_CAPTURE_BLUETOOTH 8
61 61
62static struct snd_soc_machine neo1973; 62static struct snd_soc_card neo1973;
63static struct i2c_client *i2c; 63static struct i2c_client *i2c;
64 64
65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
@@ -511,21 +511,20 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
511 DBG("Entered %s\n", __func__); 511 DBG("Entered %s\n", __func__);
512 512
513 /* set up NC codec pins */ 513 /* set up NC codec pins */
514 snd_soc_dapm_disable_pin(codec, "LOUT2"); 514 snd_soc_dapm_nc_pin(codec, "LOUT2");
515 snd_soc_dapm_disable_pin(codec, "ROUT2"); 515 snd_soc_dapm_nc_pin(codec, "ROUT2");
516 snd_soc_dapm_disable_pin(codec, "OUT3"); 516 snd_soc_dapm_nc_pin(codec, "OUT3");
517 snd_soc_dapm_disable_pin(codec, "OUT4"); 517 snd_soc_dapm_nc_pin(codec, "OUT4");
518 snd_soc_dapm_disable_pin(codec, "LINE1"); 518 snd_soc_dapm_nc_pin(codec, "LINE1");
519 snd_soc_dapm_disable_pin(codec, "LINE2"); 519 snd_soc_dapm_nc_pin(codec, "LINE2");
520
521
522 /* set endpoints to default mode */
523 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
524 520
525 /* Add neo1973 specific widgets */ 521 /* Add neo1973 specific widgets */
526 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 522 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
527 ARRAY_SIZE(wm8753_dapm_widgets)); 523 ARRAY_SIZE(wm8753_dapm_widgets));
528 524
525 /* set endpoints to default mode */
526 set_scenario_endpoints(codec, NEO_AUDIO_OFF);
527
529 /* add neo1973 specific controls */ 528 /* add neo1973 specific controls */
530 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) { 529 for (i = 0; i < ARRAY_SIZE(wm8753_neo1973_controls); i++) {
531 err = snd_ctl_add(codec->card, 530 err = snd_ctl_add(codec->card,
@@ -549,7 +548,6 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
549static struct snd_soc_dai bt_dai = { 548static struct snd_soc_dai bt_dai = {
550 .name = "Bluetooth", 549 .name = "Bluetooth",
551 .id = 0, 550 .id = 0,
552 .type = SND_SOC_DAI_PCM,
553 .playback = { 551 .playback = {
554 .channels_min = 1, 552 .channels_min = 1,
555 .channels_max = 1, 553 .channels_max = 1,
@@ -580,8 +578,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
580}, 578},
581}; 579};
582 580
583static struct snd_soc_machine neo1973 = { 581static struct snd_soc_card neo1973 = {
584 .name = "neo1973", 582 .name = "neo1973",
583 .platform = &s3c24xx_soc_platform,
585 .dai_link = neo1973_dai, 584 .dai_link = neo1973_dai,
586 .num_links = ARRAY_SIZE(neo1973_dai), 585 .num_links = ARRAY_SIZE(neo1973_dai),
587}; 586};
@@ -592,8 +591,7 @@ static struct wm8753_setup_data neo1973_wm8753_setup = {
592}; 591};
593 592
594static struct snd_soc_device neo1973_snd_devdata = { 593static struct snd_soc_device neo1973_snd_devdata = {
595 .machine = &neo1973, 594 .card = &neo1973,
596 .platform = &s3c24xx_soc_platform,
597 .codec_dev = &soc_codec_dev_wm8753, 595 .codec_dev = &soc_codec_dev_wm8753,
598 .codec_data = &neo1973_wm8753_setup, 596 .codec_data = &neo1973_wm8753_setup,
599}; 597};
@@ -603,6 +601,8 @@ static int lm4857_i2c_probe(struct i2c_client *client,
603{ 601{
604 DBG("Entered %s\n", __func__); 602 DBG("Entered %s\n", __func__);
605 603
604 i2c = client;
605
606 lm4857_write_regs(); 606 lm4857_write_regs();
607 return 0; 607 return 0;
608} 608}
@@ -611,6 +611,8 @@ static int lm4857_i2c_remove(struct i2c_client *client)
611{ 611{
612 DBG("Entered %s\n", __func__); 612 DBG("Entered %s\n", __func__);
613 613
614 i2c = NULL;
615
614 return 0; 616 return 0;
615} 617}
616 618
@@ -650,7 +652,7 @@ static void lm4857_shutdown(struct i2c_client *dev)
650} 652}
651 653
652static const struct i2c_device_id lm4857_i2c_id[] = { 654static const struct i2c_device_id lm4857_i2c_id[] = {
653 { "neo1973_lm4857", 0 } 655 { "neo1973_lm4857", 0 },
654 { } 656 { }
655}; 657};
656 658
@@ -668,48 +670,6 @@ static struct i2c_driver lm4857_i2c_driver = {
668}; 670};
669 671
670static struct platform_device *neo1973_snd_device; 672static struct platform_device *neo1973_snd_device;
671static struct i2c_client *lm4857_client;
672
673static int __init neo1973_add_lm4857_device(struct platform_device *pdev,
674 int i2c_bus,
675 unsigned short i2c_address)
676{
677 struct i2c_board_info info;
678 struct i2c_adapter *adapter;
679 struct i2c_client *client;
680 int ret;
681
682 ret = i2c_add_driver(&lm4857_i2c_driver);
683 if (ret != 0) {
684 dev_err(&pdev->dev, "can't add lm4857 driver\n");
685 return ret;
686 }
687
688 memset(&info, 0, sizeof(struct i2c_board_info));
689 info.addr = i2c_address;
690 strlcpy(info.type, "neo1973_lm4857", I2C_NAME_SIZE);
691
692 adapter = i2c_get_adapter(i2c_bus);
693 if (!adapter) {
694 dev_err(&pdev->dev, "can't get i2c adapter %d\n", i2c_bus);
695 goto err_driver;
696 }
697
698 client = i2c_new_device(adapter, &info);
699 i2c_put_adapter(adapter);
700 if (!client) {
701 dev_err(&pdev->dev, "can't add lm4857 device at 0x%x\n",
702 (unsigned int)info.addr);
703 goto err_driver;
704 }
705
706 lm4857_client = client;
707 return 0;
708
709err_driver:
710 i2c_del_driver(&lm4857_i2c_driver);
711 return -ENODEV;
712}
713 673
714static int __init neo1973_init(void) 674static int __init neo1973_init(void)
715{ 675{
@@ -736,8 +696,8 @@ static int __init neo1973_init(void)
736 return ret; 696 return ret;
737 } 697 }
738 698
739 ret = neo1973_add_lm4857_device(neo1973_snd_device, 699 ret = i2c_add_driver(&lm4857_i2c_driver);
740 neo1973_wm8753_setup, 0x7C); 700
741 if (ret != 0) 701 if (ret != 0)
742 platform_device_unregister(neo1973_snd_device); 702 platform_device_unregister(neo1973_snd_device);
743 703
@@ -748,7 +708,6 @@ static void __exit neo1973_exit(void)
748{ 708{
749 DBG("Entered %s\n", __func__); 709 DBG("Entered %s\n", __func__);
750 710
751 i2c_unregister_device(lm4857_client);
752 i2c_del_driver(&lm4857_i2c_driver); 711 i2c_del_driver(&lm4857_i2c_driver);
753 platform_device_unregister(neo1973_snd_device); 712 platform_device_unregister(neo1973_snd_device);
754} 713}
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index ded7d995a922..f3fc0aba0aaf 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -343,7 +343,8 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
343} 343}
344 344
345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params) 346 struct snd_pcm_hw_params *params,
347 struct snd_soc_dai *dai)
347{ 348{
348 struct snd_soc_pcm_runtime *rtd = substream->private_data; 349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
349 u32 iismod; 350 u32 iismod;
@@ -373,7 +374,8 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
373 return 0; 374 return 0;
374} 375}
375 376
376static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 377static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
378 struct snd_soc_dai *dai)
377{ 379{
378 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 380 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
379 unsigned long irqs; 381 unsigned long irqs;
@@ -647,8 +649,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
647} 649}
648 650
649#ifdef CONFIG_PM 651#ifdef CONFIG_PM
650static int s3c2412_i2s_suspend(struct platform_device *dev, 652static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
651 struct snd_soc_dai *dai)
652{ 653{
653 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 654 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
654 u32 iismod; 655 u32 iismod;
@@ -663,25 +664,24 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
663 iismod = readl(i2s->regs + S3C2412_IISMOD); 664 iismod = readl(i2s->regs + S3C2412_IISMOD);
664 665
665 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) 666 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
666 dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__); 667 pr_warning("%s: RXDMA active?\n", __func__);
667 668
668 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) 669 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
669 dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__); 670 pr_warning("%s: TXDMA active?\n", __func__);
670 671
671 if (iismod & S3C2412_IISCON_IIS_ACTIVE) 672 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
672 dev_warn(&dev->dev, "%s: IIS active\n", __func__); 673 pr_warning("%s: IIS active\n", __func__);
673 } 674 }
674 675
675 return 0; 676 return 0;
676} 677}
677 678
678static int s3c2412_i2s_resume(struct platform_device *pdev, 679static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
679 struct snd_soc_dai *dai)
680{ 680{
681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
682 682
683 dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n", 683 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); 684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
685 685
686 if (dai->active) { 686 if (dai->active) {
687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); 687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
@@ -711,7 +711,6 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
711struct snd_soc_dai s3c2412_i2s_dai = { 711struct snd_soc_dai s3c2412_i2s_dai = {
712 .name = "s3c2412-i2s", 712 .name = "s3c2412-i2s",
713 .id = 0, 713 .id = 0,
714 .type = SND_SOC_DAI_I2S,
715 .probe = s3c2412_i2s_probe, 714 .probe = s3c2412_i2s_probe,
716 .suspend = s3c2412_i2s_suspend, 715 .suspend = s3c2412_i2s_suspend,
717 .resume = s3c2412_i2s_resume, 716 .resume = s3c2412_i2s_resume,
@@ -730,8 +729,6 @@ struct snd_soc_dai s3c2412_i2s_dai = {
730 .ops = { 729 .ops = {
731 .trigger = s3c2412_i2s_trigger, 730 .trigger = s3c2412_i2s_trigger,
732 .hw_params = s3c2412_i2s_hw_params, 731 .hw_params = s3c2412_i2s_hw_params,
733 },
734 .dai_ops = {
735 .set_fmt = s3c2412_i2s_set_fmt, 732 .set_fmt = s3c2412_i2s_set_fmt,
736 .set_clkdiv = s3c2412_i2s_set_clkdiv, 733 .set_clkdiv = s3c2412_i2s_set_clkdiv,
737 .set_sysclk = s3c2412_i2s_set_sysclk, 734 .set_sysclk = s3c2412_i2s_set_sysclk,
@@ -739,6 +736,19 @@ struct snd_soc_dai s3c2412_i2s_dai = {
739}; 736};
740EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 737EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
741 738
739static int __init s3c2412_i2s_init(void)
740{
741 return snd_soc_register_dai(&s3c2412_i2s_dai);
742}
743module_init(s3c2412_i2s_init);
744
745static void __exit s3c2412_i2s_exit(void)
746{
747 snd_soc_unregister_dai(&s3c2412_i2s_dai);
748}
749module_exit(s3c2412_i2s_exit);
750
751
742/* Module information */ 752/* Module information */
743MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 753MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
744MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); 754MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 19c5c3cf5d8c..5822d2dd49ba 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -28,7 +28,7 @@
28#include <sound/soc.h> 28#include <sound/soc.h>
29 29
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <asm/plat-s3c/regs-ac97.h> 31#include <plat/regs-ac97.h>
32#include <mach/regs-gpio.h> 32#include <mach/regs-gpio.h>
33#include <mach/regs-clock.h> 33#include <mach/regs-clock.h>
34#include <mach/audio.h> 34#include <mach/audio.h>
@@ -271,7 +271,8 @@ static void s3c2443_ac97_remove(struct platform_device *pdev,
271} 271}
272 272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, 273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params) 274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
275{ 276{
276 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
277 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -284,7 +285,8 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
284 return 0; 285 return 0;
285} 286}
286 287
287static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) 288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
288{ 290{
289 u32 ac_glbctrl; 291 u32 ac_glbctrl;
290 292
@@ -313,7 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
313} 315}
314 316
315static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, 317static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params) 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai)
317{ 320{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 322 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -327,7 +330,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
327} 330}
328 331
329static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, 332static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
330 int cmd) 333 int cmd, struct snd_soc_dai *dai)
331{ 334{
332 u32 ac_glbctrl; 335 u32 ac_glbctrl;
333 336
@@ -356,7 +359,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
356{ 359{
357 .name = "s3c2443-ac97", 360 .name = "s3c2443-ac97",
358 .id = 0, 361 .id = 0,
359 .type = SND_SOC_DAI_AC97, 362 .ac97_control = 1,
360 .probe = s3c2443_ac97_probe, 363 .probe = s3c2443_ac97_probe,
361 .remove = s3c2443_ac97_remove, 364 .remove = s3c2443_ac97_remove,
362 .playback = { 365 .playback = {
@@ -378,7 +381,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
378{ 381{
379 .name = "pxa2xx-ac97-mic", 382 .name = "pxa2xx-ac97-mic",
380 .id = 1, 383 .id = 1,
381 .type = SND_SOC_DAI_AC97, 384 .ac97_control = 1,
382 .capture = { 385 .capture = {
383 .stream_name = "AC97 Mic Capture", 386 .stream_name = "AC97 Mic Capture",
384 .channels_min = 1, 387 .channels_min = 1,
@@ -393,6 +396,21 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
393EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); 396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
394EXPORT_SYMBOL_GPL(soc_ac97_ops); 397EXPORT_SYMBOL_GPL(soc_ac97_ops);
395 398
399static int __init s3c2443_ac97_init(void)
400{
401 return snd_soc_register_dais(s3c2443_ac97_dai,
402 ARRAY_SIZE(s3c2443_ac97_dai));
403}
404module_init(s3c2443_ac97_init);
405
406static void __exit s3c2443_ac97_exit(void)
407{
408 snd_soc_unregister_dais(s3c2443_ac97_dai,
409 ARRAY_SIZE(s3c2443_ac97_dai));
410}
411module_exit(s3c2443_ac97_exit);
412
413
396MODULE_AUTHOR("Graeme Gregory"); 414MODULE_AUTHOR("Graeme Gregory");
397MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); 415MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
398MODULE_LICENSE("GPL"); 416MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index ba4476b55fbc..6f4d439b57aa 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -243,7 +243,8 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
243} 243}
244 244
245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, 245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
246 struct snd_pcm_hw_params *params) 246 struct snd_pcm_hw_params *params,
247 struct snd_soc_dai *dai)
247{ 248{
248 struct snd_soc_pcm_runtime *rtd = substream->private_data; 249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
249 u32 iismod; 250 u32 iismod;
@@ -261,10 +262,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
261 262
262 switch (params_format(params)) { 263 switch (params_format(params)) {
263 case SNDRV_PCM_FORMAT_S8: 264 case SNDRV_PCM_FORMAT_S8:
265 iismod &= ~S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *)
267 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
264 break; 268 break;
265 case SNDRV_PCM_FORMAT_S16_LE: 269 case SNDRV_PCM_FORMAT_S16_LE:
266 iismod |= S3C2410_IISMOD_16BIT; 270 iismod |= S3C2410_IISMOD_16BIT;
271 ((struct s3c24xx_pcm_dma_params *)
272 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
267 break; 273 break;
274 default:
275 return -EINVAL;
268 } 276 }
269 277
270 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 278 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -272,7 +280,8 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
272 return 0; 280 return 0;
273} 281}
274 282
275static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 283static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
284 struct snd_soc_dai *dai)
276{ 285{
277 int ret = 0; 286 int ret = 0;
278 287
@@ -410,8 +419,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
410} 419}
411 420
412#ifdef CONFIG_PM 421#ifdef CONFIG_PM
413static int s3c24xx_i2s_suspend(struct platform_device *pdev, 422static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
414 struct snd_soc_dai *cpu_dai)
415{ 423{
416 DBG("Entered %s\n", __func__); 424 DBG("Entered %s\n", __func__);
417 425
@@ -425,8 +433,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
425 return 0; 433 return 0;
426} 434}
427 435
428static int s3c24xx_i2s_resume(struct platform_device *pdev, 436static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
429 struct snd_soc_dai *cpu_dai)
430{ 437{
431 DBG("Entered %s\n", __func__); 438 DBG("Entered %s\n", __func__);
432 clk_enable(s3c24xx_i2s.iis_clk); 439 clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +459,6 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
452struct snd_soc_dai s3c24xx_i2s_dai = { 459struct snd_soc_dai s3c24xx_i2s_dai = {
453 .name = "s3c24xx-i2s", 460 .name = "s3c24xx-i2s",
454 .id = 0, 461 .id = 0,
455 .type = SND_SOC_DAI_I2S,
456 .probe = s3c24xx_i2s_probe, 462 .probe = s3c24xx_i2s_probe,
457 .suspend = s3c24xx_i2s_suspend, 463 .suspend = s3c24xx_i2s_suspend,
458 .resume = s3c24xx_i2s_resume, 464 .resume = s3c24xx_i2s_resume,
@@ -468,8 +474,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
468 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 474 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
469 .ops = { 475 .ops = {
470 .trigger = s3c24xx_i2s_trigger, 476 .trigger = s3c24xx_i2s_trigger,
471 .hw_params = s3c24xx_i2s_hw_params,}, 477 .hw_params = s3c24xx_i2s_hw_params,
472 .dai_ops = {
473 .set_fmt = s3c24xx_i2s_set_fmt, 478 .set_fmt = s3c24xx_i2s_set_fmt,
474 .set_clkdiv = s3c24xx_i2s_set_clkdiv, 479 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
475 .set_sysclk = s3c24xx_i2s_set_sysclk, 480 .set_sysclk = s3c24xx_i2s_set_sysclk,
@@ -477,6 +482,18 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
477}; 482};
478EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 483EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
479 484
485static int __init s3c24xx_i2s_init(void)
486{
487 return snd_soc_register_dai(&s3c24xx_i2s_dai);
488}
489module_init(s3c24xx_i2s_init);
490
491static void __exit s3c24xx_i2s_exit(void)
492{
493 snd_soc_unregister_dai(&s3c24xx_i2s_dai);
494}
495module_exit(s3c24xx_i2s_exit);
496
480/* Module information */ 497/* Module information */
481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 498MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
482MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); 499MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index e13e614bada9..7c64d31d067e 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -465,6 +465,18 @@ struct snd_soc_platform s3c24xx_soc_platform = {
465}; 465};
466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
467 467
468static int __init s3c24xx_soc_platform_init(void)
469{
470 return snd_soc_register_platform(&s3c24xx_soc_platform);
471}
472module_init(s3c24xx_soc_platform_init);
473
474static void __exit s3c24xx_soc_platform_exit(void)
475{
476 snd_soc_unregister_platform(&s3c24xx_soc_platform);
477}
478module_exit(s3c24xx_soc_platform_exit);
479
468MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 480MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
469MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 481MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
470MODULE_LICENSE("GPL"); 482MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
new file mode 100644
index 000000000000..a0a4d1832a14
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -0,0 +1,373 @@
1/*
2 * Modifications by Christian Pellegrin <chripell@evolware.org>
3 *
4 * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h>
24
25#include <asm/plat-s3c24xx/regs-iis.h>
26
27#include "s3c24xx-pcm.h"
28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h"
30
31
32/* #define ENFORCE_RATES 1 */
33/*
34 Unfortunately the S3C24XX in master mode has a limited capacity of
35 generating the clock for the codec. If you define this only rates
36 that are really available will be enforced. But be careful, most
37 user level application just want the usual sampling frequencies (8,
38 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
39 operation for embedded systems. So if you aren't very lucky or your
40 hardware engineer wasn't very forward-looking it's better to leave
41 this undefined. If you do so an approximate value for the requested
42 sampling rate in the range -/+ 5% will be chosen. If this in not
43 possible an error will be returned.
44*/
45
46static struct clk *xtal;
47static struct clk *pclk;
48/* this is need because we don't have a place where to keep the
49 * pointers to the clocks in each substream. We get the clocks only
50 * when we are actually using them so we don't block stuff like
51 * frequency change or oscillator power-off */
52static int clk_users;
53static DEFINE_MUTEX(clk_lock);
54
55static unsigned int rates[33 * 2];
56#ifdef ENFORCE_RATES
57static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
58 .count = ARRAY_SIZE(rates),
59 .list = rates,
60 .mask = 0,
61};
62#endif
63
64static struct platform_device *s3c24xx_uda134x_snd_device;
65
66static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
67{
68 int ret = 0;
69#ifdef ENFORCE_RATES
70 struct snd_pcm_runtime *runtime = substream->runtime;;
71#endif
72
73 mutex_lock(&clk_lock);
74 pr_debug("%s %d\n", __func__, clk_users);
75 if (clk_users == 0) {
76 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
77 if (!xtal) {
78 printk(KERN_ERR "%s cannot get xtal\n", __func__);
79 ret = -EBUSY;
80 } else {
81 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
82 "pclk");
83 if (!pclk) {
84 printk(KERN_ERR "%s cannot get pclk\n",
85 __func__);
86 clk_put(xtal);
87 ret = -EBUSY;
88 }
89 }
90 if (!ret) {
91 int i, j;
92
93 for (i = 0; i < 2; i++) {
94 int fs = i ? 256 : 384;
95
96 rates[i*33] = clk_get_rate(xtal) / fs;
97 for (j = 1; j < 33; j++)
98 rates[i*33 + j] = clk_get_rate(pclk) /
99 (j * fs);
100 }
101 }
102 }
103 clk_users += 1;
104 mutex_unlock(&clk_lock);
105 if (!ret) {
106#ifdef ENFORCE_RATES
107 ret = snd_pcm_hw_constraint_list(runtime, 0,
108 SNDRV_PCM_HW_PARAM_RATE,
109 &hw_constraints_rates);
110 if (ret < 0)
111 printk(KERN_ERR "%s cannot set constraints\n",
112 __func__);
113#endif
114 }
115 return ret;
116}
117
118static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
119{
120 mutex_lock(&clk_lock);
121 pr_debug("%s %d\n", __func__, clk_users);
122 clk_users -= 1;
123 if (clk_users == 0) {
124 clk_put(xtal);
125 xtal = NULL;
126 clk_put(pclk);
127 pclk = NULL;
128 }
129 mutex_unlock(&clk_lock);
130}
131
132static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
138 unsigned int clk = 0;
139 int ret = 0;
140 int clk_source, fs_mode;
141 unsigned long rate = params_rate(params);
142 long err, cerr;
143 unsigned int div;
144 int i, bi;
145
146 err = 999999;
147 bi = 0;
148 for (i = 0; i < 2*33; i++) {
149 cerr = rates[i] - rate;
150 if (cerr < 0)
151 cerr = -cerr;
152 if (cerr < err) {
153 err = cerr;
154 bi = i;
155 }
156 }
157 if (bi / 33 == 1)
158 fs_mode = S3C2410_IISMOD_256FS;
159 else
160 fs_mode = S3C2410_IISMOD_384FS;
161 if (bi % 33 == 0) {
162 clk_source = S3C24XX_CLKSRC_MPLL;
163 div = 1;
164 } else {
165 clk_source = S3C24XX_CLKSRC_PCLK;
166 div = bi % 33;
167 }
168 pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
169
170 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
171 pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
172 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
173 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
174 div, clk, err);
175
176 if ((err * 100 / rate) > 5) {
177 printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
178 "too different from desired (%ld%%)\n",
179 err * 100 / rate);
180 return -EINVAL;
181 }
182
183 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
184 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
185 if (ret < 0)
186 return ret;
187
188 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
189 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
190 if (ret < 0)
191 return ret;
192
193 ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
194 SND_SOC_CLOCK_IN);
195 if (ret < 0)
196 return ret;
197
198 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
199 if (ret < 0)
200 return ret;
201
202 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
203 S3C2410_IISMOD_32FS);
204 if (ret < 0)
205 return ret;
206
207 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
208 S3C24XX_PRESCALE(div, div));
209 if (ret < 0)
210 return ret;
211
212 /* set the codec system clock for DAC and ADC */
213 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
214 SND_SOC_CLOCK_OUT);
215 if (ret < 0)
216 return ret;
217
218 return 0;
219}
220
221static struct snd_soc_ops s3c24xx_uda134x_ops = {
222 .startup = s3c24xx_uda134x_startup,
223 .shutdown = s3c24xx_uda134x_shutdown,
224 .hw_params = s3c24xx_uda134x_hw_params,
225};
226
227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
228 .name = "UDA134X",
229 .stream_name = "UDA134X",
230 .codec_dai = &uda134x_dai,
231 .cpu_dai = &s3c24xx_i2s_dai,
232 .ops = &s3c24xx_uda134x_ops,
233};
234
235static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
236 .name = "S3C24XX_UDA134X",
237 .platform = &s3c24xx_soc_platform,
238 .dai_link = &s3c24xx_uda134x_dai_link,
239 .num_links = 1,
240};
241
242static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
243
244static void setdat(int v)
245{
246 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
247}
248
249static void setclk(int v)
250{
251 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
252}
253
254static void setmode(int v)
255{
256 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
257}
258
259static struct uda134x_platform_data s3c24xx_uda134x = {
260 .l3 = {
261 .setdat = setdat,
262 .setclk = setclk,
263 .setmode = setmode,
264 .data_hold = 1,
265 .data_setup = 1,
266 .clock_high = 1,
267 .mode_hold = 1,
268 .mode = 1,
269 .mode_setup = 1,
270 },
271};
272
273static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
274 .card = &snd_soc_s3c24xx_uda134x,
275 .codec_dev = &soc_codec_dev_uda134x,
276 .codec_data = &s3c24xx_uda134x,
277};
278
279static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
280{
281 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
282 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
283 "l3 %s pin already in use", fun);
284 return -EBUSY;
285 }
286 gpio_direction_output(pin, 0);
287 return 0;
288}
289
290static int s3c24xx_uda134x_probe(struct platform_device *pdev)
291{
292 int ret;
293
294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
295
296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
297 if (s3c24xx_uda134x_l3_pins == NULL) {
298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
299 "unable to find platform data\n");
300 return -ENODEV;
301 }
302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
304
305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
306 "data") < 0)
307 return -EBUSY;
308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
309 "clk") < 0) {
310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
311 return -EBUSY;
312 }
313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
314 "mode") < 0) {
315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
317 return -EBUSY;
318 }
319
320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
321 if (!s3c24xx_uda134x_snd_device) {
322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
323 "Unable to register\n");
324 return -ENOMEM;
325 }
326
327 platform_set_drvdata(s3c24xx_uda134x_snd_device,
328 &s3c24xx_uda134x_snd_devdata);
329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
330 ret = platform_device_add(s3c24xx_uda134x_snd_device);
331 if (ret) {
332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
333 platform_device_put(s3c24xx_uda134x_snd_device);
334 }
335
336 return ret;
337}
338
339static int s3c24xx_uda134x_remove(struct platform_device *pdev)
340{
341 platform_device_unregister(s3c24xx_uda134x_snd_device);
342 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
343 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
344 gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
345 return 0;
346}
347
348static struct platform_driver s3c24xx_uda134x_driver = {
349 .probe = s3c24xx_uda134x_probe,
350 .remove = s3c24xx_uda134x_remove,
351 .driver = {
352 .name = "s3c24xx_uda134x",
353 .owner = THIS_MODULE,
354 },
355};
356
357static int __init s3c24xx_uda134x_init(void)
358{
359 return platform_driver_register(&s3c24xx_uda134x_driver);
360}
361
362static void __exit s3c24xx_uda134x_exit(void)
363{
364 platform_driver_unregister(&s3c24xx_uda134x_driver);
365}
366
367
368module_init(s3c24xx_uda134x_init);
369module_exit(s3c24xx_uda134x_exit);
370
371MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
372MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
373MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 8515d6ff03f2..a2a4f5323c17 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -23,7 +23,7 @@
23#include "s3c24xx-pcm.h" 23#include "s3c24xx-pcm.h"
24#include "s3c24xx-ac97.h" 24#include "s3c24xx-ac97.h"
25 25
26static struct snd_soc_machine smdk2443; 26static struct snd_soc_card smdk2443;
27 27
28static struct snd_soc_dai_link smdk2443_dai[] = { 28static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
@@ -34,15 +34,15 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
34}, 34},
35}; 35};
36 36
37static struct snd_soc_machine smdk2443 = { 37static struct snd_soc_card smdk2443 = {
38 .name = "SMDK2443", 38 .name = "SMDK2443",
39 .platform = &s3c24xx_soc_platform,
39 .dai_link = smdk2443_dai, 40 .dai_link = smdk2443_dai,
40 .num_links = ARRAY_SIZE(smdk2443_dai), 41 .num_links = ARRAY_SIZE(smdk2443_dai),
41}; 42};
42 43
43static struct snd_soc_device smdk2443_snd_ac97_devdata = { 44static struct snd_soc_device smdk2443_snd_ac97_devdata = {
44 .machine = &smdk2443, 45 .card = &smdk2443,
45 .platform = &s3c24xx_soc_platform,
46 .codec_dev = &soc_codec_dev_ac97, 46 .codec_dev = &soc_codec_dev_ac97,
47}; 47};
48 48
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 9faa12622d09..0dad3a0bb920 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -348,6 +348,18 @@ struct snd_soc_platform sh7760_soc_platform = {
348}; 348};
349EXPORT_SYMBOL_GPL(sh7760_soc_platform); 349EXPORT_SYMBOL_GPL(sh7760_soc_platform);
350 350
351static int __init sh7760_soc_platform_init(void)
352{
353 return snd_soc_register_platform(&sh7760_soc_platform);
354}
355module_init(sh7760_soc_platform_init);
356
357static void __exit sh7760_soc_platform_exit(void)
358{
359 snd_soc_unregister_platform(&sh7760_soc_platform);
360}
361module_exit(sh7760_soc_platform_exit);
362
351MODULE_LICENSE("GPL"); 363MODULE_LICENSE("GPL");
352MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); 364MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
353MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 365MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index df7bc345c320..eab31838badf 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -236,7 +236,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
236EXPORT_SYMBOL_GPL(soc_ac97_ops); 236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 237
238static int hac_hw_params(struct snd_pcm_substream *substream, 238static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params) 239 struct snd_pcm_hw_params *params,
240 struct snd_soc_dai *dai)
240{ 241{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; 243 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
@@ -270,7 +271,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
270{ 271{
271 .name = "HAC0", 272 .name = "HAC0",
272 .id = 0, 273 .id = 0,
273 .type = SND_SOC_DAI_AC97, 274 .ac97_control = 1,
274 .playback = { 275 .playback = {
275 .rates = AC97_RATES, 276 .rates = AC97_RATES,
276 .formats = AC97_FMTS, 277 .formats = AC97_FMTS,
@@ -290,8 +291,8 @@ struct snd_soc_dai sh4_hac_dai[] = {
290#ifdef CONFIG_CPU_SUBTYPE_SH7760 291#ifdef CONFIG_CPU_SUBTYPE_SH7760
291{ 292{
292 .name = "HAC1", 293 .name = "HAC1",
294 .ac97_control = 1,
293 .id = 1, 295 .id = 1,
294 .type = SND_SOC_DAI_AC97,
295 .playback = { 296 .playback = {
296 .rates = AC97_RATES, 297 .rates = AC97_RATES,
297 .formats = AC97_FMTS, 298 .formats = AC97_FMTS,
@@ -313,6 +314,18 @@ struct snd_soc_dai sh4_hac_dai[] = {
313}; 314};
314EXPORT_SYMBOL_GPL(sh4_hac_dai); 315EXPORT_SYMBOL_GPL(sh4_hac_dai);
315 316
317static int __init sh4_hac_init(void)
318{
319 return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
320}
321module_init(sh4_hac_init);
322
323static void __exit sh4_hac_exit(void)
324{
325 snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
326}
327module_exit(sh4_hac_exit);
328
316MODULE_LICENSE("GPL"); 329MODULE_LICENSE("GPL");
317MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); 330MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
318MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 331MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 92bfaf4774a7..ce7f95b59de3 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
38 .ops = NULL, 38 .ops = NULL,
39}; 39};
40 40
41static struct snd_soc_machine sh7760_ac97_soc_machine = { 41static struct snd_soc_card sh7760_ac97_soc_machine = {
42 .name = "SH7760 AC97", 42 .name = "SH7760 AC97",
43 .platform = &sh7760_soc_platform,
43 .dai_link = &sh7760_ac97_dai, 44 .dai_link = &sh7760_ac97_dai,
44 .num_links = 1, 45 .num_links = 1,
45}; 46};
46 47
47static struct snd_soc_device sh7760_ac97_snd_devdata = { 48static struct snd_soc_device sh7760_ac97_snd_devdata = {
48 .machine = &sh7760_ac97_soc_machine, 49 .card = &sh7760_ac97_soc_machine,
49 .platform = &sh7760_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 55c3464163ab..d1e5390fddeb 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -89,7 +89,8 @@ struct ssi_priv {
89 * track usage of the SSI; it is simplex-only so prevent attempts of 89 * track usage of the SSI; it is simplex-only so prevent attempts of
90 * concurrent playback + capture. FIXME: any locking required? 90 * concurrent playback + capture. FIXME: any locking required?
91 */ 91 */
92static int ssi_startup(struct snd_pcm_substream *substream) 92static int ssi_startup(struct snd_pcm_substream *substream,
93 struct snd_soc_dai *dai)
93{ 94{
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 96 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -101,7 +102,8 @@ static int ssi_startup(struct snd_pcm_substream *substream)
101 return 0; 102 return 0;
102} 103}
103 104
104static void ssi_shutdown(struct snd_pcm_substream *substream) 105static void ssi_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai)
105{ 107{
106 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
107 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 109 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -109,7 +111,8 @@ static void ssi_shutdown(struct snd_pcm_substream *substream)
109 ssi->inuse = 0; 111 ssi->inuse = 0;
110} 112}
111 113
112static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) 114static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
115 struct snd_soc_dai *dai)
113{ 116{
114 struct snd_soc_pcm_runtime *rtd = substream->private_data; 117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
115 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 118 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -129,7 +132,8 @@ static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
129} 132}
130 133
131static int ssi_hw_params(struct snd_pcm_substream *substream, 134static int ssi_hw_params(struct snd_pcm_substream *substream,
132 struct snd_pcm_hw_params *params) 135 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai)
133{ 137{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 139 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -336,7 +340,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
336{ 340{
337 .name = "SSI0", 341 .name = "SSI0",
338 .id = 0, 342 .id = 0,
339 .type = SND_SOC_DAI_I2S,
340 .playback = { 343 .playback = {
341 .rates = SSI_RATES, 344 .rates = SSI_RATES,
342 .formats = SSI_FMTS, 345 .formats = SSI_FMTS,
@@ -354,8 +357,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
354 .shutdown = ssi_shutdown, 357 .shutdown = ssi_shutdown,
355 .trigger = ssi_trigger, 358 .trigger = ssi_trigger,
356 .hw_params = ssi_hw_params, 359 .hw_params = ssi_hw_params,
357 },
358 .dai_ops = {
359 .set_sysclk = ssi_set_sysclk, 360 .set_sysclk = ssi_set_sysclk,
360 .set_clkdiv = ssi_set_clkdiv, 361 .set_clkdiv = ssi_set_clkdiv,
361 .set_fmt = ssi_set_fmt, 362 .set_fmt = ssi_set_fmt,
@@ -365,7 +366,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
365{ 366{
366 .name = "SSI1", 367 .name = "SSI1",
367 .id = 1, 368 .id = 1,
368 .type = SND_SOC_DAI_I2S,
369 .playback = { 369 .playback = {
370 .rates = SSI_RATES, 370 .rates = SSI_RATES,
371 .formats = SSI_FMTS, 371 .formats = SSI_FMTS,
@@ -383,8 +383,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
383 .shutdown = ssi_shutdown, 383 .shutdown = ssi_shutdown,
384 .trigger = ssi_trigger, 384 .trigger = ssi_trigger,
385 .hw_params = ssi_hw_params, 385 .hw_params = ssi_hw_params,
386 },
387 .dai_ops = {
388 .set_sysclk = ssi_set_sysclk, 386 .set_sysclk = ssi_set_sysclk,
389 .set_clkdiv = ssi_set_clkdiv, 387 .set_clkdiv = ssi_set_clkdiv,
390 .set_fmt = ssi_set_fmt, 388 .set_fmt = ssi_set_fmt,
@@ -394,6 +392,18 @@ struct snd_soc_dai sh4_ssi_dai[] = {
394}; 392};
395EXPORT_SYMBOL_GPL(sh4_ssi_dai); 393EXPORT_SYMBOL_GPL(sh4_ssi_dai);
396 394
395static int __init sh4_ssi_init(void)
396{
397 return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
398}
399module_init(sh4_ssi_init);
400
401static void __exit sh4_ssi_exit(void)
402{
403 snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
404}
405module_exit(sh4_ssi_exit);
406
397MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL");
398MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); 408MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
399MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 409MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index ad381138fc2e..55fdb4abb179 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4,8 +4,7 @@
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2005 Openedhand Ltd.
6 * 6 *
7 * Author: Liam Girdwood 7 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
8 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
9 * with code, comments and ideas from :- 8 * with code, comments and ideas from :-
10 * Richard Purdie <richard@openedhand.com> 9 * Richard Purdie <richard@openedhand.com>
11 * 10 *
@@ -27,6 +26,7 @@
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/pm.h> 27#include <linux/pm.h>
29#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -35,18 +35,23 @@
35#include <sound/soc-dapm.h> 35#include <sound/soc-dapm.h>
36#include <sound/initval.h> 36#include <sound/initval.h>
37 37
38/* debug */
39#define SOC_DEBUG 0
40#if SOC_DEBUG
41#define dbg(format, arg...) printk(format, ## arg)
42#else
43#define dbg(format, arg...)
44#endif
45
46static DEFINE_MUTEX(pcm_mutex); 38static DEFINE_MUTEX(pcm_mutex);
47static DEFINE_MUTEX(io_mutex); 39static DEFINE_MUTEX(io_mutex);
48static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 40static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
49 41
42#ifdef CONFIG_DEBUG_FS
43static struct dentry *debugfs_root;
44#endif
45
46static DEFINE_MUTEX(client_mutex);
47static LIST_HEAD(card_list);
48static LIST_HEAD(dai_list);
49static LIST_HEAD(platform_list);
50static LIST_HEAD(codec_list);
51
52static int snd_soc_register_card(struct snd_soc_card *card);
53static int snd_soc_unregister_card(struct snd_soc_card *card);
54
50/* 55/*
51 * This is a timeout to do a DAPM powerdown after a stream is closed(). 56 * This is a timeout to do a DAPM powerdown after a stream is closed().
52 * It can be used to eliminate pops between different playback streams, e.g. 57 * It can be used to eliminate pops between different playback streams, e.g.
@@ -96,8 +101,8 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
96 codec->ac97->dev.parent = NULL; 101 codec->ac97->dev.parent = NULL;
97 codec->ac97->dev.release = soc_ac97_device_release; 102 codec->ac97->dev.release = soc_ac97_device_release;
98 103
99 snprintf(codec->ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s", 104 dev_set_name(&codec->ac97->dev, "%d-%d:%s",
100 codec->card->number, 0, codec->name); 105 codec->card->number, 0, codec->name);
101 err = device_register(&codec->ac97->dev); 106 err = device_register(&codec->ac97->dev);
102 if (err < 0) { 107 if (err < 0) {
103 snd_printk(KERN_ERR "Can't register ac97 bus\n"); 108 snd_printk(KERN_ERR "Can't register ac97 bus\n");
@@ -108,20 +113,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
108} 113}
109#endif 114#endif
110 115
111static inline const char *get_dai_name(int type)
112{
113 switch (type) {
114 case SND_SOC_DAI_AC97_BUS:
115 case SND_SOC_DAI_AC97:
116 return "AC97";
117 case SND_SOC_DAI_I2S:
118 return "I2S";
119 case SND_SOC_DAI_PCM:
120 return "PCM";
121 }
122 return NULL;
123}
124
125/* 116/*
126 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 117 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
127 * then initialized and any private data can be allocated. This also calls 118 * then initialized and any private data can be allocated. This also calls
@@ -131,9 +122,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
131{ 122{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_device *socdev = rtd->socdev; 124 struct snd_soc_device *socdev = rtd->socdev;
125 struct snd_soc_card *card = socdev->card;
134 struct snd_pcm_runtime *runtime = substream->runtime; 126 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct snd_soc_dai_link *machine = rtd->dai; 127 struct snd_soc_dai_link *machine = rtd->dai;
136 struct snd_soc_platform *platform = socdev->platform; 128 struct snd_soc_platform *platform = card->platform;
137 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 129 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
138 struct snd_soc_dai *codec_dai = machine->codec_dai; 130 struct snd_soc_dai *codec_dai = machine->codec_dai;
139 int ret = 0; 131 int ret = 0;
@@ -142,7 +134,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
142 134
143 /* startup the audio subsystem */ 135 /* startup the audio subsystem */
144 if (cpu_dai->ops.startup) { 136 if (cpu_dai->ops.startup) {
145 ret = cpu_dai->ops.startup(substream); 137 ret = cpu_dai->ops.startup(substream, cpu_dai);
146 if (ret < 0) { 138 if (ret < 0) {
147 printk(KERN_ERR "asoc: can't open interface %s\n", 139 printk(KERN_ERR "asoc: can't open interface %s\n",
148 cpu_dai->name); 140 cpu_dai->name);
@@ -159,7 +151,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
159 } 151 }
160 152
161 if (codec_dai->ops.startup) { 153 if (codec_dai->ops.startup) {
162 ret = codec_dai->ops.startup(substream); 154 ret = codec_dai->ops.startup(substream, codec_dai);
163 if (ret < 0) { 155 if (ret < 0) {
164 printk(KERN_ERR "asoc: can't open codec %s\n", 156 printk(KERN_ERR "asoc: can't open codec %s\n",
165 codec_dai->name); 157 codec_dai->name);
@@ -229,12 +221,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
229 goto machine_err; 221 goto machine_err;
230 } 222 }
231 223
232 dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 224 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
233 dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); 225 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
234 dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 226 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
235 runtime->hw.channels_max); 227 runtime->hw.channels_max);
236 dbg("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 228 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
237 runtime->hw.rate_max); 229 runtime->hw.rate_max);
238 230
239 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 231 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
240 cpu_dai->playback.active = codec_dai->playback.active = 1; 232 cpu_dai->playback.active = codec_dai->playback.active = 1;
@@ -256,7 +248,7 @@ codec_dai_err:
256 248
257platform_err: 249platform_err:
258 if (cpu_dai->ops.shutdown) 250 if (cpu_dai->ops.shutdown)
259 cpu_dai->ops.shutdown(substream); 251 cpu_dai->ops.shutdown(substream, cpu_dai);
260out: 252out:
261 mutex_unlock(&pcm_mutex); 253 mutex_unlock(&pcm_mutex);
262 return ret; 254 return ret;
@@ -269,8 +261,9 @@ out:
269 */ 261 */
270static void close_delayed_work(struct work_struct *work) 262static void close_delayed_work(struct work_struct *work)
271{ 263{
272 struct snd_soc_device *socdev = 264 struct snd_soc_card *card = container_of(work, struct snd_soc_card,
273 container_of(work, struct snd_soc_device, delayed_work.work); 265 delayed_work.work);
266 struct snd_soc_device *socdev = card->socdev;
274 struct snd_soc_codec *codec = socdev->codec; 267 struct snd_soc_codec *codec = socdev->codec;
275 struct snd_soc_dai *codec_dai; 268 struct snd_soc_dai *codec_dai;
276 int i; 269 int i;
@@ -279,18 +272,18 @@ static void close_delayed_work(struct work_struct *work)
279 for (i = 0; i < codec->num_dai; i++) { 272 for (i = 0; i < codec->num_dai; i++) {
280 codec_dai = &codec->dai[i]; 273 codec_dai = &codec->dai[i];
281 274
282 dbg("pop wq checking: %s status: %s waiting: %s\n", 275 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
283 codec_dai->playback.stream_name, 276 codec_dai->playback.stream_name,
284 codec_dai->playback.active ? "active" : "inactive", 277 codec_dai->playback.active ? "active" : "inactive",
285 codec_dai->pop_wait ? "yes" : "no"); 278 codec_dai->pop_wait ? "yes" : "no");
286 279
287 /* are we waiting on this codec DAI stream */ 280 /* are we waiting on this codec DAI stream */
288 if (codec_dai->pop_wait == 1) { 281 if (codec_dai->pop_wait == 1) {
289 282
290 /* Reduce power if no longer active */ 283 /* Reduce power if no longer active */
291 if (codec->active == 0) { 284 if (codec->active == 0) {
292 dbg("pop wq D1 %s %s\n", codec->name, 285 pr_debug("pop wq D1 %s %s\n", codec->name,
293 codec_dai->playback.stream_name); 286 codec_dai->playback.stream_name);
294 snd_soc_dapm_set_bias_level(socdev, 287 snd_soc_dapm_set_bias_level(socdev,
295 SND_SOC_BIAS_PREPARE); 288 SND_SOC_BIAS_PREPARE);
296 } 289 }
@@ -302,8 +295,8 @@ static void close_delayed_work(struct work_struct *work)
302 295
303 /* Fall into standby if no longer active */ 296 /* Fall into standby if no longer active */
304 if (codec->active == 0) { 297 if (codec->active == 0) {
305 dbg("pop wq D3 %s %s\n", codec->name, 298 pr_debug("pop wq D3 %s %s\n", codec->name,
306 codec_dai->playback.stream_name); 299 codec_dai->playback.stream_name);
307 snd_soc_dapm_set_bias_level(socdev, 300 snd_soc_dapm_set_bias_level(socdev,
308 SND_SOC_BIAS_STANDBY); 301 SND_SOC_BIAS_STANDBY);
309 } 302 }
@@ -321,8 +314,9 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
321{ 314{
322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
323 struct snd_soc_device *socdev = rtd->socdev; 316 struct snd_soc_device *socdev = rtd->socdev;
317 struct snd_soc_card *card = socdev->card;
324 struct snd_soc_dai_link *machine = rtd->dai; 318 struct snd_soc_dai_link *machine = rtd->dai;
325 struct snd_soc_platform *platform = socdev->platform; 319 struct snd_soc_platform *platform = card->platform;
326 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 320 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
327 struct snd_soc_dai *codec_dai = machine->codec_dai; 321 struct snd_soc_dai *codec_dai = machine->codec_dai;
328 struct snd_soc_codec *codec = socdev->codec; 322 struct snd_soc_codec *codec = socdev->codec;
@@ -347,10 +341,10 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
347 snd_soc_dai_digital_mute(codec_dai, 1); 341 snd_soc_dai_digital_mute(codec_dai, 1);
348 342
349 if (cpu_dai->ops.shutdown) 343 if (cpu_dai->ops.shutdown)
350 cpu_dai->ops.shutdown(substream); 344 cpu_dai->ops.shutdown(substream, cpu_dai);
351 345
352 if (codec_dai->ops.shutdown) 346 if (codec_dai->ops.shutdown)
353 codec_dai->ops.shutdown(substream); 347 codec_dai->ops.shutdown(substream, codec_dai);
354 348
355 if (machine->ops && machine->ops->shutdown) 349 if (machine->ops && machine->ops->shutdown)
356 machine->ops->shutdown(substream); 350 machine->ops->shutdown(substream);
@@ -362,7 +356,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
362 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 356 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
363 /* start delayed pop wq here for playback streams */ 357 /* start delayed pop wq here for playback streams */
364 codec_dai->pop_wait = 1; 358 codec_dai->pop_wait = 1;
365 schedule_delayed_work(&socdev->delayed_work, 359 schedule_delayed_work(&card->delayed_work,
366 msecs_to_jiffies(pmdown_time)); 360 msecs_to_jiffies(pmdown_time));
367 } else { 361 } else {
368 /* capture streams can be powered down now */ 362 /* capture streams can be powered down now */
@@ -388,8 +382,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
388{ 382{
389 struct snd_soc_pcm_runtime *rtd = substream->private_data; 383 struct snd_soc_pcm_runtime *rtd = substream->private_data;
390 struct snd_soc_device *socdev = rtd->socdev; 384 struct snd_soc_device *socdev = rtd->socdev;
385 struct snd_soc_card *card = socdev->card;
391 struct snd_soc_dai_link *machine = rtd->dai; 386 struct snd_soc_dai_link *machine = rtd->dai;
392 struct snd_soc_platform *platform = socdev->platform; 387 struct snd_soc_platform *platform = card->platform;
393 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 388 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
394 struct snd_soc_dai *codec_dai = machine->codec_dai; 389 struct snd_soc_dai *codec_dai = machine->codec_dai;
395 struct snd_soc_codec *codec = socdev->codec; 390 struct snd_soc_codec *codec = socdev->codec;
@@ -414,7 +409,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
414 } 409 }
415 410
416 if (codec_dai->ops.prepare) { 411 if (codec_dai->ops.prepare) {
417 ret = codec_dai->ops.prepare(substream); 412 ret = codec_dai->ops.prepare(substream, codec_dai);
418 if (ret < 0) { 413 if (ret < 0) {
419 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 414 printk(KERN_ERR "asoc: codec DAI prepare error\n");
420 goto out; 415 goto out;
@@ -422,58 +417,49 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
422 } 417 }
423 418
424 if (cpu_dai->ops.prepare) { 419 if (cpu_dai->ops.prepare) {
425 ret = cpu_dai->ops.prepare(substream); 420 ret = cpu_dai->ops.prepare(substream, cpu_dai);
426 if (ret < 0) { 421 if (ret < 0) {
427 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 422 printk(KERN_ERR "asoc: cpu DAI prepare error\n");
428 goto out; 423 goto out;
429 } 424 }
430 } 425 }
431 426
432 /* we only want to start a DAPM playback stream if we are not waiting 427 /* cancel any delayed stream shutdown that is pending */
433 * on an existing one stopping */ 428 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
434 if (codec_dai->pop_wait) { 429 codec_dai->pop_wait) {
435 /* we are waiting for the delayed work to start */ 430 codec_dai->pop_wait = 0;
436 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 431 cancel_delayed_work(&card->delayed_work);
437 snd_soc_dapm_stream_event(socdev->codec, 432 }
438 codec_dai->capture.stream_name,
439 SND_SOC_DAPM_STREAM_START);
440 else {
441 codec_dai->pop_wait = 0;
442 cancel_delayed_work(&socdev->delayed_work);
443 snd_soc_dai_digital_mute(codec_dai, 0);
444 }
445 } else {
446 /* no delayed work - do we need to power up codec */
447 if (codec->bias_level != SND_SOC_BIAS_ON) {
448 433
449 snd_soc_dapm_set_bias_level(socdev, 434 /* do we need to power up codec */
450 SND_SOC_BIAS_PREPARE); 435 if (codec->bias_level != SND_SOC_BIAS_ON) {
436 snd_soc_dapm_set_bias_level(socdev,
437 SND_SOC_BIAS_PREPARE);
451 438
452 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 439 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
453 snd_soc_dapm_stream_event(codec, 440 snd_soc_dapm_stream_event(codec,
454 codec_dai->playback.stream_name, 441 codec_dai->playback.stream_name,
455 SND_SOC_DAPM_STREAM_START); 442 SND_SOC_DAPM_STREAM_START);
456 else 443 else
457 snd_soc_dapm_stream_event(codec, 444 snd_soc_dapm_stream_event(codec,
458 codec_dai->capture.stream_name, 445 codec_dai->capture.stream_name,
459 SND_SOC_DAPM_STREAM_START); 446 SND_SOC_DAPM_STREAM_START);
460 447
461 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); 448 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
462 snd_soc_dai_digital_mute(codec_dai, 0); 449 snd_soc_dai_digital_mute(codec_dai, 0);
463 450
464 } else { 451 } else {
465 /* codec already powered - power on widgets */ 452 /* codec already powered - power on widgets */
466 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 453 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
467 snd_soc_dapm_stream_event(codec, 454 snd_soc_dapm_stream_event(codec,
468 codec_dai->playback.stream_name, 455 codec_dai->playback.stream_name,
469 SND_SOC_DAPM_STREAM_START); 456 SND_SOC_DAPM_STREAM_START);
470 else 457 else
471 snd_soc_dapm_stream_event(codec, 458 snd_soc_dapm_stream_event(codec,
472 codec_dai->capture.stream_name, 459 codec_dai->capture.stream_name,
473 SND_SOC_DAPM_STREAM_START); 460 SND_SOC_DAPM_STREAM_START);
474 461
475 snd_soc_dai_digital_mute(codec_dai, 0); 462 snd_soc_dai_digital_mute(codec_dai, 0);
476 }
477 } 463 }
478 464
479out: 465out:
@@ -492,7 +478,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
492 struct snd_soc_pcm_runtime *rtd = substream->private_data; 478 struct snd_soc_pcm_runtime *rtd = substream->private_data;
493 struct snd_soc_device *socdev = rtd->socdev; 479 struct snd_soc_device *socdev = rtd->socdev;
494 struct snd_soc_dai_link *machine = rtd->dai; 480 struct snd_soc_dai_link *machine = rtd->dai;
495 struct snd_soc_platform *platform = socdev->platform; 481 struct snd_soc_card *card = socdev->card;
482 struct snd_soc_platform *platform = card->platform;
496 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 483 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
497 struct snd_soc_dai *codec_dai = machine->codec_dai; 484 struct snd_soc_dai *codec_dai = machine->codec_dai;
498 int ret = 0; 485 int ret = 0;
@@ -508,7 +495,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
508 } 495 }
509 496
510 if (codec_dai->ops.hw_params) { 497 if (codec_dai->ops.hw_params) {
511 ret = codec_dai->ops.hw_params(substream, params); 498 ret = codec_dai->ops.hw_params(substream, params, codec_dai);
512 if (ret < 0) { 499 if (ret < 0) {
513 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 500 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
514 codec_dai->name); 501 codec_dai->name);
@@ -517,7 +504,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
517 } 504 }
518 505
519 if (cpu_dai->ops.hw_params) { 506 if (cpu_dai->ops.hw_params) {
520 ret = cpu_dai->ops.hw_params(substream, params); 507 ret = cpu_dai->ops.hw_params(substream, params, cpu_dai);
521 if (ret < 0) { 508 if (ret < 0) {
522 printk(KERN_ERR "asoc: interface %s hw params failed\n", 509 printk(KERN_ERR "asoc: interface %s hw params failed\n",
523 cpu_dai->name); 510 cpu_dai->name);
@@ -540,11 +527,11 @@ out:
540 527
541platform_err: 528platform_err:
542 if (cpu_dai->ops.hw_free) 529 if (cpu_dai->ops.hw_free)
543 cpu_dai->ops.hw_free(substream); 530 cpu_dai->ops.hw_free(substream, cpu_dai);
544 531
545interface_err: 532interface_err:
546 if (codec_dai->ops.hw_free) 533 if (codec_dai->ops.hw_free)
547 codec_dai->ops.hw_free(substream); 534 codec_dai->ops.hw_free(substream, codec_dai);
548 535
549codec_err: 536codec_err:
550 if (machine->ops && machine->ops->hw_free) 537 if (machine->ops && machine->ops->hw_free)
@@ -562,7 +549,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
562 struct snd_soc_pcm_runtime *rtd = substream->private_data; 549 struct snd_soc_pcm_runtime *rtd = substream->private_data;
563 struct snd_soc_device *socdev = rtd->socdev; 550 struct snd_soc_device *socdev = rtd->socdev;
564 struct snd_soc_dai_link *machine = rtd->dai; 551 struct snd_soc_dai_link *machine = rtd->dai;
565 struct snd_soc_platform *platform = socdev->platform; 552 struct snd_soc_card *card = socdev->card;
553 struct snd_soc_platform *platform = card->platform;
566 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 554 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
567 struct snd_soc_dai *codec_dai = machine->codec_dai; 555 struct snd_soc_dai *codec_dai = machine->codec_dai;
568 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
@@ -583,10 +571,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
583 571
584 /* now free hw params for the DAI's */ 572 /* now free hw params for the DAI's */
585 if (codec_dai->ops.hw_free) 573 if (codec_dai->ops.hw_free)
586 codec_dai->ops.hw_free(substream); 574 codec_dai->ops.hw_free(substream, codec_dai);
587 575
588 if (cpu_dai->ops.hw_free) 576 if (cpu_dai->ops.hw_free)
589 cpu_dai->ops.hw_free(substream); 577 cpu_dai->ops.hw_free(substream, cpu_dai);
590 578
591 mutex_unlock(&pcm_mutex); 579 mutex_unlock(&pcm_mutex);
592 return 0; 580 return 0;
@@ -596,14 +584,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
596{ 584{
597 struct snd_soc_pcm_runtime *rtd = substream->private_data; 585 struct snd_soc_pcm_runtime *rtd = substream->private_data;
598 struct snd_soc_device *socdev = rtd->socdev; 586 struct snd_soc_device *socdev = rtd->socdev;
587 struct snd_soc_card *card= socdev->card;
599 struct snd_soc_dai_link *machine = rtd->dai; 588 struct snd_soc_dai_link *machine = rtd->dai;
600 struct snd_soc_platform *platform = socdev->platform; 589 struct snd_soc_platform *platform = card->platform;
601 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 590 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
602 struct snd_soc_dai *codec_dai = machine->codec_dai; 591 struct snd_soc_dai *codec_dai = machine->codec_dai;
603 int ret; 592 int ret;
604 593
605 if (codec_dai->ops.trigger) { 594 if (codec_dai->ops.trigger) {
606 ret = codec_dai->ops.trigger(substream, cmd); 595 ret = codec_dai->ops.trigger(substream, cmd, codec_dai);
607 if (ret < 0) 596 if (ret < 0)
608 return ret; 597 return ret;
609 } 598 }
@@ -615,7 +604,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
615 } 604 }
616 605
617 if (cpu_dai->ops.trigger) { 606 if (cpu_dai->ops.trigger) {
618 ret = cpu_dai->ops.trigger(substream, cmd); 607 ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai);
619 if (ret < 0) 608 if (ret < 0)
620 return ret; 609 return ret;
621 } 610 }
@@ -637,8 +626,8 @@ static struct snd_pcm_ops soc_pcm_ops = {
637static int soc_suspend(struct platform_device *pdev, pm_message_t state) 626static int soc_suspend(struct platform_device *pdev, pm_message_t state)
638{ 627{
639 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
640 struct snd_soc_machine *machine = socdev->machine; 629 struct snd_soc_card *card = socdev->card;
641 struct snd_soc_platform *platform = socdev->platform; 630 struct snd_soc_platform *platform = card->platform;
642 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 631 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
643 struct snd_soc_codec *codec = socdev->codec; 632 struct snd_soc_codec *codec = socdev->codec;
644 int i; 633 int i;
@@ -654,29 +643,29 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
654 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot); 643 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot);
655 644
656 /* mute any active DAC's */ 645 /* mute any active DAC's */
657 for (i = 0; i < machine->num_links; i++) { 646 for (i = 0; i < card->num_links; i++) {
658 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 647 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
659 if (dai->dai_ops.digital_mute && dai->playback.active) 648 if (dai->ops.digital_mute && dai->playback.active)
660 dai->dai_ops.digital_mute(dai, 1); 649 dai->ops.digital_mute(dai, 1);
661 } 650 }
662 651
663 /* suspend all pcms */ 652 /* suspend all pcms */
664 for (i = 0; i < machine->num_links; i++) 653 for (i = 0; i < card->num_links; i++)
665 snd_pcm_suspend_all(machine->dai_link[i].pcm); 654 snd_pcm_suspend_all(card->dai_link[i].pcm);
666 655
667 if (machine->suspend_pre) 656 if (card->suspend_pre)
668 machine->suspend_pre(pdev, state); 657 card->suspend_pre(pdev, state);
669 658
670 for (i = 0; i < machine->num_links; i++) { 659 for (i = 0; i < card->num_links; i++) {
671 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 660 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
672 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) 661 if (cpu_dai->suspend && !cpu_dai->ac97_control)
673 cpu_dai->suspend(pdev, cpu_dai); 662 cpu_dai->suspend(cpu_dai);
674 if (platform->suspend) 663 if (platform->suspend)
675 platform->suspend(pdev, cpu_dai); 664 platform->suspend(cpu_dai);
676 } 665 }
677 666
678 /* close any waiting streams and save state */ 667 /* close any waiting streams and save state */
679 run_delayed_work(&socdev->delayed_work); 668 run_delayed_work(&card->delayed_work);
680 codec->suspend_bias_level = codec->bias_level; 669 codec->suspend_bias_level = codec->bias_level;
681 670
682 for (i = 0; i < codec->num_dai; i++) { 671 for (i = 0; i < codec->num_dai; i++) {
@@ -693,14 +682,14 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
693 if (codec_dev->suspend) 682 if (codec_dev->suspend)
694 codec_dev->suspend(pdev, state); 683 codec_dev->suspend(pdev, state);
695 684
696 for (i = 0; i < machine->num_links; i++) { 685 for (i = 0; i < card->num_links; i++) {
697 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 686 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
698 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) 687 if (cpu_dai->suspend && cpu_dai->ac97_control)
699 cpu_dai->suspend(pdev, cpu_dai); 688 cpu_dai->suspend(cpu_dai);
700 } 689 }
701 690
702 if (machine->suspend_post) 691 if (card->suspend_post)
703 machine->suspend_post(pdev, state); 692 card->suspend_post(pdev, state);
704 693
705 return 0; 694 return 0;
706} 695}
@@ -710,11 +699,11 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
710 */ 699 */
711static void soc_resume_deferred(struct work_struct *work) 700static void soc_resume_deferred(struct work_struct *work)
712{ 701{
713 struct snd_soc_device *socdev = container_of(work, 702 struct snd_soc_card *card = container_of(work,
714 struct snd_soc_device, 703 struct snd_soc_card,
715 deferred_resume_work); 704 deferred_resume_work);
716 struct snd_soc_machine *machine = socdev->machine; 705 struct snd_soc_device *socdev = card->socdev;
717 struct snd_soc_platform *platform = socdev->platform; 706 struct snd_soc_platform *platform = card->platform;
718 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 707 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
719 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = socdev->codec;
720 struct platform_device *pdev = to_platform_device(socdev->dev); 709 struct platform_device *pdev = to_platform_device(socdev->dev);
@@ -724,15 +713,15 @@ static void soc_resume_deferred(struct work_struct *work)
724 * so userspace apps are blocked from touching us 713 * so userspace apps are blocked from touching us
725 */ 714 */
726 715
727 dev_info(socdev->dev, "starting resume work\n"); 716 dev_dbg(socdev->dev, "starting resume work\n");
728 717
729 if (machine->resume_pre) 718 if (card->resume_pre)
730 machine->resume_pre(pdev); 719 card->resume_pre(pdev);
731 720
732 for (i = 0; i < machine->num_links; i++) { 721 for (i = 0; i < card->num_links; i++) {
733 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 722 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
734 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) 723 if (cpu_dai->resume && cpu_dai->ac97_control)
735 cpu_dai->resume(pdev, cpu_dai); 724 cpu_dai->resume(cpu_dai);
736 } 725 }
737 726
738 if (codec_dev->resume) 727 if (codec_dev->resume)
@@ -750,24 +739,24 @@ static void soc_resume_deferred(struct work_struct *work)
750 } 739 }
751 740
752 /* unmute any active DACs */ 741 /* unmute any active DACs */
753 for (i = 0; i < machine->num_links; i++) { 742 for (i = 0; i < card->num_links; i++) {
754 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 743 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
755 if (dai->dai_ops.digital_mute && dai->playback.active) 744 if (dai->ops.digital_mute && dai->playback.active)
756 dai->dai_ops.digital_mute(dai, 0); 745 dai->ops.digital_mute(dai, 0);
757 } 746 }
758 747
759 for (i = 0; i < machine->num_links; i++) { 748 for (i = 0; i < card->num_links; i++) {
760 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 749 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
761 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) 750 if (cpu_dai->resume && !cpu_dai->ac97_control)
762 cpu_dai->resume(pdev, cpu_dai); 751 cpu_dai->resume(cpu_dai);
763 if (platform->resume) 752 if (platform->resume)
764 platform->resume(pdev, cpu_dai); 753 platform->resume(cpu_dai);
765 } 754 }
766 755
767 if (machine->resume_post) 756 if (card->resume_post)
768 machine->resume_post(pdev); 757 card->resume_post(pdev);
769 758
770 dev_info(socdev->dev, "resume work completed\n"); 759 dev_dbg(socdev->dev, "resume work completed\n");
771 760
772 /* userspace can access us now we are back as we were before */ 761 /* userspace can access us now we are back as we were before */
773 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0); 762 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0);
@@ -777,11 +766,12 @@ static void soc_resume_deferred(struct work_struct *work)
777static int soc_resume(struct platform_device *pdev) 766static int soc_resume(struct platform_device *pdev)
778{ 767{
779 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 768 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
769 struct snd_soc_card *card = socdev->card;
780 770
781 dev_info(socdev->dev, "scheduling resume work\n"); 771 dev_dbg(socdev->dev, "scheduling resume work\n");
782 772
783 if (!schedule_work(&socdev->deferred_resume_work)) 773 if (!schedule_work(&card->deferred_resume_work))
784 dev_err(socdev->dev, "work item may be lost\n"); 774 dev_err(socdev->dev, "resume work item may be lost\n");
785 775
786 return 0; 776 return 0;
787} 777}
@@ -791,23 +781,83 @@ static int soc_resume(struct platform_device *pdev)
791#define soc_resume NULL 781#define soc_resume NULL
792#endif 782#endif
793 783
794/* probes a new socdev */ 784static void snd_soc_instantiate_card(struct snd_soc_card *card)
795static int soc_probe(struct platform_device *pdev)
796{ 785{
797 int ret = 0, i; 786 struct platform_device *pdev = container_of(card->dev,
798 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 struct platform_device,
799 struct snd_soc_machine *machine = socdev->machine; 788 dev);
800 struct snd_soc_platform *platform = socdev->platform; 789 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
801 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 790 struct snd_soc_platform *platform;
791 struct snd_soc_dai *dai;
792 int i, found, ret, ac97;
793
794 if (card->instantiated)
795 return;
796
797 found = 0;
798 list_for_each_entry(platform, &platform_list, list)
799 if (card->platform == platform) {
800 found = 1;
801 break;
802 }
803 if (!found) {
804 dev_dbg(card->dev, "Platform %s not registered\n",
805 card->platform->name);
806 return;
807 }
802 808
803 if (machine->probe) { 809 ac97 = 0;
804 ret = machine->probe(pdev); 810 for (i = 0; i < card->num_links; i++) {
811 found = 0;
812 list_for_each_entry(dai, &dai_list, list)
813 if (card->dai_link[i].cpu_dai == dai) {
814 found = 1;
815 break;
816 }
817 if (!found) {
818 dev_dbg(card->dev, "DAI %s not registered\n",
819 card->dai_link[i].cpu_dai->name);
820 return;
821 }
822
823 if (card->dai_link[i].cpu_dai->ac97_control)
824 ac97 = 1;
825 }
826
827 /* If we have AC97 in the system then don't wait for the
828 * codec. This will need revisiting if we have to handle
829 * systems with mixed AC97 and non-AC97 parts. Only check for
830 * DAIs currently; we can't do this per link since some AC97
831 * codecs have non-AC97 DAIs.
832 */
833 if (!ac97)
834 for (i = 0; i < card->num_links; i++) {
835 found = 0;
836 list_for_each_entry(dai, &dai_list, list)
837 if (card->dai_link[i].codec_dai == dai) {
838 found = 1;
839 break;
840 }
841 if (!found) {
842 dev_dbg(card->dev, "DAI %s not registered\n",
843 card->dai_link[i].codec_dai->name);
844 return;
845 }
846 }
847
848 /* Note that we do not current check for codec components */
849
850 dev_dbg(card->dev, "All components present, instantiating\n");
851
852 /* Found everything, bring it up */
853 if (card->probe) {
854 ret = card->probe(pdev);
805 if (ret < 0) 855 if (ret < 0)
806 return ret; 856 return;
807 } 857 }
808 858
809 for (i = 0; i < machine->num_links; i++) { 859 for (i = 0; i < card->num_links; i++) {
810 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 860 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
811 if (cpu_dai->probe) { 861 if (cpu_dai->probe) {
812 ret = cpu_dai->probe(pdev, cpu_dai); 862 ret = cpu_dai->probe(pdev, cpu_dai);
813 if (ret < 0) 863 if (ret < 0)
@@ -828,13 +878,15 @@ static int soc_probe(struct platform_device *pdev)
828 } 878 }
829 879
830 /* DAPM stream work */ 880 /* DAPM stream work */
831 INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); 881 INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);
832#ifdef CONFIG_PM 882#ifdef CONFIG_PM
833 /* deferred resume work */ 883 /* deferred resume work */
834 INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred); 884 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
835#endif 885#endif
836 886
837 return 0; 887 card->instantiated = 1;
888
889 return;
838 890
839platform_err: 891platform_err:
840 if (codec_dev->remove) 892 if (codec_dev->remove)
@@ -842,15 +894,45 @@ platform_err:
842 894
843cpu_dai_err: 895cpu_dai_err:
844 for (i--; i >= 0; i--) { 896 for (i--; i >= 0; i--) {
845 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 897 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
846 if (cpu_dai->remove) 898 if (cpu_dai->remove)
847 cpu_dai->remove(pdev, cpu_dai); 899 cpu_dai->remove(pdev, cpu_dai);
848 } 900 }
849 901
850 if (machine->remove) 902 if (card->remove)
851 machine->remove(pdev); 903 card->remove(pdev);
904}
852 905
853 return ret; 906/*
907 * Attempt to initialise any uninitalised cards. Must be called with
908 * client_mutex.
909 */
910static void snd_soc_instantiate_cards(void)
911{
912 struct snd_soc_card *card;
913 list_for_each_entry(card, &card_list, list)
914 snd_soc_instantiate_card(card);
915}
916
917/* probes a new socdev */
918static int soc_probe(struct platform_device *pdev)
919{
920 int ret = 0;
921 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
922 struct snd_soc_card *card = socdev->card;
923
924 /* Bodge while we push things out of socdev */
925 card->socdev = socdev;
926
927 /* Bodge while we unpick instantiation */
928 card->dev = &pdev->dev;
929 ret = snd_soc_register_card(card);
930 if (ret != 0) {
931 dev_err(&pdev->dev, "Failed to register card\n");
932 return ret;
933 }
934
935 return 0;
854} 936}
855 937
856/* removes a socdev */ 938/* removes a socdev */
@@ -858,11 +940,11 @@ static int soc_remove(struct platform_device *pdev)
858{ 940{
859 int i; 941 int i;
860 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
861 struct snd_soc_machine *machine = socdev->machine; 943 struct snd_soc_card *card = socdev->card;
862 struct snd_soc_platform *platform = socdev->platform; 944 struct snd_soc_platform *platform = card->platform;
863 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 945 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
864 946
865 run_delayed_work(&socdev->delayed_work); 947 run_delayed_work(&card->delayed_work);
866 948
867 if (platform->remove) 949 if (platform->remove)
868 platform->remove(pdev); 950 platform->remove(pdev);
@@ -870,14 +952,16 @@ static int soc_remove(struct platform_device *pdev)
870 if (codec_dev->remove) 952 if (codec_dev->remove)
871 codec_dev->remove(pdev); 953 codec_dev->remove(pdev);
872 954
873 for (i = 0; i < machine->num_links; i++) { 955 for (i = 0; i < card->num_links; i++) {
874 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 956 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
875 if (cpu_dai->remove) 957 if (cpu_dai->remove)
876 cpu_dai->remove(pdev, cpu_dai); 958 cpu_dai->remove(pdev, cpu_dai);
877 } 959 }
878 960
879 if (machine->remove) 961 if (card->remove)
880 machine->remove(pdev); 962 card->remove(pdev);
963
964 snd_soc_unregister_card(card);
881 965
882 return 0; 966 return 0;
883} 967}
@@ -899,6 +983,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
899 struct snd_soc_dai_link *dai_link, int num) 983 struct snd_soc_dai_link *dai_link, int num)
900{ 984{
901 struct snd_soc_codec *codec = socdev->codec; 985 struct snd_soc_codec *codec = socdev->codec;
986 struct snd_soc_card *card = socdev->card;
987 struct snd_soc_platform *platform = card->platform;
902 struct snd_soc_dai *codec_dai = dai_link->codec_dai; 988 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
903 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; 989 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
904 struct snd_soc_pcm_runtime *rtd; 990 struct snd_soc_pcm_runtime *rtd;
@@ -915,8 +1001,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
915 codec_dai->codec = socdev->codec; 1001 codec_dai->codec = socdev->codec;
916 1002
917 /* check client and interface hw capabilities */ 1003 /* check client and interface hw capabilities */
918 sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name, 1004 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
919 get_dai_name(cpu_dai->type), num); 1005 num);
920 1006
921 if (codec_dai->playback.channels_min) 1007 if (codec_dai->playback.channels_min)
922 playback = 1; 1008 playback = 1;
@@ -934,13 +1020,13 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
934 1020
935 dai_link->pcm = pcm; 1021 dai_link->pcm = pcm;
936 pcm->private_data = rtd; 1022 pcm->private_data = rtd;
937 soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap; 1023 soc_pcm_ops.mmap = platform->pcm_ops->mmap;
938 soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer; 1024 soc_pcm_ops.pointer = platform->pcm_ops->pointer;
939 soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl; 1025 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
940 soc_pcm_ops.copy = socdev->platform->pcm_ops->copy; 1026 soc_pcm_ops.copy = platform->pcm_ops->copy;
941 soc_pcm_ops.silence = socdev->platform->pcm_ops->silence; 1027 soc_pcm_ops.silence = platform->pcm_ops->silence;
942 soc_pcm_ops.ack = socdev->platform->pcm_ops->ack; 1028 soc_pcm_ops.ack = platform->pcm_ops->ack;
943 soc_pcm_ops.page = socdev->platform->pcm_ops->page; 1029 soc_pcm_ops.page = platform->pcm_ops->page;
944 1030
945 if (playback) 1031 if (playback)
946 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 1032 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -948,24 +1034,22 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
948 if (capture) 1034 if (capture)
949 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 1035 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
950 1036
951 ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm); 1037 ret = platform->pcm_new(codec->card, codec_dai, pcm);
952 if (ret < 0) { 1038 if (ret < 0) {
953 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 1039 printk(KERN_ERR "asoc: platform pcm constructor failed\n");
954 kfree(rtd); 1040 kfree(rtd);
955 return ret; 1041 return ret;
956 } 1042 }
957 1043
958 pcm->private_free = socdev->platform->pcm_free; 1044 pcm->private_free = platform->pcm_free;
959 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1045 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
960 cpu_dai->name); 1046 cpu_dai->name);
961 return ret; 1047 return ret;
962} 1048}
963 1049
964/* codec register dump */ 1050/* codec register dump */
965static ssize_t codec_reg_show(struct device *dev, 1051static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf)
966 struct device_attribute *attr, char *buf)
967{ 1052{
968 struct snd_soc_device *devdata = dev_get_drvdata(dev);
969 struct snd_soc_codec *codec = devdata->codec; 1053 struct snd_soc_codec *codec = devdata->codec;
970 int i, step = 1, count = 0; 1054 int i, step = 1, count = 0;
971 1055
@@ -1002,8 +1086,110 @@ static ssize_t codec_reg_show(struct device *dev,
1002 1086
1003 return count; 1087 return count;
1004} 1088}
1089static ssize_t codec_reg_show(struct device *dev,
1090 struct device_attribute *attr, char *buf)
1091{
1092 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1093 return soc_codec_reg_show(devdata, buf);
1094}
1095
1005static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 1096static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1006 1097
1098#ifdef CONFIG_DEBUG_FS
1099static int codec_reg_open_file(struct inode *inode, struct file *file)
1100{
1101 file->private_data = inode->i_private;
1102 return 0;
1103}
1104
1105static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1106 size_t count, loff_t *ppos)
1107{
1108 ssize_t ret;
1109 struct snd_soc_codec *codec = file->private_data;
1110 struct device *card_dev = codec->card->dev;
1111 struct snd_soc_device *devdata = card_dev->driver_data;
1112 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1113 if (!buf)
1114 return -ENOMEM;
1115 ret = soc_codec_reg_show(devdata, buf);
1116 if (ret >= 0)
1117 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1118 kfree(buf);
1119 return ret;
1120}
1121
1122static ssize_t codec_reg_write_file(struct file *file,
1123 const char __user *user_buf, size_t count, loff_t *ppos)
1124{
1125 char buf[32];
1126 int buf_size;
1127 char *start = buf;
1128 unsigned long reg, value;
1129 int step = 1;
1130 struct snd_soc_codec *codec = file->private_data;
1131
1132 buf_size = min(count, (sizeof(buf)-1));
1133 if (copy_from_user(buf, user_buf, buf_size))
1134 return -EFAULT;
1135 buf[buf_size] = 0;
1136
1137 if (codec->reg_cache_step)
1138 step = codec->reg_cache_step;
1139
1140 while (*start == ' ')
1141 start++;
1142 reg = simple_strtoul(start, &start, 16);
1143 if ((reg >= codec->reg_cache_size) || (reg % step))
1144 return -EINVAL;
1145 while (*start == ' ')
1146 start++;
1147 if (strict_strtoul(start, 16, &value))
1148 return -EINVAL;
1149 codec->write(codec, reg, value);
1150 return buf_size;
1151}
1152
1153static const struct file_operations codec_reg_fops = {
1154 .open = codec_reg_open_file,
1155 .read = codec_reg_read_file,
1156 .write = codec_reg_write_file,
1157};
1158
1159static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1160{
1161 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1162 debugfs_root, codec,
1163 &codec_reg_fops);
1164 if (!codec->debugfs_reg)
1165 printk(KERN_WARNING
1166 "ASoC: Failed to create codec register debugfs file\n");
1167
1168 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1169 debugfs_root,
1170 &codec->pop_time);
1171 if (!codec->debugfs_pop_time)
1172 printk(KERN_WARNING
1173 "Failed to create pop time debugfs file\n");
1174}
1175
1176static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1177{
1178 debugfs_remove(codec->debugfs_pop_time);
1179 debugfs_remove(codec->debugfs_reg);
1180}
1181
1182#else
1183
1184static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1185{
1186}
1187
1188static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1189{
1190}
1191#endif
1192
1007/** 1193/**
1008 * snd_soc_new_ac97_codec - initailise AC97 device 1194 * snd_soc_new_ac97_codec - initailise AC97 device
1009 * @codec: audio codec 1195 * @codec: audio codec
@@ -1114,6 +1300,8 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1114/** 1300/**
1115 * snd_soc_new_pcms - create new sound card and pcms 1301 * snd_soc_new_pcms - create new sound card and pcms
1116 * @socdev: the SoC audio device 1302 * @socdev: the SoC audio device
1303 * @idx: ALSA card index
1304 * @xid: card identification
1117 * 1305 *
1118 * Create a new sound card based upon the codec and interface pcms. 1306 * Create a new sound card based upon the codec and interface pcms.
1119 * 1307 *
@@ -1122,7 +1310,7 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1122int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) 1310int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1123{ 1311{
1124 struct snd_soc_codec *codec = socdev->codec; 1312 struct snd_soc_codec *codec = socdev->codec;
1125 struct snd_soc_machine *machine = socdev->machine; 1313 struct snd_soc_card *card = socdev->card;
1126 int ret = 0, i; 1314 int ret = 0, i;
1127 1315
1128 mutex_lock(&codec->mutex); 1316 mutex_lock(&codec->mutex);
@@ -1141,11 +1329,11 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1141 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); 1329 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1142 1330
1143 /* create the pcms */ 1331 /* create the pcms */
1144 for (i = 0; i < machine->num_links; i++) { 1332 for (i = 0; i < card->num_links; i++) {
1145 ret = soc_new_pcm(socdev, &machine->dai_link[i], i); 1333 ret = soc_new_pcm(socdev, &card->dai_link[i], i);
1146 if (ret < 0) { 1334 if (ret < 0) {
1147 printk(KERN_ERR "asoc: can't create pcm %s\n", 1335 printk(KERN_ERR "asoc: can't create pcm %s\n",
1148 machine->dai_link[i].stream_name); 1336 card->dai_link[i].stream_name);
1149 mutex_unlock(&codec->mutex); 1337 mutex_unlock(&codec->mutex);
1150 return ret; 1338 return ret;
1151 } 1339 }
@@ -1157,7 +1345,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1157EXPORT_SYMBOL_GPL(snd_soc_new_pcms); 1345EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1158 1346
1159/** 1347/**
1160 * snd_soc_register_card - register sound card 1348 * snd_soc_init_card - register sound card
1161 * @socdev: the SoC audio device 1349 * @socdev: the SoC audio device
1162 * 1350 *
1163 * Register a SoC sound card. Also registers an AC97 device if the 1351 * Register a SoC sound card. Also registers an AC97 device if the
@@ -1165,29 +1353,28 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1165 * 1353 *
1166 * Returns 0 for success, else error. 1354 * Returns 0 for success, else error.
1167 */ 1355 */
1168int snd_soc_register_card(struct snd_soc_device *socdev) 1356int snd_soc_init_card(struct snd_soc_device *socdev)
1169{ 1357{
1170 struct snd_soc_codec *codec = socdev->codec; 1358 struct snd_soc_codec *codec = socdev->codec;
1171 struct snd_soc_machine *machine = socdev->machine; 1359 struct snd_soc_card *card = socdev->card;
1172 int ret = 0, i, ac97 = 0, err = 0; 1360 int ret = 0, i, ac97 = 0, err = 0;
1173 1361
1174 for (i = 0; i < machine->num_links; i++) { 1362 for (i = 0; i < card->num_links; i++) {
1175 if (socdev->machine->dai_link[i].init) { 1363 if (card->dai_link[i].init) {
1176 err = socdev->machine->dai_link[i].init(codec); 1364 err = card->dai_link[i].init(codec);
1177 if (err < 0) { 1365 if (err < 0) {
1178 printk(KERN_ERR "asoc: failed to init %s\n", 1366 printk(KERN_ERR "asoc: failed to init %s\n",
1179 socdev->machine->dai_link[i].stream_name); 1367 card->dai_link[i].stream_name);
1180 continue; 1368 continue;
1181 } 1369 }
1182 } 1370 }
1183 if (socdev->machine->dai_link[i].codec_dai->type == 1371 if (card->dai_link[i].codec_dai->ac97_control)
1184 SND_SOC_DAI_AC97_BUS)
1185 ac97 = 1; 1372 ac97 = 1;
1186 } 1373 }
1187 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1374 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1188 "%s", machine->name); 1375 "%s", card->name);
1189 snprintf(codec->card->longname, sizeof(codec->card->longname), 1376 snprintf(codec->card->longname, sizeof(codec->card->longname),
1190 "%s (%s)", machine->name, codec->name); 1377 "%s (%s)", card->name, codec->name);
1191 1378
1192 ret = snd_card_register(codec->card); 1379 ret = snd_card_register(codec->card);
1193 if (ret < 0) { 1380 if (ret < 0) {
@@ -1217,12 +1404,13 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1217 if (err < 0) 1404 if (err < 0)
1218 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1405 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1219 1406
1407 soc_init_codec_debugfs(socdev->codec);
1220 mutex_unlock(&codec->mutex); 1408 mutex_unlock(&codec->mutex);
1221 1409
1222out: 1410out:
1223 return ret; 1411 return ret;
1224} 1412}
1225EXPORT_SYMBOL_GPL(snd_soc_register_card); 1413EXPORT_SYMBOL_GPL(snd_soc_init_card);
1226 1414
1227/** 1415/**
1228 * snd_soc_free_pcms - free sound card and pcms 1416 * snd_soc_free_pcms - free sound card and pcms
@@ -1240,10 +1428,11 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
1240#endif 1428#endif
1241 1429
1242 mutex_lock(&codec->mutex); 1430 mutex_lock(&codec->mutex);
1431 soc_cleanup_codec_debugfs(socdev->codec);
1243#ifdef CONFIG_SND_SOC_AC97_BUS 1432#ifdef CONFIG_SND_SOC_AC97_BUS
1244 for (i = 0; i < codec->num_dai; i++) { 1433 for (i = 0; i < codec->num_dai; i++) {
1245 codec_dai = &codec->dai[i]; 1434 codec_dai = &codec->dai[i];
1246 if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) { 1435 if (codec_dai->ac97_control && codec->ac97) {
1247 soc_ac97_dev_unregister(codec); 1436 soc_ac97_dev_unregister(codec);
1248 goto free_card; 1437 goto free_card;
1249 } 1438 }
@@ -1285,7 +1474,7 @@ EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
1285 * snd_soc_cnew - create new control 1474 * snd_soc_cnew - create new control
1286 * @_template: control template 1475 * @_template: control template
1287 * @data: control private data 1476 * @data: control private data
1288 * @lnng_name: control long name 1477 * @long_name: control long name
1289 * 1478 *
1290 * Create a new mixer control from a template control. 1479 * Create a new mixer control from a template control.
1291 * 1480 *
@@ -1335,7 +1524,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_enum_double);
1335/** 1524/**
1336 * snd_soc_get_enum_double - enumerated double mixer get callback 1525 * snd_soc_get_enum_double - enumerated double mixer get callback
1337 * @kcontrol: mixer control 1526 * @kcontrol: mixer control
1338 * @uinfo: control element information 1527 * @ucontrol: control element information
1339 * 1528 *
1340 * Callback to get the value of a double enumerated mixer. 1529 * Callback to get the value of a double enumerated mixer.
1341 * 1530 *
@@ -1364,7 +1553,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_enum_double);
1364/** 1553/**
1365 * snd_soc_put_enum_double - enumerated double mixer put callback 1554 * snd_soc_put_enum_double - enumerated double mixer put callback
1366 * @kcontrol: mixer control 1555 * @kcontrol: mixer control
1367 * @uinfo: control element information 1556 * @ucontrol: control element information
1368 * 1557 *
1369 * Callback to set the value of a double enumerated mixer. 1558 * Callback to set the value of a double enumerated mixer.
1370 * 1559 *
@@ -1396,6 +1585,80 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1396EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1585EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1397 1586
1398/** 1587/**
1588 * snd_soc_get_value_enum_double - semi enumerated double mixer get callback
1589 * @kcontrol: mixer control
1590 * @ucontrol: control element information
1591 *
1592 * Callback to get the value of a double semi enumerated mixer.
1593 *
1594 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1595 * used for handling bitfield coded enumeration for example.
1596 *
1597 * Returns 0 for success.
1598 */
1599int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
1600 struct snd_ctl_elem_value *ucontrol)
1601{
1602 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1603 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1604 unsigned short reg_val, val, mux;
1605
1606 reg_val = snd_soc_read(codec, e->reg);
1607 val = (reg_val >> e->shift_l) & e->mask;
1608 for (mux = 0; mux < e->max; mux++) {
1609 if (val == e->values[mux])
1610 break;
1611 }
1612 ucontrol->value.enumerated.item[0] = mux;
1613 if (e->shift_l != e->shift_r) {
1614 val = (reg_val >> e->shift_r) & e->mask;
1615 for (mux = 0; mux < e->max; mux++) {
1616 if (val == e->values[mux])
1617 break;
1618 }
1619 ucontrol->value.enumerated.item[1] = mux;
1620 }
1621
1622 return 0;
1623}
1624EXPORT_SYMBOL_GPL(snd_soc_get_value_enum_double);
1625
1626/**
1627 * snd_soc_put_value_enum_double - semi enumerated double mixer put callback
1628 * @kcontrol: mixer control
1629 * @ucontrol: control element information
1630 *
1631 * Callback to set the value of a double semi enumerated mixer.
1632 *
1633 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1634 * used for handling bitfield coded enumeration for example.
1635 *
1636 * Returns 0 for success.
1637 */
1638int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1639 struct snd_ctl_elem_value *ucontrol)
1640{
1641 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1642 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1643 unsigned short val;
1644 unsigned short mask;
1645
1646 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1647 return -EINVAL;
1648 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
1649 mask = e->mask << e->shift_l;
1650 if (e->shift_l != e->shift_r) {
1651 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1652 return -EINVAL;
1653 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
1654 mask |= e->mask << e->shift_r;
1655 }
1656
1657 return snd_soc_update_bits(codec, e->reg, mask, val);
1658}
1659EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
1660
1661/**
1399 * snd_soc_info_enum_ext - external enumerated single mixer info callback 1662 * snd_soc_info_enum_ext - external enumerated single mixer info callback
1400 * @kcontrol: mixer control 1663 * @kcontrol: mixer control
1401 * @uinfo: control element information 1664 * @uinfo: control element information
@@ -1463,7 +1726,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1463 struct soc_mixer_control *mc = 1726 struct soc_mixer_control *mc =
1464 (struct soc_mixer_control *)kcontrol->private_value; 1727 (struct soc_mixer_control *)kcontrol->private_value;
1465 int max = mc->max; 1728 int max = mc->max;
1466 unsigned int shift = mc->min; 1729 unsigned int shift = mc->shift;
1467 unsigned int rshift = mc->rshift; 1730 unsigned int rshift = mc->rshift;
1468 1731
1469 if (max == 1) 1732 if (max == 1)
@@ -1481,7 +1744,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
1481/** 1744/**
1482 * snd_soc_get_volsw - single mixer get callback 1745 * snd_soc_get_volsw - single mixer get callback
1483 * @kcontrol: mixer control 1746 * @kcontrol: mixer control
1484 * @uinfo: control element information 1747 * @ucontrol: control element information
1485 * 1748 *
1486 * Callback to get the value of a single mixer control. 1749 * Callback to get the value of a single mixer control.
1487 * 1750 *
@@ -1520,7 +1783,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
1520/** 1783/**
1521 * snd_soc_put_volsw - single mixer put callback 1784 * snd_soc_put_volsw - single mixer put callback
1522 * @kcontrol: mixer control 1785 * @kcontrol: mixer control
1523 * @uinfo: control element information 1786 * @ucontrol: control element information
1524 * 1787 *
1525 * Callback to set the value of a single mixer control. 1788 * Callback to set the value of a single mixer control.
1526 * 1789 *
@@ -1588,7 +1851,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
1588/** 1851/**
1589 * snd_soc_get_volsw_2r - double mixer get callback 1852 * snd_soc_get_volsw_2r - double mixer get callback
1590 * @kcontrol: mixer control 1853 * @kcontrol: mixer control
1591 * @uinfo: control element information 1854 * @ucontrol: control element information
1592 * 1855 *
1593 * Callback to get the value of a double mixer control that spans 2 registers. 1856 * Callback to get the value of a double mixer control that spans 2 registers.
1594 * 1857 *
@@ -1625,7 +1888,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
1625/** 1888/**
1626 * snd_soc_put_volsw_2r - double mixer set callback 1889 * snd_soc_put_volsw_2r - double mixer set callback
1627 * @kcontrol: mixer control 1890 * @kcontrol: mixer control
1628 * @uinfo: control element information 1891 * @ucontrol: control element information
1629 * 1892 *
1630 * Callback to set the value of a double mixer control that spans 2 registers. 1893 * Callback to set the value of a double mixer control that spans 2 registers.
1631 * 1894 *
@@ -1695,7 +1958,7 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_s8);
1695/** 1958/**
1696 * snd_soc_get_volsw_s8 - signed mixer get callback 1959 * snd_soc_get_volsw_s8 - signed mixer get callback
1697 * @kcontrol: mixer control 1960 * @kcontrol: mixer control
1698 * @uinfo: control element information 1961 * @ucontrol: control element information
1699 * 1962 *
1700 * Callback to get the value of a signed mixer control. 1963 * Callback to get the value of a signed mixer control.
1701 * 1964 *
@@ -1722,7 +1985,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_s8);
1722/** 1985/**
1723 * snd_soc_put_volsw_sgn - signed mixer put callback 1986 * snd_soc_put_volsw_sgn - signed mixer put callback
1724 * @kcontrol: mixer control 1987 * @kcontrol: mixer control
1725 * @uinfo: control element information 1988 * @ucontrol: control element information
1726 * 1989 *
1727 * Callback to set the value of a signed mixer control. 1990 * Callback to set the value of a signed mixer control.
1728 * 1991 *
@@ -1757,8 +2020,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1757int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 2020int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1758 unsigned int freq, int dir) 2021 unsigned int freq, int dir)
1759{ 2022{
1760 if (dai->dai_ops.set_sysclk) 2023 if (dai->ops.set_sysclk)
1761 return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir); 2024 return dai->ops.set_sysclk(dai, clk_id, freq, dir);
1762 else 2025 else
1763 return -EINVAL; 2026 return -EINVAL;
1764} 2027}
@@ -1767,7 +2030,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
1767/** 2030/**
1768 * snd_soc_dai_set_clkdiv - configure DAI clock dividers. 2031 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
1769 * @dai: DAI 2032 * @dai: DAI
1770 * @clk_id: DAI specific clock divider ID 2033 * @div_id: DAI specific clock divider ID
1771 * @div: new clock divisor. 2034 * @div: new clock divisor.
1772 * 2035 *
1773 * Configures the clock dividers. This is used to derive the best DAI bit and 2036 * Configures the clock dividers. This is used to derive the best DAI bit and
@@ -1777,8 +2040,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
1777int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 2040int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
1778 int div_id, int div) 2041 int div_id, int div)
1779{ 2042{
1780 if (dai->dai_ops.set_clkdiv) 2043 if (dai->ops.set_clkdiv)
1781 return dai->dai_ops.set_clkdiv(dai, div_id, div); 2044 return dai->ops.set_clkdiv(dai, div_id, div);
1782 else 2045 else
1783 return -EINVAL; 2046 return -EINVAL;
1784} 2047}
@@ -1796,8 +2059,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
1796int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2059int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
1797 int pll_id, unsigned int freq_in, unsigned int freq_out) 2060 int pll_id, unsigned int freq_in, unsigned int freq_out)
1798{ 2061{
1799 if (dai->dai_ops.set_pll) 2062 if (dai->ops.set_pll)
1800 return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out); 2063 return dai->ops.set_pll(dai, pll_id, freq_in, freq_out);
1801 else 2064 else
1802 return -EINVAL; 2065 return -EINVAL;
1803} 2066}
@@ -1806,15 +2069,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
1806/** 2069/**
1807 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 2070 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
1808 * @dai: DAI 2071 * @dai: DAI
1809 * @clk_id: DAI specific clock ID
1810 * @fmt: SND_SOC_DAIFMT_ format value. 2072 * @fmt: SND_SOC_DAIFMT_ format value.
1811 * 2073 *
1812 * Configures the DAI hardware format and clocking. 2074 * Configures the DAI hardware format and clocking.
1813 */ 2075 */
1814int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2076int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1815{ 2077{
1816 if (dai->dai_ops.set_fmt) 2078 if (dai->ops.set_fmt)
1817 return dai->dai_ops.set_fmt(dai, fmt); 2079 return dai->ops.set_fmt(dai, fmt);
1818 else 2080 else
1819 return -EINVAL; 2081 return -EINVAL;
1820} 2082}
@@ -1832,8 +2094,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
1832int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2094int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
1833 unsigned int mask, int slots) 2095 unsigned int mask, int slots)
1834{ 2096{
1835 if (dai->dai_ops.set_sysclk) 2097 if (dai->ops.set_sysclk)
1836 return dai->dai_ops.set_tdm_slot(dai, mask, slots); 2098 return dai->ops.set_tdm_slot(dai, mask, slots);
1837 else 2099 else
1838 return -EINVAL; 2100 return -EINVAL;
1839} 2101}
@@ -1848,8 +2110,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
1848 */ 2110 */
1849int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) 2111int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
1850{ 2112{
1851 if (dai->dai_ops.set_sysclk) 2113 if (dai->ops.set_sysclk)
1852 return dai->dai_ops.set_tristate(dai, tristate); 2114 return dai->ops.set_tristate(dai, tristate);
1853 else 2115 else
1854 return -EINVAL; 2116 return -EINVAL;
1855} 2117}
@@ -1864,21 +2126,242 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
1864 */ 2126 */
1865int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 2127int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
1866{ 2128{
1867 if (dai->dai_ops.digital_mute) 2129 if (dai->ops.digital_mute)
1868 return dai->dai_ops.digital_mute(dai, mute); 2130 return dai->ops.digital_mute(dai, mute);
1869 else 2131 else
1870 return -EINVAL; 2132 return -EINVAL;
1871} 2133}
1872EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 2134EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1873 2135
1874static int __devinit snd_soc_init(void) 2136/**
2137 * snd_soc_register_card - Register a card with the ASoC core
2138 *
2139 * @card: Card to register
2140 *
2141 * Note that currently this is an internal only function: it will be
2142 * exposed to machine drivers after further backporting of ASoC v2
2143 * registration APIs.
2144 */
2145static int snd_soc_register_card(struct snd_soc_card *card)
2146{
2147 if (!card->name || !card->dev)
2148 return -EINVAL;
2149
2150 INIT_LIST_HEAD(&card->list);
2151 card->instantiated = 0;
2152
2153 mutex_lock(&client_mutex);
2154 list_add(&card->list, &card_list);
2155 snd_soc_instantiate_cards();
2156 mutex_unlock(&client_mutex);
2157
2158 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
2159
2160 return 0;
2161}
2162
2163/**
2164 * snd_soc_unregister_card - Unregister a card with the ASoC core
2165 *
2166 * @card: Card to unregister
2167 *
2168 * Note that currently this is an internal only function: it will be
2169 * exposed to machine drivers after further backporting of ASoC v2
2170 * registration APIs.
2171 */
2172static int snd_soc_unregister_card(struct snd_soc_card *card)
2173{
2174 mutex_lock(&client_mutex);
2175 list_del(&card->list);
2176 mutex_unlock(&client_mutex);
2177
2178 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
2179
2180 return 0;
2181}
2182
2183/**
2184 * snd_soc_register_dai - Register a DAI with the ASoC core
2185 *
2186 * @dai: DAI to register
2187 */
2188int snd_soc_register_dai(struct snd_soc_dai *dai)
2189{
2190 if (!dai->name)
2191 return -EINVAL;
2192
2193 /* The device should become mandatory over time */
2194 if (!dai->dev)
2195 printk(KERN_WARNING "No device for DAI %s\n", dai->name);
2196
2197 INIT_LIST_HEAD(&dai->list);
2198
2199 mutex_lock(&client_mutex);
2200 list_add(&dai->list, &dai_list);
2201 snd_soc_instantiate_cards();
2202 mutex_unlock(&client_mutex);
2203
2204 pr_debug("Registered DAI '%s'\n", dai->name);
2205
2206 return 0;
2207}
2208EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2209
2210/**
2211 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
2212 *
2213 * @dai: DAI to unregister
2214 */
2215void snd_soc_unregister_dai(struct snd_soc_dai *dai)
2216{
2217 mutex_lock(&client_mutex);
2218 list_del(&dai->list);
2219 mutex_unlock(&client_mutex);
2220
2221 pr_debug("Unregistered DAI '%s'\n", dai->name);
2222}
2223EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2224
2225/**
2226 * snd_soc_register_dais - Register multiple DAIs with the ASoC core
2227 *
2228 * @dai: Array of DAIs to register
2229 * @count: Number of DAIs
2230 */
2231int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count)
2232{
2233 int i, ret;
2234
2235 for (i = 0; i < count; i++) {
2236 ret = snd_soc_register_dai(&dai[i]);
2237 if (ret != 0)
2238 goto err;
2239 }
2240
2241 return 0;
2242
2243err:
2244 for (i--; i >= 0; i--)
2245 snd_soc_unregister_dai(&dai[i]);
2246
2247 return ret;
2248}
2249EXPORT_SYMBOL_GPL(snd_soc_register_dais);
2250
2251/**
2252 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
2253 *
2254 * @dai: Array of DAIs to unregister
2255 * @count: Number of DAIs
2256 */
2257void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count)
2258{
2259 int i;
2260
2261 for (i = 0; i < count; i++)
2262 snd_soc_unregister_dai(&dai[i]);
2263}
2264EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
2265
2266/**
2267 * snd_soc_register_platform - Register a platform with the ASoC core
2268 *
2269 * @platform: platform to register
2270 */
2271int snd_soc_register_platform(struct snd_soc_platform *platform)
2272{
2273 if (!platform->name)
2274 return -EINVAL;
2275
2276 INIT_LIST_HEAD(&platform->list);
2277
2278 mutex_lock(&client_mutex);
2279 list_add(&platform->list, &platform_list);
2280 snd_soc_instantiate_cards();
2281 mutex_unlock(&client_mutex);
2282
2283 pr_debug("Registered platform '%s'\n", platform->name);
2284
2285 return 0;
2286}
2287EXPORT_SYMBOL_GPL(snd_soc_register_platform);
2288
2289/**
2290 * snd_soc_unregister_platform - Unregister a platform from the ASoC core
2291 *
2292 * @platform: platform to unregister
2293 */
2294void snd_soc_unregister_platform(struct snd_soc_platform *platform)
2295{
2296 mutex_lock(&client_mutex);
2297 list_del(&platform->list);
2298 mutex_unlock(&client_mutex);
2299
2300 pr_debug("Unregistered platform '%s'\n", platform->name);
2301}
2302EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2303
2304/**
2305 * snd_soc_register_codec - Register a codec with the ASoC core
2306 *
2307 * @codec: codec to register
2308 */
2309int snd_soc_register_codec(struct snd_soc_codec *codec)
2310{
2311 if (!codec->name)
2312 return -EINVAL;
2313
2314 /* The device should become mandatory over time */
2315 if (!codec->dev)
2316 printk(KERN_WARNING "No device for codec %s\n", codec->name);
2317
2318 INIT_LIST_HEAD(&codec->list);
2319
2320 mutex_lock(&client_mutex);
2321 list_add(&codec->list, &codec_list);
2322 snd_soc_instantiate_cards();
2323 mutex_unlock(&client_mutex);
2324
2325 pr_debug("Registered codec '%s'\n", codec->name);
2326
2327 return 0;
2328}
2329EXPORT_SYMBOL_GPL(snd_soc_register_codec);
2330
2331/**
2332 * snd_soc_unregister_codec - Unregister a codec from the ASoC core
2333 *
2334 * @codec: codec to unregister
2335 */
2336void snd_soc_unregister_codec(struct snd_soc_codec *codec)
1875{ 2337{
1876 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 2338 mutex_lock(&client_mutex);
2339 list_del(&codec->list);
2340 mutex_unlock(&client_mutex);
2341
2342 pr_debug("Unregistered codec '%s'\n", codec->name);
2343}
2344EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
2345
2346static int __init snd_soc_init(void)
2347{
2348#ifdef CONFIG_DEBUG_FS
2349 debugfs_root = debugfs_create_dir("asoc", NULL);
2350 if (IS_ERR(debugfs_root) || !debugfs_root) {
2351 printk(KERN_WARNING
2352 "ASoC: Failed to create debugfs directory\n");
2353 debugfs_root = NULL;
2354 }
2355#endif
2356
1877 return platform_driver_register(&soc_driver); 2357 return platform_driver_register(&soc_driver);
1878} 2358}
1879 2359
1880static void snd_soc_exit(void) 2360static void __exit snd_soc_exit(void)
1881{ 2361{
2362#ifdef CONFIG_DEBUG_FS
2363 debugfs_remove_recursive(debugfs_root);
2364#endif
1882 platform_driver_unregister(&soc_driver); 2365 platform_driver_unregister(&soc_driver);
1883} 2366}
1884 2367
@@ -1886,7 +2369,7 @@ module_init(snd_soc_init);
1886module_exit(snd_soc_exit); 2369module_exit(snd_soc_exit);
1887 2370
1888/* Module information */ 2371/* Module information */
1889MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 2372MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1890MODULE_DESCRIPTION("ALSA SoC Core"); 2373MODULE_DESCRIPTION("ALSA SoC Core");
1891MODULE_LICENSE("GPL"); 2374MODULE_LICENSE("GPL");
1892MODULE_ALIAS("platform:soc-audio"); 2375MODULE_ALIAS("platform:soc-audio");
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 9ca9c08610fa..493a4e8aa273 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -2,8 +2,7 @@
2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management 2 * soc-dapm.c -- ALSA SoC Dynamic Audio Power Management
3 * 3 *
4 * Copyright 2005 Wolfson Microelectronics PLC. 4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 * 6 *
8 * This program is free software; you can redistribute it and/or modify it 7 * 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 8 * under the terms of the GNU General Public License as published by the
@@ -38,7 +37,6 @@
38#include <linux/bitops.h> 37#include <linux/bitops.h>
39#include <linux/platform_device.h> 38#include <linux/platform_device.h>
40#include <linux/jiffies.h> 39#include <linux/jiffies.h>
41#include <linux/debugfs.h>
42#include <sound/core.h> 40#include <sound/core.h>
43#include <sound/pcm.h> 41#include <sound/pcm.h>
44#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
@@ -55,30 +53,28 @@
55/* dapm power sequences - make this per codec in the future */ 53/* dapm power sequences - make this per codec in the future */
56static int dapm_up_seq[] = { 54static int dapm_up_seq[] = {
57 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, 55 snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic,
58 snd_soc_dapm_mux, snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_pga, 56 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac,
59 snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post 57 snd_soc_dapm_mixer, snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp,
58 snd_soc_dapm_spk, snd_soc_dapm_post
60}; 59};
61static int dapm_down_seq[] = { 60static int dapm_down_seq[] = {
62 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 61 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk,
63 snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, 62 snd_soc_dapm_pga, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic,
64 snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_post 63 snd_soc_dapm_micbias, snd_soc_dapm_mux, snd_soc_dapm_value_mux,
64 snd_soc_dapm_post
65}; 65};
66 66
67static int dapm_status = 1; 67static int dapm_status = 1;
68module_param(dapm_status, int, 0); 68module_param(dapm_status, int, 0);
69MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 69MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
70 70
71static struct dentry *asoc_debugfs; 71static void pop_wait(u32 pop_time)
72
73static u32 pop_time;
74
75static void pop_wait(void)
76{ 72{
77 if (pop_time) 73 if (pop_time)
78 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 74 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
79} 75}
80 76
81static void pop_dbg(const char *fmt, ...) 77static void pop_dbg(u32 pop_time, const char *fmt, ...)
82{ 78{
83 va_list args; 79 va_list args;
84 80
@@ -86,7 +82,7 @@ static void pop_dbg(const char *fmt, ...)
86 82
87 if (pop_time) { 83 if (pop_time) {
88 vprintk(fmt, args); 84 vprintk(fmt, args);
89 pop_wait(); 85 pop_wait(pop_time);
90 } 86 }
91 87
92 va_end(args); 88 va_end(args);
@@ -140,6 +136,25 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
140 } 136 }
141 } 137 }
142 break; 138 break;
139 case snd_soc_dapm_value_mux: {
140 struct soc_enum *e = (struct soc_enum *)
141 w->kcontrols[i].private_value;
142 int val, item;
143
144 val = snd_soc_read(w->codec, e->reg);
145 val = (val >> e->shift_l) & e->mask;
146 for (item = 0; item < e->max; item++) {
147 if (val == e->values[item])
148 break;
149 }
150
151 p->connect = 0;
152 for (i = 0; i < e->max; i++) {
153 if (!(strcmp(p->name, e->texts[i])) && item == i)
154 p->connect = 1;
155 }
156 }
157 break;
143 /* does not effect routing - always connected */ 158 /* does not effect routing - always connected */
144 case snd_soc_dapm_pga: 159 case snd_soc_dapm_pga:
145 case snd_soc_dapm_output: 160 case snd_soc_dapm_output:
@@ -231,10 +246,11 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
231 246
232 change = old != new; 247 change = old != new;
233 if (change) { 248 if (change) {
234 pop_dbg("pop test %s : %s in %d ms\n", widget->name, 249 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
235 widget->power ? "on" : "off", pop_time); 250 widget->name, widget->power ? "on" : "off",
251 codec->pop_time);
236 snd_soc_write(codec, widget->reg, new); 252 snd_soc_write(codec, widget->reg, new);
237 pop_wait(); 253 pop_wait(codec->pop_time);
238 } 254 }
239 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 255 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
240 old, new, change); 256 old, new, change);
@@ -294,7 +310,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
294 struct snd_soc_dapm_widget *w) 310 struct snd_soc_dapm_widget *w)
295{ 311{
296 int i, ret = 0; 312 int i, ret = 0;
297 char name[32]; 313 size_t name_len;
298 struct snd_soc_dapm_path *path; 314 struct snd_soc_dapm_path *path;
299 315
300 /* add kcontrol */ 316 /* add kcontrol */
@@ -308,11 +324,16 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
308 continue; 324 continue;
309 325
310 /* add dapm control with long name */ 326 /* add dapm control with long name */
311 snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name); 327 name_len = 2 + strlen(w->name)
312 path->long_name = kstrdup (name, GFP_KERNEL); 328 + strlen(w->kcontrols[i].name);
329 path->long_name = kmalloc(name_len, GFP_KERNEL);
313 if (path->long_name == NULL) 330 if (path->long_name == NULL)
314 return -ENOMEM; 331 return -ENOMEM;
315 332
333 snprintf(path->long_name, name_len, "%s %s",
334 w->name, w->kcontrols[i].name);
335 path->long_name[name_len - 1] = '\0';
336
316 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 337 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
317 path->long_name); 338 path->long_name);
318 ret = snd_ctl_add(codec->card, path->kcontrol); 339 ret = snd_ctl_add(codec->card, path->kcontrol);
@@ -653,6 +674,7 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
653 case snd_soc_dapm_vmid: 674 case snd_soc_dapm_vmid:
654 continue; 675 continue;
655 case snd_soc_dapm_mux: 676 case snd_soc_dapm_mux:
677 case snd_soc_dapm_value_mux:
656 case snd_soc_dapm_output: 678 case snd_soc_dapm_output:
657 case snd_soc_dapm_input: 679 case snd_soc_dapm_input:
658 case snd_soc_dapm_switch: 680 case snd_soc_dapm_switch:
@@ -822,23 +844,9 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
822 844
823int snd_soc_dapm_sys_add(struct device *dev) 845int snd_soc_dapm_sys_add(struct device *dev)
824{ 846{
825 int ret = 0;
826
827 if (!dapm_status) 847 if (!dapm_status)
828 return 0; 848 return 0;
829 849 return device_create_file(dev, &dev_attr_dapm_widget);
830 ret = device_create_file(dev, &dev_attr_dapm_widget);
831 if (ret != 0)
832 return ret;
833
834 asoc_debugfs = debugfs_create_dir("asoc", NULL);
835 if (!IS_ERR(asoc_debugfs))
836 debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
837 &pop_time);
838 else
839 asoc_debugfs = NULL;
840
841 return 0;
842} 850}
843 851
844static void snd_soc_dapm_sys_remove(struct device *dev) 852static void snd_soc_dapm_sys_remove(struct device *dev)
@@ -846,9 +854,6 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
846 if (dapm_status) { 854 if (dapm_status) {
847 device_remove_file(dev, &dev_attr_dapm_widget); 855 device_remove_file(dev, &dev_attr_dapm_widget);
848 } 856 }
849
850 if (asoc_debugfs)
851 debugfs_remove_recursive(asoc_debugfs);
852} 857}
853 858
854/* free all dapm widgets and resources */ 859/* free all dapm widgets and resources */
@@ -977,6 +982,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
977 path->connect = 1; 982 path->connect = 1;
978 return 0; 983 return 0;
979 case snd_soc_dapm_mux: 984 case snd_soc_dapm_mux:
985 case snd_soc_dapm_value_mux:
980 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 986 ret = dapm_connect_mux(codec, wsource, wsink, path, control,
981 &wsink->kcontrols[0]); 987 &wsink->kcontrols[0]);
982 if (ret != 0) 988 if (ret != 0)
@@ -1008,28 +1014,6 @@ err:
1008} 1014}
1009 1015
1010/** 1016/**
1011 * snd_soc_dapm_connect_input - connect dapm widgets
1012 * @codec: audio codec
1013 * @sink: name of target widget
1014 * @control: mixer control name
1015 * @source: name of source name
1016 *
1017 * Connects 2 dapm widgets together via a named audio path. The sink is
1018 * the widget receiving the audio signal, whilst the source is the sender
1019 * of the audio signal.
1020 *
1021 * This function has been deprecated in favour of snd_soc_dapm_add_routes().
1022 *
1023 * Returns 0 for success else error.
1024 */
1025int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
1026 const char *control, const char *source)
1027{
1028 return snd_soc_dapm_add_route(codec, sink, control, source);
1029}
1030EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
1031
1032/**
1033 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 1017 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1034 * @codec: codec 1018 * @codec: codec
1035 * @route: audio routes 1019 * @route: audio routes
@@ -1086,6 +1070,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1086 dapm_new_mixer(codec, w); 1070 dapm_new_mixer(codec, w);
1087 break; 1071 break;
1088 case snd_soc_dapm_mux: 1072 case snd_soc_dapm_mux:
1073 case snd_soc_dapm_value_mux:
1089 dapm_new_mux(codec, w); 1074 dapm_new_mux(codec, w);
1090 break; 1075 break;
1091 case snd_soc_dapm_adc: 1076 case snd_soc_dapm_adc:
@@ -1116,7 +1101,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
1116/** 1101/**
1117 * snd_soc_dapm_get_volsw - dapm mixer get callback 1102 * snd_soc_dapm_get_volsw - dapm mixer get callback
1118 * @kcontrol: mixer control 1103 * @kcontrol: mixer control
1119 * @uinfo: control element information 1104 * @ucontrol: control element information
1120 * 1105 *
1121 * Callback to get the value of a dapm mixer control. 1106 * Callback to get the value of a dapm mixer control.
1122 * 1107 *
@@ -1161,7 +1146,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_volsw);
1161/** 1146/**
1162 * snd_soc_dapm_put_volsw - dapm mixer set callback 1147 * snd_soc_dapm_put_volsw - dapm mixer set callback
1163 * @kcontrol: mixer control 1148 * @kcontrol: mixer control
1164 * @uinfo: control element information 1149 * @ucontrol: control element information
1165 * 1150 *
1166 * Callback to set the value of a dapm mixer control. 1151 * Callback to set the value of a dapm mixer control.
1167 * 1152 *
@@ -1232,7 +1217,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1232/** 1217/**
1233 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback 1218 * snd_soc_dapm_get_enum_double - dapm enumerated double mixer get callback
1234 * @kcontrol: mixer control 1219 * @kcontrol: mixer control
1235 * @uinfo: control element information 1220 * @ucontrol: control element information
1236 * 1221 *
1237 * Callback to get the value of a dapm enumerated double mixer control. 1222 * Callback to get the value of a dapm enumerated double mixer control.
1238 * 1223 *
@@ -1260,7 +1245,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_double);
1260/** 1245/**
1261 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback 1246 * snd_soc_dapm_put_enum_double - dapm enumerated double mixer set callback
1262 * @kcontrol: mixer control 1247 * @kcontrol: mixer control
1263 * @uinfo: control element information 1248 * @ucontrol: control element information
1264 * 1249 *
1265 * Callback to set the value of a dapm enumerated double mixer control. 1250 * Callback to set the value of a dapm enumerated double mixer control.
1266 * 1251 *
@@ -1313,6 +1298,103 @@ out:
1313EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1298EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1314 1299
1315/** 1300/**
1301 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1302 * callback
1303 * @kcontrol: mixer control
1304 * @ucontrol: control element information
1305 *
1306 * Callback to get the value of a dapm semi enumerated double mixer control.
1307 *
1308 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1309 * used for handling bitfield coded enumeration for example.
1310 *
1311 * Returns 0 for success.
1312 */
1313int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1314 struct snd_ctl_elem_value *ucontrol)
1315{
1316 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1317 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1318 unsigned short reg_val, val, mux;
1319
1320 reg_val = snd_soc_read(widget->codec, e->reg);
1321 val = (reg_val >> e->shift_l) & e->mask;
1322 for (mux = 0; mux < e->max; mux++) {
1323 if (val == e->values[mux])
1324 break;
1325 }
1326 ucontrol->value.enumerated.item[0] = mux;
1327 if (e->shift_l != e->shift_r) {
1328 val = (reg_val >> e->shift_r) & e->mask;
1329 for (mux = 0; mux < e->max; mux++) {
1330 if (val == e->values[mux])
1331 break;
1332 }
1333 ucontrol->value.enumerated.item[1] = mux;
1334 }
1335
1336 return 0;
1337}
1338EXPORT_SYMBOL_GPL(snd_soc_dapm_get_value_enum_double);
1339
1340/**
1341 * snd_soc_dapm_put_value_enum_double - dapm semi enumerated double mixer set
1342 * callback
1343 * @kcontrol: mixer control
1344 * @ucontrol: control element information
1345 *
1346 * Callback to set the value of a dapm semi enumerated double mixer control.
1347 *
1348 * Semi enumerated mixer: the enumerated items are referred as values. Can be
1349 * used for handling bitfield coded enumeration for example.
1350 *
1351 * Returns 0 for success.
1352 */
1353int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1354 struct snd_ctl_elem_value *ucontrol)
1355{
1356 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1357 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1358 unsigned short val, mux;
1359 unsigned short mask;
1360 int ret = 0;
1361
1362 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1363 return -EINVAL;
1364 mux = ucontrol->value.enumerated.item[0];
1365 val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
1366 mask = e->mask << e->shift_l;
1367 if (e->shift_l != e->shift_r) {
1368 if (ucontrol->value.enumerated.item[1] > e->max - 1)
1369 return -EINVAL;
1370 val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
1371 mask |= e->mask << e->shift_r;
1372 }
1373
1374 mutex_lock(&widget->codec->mutex);
1375 widget->value = val;
1376 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
1377 if (widget->event) {
1378 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1379 ret = widget->event(widget,
1380 kcontrol, SND_SOC_DAPM_PRE_REG);
1381 if (ret < 0)
1382 goto out;
1383 }
1384 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1385 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1386 ret = widget->event(widget,
1387 kcontrol, SND_SOC_DAPM_POST_REG);
1388 } else
1389 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1390
1391out:
1392 mutex_unlock(&widget->codec->mutex);
1393 return ret;
1394}
1395EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
1396
1397/**
1316 * snd_soc_dapm_new_control - create new dapm control 1398 * snd_soc_dapm_new_control - create new dapm control
1317 * @codec: audio codec 1399 * @codec: audio codec
1318 * @widget: widget template 1400 * @widget: widget template
@@ -1359,8 +1441,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1359 1441
1360 for (i = 0; i < num; i++) { 1442 for (i = 0; i < num; i++) {
1361 ret = snd_soc_dapm_new_control(codec, widget); 1443 ret = snd_soc_dapm_new_control(codec, widget);
1362 if (ret < 0) 1444 if (ret < 0) {
1445 printk(KERN_ERR
1446 "ASoC: Failed to create DAPM control %s: %d\n",
1447 widget->name, ret);
1363 return ret; 1448 return ret;
1449 }
1364 widget++; 1450 widget++;
1365 } 1451 }
1366 return 0; 1452 return 0;
@@ -1441,11 +1527,11 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1441 enum snd_soc_bias_level level) 1527 enum snd_soc_bias_level level)
1442{ 1528{
1443 struct snd_soc_codec *codec = socdev->codec; 1529 struct snd_soc_codec *codec = socdev->codec;
1444 struct snd_soc_machine *machine = socdev->machine; 1530 struct snd_soc_card *card = socdev->card;
1445 int ret = 0; 1531 int ret = 0;
1446 1532
1447 if (machine->set_bias_level) 1533 if (card->set_bias_level)
1448 ret = machine->set_bias_level(machine, level); 1534 ret = card->set_bias_level(card, level);
1449 if (ret == 0 && codec->set_bias_level) 1535 if (ret == 0 && codec->set_bias_level)
1450 ret = codec->set_bias_level(codec, level); 1536 ret = codec->set_bias_level(codec, level);
1451 1537
@@ -1454,7 +1540,7 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1454 1540
1455/** 1541/**
1456 * snd_soc_dapm_enable_pin - enable pin. 1542 * snd_soc_dapm_enable_pin - enable pin.
1457 * @snd_soc_codec: SoC codec 1543 * @codec: SoC codec
1458 * @pin: pin name 1544 * @pin: pin name
1459 * 1545 *
1460 * Enables input/output pin and it's parents or children widgets iff there is 1546 * Enables input/output pin and it's parents or children widgets iff there is
@@ -1484,6 +1570,26 @@ int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, char *pin)
1484EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 1570EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
1485 1571
1486/** 1572/**
1573 * snd_soc_dapm_nc_pin - permanently disable pin.
1574 * @codec: SoC codec
1575 * @pin: pin name
1576 *
1577 * Marks the specified pin as being not connected, disabling it along
1578 * any parent or child widgets. At present this is identical to
1579 * snd_soc_dapm_disable_pin() but in future it will be extended to do
1580 * additional things such as disabling controls which only affect
1581 * paths through the pin.
1582 *
1583 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
1584 * do any widget power switching.
1585 */
1586int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, char *pin)
1587{
1588 return snd_soc_dapm_set_pin(codec, pin, 0);
1589}
1590EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
1591
1592/**
1487 * snd_soc_dapm_get_pin_status - get audio pin status 1593 * snd_soc_dapm_get_pin_status - get audio pin status
1488 * @codec: audio codec 1594 * @codec: audio codec
1489 * @pin: audio signal pin endpoint (or start point) 1595 * @pin: audio signal pin endpoint (or start point)
@@ -1521,6 +1627,6 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
1521EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 1627EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
1522 1628
1523/* Module information */ 1629/* Module information */
1524MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com"); 1630MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1525MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 1631MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
1526MODULE_LICENSE("GPL"); 1632MODULE_LICENSE("GPL");
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 4ae07e236b36..2b302bbffe73 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/err.h> 12#include <linux/err.h>
13#include <sound/core.h>
13 14
14#ifdef CONFIG_SOUND_OSS_CORE 15#ifdef CONFIG_SOUND_OSS_CORE
15static int __init init_oss_soundcore(void); 16static int __init init_oss_soundcore(void);
@@ -57,7 +58,7 @@ module_exit(cleanup_soundcore);
57/* 58/*
58 * OSS sound core handling. Breaks out sound functions to submodules 59 * OSS sound core handling. Breaks out sound functions to submodules
59 * 60 *
60 * Author: Alan Cox <alan.cox@linux.org> 61 * Author: Alan Cox <alan@lxorguk.ukuu.org.uk>
61 * 62 *
62 * Fixes: 63 * Fixes:
63 * 64 *
@@ -220,9 +221,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
220 else 221 else
221 sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP); 222 sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
222 223
223 device_create_drvdata(sound_class, dev, 224 device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
224 MKDEV(SOUND_MAJOR, s->unit_minor), 225 NULL, s->name+6);
225 NULL, s->name+6);
226 return r; 226 return r;
227 227
228 fail: 228 fail:
@@ -458,7 +458,7 @@ EXPORT_SYMBOL(unregister_sound_mixer);
458 458
459void unregister_sound_midi(int unit) 459void unregister_sound_midi(int unit)
460{ 460{
461 return sound_remove_unit(&chains[2], unit); 461 sound_remove_unit(&chains[2], unit);
462} 462}
463 463
464EXPORT_SYMBOL(unregister_sound_midi); 464EXPORT_SYMBOL(unregister_sound_midi);
@@ -475,7 +475,7 @@ EXPORT_SYMBOL(unregister_sound_midi);
475 475
476void unregister_sound_dsp(int unit) 476void unregister_sound_dsp(int unit)
477{ 477{
478 return sound_remove_unit(&chains[3], unit); 478 sound_remove_unit(&chains[3], unit);
479} 479}
480 480
481 481
@@ -508,7 +508,7 @@ static struct sound_unit *__look_for_unit(int chain, int unit)
508 return NULL; 508 return NULL;
509} 509}
510 510
511int soundcore_open(struct inode *inode, struct file *file) 511static int soundcore_open(struct inode *inode, struct file *file)
512{ 512{
513 int chain; 513 int chain;
514 int unit = iminor(inode); 514 int unit = iminor(inode);
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c
index 49acee0c4840..f87933e48812 100644
--- a/sound/sparc/amd7930.c
+++ b/sound/sparc/amd7930.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Driver for AMD7930 sound chips found on Sparcs. 2 * Driver for AMD7930 sound chips found on Sparcs.
3 * Copyright (C) 2002 David S. Miller <davem@redhat.com> 3 * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
4 * 4 *
5 * Based entirely upon drivers/sbus/audio/amd7930.c which is: 5 * Based entirely upon drivers/sbus/audio/amd7930.c which is:
6 * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) 6 * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu)
@@ -35,6 +35,8 @@
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/moduleparam.h> 37#include <linux/moduleparam.h>
38#include <linux/of.h>
39#include <linux/of_device.h>
38 40
39#include <sound/core.h> 41#include <sound/core.h>
40#include <sound/pcm.h> 42#include <sound/pcm.h>
@@ -44,7 +46,6 @@
44 46
45#include <asm/io.h> 47#include <asm/io.h>
46#include <asm/irq.h> 48#include <asm/irq.h>
47#include <asm/sbus.h>
48#include <asm/prom.h> 49#include <asm/prom.h>
49 50
50static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
@@ -335,8 +336,8 @@ struct snd_amd7930 {
335 int pgain; 336 int pgain;
336 int mgain; 337 int mgain;
337 338
339 struct of_device *op;
338 unsigned int irq; 340 unsigned int irq;
339 unsigned int regs_size;
340 struct snd_amd7930 *next; 341 struct snd_amd7930 *next;
341}; 342};
342 343
@@ -905,13 +906,16 @@ static int __devinit snd_amd7930_mixer(struct snd_amd7930 *amd)
905 906
906static int snd_amd7930_free(struct snd_amd7930 *amd) 907static int snd_amd7930_free(struct snd_amd7930 *amd)
907{ 908{
909 struct of_device *op = amd->op;
910
908 amd7930_idle(amd); 911 amd7930_idle(amd);
909 912
910 if (amd->irq) 913 if (amd->irq)
911 free_irq(amd->irq, amd); 914 free_irq(amd->irq, amd);
912 915
913 if (amd->regs) 916 if (amd->regs)
914 sbus_iounmap(amd->regs, amd->regs_size); 917 of_iounmap(&op->resource[0], amd->regs,
918 resource_size(&op->resource[0]));
915 919
916 kfree(amd); 920 kfree(amd);
917 921
@@ -930,13 +934,12 @@ static struct snd_device_ops snd_amd7930_dev_ops = {
930}; 934};
931 935
932static int __devinit snd_amd7930_create(struct snd_card *card, 936static int __devinit snd_amd7930_create(struct snd_card *card,
933 struct resource *rp, 937 struct of_device *op,
934 unsigned int reg_size,
935 int irq, int dev, 938 int irq, int dev,
936 struct snd_amd7930 **ramd) 939 struct snd_amd7930 **ramd)
937{ 940{
938 unsigned long flags;
939 struct snd_amd7930 *amd; 941 struct snd_amd7930 *amd;
942 unsigned long flags;
940 int err; 943 int err;
941 944
942 *ramd = NULL; 945 *ramd = NULL;
@@ -946,9 +949,10 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
946 949
947 spin_lock_init(&amd->lock); 950 spin_lock_init(&amd->lock);
948 amd->card = card; 951 amd->card = card;
949 amd->regs_size = reg_size; 952 amd->op = op;
950 953
951 amd->regs = sbus_ioremap(rp, 0, amd->regs_size, "amd7930"); 954 amd->regs = of_ioremap(&op->resource[0], 0,
955 resource_size(&op->resource[0]), "amd7930");
952 if (!amd->regs) { 956 if (!amd->regs) {
953 snd_printk("amd7930-%d: Unable to map chip registers.\n", dev); 957 snd_printk("amd7930-%d: Unable to map chip registers.\n", dev);
954 return -EIO; 958 return -EIO;
@@ -997,12 +1001,15 @@ static int __devinit snd_amd7930_create(struct snd_card *card,
997 return 0; 1001 return 0;
998} 1002}
999 1003
1000static int __devinit amd7930_attach_common(struct resource *rp, int irq) 1004static int __devinit amd7930_sbus_probe(struct of_device *op, const struct of_device_id *match)
1001{ 1005{
1006 struct resource *rp = &op->resource[0];
1002 static int dev_num; 1007 static int dev_num;
1003 struct snd_card *card; 1008 struct snd_card *card;
1004 struct snd_amd7930 *amd; 1009 struct snd_amd7930 *amd;
1005 int err; 1010 int err, irq;
1011
1012 irq = op->irqs[0];
1006 1013
1007 if (dev_num >= SNDRV_CARDS) 1014 if (dev_num >= SNDRV_CARDS)
1008 return -ENODEV; 1015 return -ENODEV;
@@ -1023,8 +1030,7 @@ static int __devinit amd7930_attach_common(struct resource *rp, int irq)
1023 (unsigned long long)rp->start, 1030 (unsigned long long)rp->start,
1024 irq); 1031 irq);
1025 1032
1026 if ((err = snd_amd7930_create(card, rp, 1033 if ((err = snd_amd7930_create(card, op,
1027 (rp->end - rp->start) + 1,
1028 irq, dev_num, &amd)) < 0) 1034 irq, dev_num, &amd)) < 0)
1029 goto out_err; 1035 goto out_err;
1030 1036
@@ -1049,43 +1055,7 @@ out_err:
1049 return err; 1055 return err;
1050} 1056}
1051 1057
1052static int __devinit amd7930_obio_attach(struct device_node *dp) 1058static const struct of_device_id amd7930_match[] = {
1053{
1054 const struct linux_prom_registers *regs;
1055 const struct linux_prom_irqs *irqp;
1056 struct resource res, *rp;
1057 int len;
1058
1059 irqp = of_get_property(dp, "intr", &len);
1060 if (!irqp) {
1061 snd_printk("%s: Firmware node lacks IRQ property.\n",
1062 dp->full_name);
1063 return -ENODEV;
1064 }
1065
1066 regs = of_get_property(dp, "reg", &len);
1067 if (!regs) {
1068 snd_printk("%s: Firmware node lacks register property.\n",
1069 dp->full_name);
1070 return -ENODEV;
1071 }
1072
1073 rp = &res;
1074 rp->start = regs->phys_addr;
1075 rp->end = rp->start + regs->reg_size - 1;
1076 rp->flags = IORESOURCE_IO | (regs->which_io & 0xff);
1077
1078 return amd7930_attach_common(rp, irqp->pri);
1079}
1080
1081static int __devinit amd7930_sbus_probe(struct of_device *dev, const struct of_device_id *match)
1082{
1083 struct sbus_dev *sdev = to_sbus_device(&dev->dev);
1084
1085 return amd7930_attach_common(&sdev->resource[0], sdev->irqs[0]);
1086}
1087
1088static struct of_device_id amd7930_match[] = {
1089 { 1059 {
1090 .name = "audio", 1060 .name = "audio",
1091 }, 1061 },
@@ -1100,20 +1070,7 @@ static struct of_platform_driver amd7930_sbus_driver = {
1100 1070
1101static int __init amd7930_init(void) 1071static int __init amd7930_init(void)
1102{ 1072{
1103 struct device_node *dp; 1073 return of_register_driver(&amd7930_sbus_driver, &of_bus_type);
1104
1105 /* Try to find the sun4c "audio" node first. */
1106 dp = of_find_node_by_path("/");
1107 dp = dp->child;
1108 while (dp) {
1109 if (!strcmp(dp->name, "audio"))
1110 amd7930_obio_attach(dp);
1111
1112 dp = dp->sibling;
1113 }
1114
1115 /* Probe each SBUS for amd7930 chips. */
1116 return of_register_driver(&amd7930_sbus_driver, &sbus_bus_type);
1117} 1074}
1118 1075
1119static void __exit amd7930_exit(void) 1076static void __exit amd7930_exit(void)
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c
index 791d2fb821d1..41c387587474 100644
--- a/sound/sparc/cs4231.c
+++ b/sound/sparc/cs4231.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Driver for CS4231 sound chips found on Sparcs. 2 * Driver for CS4231 sound chips found on Sparcs.
3 * Copyright (C) 2002 David S. Miller <davem@redhat.com> 3 * Copyright (C) 2002, 2008 David S. Miller <davem@davemloft.net>
4 * 4 *
5 * Based entirely upon drivers/sbus/audio/cs4231.c which is: 5 * Based entirely upon drivers/sbus/audio/cs4231.c which is:
6 * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu) 6 * Copyright (C) 1996, 1997, 1998 Derrick J Brashear (shadow@andrew.cmu.edu)
@@ -17,7 +17,8 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/irq.h> 18#include <linux/irq.h>
19#include <linux/io.h> 19#include <linux/io.h>
20 20#include <linux/of.h>
21#include <linux/of_device.h>
21 22
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
@@ -29,13 +30,12 @@
29 30
30#ifdef CONFIG_SBUS 31#ifdef CONFIG_SBUS
31#define SBUS_SUPPORT 32#define SBUS_SUPPORT
32#include <asm/sbus.h>
33#endif 33#endif
34 34
35#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64) 35#if defined(CONFIG_PCI) && defined(CONFIG_SPARC64)
36#define EBUS_SUPPORT 36#define EBUS_SUPPORT
37#include <linux/pci.h> 37#include <linux/pci.h>
38#include <asm/ebus.h> 38#include <asm/ebus_dma.h>
39#endif 39#endif
40 40
41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 41static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
@@ -70,8 +70,6 @@ struct cs4231_dma_control {
70 int (*request)(struct cs4231_dma_control *dma_cont, 70 int (*request)(struct cs4231_dma_control *dma_cont,
71 dma_addr_t bus_addr, size_t len); 71 dma_addr_t bus_addr, size_t len);
72 unsigned int (*address)(struct cs4231_dma_control *dma_cont); 72 unsigned int (*address)(struct cs4231_dma_control *dma_cont);
73 void (*preallocate)(struct snd_cs4231 *chip,
74 struct snd_pcm *pcm);
75#ifdef EBUS_SUPPORT 73#ifdef EBUS_SUPPORT
76 struct ebus_dma_info ebus_info; 74 struct ebus_dma_info ebus_info;
77#endif 75#endif
@@ -114,21 +112,12 @@ struct snd_cs4231 {
114 struct mutex mce_mutex; /* mutex for mce register */ 112 struct mutex mce_mutex; /* mutex for mce register */
115 struct mutex open_mutex; /* mutex for ALSA open/close */ 113 struct mutex open_mutex; /* mutex for ALSA open/close */
116 114
117 union { 115 struct of_device *op;
118#ifdef SBUS_SUPPORT
119 struct sbus_dev *sdev;
120#endif
121#ifdef EBUS_SUPPORT
122 struct pci_dev *pdev;
123#endif
124 } dev_u;
125 unsigned int irq[2]; 116 unsigned int irq[2];
126 unsigned int regs_size; 117 unsigned int regs_size;
127 struct snd_cs4231 *next; 118 struct snd_cs4231 *next;
128}; 119};
129 120
130static struct snd_cs4231 *cs4231_list;
131
132/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for 121/* Eventually we can use sound/isa/cs423x/cs4231_lib.c directly, but for
133 * now.... -DaveM 122 * now.... -DaveM
134 */ 123 */
@@ -267,27 +256,19 @@ static unsigned char snd_cs4231_original_image[32] =
267 256
268static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr) 257static u8 __cs4231_readb(struct snd_cs4231 *cp, void __iomem *reg_addr)
269{ 258{
270#ifdef EBUS_SUPPORT
271 if (cp->flags & CS4231_FLAG_EBUS) 259 if (cp->flags & CS4231_FLAG_EBUS)
272 return readb(reg_addr); 260 return readb(reg_addr);
273 else 261 else
274#endif
275#ifdef SBUS_SUPPORT
276 return sbus_readb(reg_addr); 262 return sbus_readb(reg_addr);
277#endif
278} 263}
279 264
280static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val, 265static void __cs4231_writeb(struct snd_cs4231 *cp, u8 val,
281 void __iomem *reg_addr) 266 void __iomem *reg_addr)
282{ 267{
283#ifdef EBUS_SUPPORT
284 if (cp->flags & CS4231_FLAG_EBUS) 268 if (cp->flags & CS4231_FLAG_EBUS)
285 return writeb(val, reg_addr); 269 return writeb(val, reg_addr);
286 else 270 else
287#endif
288#ifdef SBUS_SUPPORT
289 return sbus_writeb(val, reg_addr); 271 return sbus_writeb(val, reg_addr);
290#endif
291} 272}
292 273
293/* 274/*
@@ -1258,7 +1239,9 @@ static int __init snd_cs4231_pcm(struct snd_card *card)
1258 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; 1239 pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX;
1259 strcpy(pcm->name, "CS4231"); 1240 strcpy(pcm->name, "CS4231");
1260 1241
1261 chip->p_dma.preallocate(chip, pcm); 1242 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1243 &chip->op->dev,
1244 64 * 1024, 128 * 1024);
1262 1245
1263 chip->pcm = pcm; 1246 chip->pcm = pcm;
1264 1247
@@ -1627,8 +1610,7 @@ static int __init cs4231_attach_finish(struct snd_card *card)
1627 if (err < 0) 1610 if (err < 0)
1628 goto out_err; 1611 goto out_err;
1629 1612
1630 chip->next = cs4231_list; 1613 dev_set_drvdata(&chip->op->dev, chip);
1631 cs4231_list = chip;
1632 1614
1633 dev++; 1615 dev++;
1634 return 0; 1616 return 0;
@@ -1783,24 +1765,19 @@ static unsigned int sbus_dma_addr(struct cs4231_dma_control *dma_cont)
1783 return sbus_readl(base->regs + base->dir + APCVA); 1765 return sbus_readl(base->regs + base->dir + APCVA);
1784} 1766}
1785 1767
1786static void sbus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
1787{
1788 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_SBUS,
1789 snd_dma_sbus_data(chip->dev_u.sdev),
1790 64 * 1024, 128 * 1024);
1791}
1792
1793/* 1768/*
1794 * Init and exit routines 1769 * Init and exit routines
1795 */ 1770 */
1796 1771
1797static int snd_cs4231_sbus_free(struct snd_cs4231 *chip) 1772static int snd_cs4231_sbus_free(struct snd_cs4231 *chip)
1798{ 1773{
1774 struct of_device *op = chip->op;
1775
1799 if (chip->irq[0]) 1776 if (chip->irq[0])
1800 free_irq(chip->irq[0], chip); 1777 free_irq(chip->irq[0], chip);
1801 1778
1802 if (chip->port) 1779 if (chip->port)
1803 sbus_iounmap(chip->port, chip->regs_size); 1780 of_iounmap(&op->resource[0], chip->port, chip->regs_size);
1804 1781
1805 return 0; 1782 return 0;
1806} 1783}
@@ -1817,7 +1794,7 @@ static struct snd_device_ops snd_cs4231_sbus_dev_ops = {
1817}; 1794};
1818 1795
1819static int __init snd_cs4231_sbus_create(struct snd_card *card, 1796static int __init snd_cs4231_sbus_create(struct snd_card *card,
1820 struct sbus_dev *sdev, 1797 struct of_device *op,
1821 int dev) 1798 int dev)
1822{ 1799{
1823 struct snd_cs4231 *chip = card->private_data; 1800 struct snd_cs4231 *chip = card->private_data;
@@ -1828,13 +1805,13 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1828 spin_lock_init(&chip->p_dma.sbus_info.lock); 1805 spin_lock_init(&chip->p_dma.sbus_info.lock);
1829 mutex_init(&chip->mce_mutex); 1806 mutex_init(&chip->mce_mutex);
1830 mutex_init(&chip->open_mutex); 1807 mutex_init(&chip->open_mutex);
1831 chip->dev_u.sdev = sdev; 1808 chip->op = op;
1832 chip->regs_size = sdev->reg_addrs[0].reg_size; 1809 chip->regs_size = resource_size(&op->resource[0]);
1833 memcpy(&chip->image, &snd_cs4231_original_image, 1810 memcpy(&chip->image, &snd_cs4231_original_image,
1834 sizeof(snd_cs4231_original_image)); 1811 sizeof(snd_cs4231_original_image));
1835 1812
1836 chip->port = sbus_ioremap(&sdev->resource[0], 0, 1813 chip->port = of_ioremap(&op->resource[0], 0,
1837 chip->regs_size, "cs4231"); 1814 chip->regs_size, "cs4231");
1838 if (!chip->port) { 1815 if (!chip->port) {
1839 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev); 1816 snd_printdd("cs4231-%d: Unable to map chip registers.\n", dev);
1840 return -EIO; 1817 return -EIO;
@@ -1849,22 +1826,20 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1849 chip->p_dma.enable = sbus_dma_enable; 1826 chip->p_dma.enable = sbus_dma_enable;
1850 chip->p_dma.request = sbus_dma_request; 1827 chip->p_dma.request = sbus_dma_request;
1851 chip->p_dma.address = sbus_dma_addr; 1828 chip->p_dma.address = sbus_dma_addr;
1852 chip->p_dma.preallocate = sbus_dma_preallocate;
1853 1829
1854 chip->c_dma.prepare = sbus_dma_prepare; 1830 chip->c_dma.prepare = sbus_dma_prepare;
1855 chip->c_dma.enable = sbus_dma_enable; 1831 chip->c_dma.enable = sbus_dma_enable;
1856 chip->c_dma.request = sbus_dma_request; 1832 chip->c_dma.request = sbus_dma_request;
1857 chip->c_dma.address = sbus_dma_addr; 1833 chip->c_dma.address = sbus_dma_addr;
1858 chip->c_dma.preallocate = sbus_dma_preallocate;
1859 1834
1860 if (request_irq(sdev->irqs[0], snd_cs4231_sbus_interrupt, 1835 if (request_irq(op->irqs[0], snd_cs4231_sbus_interrupt,
1861 IRQF_SHARED, "cs4231", chip)) { 1836 IRQF_SHARED, "cs4231", chip)) {
1862 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n", 1837 snd_printdd("cs4231-%d: Unable to grab SBUS IRQ %d\n",
1863 dev, sdev->irqs[0]); 1838 dev, op->irqs[0]);
1864 snd_cs4231_sbus_free(chip); 1839 snd_cs4231_sbus_free(chip);
1865 return -EBUSY; 1840 return -EBUSY;
1866 } 1841 }
1867 chip->irq[0] = sdev->irqs[0]; 1842 chip->irq[0] = op->irqs[0];
1868 1843
1869 if (snd_cs4231_probe(chip) < 0) { 1844 if (snd_cs4231_probe(chip) < 0) {
1870 snd_cs4231_sbus_free(chip); 1845 snd_cs4231_sbus_free(chip);
@@ -1881,9 +1856,9 @@ static int __init snd_cs4231_sbus_create(struct snd_card *card,
1881 return 0; 1856 return 0;
1882} 1857}
1883 1858
1884static int __init cs4231_sbus_attach(struct sbus_dev *sdev) 1859static int __devinit cs4231_sbus_probe(struct of_device *op, const struct of_device_id *match)
1885{ 1860{
1886 struct resource *rp = &sdev->resource[0]; 1861 struct resource *rp = &op->resource[0];
1887 struct snd_card *card; 1862 struct snd_card *card;
1888 int err; 1863 int err;
1889 1864
@@ -1895,9 +1870,9 @@ static int __init cs4231_sbus_attach(struct sbus_dev *sdev)
1895 card->shortname, 1870 card->shortname,
1896 rp->flags & 0xffL, 1871 rp->flags & 0xffL,
1897 (unsigned long long)rp->start, 1872 (unsigned long long)rp->start,
1898 sdev->irqs[0]); 1873 op->irqs[0]);
1899 1874
1900 err = snd_cs4231_sbus_create(card, sdev, dev); 1875 err = snd_cs4231_sbus_create(card, op, dev);
1901 if (err < 0) { 1876 if (err < 0) {
1902 snd_card_free(card); 1877 snd_card_free(card);
1903 return err; 1878 return err;
@@ -1950,30 +1925,25 @@ static unsigned int _ebus_dma_addr(struct cs4231_dma_control *dma_cont)
1950 return ebus_dma_addr(&dma_cont->ebus_info); 1925 return ebus_dma_addr(&dma_cont->ebus_info);
1951} 1926}
1952 1927
1953static void _ebus_dma_preallocate(struct snd_cs4231 *chip, struct snd_pcm *pcm)
1954{
1955 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1956 snd_dma_pci_data(chip->dev_u.pdev),
1957 64*1024, 128*1024);
1958}
1959
1960/* 1928/*
1961 * Init and exit routines 1929 * Init and exit routines
1962 */ 1930 */
1963 1931
1964static int snd_cs4231_ebus_free(struct snd_cs4231 *chip) 1932static int snd_cs4231_ebus_free(struct snd_cs4231 *chip)
1965{ 1933{
1934 struct of_device *op = chip->op;
1935
1966 if (chip->c_dma.ebus_info.regs) { 1936 if (chip->c_dma.ebus_info.regs) {
1967 ebus_dma_unregister(&chip->c_dma.ebus_info); 1937 ebus_dma_unregister(&chip->c_dma.ebus_info);
1968 iounmap(chip->c_dma.ebus_info.regs); 1938 of_iounmap(&op->resource[2], chip->c_dma.ebus_info.regs, 0x10);
1969 } 1939 }
1970 if (chip->p_dma.ebus_info.regs) { 1940 if (chip->p_dma.ebus_info.regs) {
1971 ebus_dma_unregister(&chip->p_dma.ebus_info); 1941 ebus_dma_unregister(&chip->p_dma.ebus_info);
1972 iounmap(chip->p_dma.ebus_info.regs); 1942 of_iounmap(&op->resource[1], chip->p_dma.ebus_info.regs, 0x10);
1973 } 1943 }
1974 1944
1975 if (chip->port) 1945 if (chip->port)
1976 iounmap(chip->port); 1946 of_iounmap(&op->resource[0], chip->port, 0x10);
1977 1947
1978 return 0; 1948 return 0;
1979} 1949}
@@ -1990,7 +1960,7 @@ static struct snd_device_ops snd_cs4231_ebus_dev_ops = {
1990}; 1960};
1991 1961
1992static int __init snd_cs4231_ebus_create(struct snd_card *card, 1962static int __init snd_cs4231_ebus_create(struct snd_card *card,
1993 struct linux_ebus_device *edev, 1963 struct of_device *op,
1994 int dev) 1964 int dev)
1995{ 1965{
1996 struct snd_cs4231 *chip = card->private_data; 1966 struct snd_cs4231 *chip = card->private_data;
@@ -2002,35 +1972,35 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
2002 mutex_init(&chip->mce_mutex); 1972 mutex_init(&chip->mce_mutex);
2003 mutex_init(&chip->open_mutex); 1973 mutex_init(&chip->open_mutex);
2004 chip->flags |= CS4231_FLAG_EBUS; 1974 chip->flags |= CS4231_FLAG_EBUS;
2005 chip->dev_u.pdev = edev->bus->self; 1975 chip->op = op;
2006 memcpy(&chip->image, &snd_cs4231_original_image, 1976 memcpy(&chip->image, &snd_cs4231_original_image,
2007 sizeof(snd_cs4231_original_image)); 1977 sizeof(snd_cs4231_original_image));
2008 strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)"); 1978 strcpy(chip->c_dma.ebus_info.name, "cs4231(capture)");
2009 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1979 chip->c_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2010 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback; 1980 chip->c_dma.ebus_info.callback = snd_cs4231_ebus_capture_callback;
2011 chip->c_dma.ebus_info.client_cookie = chip; 1981 chip->c_dma.ebus_info.client_cookie = chip;
2012 chip->c_dma.ebus_info.irq = edev->irqs[0]; 1982 chip->c_dma.ebus_info.irq = op->irqs[0];
2013 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)"); 1983 strcpy(chip->p_dma.ebus_info.name, "cs4231(play)");
2014 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER; 1984 chip->p_dma.ebus_info.flags = EBUS_DMA_FLAG_USE_EBDMA_HANDLER;
2015 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback; 1985 chip->p_dma.ebus_info.callback = snd_cs4231_ebus_play_callback;
2016 chip->p_dma.ebus_info.client_cookie = chip; 1986 chip->p_dma.ebus_info.client_cookie = chip;
2017 chip->p_dma.ebus_info.irq = edev->irqs[1]; 1987 chip->p_dma.ebus_info.irq = op->irqs[1];
2018 1988
2019 chip->p_dma.prepare = _ebus_dma_prepare; 1989 chip->p_dma.prepare = _ebus_dma_prepare;
2020 chip->p_dma.enable = _ebus_dma_enable; 1990 chip->p_dma.enable = _ebus_dma_enable;
2021 chip->p_dma.request = _ebus_dma_request; 1991 chip->p_dma.request = _ebus_dma_request;
2022 chip->p_dma.address = _ebus_dma_addr; 1992 chip->p_dma.address = _ebus_dma_addr;
2023 chip->p_dma.preallocate = _ebus_dma_preallocate;
2024 1993
2025 chip->c_dma.prepare = _ebus_dma_prepare; 1994 chip->c_dma.prepare = _ebus_dma_prepare;
2026 chip->c_dma.enable = _ebus_dma_enable; 1995 chip->c_dma.enable = _ebus_dma_enable;
2027 chip->c_dma.request = _ebus_dma_request; 1996 chip->c_dma.request = _ebus_dma_request;
2028 chip->c_dma.address = _ebus_dma_addr; 1997 chip->c_dma.address = _ebus_dma_addr;
2029 chip->c_dma.preallocate = _ebus_dma_preallocate;
2030 1998
2031 chip->port = ioremap(edev->resource[0].start, 0x10); 1999 chip->port = of_ioremap(&op->resource[0], 0, 0x10, "cs4231");
2032 chip->p_dma.ebus_info.regs = ioremap(edev->resource[1].start, 0x10); 2000 chip->p_dma.ebus_info.regs =
2033 chip->c_dma.ebus_info.regs = ioremap(edev->resource[2].start, 0x10); 2001 of_ioremap(&op->resource[1], 0, 0x10, "cs4231_pdma");
2002 chip->c_dma.ebus_info.regs =
2003 of_ioremap(&op->resource[2], 0, 0x10, "cs4231_cdma");
2034 if (!chip->port || !chip->p_dma.ebus_info.regs || 2004 if (!chip->port || !chip->p_dma.ebus_info.regs ||
2035 !chip->c_dma.ebus_info.regs) { 2005 !chip->c_dma.ebus_info.regs) {
2036 snd_cs4231_ebus_free(chip); 2006 snd_cs4231_ebus_free(chip);
@@ -2078,7 +2048,7 @@ static int __init snd_cs4231_ebus_create(struct snd_card *card,
2078 return 0; 2048 return 0;
2079} 2049}
2080 2050
2081static int __init cs4231_ebus_attach(struct linux_ebus_device *edev) 2051static int __devinit cs4231_ebus_probe(struct of_device *op, const struct of_device_id *match)
2082{ 2052{
2083 struct snd_card *card; 2053 struct snd_card *card;
2084 int err; 2054 int err;
@@ -2087,12 +2057,12 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
2087 if (err) 2057 if (err)
2088 return err; 2058 return err;
2089 2059
2090 sprintf(card->longname, "%s at 0x%lx, irq %d", 2060 sprintf(card->longname, "%s at 0x%llx, irq %d",
2091 card->shortname, 2061 card->shortname,
2092 edev->resource[0].start, 2062 op->resource[0].start,
2093 edev->irqs[0]); 2063 op->irqs[0]);
2094 2064
2095 err = snd_cs4231_ebus_create(card, edev, dev); 2065 err = snd_cs4231_ebus_create(card, op, dev);
2096 if (err < 0) { 2066 if (err < 0) {
2097 snd_card_free(card); 2067 snd_card_free(card);
2098 return err; 2068 return err;
@@ -2102,68 +2072,57 @@ static int __init cs4231_ebus_attach(struct linux_ebus_device *edev)
2102} 2072}
2103#endif 2073#endif
2104 2074
2105static int __init cs4231_init(void) 2075static int __devinit cs4231_probe(struct of_device *op, const struct of_device_id *match)
2106{ 2076{
2107#ifdef SBUS_SUPPORT
2108 struct sbus_bus *sbus;
2109 struct sbus_dev *sdev;
2110#endif
2111#ifdef EBUS_SUPPORT 2077#ifdef EBUS_SUPPORT
2112 struct linux_ebus *ebus; 2078 if (!strcmp(op->node->parent->name, "ebus"))
2113 struct linux_ebus_device *edev; 2079 return cs4231_ebus_probe(op, match);
2114#endif 2080#endif
2115 int found;
2116
2117 found = 0;
2118
2119#ifdef SBUS_SUPPORT 2081#ifdef SBUS_SUPPORT
2120 for_all_sbusdev(sdev, sbus) { 2082 if (!strcmp(op->node->parent->name, "sbus") ||
2121 if (!strcmp(sdev->prom_name, "SUNW,CS4231")) { 2083 !strcmp(op->node->parent->name, "sbi"))
2122 if (cs4231_sbus_attach(sdev) == 0) 2084 return cs4231_sbus_probe(op, match);
2123 found++;
2124 }
2125 }
2126#endif 2085#endif
2127#ifdef EBUS_SUPPORT 2086 return -ENODEV;
2128 for_each_ebus(ebus) { 2087}
2129 for_each_ebusdev(edev, ebus) {
2130 int match = 0;
2131
2132 if (!strcmp(edev->prom_node->name, "SUNW,CS4231")) {
2133 match = 1;
2134 } else if (!strcmp(edev->prom_node->name, "audio")) {
2135 const char *compat;
2136
2137 compat = of_get_property(edev->prom_node,
2138 "compatible", NULL);
2139 if (compat && !strcmp(compat, "SUNW,CS4231"))
2140 match = 1;
2141 }
2142 2088
2143 if (match && 2089static int __devexit cs4231_remove(struct of_device *op)
2144 cs4231_ebus_attach(edev) == 0) 2090{
2145 found++; 2091 struct snd_cs4231 *chip = dev_get_drvdata(&op->dev);
2146 }
2147 }
2148#endif
2149 2092
2093 snd_card_free(chip->card);
2150 2094
2151 return (found > 0) ? 0 : -EIO; 2095 return 0;
2152} 2096}
2153 2097
2154static void __exit cs4231_exit(void) 2098static const struct of_device_id cs4231_match[] = {
2155{ 2099 {
2156 struct snd_cs4231 *p = cs4231_list; 2100 .name = "SUNW,CS4231",
2101 },
2102 {
2103 .name = "audio",
2104 .compatible = "SUNW,CS4231",
2105 },
2106 {},
2107};
2157 2108
2158 while (p != NULL) { 2109MODULE_DEVICE_TABLE(of, cs4231_match);
2159 struct snd_cs4231 *next = p->next;
2160 2110
2161 snd_card_free(p->card); 2111static struct of_platform_driver cs4231_driver = {
2112 .name = "audio",
2113 .match_table = cs4231_match,
2114 .probe = cs4231_probe,
2115 .remove = __devexit_p(cs4231_remove),
2116};
2162 2117
2163 p = next; 2118static int __init cs4231_init(void)
2164 } 2119{
2120 return of_register_driver(&cs4231_driver, &of_bus_type);
2121}
2165 2122
2166 cs4231_list = NULL; 2123static void __exit cs4231_exit(void)
2124{
2125 of_unregister_driver(&cs4231_driver);
2167} 2126}
2168 2127
2169module_init(cs4231_init); 2128module_init(cs4231_init);
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index c534a2a849fa..23ed6f04a718 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -57,6 +57,7 @@
57#include <linux/delay.h> 57#include <linux/delay.h>
58#include <linux/irq.h> 58#include <linux/irq.h>
59#include <linux/io.h> 59#include <linux/io.h>
60#include <linux/dma-mapping.h>
60 61
61#include <sound/core.h> 62#include <sound/core.h>
62#include <sound/pcm.h> 63#include <sound/pcm.h>
@@ -66,7 +67,7 @@
66#include <sound/initval.h> 67#include <sound/initval.h>
67 68
68#include <linux/of.h> 69#include <linux/of.h>
69#include <asm/sbus.h> 70#include <linux/of_device.h>
70#include <asm/atomic.h> 71#include <asm/atomic.h>
71 72
72MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets"); 73MODULE_AUTHOR("Rudolf Koenig, Brent Baccala and Martin Habets");
@@ -297,7 +298,7 @@ struct dbri_streaminfo {
297/* This structure holds the information for both chips (DBRI & CS4215) */ 298/* This structure holds the information for both chips (DBRI & CS4215) */
298struct snd_dbri { 299struct snd_dbri {
299 int regs_size, irq; /* Needed for unload */ 300 int regs_size, irq; /* Needed for unload */
300 struct sbus_dev *sdev; /* SBUS device info */ 301 struct of_device *op; /* OF device info */
301 spinlock_t lock; 302 spinlock_t lock;
302 303
303 struct dbri_dma *dma; /* Pointer to our DMA block */ 304 struct dbri_dma *dma; /* Pointer to our DMA block */
@@ -2093,14 +2094,15 @@ static int snd_dbri_hw_params(struct snd_pcm_substream *substream,
2093 */ 2094 */
2094 if (info->dvma_buffer == 0) { 2095 if (info->dvma_buffer == 0) {
2095 if (DBRI_STREAMNO(substream) == DBRI_PLAY) 2096 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2096 direction = SBUS_DMA_TODEVICE; 2097 direction = DMA_TO_DEVICE;
2097 else 2098 else
2098 direction = SBUS_DMA_FROMDEVICE; 2099 direction = DMA_FROM_DEVICE;
2099 2100
2100 info->dvma_buffer = sbus_map_single(dbri->sdev, 2101 info->dvma_buffer =
2101 runtime->dma_area, 2102 dma_map_single(&dbri->op->dev,
2102 params_buffer_bytes(hw_params), 2103 runtime->dma_area,
2103 direction); 2104 params_buffer_bytes(hw_params),
2105 direction);
2104 } 2106 }
2105 2107
2106 direction = params_buffer_bytes(hw_params); 2108 direction = params_buffer_bytes(hw_params);
@@ -2121,12 +2123,12 @@ static int snd_dbri_hw_free(struct snd_pcm_substream *substream)
2121 */ 2123 */
2122 if (info->dvma_buffer) { 2124 if (info->dvma_buffer) {
2123 if (DBRI_STREAMNO(substream) == DBRI_PLAY) 2125 if (DBRI_STREAMNO(substream) == DBRI_PLAY)
2124 direction = SBUS_DMA_TODEVICE; 2126 direction = DMA_TO_DEVICE;
2125 else 2127 else
2126 direction = SBUS_DMA_FROMDEVICE; 2128 direction = DMA_FROM_DEVICE;
2127 2129
2128 sbus_unmap_single(dbri->sdev, info->dvma_buffer, 2130 dma_unmap_single(&dbri->op->dev, info->dvma_buffer,
2129 substream->runtime->buffer_size, direction); 2131 substream->runtime->buffer_size, direction);
2130 info->dvma_buffer = 0; 2132 info->dvma_buffer = 0;
2131 } 2133 }
2132 if (info->pipe != -1) { 2134 if (info->pipe != -1) {
@@ -2519,31 +2521,34 @@ static void __devinit snd_dbri_proc(struct snd_card *card)
2519static void snd_dbri_free(struct snd_dbri *dbri); 2521static void snd_dbri_free(struct snd_dbri *dbri);
2520 2522
2521static int __devinit snd_dbri_create(struct snd_card *card, 2523static int __devinit snd_dbri_create(struct snd_card *card,
2522 struct sbus_dev *sdev, 2524 struct of_device *op,
2523 int irq, int dev) 2525 int irq, int dev)
2524{ 2526{
2525 struct snd_dbri *dbri = card->private_data; 2527 struct snd_dbri *dbri = card->private_data;
2526 int err; 2528 int err;
2527 2529
2528 spin_lock_init(&dbri->lock); 2530 spin_lock_init(&dbri->lock);
2529 dbri->sdev = sdev; 2531 dbri->op = op;
2530 dbri->irq = irq; 2532 dbri->irq = irq;
2531 2533
2532 dbri->dma = sbus_alloc_consistent(sdev, sizeof(struct dbri_dma), 2534 dbri->dma = dma_alloc_coherent(&op->dev,
2533 &dbri->dma_dvma); 2535 sizeof(struct dbri_dma),
2536 &dbri->dma_dvma, GFP_ATOMIC);
2537 if (!dbri->dma)
2538 return -ENOMEM;
2534 memset((void *)dbri->dma, 0, sizeof(struct dbri_dma)); 2539 memset((void *)dbri->dma, 0, sizeof(struct dbri_dma));
2535 2540
2536 dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n", 2541 dprintk(D_GEN, "DMA Cmd Block 0x%p (0x%08x)\n",
2537 dbri->dma, dbri->dma_dvma); 2542 dbri->dma, dbri->dma_dvma);
2538 2543
2539 /* Map the registers into memory. */ 2544 /* Map the registers into memory. */
2540 dbri->regs_size = sdev->reg_addrs[0].reg_size; 2545 dbri->regs_size = resource_size(&op->resource[0]);
2541 dbri->regs = sbus_ioremap(&sdev->resource[0], 0, 2546 dbri->regs = of_ioremap(&op->resource[0], 0,
2542 dbri->regs_size, "DBRI Registers"); 2547 dbri->regs_size, "DBRI Registers");
2543 if (!dbri->regs) { 2548 if (!dbri->regs) {
2544 printk(KERN_ERR "DBRI: could not allocate registers\n"); 2549 printk(KERN_ERR "DBRI: could not allocate registers\n");
2545 sbus_free_consistent(sdev, sizeof(struct dbri_dma), 2550 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2546 (void *)dbri->dma, dbri->dma_dvma); 2551 (void *)dbri->dma, dbri->dma_dvma);
2547 return -EIO; 2552 return -EIO;
2548 } 2553 }
2549 2554
@@ -2551,9 +2556,9 @@ static int __devinit snd_dbri_create(struct snd_card *card,
2551 "DBRI audio", dbri); 2556 "DBRI audio", dbri);
2552 if (err) { 2557 if (err) {
2553 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq); 2558 printk(KERN_ERR "DBRI: Can't get irq %d\n", dbri->irq);
2554 sbus_iounmap(dbri->regs, dbri->regs_size); 2559 of_iounmap(&op->resource[0], dbri->regs, dbri->regs_size);
2555 sbus_free_consistent(sdev, sizeof(struct dbri_dma), 2560 dma_free_coherent(&op->dev, sizeof(struct dbri_dma),
2556 (void *)dbri->dma, dbri->dma_dvma); 2561 (void *)dbri->dma, dbri->dma_dvma);
2557 return err; 2562 return err;
2558 } 2563 }
2559 2564
@@ -2577,27 +2582,23 @@ static void snd_dbri_free(struct snd_dbri *dbri)
2577 free_irq(dbri->irq, dbri); 2582 free_irq(dbri->irq, dbri);
2578 2583
2579 if (dbri->regs) 2584 if (dbri->regs)
2580 sbus_iounmap(dbri->regs, dbri->regs_size); 2585 of_iounmap(&dbri->op->resource[0], dbri->regs, dbri->regs_size);
2581 2586
2582 if (dbri->dma) 2587 if (dbri->dma)
2583 sbus_free_consistent(dbri->sdev, sizeof(struct dbri_dma), 2588 dma_free_coherent(&dbri->op->dev,
2584 (void *)dbri->dma, dbri->dma_dvma); 2589 sizeof(struct dbri_dma),
2590 (void *)dbri->dma, dbri->dma_dvma);
2585} 2591}
2586 2592
2587static int __devinit dbri_probe(struct of_device *of_dev, 2593static int __devinit dbri_probe(struct of_device *op, const struct of_device_id *match)
2588 const struct of_device_id *match)
2589{ 2594{
2590 struct sbus_dev *sdev = to_sbus_device(&of_dev->dev);
2591 struct snd_dbri *dbri; 2595 struct snd_dbri *dbri;
2592 int irq;
2593 struct resource *rp; 2596 struct resource *rp;
2594 struct snd_card *card; 2597 struct snd_card *card;
2595 static int dev = 0; 2598 static int dev = 0;
2599 int irq;
2596 int err; 2600 int err;
2597 2601
2598 dprintk(D_GEN, "DBRI: Found %s in SBUS slot %d\n",
2599 sdev->prom_name, sdev->slot);
2600
2601 if (dev >= SNDRV_CARDS) 2602 if (dev >= SNDRV_CARDS)
2602 return -ENODEV; 2603 return -ENODEV;
2603 if (!enable[dev]) { 2604 if (!enable[dev]) {
@@ -2605,7 +2606,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2605 return -ENOENT; 2606 return -ENOENT;
2606 } 2607 }
2607 2608
2608 irq = sdev->irqs[0]; 2609 irq = op->irqs[0];
2609 if (irq <= 0) { 2610 if (irq <= 0) {
2610 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev); 2611 printk(KERN_ERR "DBRI-%d: No IRQ.\n", dev);
2611 return -ENODEV; 2612 return -ENODEV;
@@ -2618,12 +2619,12 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2618 2619
2619 strcpy(card->driver, "DBRI"); 2620 strcpy(card->driver, "DBRI");
2620 strcpy(card->shortname, "Sun DBRI"); 2621 strcpy(card->shortname, "Sun DBRI");
2621 rp = &sdev->resource[0]; 2622 rp = &op->resource[0];
2622 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d", 2623 sprintf(card->longname, "%s at 0x%02lx:0x%016Lx, irq %d",
2623 card->shortname, 2624 card->shortname,
2624 rp->flags & 0xffL, (unsigned long long)rp->start, irq); 2625 rp->flags & 0xffL, (unsigned long long)rp->start, irq);
2625 2626
2626 err = snd_dbri_create(card, sdev, irq, dev); 2627 err = snd_dbri_create(card, op, irq, dev);
2627 if (err < 0) { 2628 if (err < 0) {
2628 snd_card_free(card); 2629 snd_card_free(card);
2629 return err; 2630 return err;
@@ -2640,7 +2641,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2640 2641
2641 /* /proc file handling */ 2642 /* /proc file handling */
2642 snd_dbri_proc(card); 2643 snd_dbri_proc(card);
2643 dev_set_drvdata(&of_dev->dev, card); 2644 dev_set_drvdata(&op->dev, card);
2644 2645
2645 err = snd_card_register(card); 2646 err = snd_card_register(card);
2646 if (err < 0) 2647 if (err < 0)
@@ -2648,7 +2649,7 @@ static int __devinit dbri_probe(struct of_device *of_dev,
2648 2649
2649 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n", 2650 printk(KERN_INFO "audio%d at %p (irq %d) is DBRI(%c)+CS4215(%d)\n",
2650 dev, dbri->regs, 2651 dev, dbri->regs,
2651 dbri->irq, sdev->prom_name[9], dbri->mm.version); 2652 dbri->irq, op->node->name[9], dbri->mm.version);
2652 dev++; 2653 dev++;
2653 2654
2654 return 0; 2655 return 0;
@@ -2659,19 +2660,19 @@ _err:
2659 return err; 2660 return err;
2660} 2661}
2661 2662
2662static int __devexit dbri_remove(struct of_device *dev) 2663static int __devexit dbri_remove(struct of_device *op)
2663{ 2664{
2664 struct snd_card *card = dev_get_drvdata(&dev->dev); 2665 struct snd_card *card = dev_get_drvdata(&op->dev);
2665 2666
2666 snd_dbri_free(card->private_data); 2667 snd_dbri_free(card->private_data);
2667 snd_card_free(card); 2668 snd_card_free(card);
2668 2669
2669 dev_set_drvdata(&dev->dev, NULL); 2670 dev_set_drvdata(&op->dev, NULL);
2670 2671
2671 return 0; 2672 return 0;
2672} 2673}
2673 2674
2674static struct of_device_id dbri_match[] = { 2675static const struct of_device_id dbri_match[] = {
2675 { 2676 {
2676 .name = "SUNW,DBRIe", 2677 .name = "SUNW,DBRIe",
2677 }, 2678 },
@@ -2693,7 +2694,7 @@ static struct of_platform_driver dbri_sbus_driver = {
2693/* Probe for the dbri chip and then attach the driver. */ 2694/* Probe for the dbri chip and then attach the driver. */
2694static int __init dbri_init(void) 2695static int __init dbri_init(void)
2695{ 2696{
2696 return of_register_driver(&dbri_sbus_driver, &sbus_bus_type); 2697 return of_register_driver(&dbri_sbus_driver, &of_bus_type);
2697} 2698}
2698 2699
2699static void __exit dbri_exit(void) 2700static void __exit dbri_exit(void)
diff --git a/sound/usb/caiaq/caiaq-control.c b/sound/usb/caiaq/caiaq-control.c
index 798ca124da58..ccd763dd7167 100644
--- a/sound/usb/caiaq/caiaq-control.c
+++ b/sound/usb/caiaq/caiaq-control.c
@@ -247,69 +247,56 @@ static struct caiaq_controller a8dj_controller[] = {
247 { "Software lock", 40 } 247 { "Software lock", 40 }
248}; 248};
249 249
250int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) 250static int __devinit add_controls(struct caiaq_controller *c, int num,
251 struct snd_usb_caiaqdev *dev)
251{ 252{
252 int i; 253 int i, ret;
253 struct snd_kcontrol *kc; 254 struct snd_kcontrol *kc;
254 255
256 for (i = 0; i < num; i++, c++) {
257 kcontrol_template.name = c->name;
258 kcontrol_template.private_value = c->index;
259 kc = snd_ctl_new1(&kcontrol_template, dev);
260 ret = snd_ctl_add(dev->chip.card, kc);
261 if (ret < 0)
262 return ret;
263 }
264
265 return 0;
266}
267
268int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
269{
270 int ret = 0;
271
255 switch (dev->chip.usb_id) { 272 switch (dev->chip.usb_id) {
256 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 273 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
257 for (i = 0; i < ARRAY_SIZE(ak1_controller); i++) { 274 ret = add_controls(ak1_controller,
258 struct caiaq_controller *c = ak1_controller + i; 275 ARRAY_SIZE(ak1_controller), dev);
259 kcontrol_template.name = c->name;
260 kcontrol_template.private_value = c->index;
261 kc = snd_ctl_new1(&kcontrol_template, dev);
262 snd_ctl_add(dev->chip.card, kc);
263 }
264
265 break; 276 break;
266 277
267 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
268 for (i = 0; i < ARRAY_SIZE(rk2_controller); i++) { 279 ret = add_controls(rk2_controller,
269 struct caiaq_controller *c = rk2_controller + i; 280 ARRAY_SIZE(rk2_controller), dev);
270 kcontrol_template.name = c->name;
271 kcontrol_template.private_value = c->index;
272 kc = snd_ctl_new1(&kcontrol_template, dev);
273 snd_ctl_add(dev->chip.card, kc);
274 }
275
276 break; 281 break;
277 282
278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 283 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
279 for (i = 0; i < ARRAY_SIZE(rk3_controller); i++) { 284 ret = add_controls(rk3_controller,
280 struct caiaq_controller *c = rk3_controller + i; 285 ARRAY_SIZE(rk3_controller), dev);
281 kcontrol_template.name = c->name;
282 kcontrol_template.private_value = c->index;
283 kc = snd_ctl_new1(&kcontrol_template, dev);
284 snd_ctl_add(dev->chip.card, kc);
285 }
286
287 break; 286 break;
288 287
289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 288 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
291 for (i = 0; i < ARRAY_SIZE(kore_controller); i++) { 290 ret = add_controls(kore_controller,
292 struct caiaq_controller *c = kore_controller + i; 291 ARRAY_SIZE(kore_controller), dev);
293 kcontrol_template.name = c->name;
294 kcontrol_template.private_value = c->index;
295 kc = snd_ctl_new1(&kcontrol_template, dev);
296 snd_ctl_add(dev->chip.card, kc);
297 }
298
299 break; 292 break;
300 293
301 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): 294 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
302 for (i = 0; i < ARRAY_SIZE(a8dj_controller); i++) { 295 ret = add_controls(a8dj_controller,
303 struct caiaq_controller *c = a8dj_controller + i; 296 ARRAY_SIZE(a8dj_controller), dev);
304 kcontrol_template.name = c->name;
305 kcontrol_template.private_value = c->index;
306 kc = snd_ctl_new1(&kcontrol_template, dev);
307 snd_ctl_add(dev->chip.card, kc);
308 }
309
310 break; 297 break;
311 } 298 }
312 299
313 return 0; 300 return ret;
314} 301}
315 302
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 83175083e50f..41c36b055f6b 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -42,7 +42,7 @@
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.8"); 45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.10");
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},"
@@ -446,7 +446,7 @@ static int __devinit snd_probe(struct usb_interface *intf,
446 if (!card) 446 if (!card)
447 return -ENOMEM; 447 return -ENOMEM;
448 448
449 dev_set_drvdata(&intf->dev, card); 449 usb_set_intfdata(intf, card);
450 ret = init_card(caiaqdev(card)); 450 ret = init_card(caiaqdev(card));
451 if (ret < 0) { 451 if (ret < 0) {
452 log("unable to init card! (ret=%d)\n", ret); 452 log("unable to init card! (ret=%d)\n", ret);
@@ -460,7 +460,7 @@ static int __devinit snd_probe(struct usb_interface *intf,
460static void snd_disconnect(struct usb_interface *intf) 460static void snd_disconnect(struct usb_interface *intf)
461{ 461{
462 struct snd_usb_caiaqdev *dev; 462 struct snd_usb_caiaqdev *dev;
463 struct snd_card *card = dev_get_drvdata(&intf->dev); 463 struct snd_card *card = usb_get_intfdata(intf);
464 464
465 debug("%s(%p)\n", __func__, intf); 465 debug("%s(%p)\n", __func__, intf);
466 466
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
index f9fbdbae269d..ab56e738c5fc 100644
--- a/sound/usb/caiaq/caiaq-device.h
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -75,6 +75,7 @@ struct snd_usb_caiaqdev {
75 wait_queue_head_t ep1_wait_queue; 75 wait_queue_head_t ep1_wait_queue;
76 wait_queue_head_t prepare_wait_queue; 76 wait_queue_head_t prepare_wait_queue;
77 int spec_received, audio_parm_answer; 77 int spec_received, audio_parm_answer;
78 int midi_out_active;
78 79
79 char vendor_name[CAIAQ_USB_STR_LEN]; 80 char vendor_name[CAIAQ_USB_STR_LEN];
80 char product_name[CAIAQ_USB_STR_LEN]; 81 char product_name[CAIAQ_USB_STR_LEN];
diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c
index 30b57f97c6e4..f19fd360c936 100644
--- a/sound/usb/caiaq/caiaq-midi.c
+++ b/sound/usb/caiaq/caiaq-midi.c
@@ -59,6 +59,11 @@ static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substrea
59 59
60static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream) 60static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
61{ 61{
62 struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
63 if (dev->midi_out_active) {
64 usb_kill_urb(&dev->midi_out_urb);
65 dev->midi_out_active = 0;
66 }
62 return 0; 67 return 0;
63} 68}
64 69
@@ -69,7 +74,8 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
69 74
70 dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE; 75 dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
71 dev->midi_out_buf[1] = 0; /* port */ 76 dev->midi_out_buf[1] = 0; /* port */
72 len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3); 77 len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3,
78 EP1_BUFSIZE - 3);
73 79
74 if (len <= 0) 80 if (len <= 0)
75 return; 81 return;
@@ -79,24 +85,24 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
79 85
80 ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC); 86 ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
81 if (ret < 0) 87 if (ret < 0)
82 log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n", 88 log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
83 substream, ret); 89 "ret=%d, len=%d\n",
90 substream, ret, len);
91 else
92 dev->midi_out_active = 1;
84} 93}
85 94
86static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up) 95static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
87{ 96{
88 struct snd_usb_caiaqdev *dev = substream->rmidi->private_data; 97 struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
89 98
90 if (dev->midi_out_substream != NULL) 99 if (up) {
91 return; 100 dev->midi_out_substream = substream;
92 101 if (!dev->midi_out_active)
93 if (!up) { 102 snd_usb_caiaq_midi_send(dev, substream);
103 } else {
94 dev->midi_out_substream = NULL; 104 dev->midi_out_substream = NULL;
95 return;
96 } 105 }
97
98 dev->midi_out_substream = substream;
99 snd_usb_caiaq_midi_send(dev, substream);
100} 106}
101 107
102 108
@@ -161,16 +167,14 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
161void snd_usb_caiaq_midi_output_done(struct urb* urb) 167void snd_usb_caiaq_midi_output_done(struct urb* urb)
162{ 168{
163 struct snd_usb_caiaqdev *dev = urb->context; 169 struct snd_usb_caiaqdev *dev = urb->context;
164 char *buf = urb->transfer_buffer;
165 170
171 dev->midi_out_active = 0;
166 if (urb->status != 0) 172 if (urb->status != 0)
167 return; 173 return;
168 174
169 if (!dev->midi_out_substream) 175 if (!dev->midi_out_substream)
170 return; 176 return;
171 177
172 snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);
173 dev->midi_out_substream = NULL;
174 snd_usb_caiaq_midi_send(dev, dev->midi_out_substream); 178 snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
175} 179}
176 180
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index bbd70d5814a0..c709b9563226 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -3709,7 +3709,7 @@ static int usb_audio_probe(struct usb_interface *intf,
3709 void *chip; 3709 void *chip;
3710 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id); 3710 chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
3711 if (chip) { 3711 if (chip) {
3712 dev_set_drvdata(&intf->dev, chip); 3712 usb_set_intfdata(intf, chip);
3713 return 0; 3713 return 0;
3714 } else 3714 } else
3715 return -EIO; 3715 return -EIO;
@@ -3718,13 +3718,13 @@ static int usb_audio_probe(struct usb_interface *intf,
3718static void usb_audio_disconnect(struct usb_interface *intf) 3718static void usb_audio_disconnect(struct usb_interface *intf)
3719{ 3719{
3720 snd_usb_audio_disconnect(interface_to_usbdev(intf), 3720 snd_usb_audio_disconnect(interface_to_usbdev(intf),
3721 dev_get_drvdata(&intf->dev)); 3721 usb_get_intfdata(intf));
3722} 3722}
3723 3723
3724#ifdef CONFIG_PM 3724#ifdef CONFIG_PM
3725static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) 3725static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
3726{ 3726{
3727 struct snd_usb_audio *chip = dev_get_drvdata(&intf->dev); 3727 struct snd_usb_audio *chip = usb_get_intfdata(intf);
3728 struct list_head *p; 3728 struct list_head *p;
3729 struct snd_usb_stream *as; 3729 struct snd_usb_stream *as;
3730 3730
@@ -3744,7 +3744,7 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
3744 3744
3745static int usb_audio_resume(struct usb_interface *intf) 3745static int usb_audio_resume(struct usb_interface *intf)
3746{ 3746{
3747 struct snd_usb_audio *chip = dev_get_drvdata(&intf->dev); 3747 struct snd_usb_audio *chip = usb_get_intfdata(intf);
3748 3748
3749 if (chip == (void *)-1L) 3749 if (chip == (void *)-1L)
3750 return 0; 3750 return 0;
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 5962e4b84423..320641ab5be7 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -880,7 +880,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
880 snd_rawmidi_transmit_ack(substream, 1); 880 snd_rawmidi_transmit_ack(substream, 1);
881 return; 881 return;
882 } 882 }
883 tasklet_hi_schedule(&port->ep->tasklet); 883 tasklet_schedule(&port->ep->tasklet);
884 } 884 }
885} 885}
886 886
@@ -1392,8 +1392,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1392 for (i = 0; i < intfd->bNumEndpoints; ++i) { 1392 for (i = 0; i < intfd->bNumEndpoints; ++i) {
1393 hostep = &hostif->endpoint[i]; 1393 hostep = &hostif->endpoint[i];
1394 ep = get_ep_desc(hostep); 1394 ep = get_ep_desc(hostep);
1395 if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK && 1395 if (!usb_endpoint_xfer_bulk(ep) && !usb_endpoint_xfer_int(ep))
1396 (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
1397 continue; 1396 continue;
1398 ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra; 1397 ms_ep = (struct usb_ms_endpoint_descriptor*)hostep->extra;
1399 if (hostep->extralen < 4 || 1398 if (hostep->extralen < 4 ||
@@ -1401,15 +1400,15 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1401 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT || 1400 ms_ep->bDescriptorType != USB_DT_CS_ENDPOINT ||
1402 ms_ep->bDescriptorSubtype != MS_GENERAL) 1401 ms_ep->bDescriptorSubtype != MS_GENERAL)
1403 continue; 1402 continue;
1404 if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { 1403 if (usb_endpoint_dir_out(ep)) {
1405 if (endpoints[epidx].out_ep) { 1404 if (endpoints[epidx].out_ep) {
1406 if (++epidx >= MIDI_MAX_ENDPOINTS) { 1405 if (++epidx >= MIDI_MAX_ENDPOINTS) {
1407 snd_printk(KERN_WARNING "too many endpoints\n"); 1406 snd_printk(KERN_WARNING "too many endpoints\n");
1408 break; 1407 break;
1409 } 1408 }
1410 } 1409 }
1411 endpoints[epidx].out_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1410 endpoints[epidx].out_ep = usb_endpoint_num(ep);
1412 if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) 1411 if (usb_endpoint_xfer_int(ep))
1413 endpoints[epidx].out_interval = ep->bInterval; 1412 endpoints[epidx].out_interval = ep->bInterval;
1414 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1413 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
1415 /* 1414 /*
@@ -1428,8 +1427,8 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1428 break; 1427 break;
1429 } 1428 }
1430 } 1429 }
1431 endpoints[epidx].in_ep = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1430 endpoints[epidx].in_ep = usb_endpoint_num(ep);
1432 if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) 1431 if (usb_endpoint_xfer_int(ep))
1433 endpoints[epidx].in_interval = ep->bInterval; 1432 endpoints[epidx].in_interval = ep->bInterval;
1434 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1433 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW)
1435 endpoints[epidx].in_interval = 1; 1434 endpoints[epidx].in_interval = 1;
@@ -1495,20 +1494,20 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
1495 1494
1496 for (i = 0; i < intfd->bNumEndpoints; ++i) { 1495 for (i = 0; i < intfd->bNumEndpoints; ++i) {
1497 epd = get_endpoint(hostif, i); 1496 epd = get_endpoint(hostif, i);
1498 if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK && 1497 if (!usb_endpoint_xfer_bulk(epd) &&
1499 (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) 1498 !usb_endpoint_xfer_int(epd))
1500 continue; 1499 continue;
1501 if (out_eps < max_endpoints && 1500 if (out_eps < max_endpoints &&
1502 (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { 1501 usb_endpoint_dir_out(epd)) {
1503 endpoint[out_eps].out_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1502 endpoint[out_eps].out_ep = usb_endpoint_num(epd);
1504 if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) 1503 if (usb_endpoint_xfer_int(epd))
1505 endpoint[out_eps].out_interval = epd->bInterval; 1504 endpoint[out_eps].out_interval = epd->bInterval;
1506 ++out_eps; 1505 ++out_eps;
1507 } 1506 }
1508 if (in_eps < max_endpoints && 1507 if (in_eps < max_endpoints &&
1509 (epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { 1508 usb_endpoint_dir_in(epd)) {
1510 endpoint[in_eps].in_ep = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1509 endpoint[in_eps].in_ep = usb_endpoint_num(epd);
1511 if ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) 1510 if (usb_endpoint_xfer_int(epd))
1512 endpoint[in_eps].in_interval = epd->bInterval; 1511 endpoint[in_eps].in_interval = epd->bInterval;
1513 ++in_eps; 1512 ++in_eps;
1514 } 1513 }
@@ -1607,21 +1606,19 @@ static int snd_usbmidi_create_endpoints_midiman(struct snd_usb_midi* umidi,
1607 } 1606 }
1608 1607
1609 epd = get_endpoint(hostif, 0); 1608 epd = get_endpoint(hostif, 0);
1610 if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN || 1609 if (!usb_endpoint_dir_in(epd) || !usb_endpoint_xfer_int(epd)) {
1611 (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
1612 snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n"); 1610 snd_printdd(KERN_ERR "endpoint[0] isn't interrupt\n");
1613 return -ENXIO; 1611 return -ENXIO;
1614 } 1612 }
1615 epd = get_endpoint(hostif, 2); 1613 epd = get_endpoint(hostif, 2);
1616 if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || 1614 if (!usb_endpoint_dir_out(epd) || !usb_endpoint_xfer_bulk(epd)) {
1617 (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) {
1618 snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n"); 1615 snd_printdd(KERN_ERR "endpoint[2] isn't bulk output\n");
1619 return -ENXIO; 1616 return -ENXIO;
1620 } 1617 }
1621 if (endpoint->out_cables > 0x0001) { 1618 if (endpoint->out_cables > 0x0001) {
1622 epd = get_endpoint(hostif, 4); 1619 epd = get_endpoint(hostif, 4);
1623 if ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_OUT || 1620 if (!usb_endpoint_dir_out(epd) ||
1624 (epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_BULK) { 1621 !usb_endpoint_xfer_bulk(epd)) {
1625 snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n"); 1622 snd_printdd(KERN_ERR "endpoint[4] isn't bulk output\n");
1626 return -ENXIO; 1623 return -ENXIO;
1627 } 1624 }
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index a49246113e75..00397c8a765b 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1755,11 +1755,10 @@ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer)
1755 if (get_iface_desc(hostif)->bNumEndpoints < 1) 1755 if (get_iface_desc(hostif)->bNumEndpoints < 1)
1756 return 0; 1756 return 0;
1757 ep = get_endpoint(hostif, 0); 1757 ep = get_endpoint(hostif, 0);
1758 if ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) != USB_DIR_IN || 1758 if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep))
1759 (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT)
1760 return 0; 1759 return 0;
1761 1760
1762 epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1761 epnum = usb_endpoint_num(ep);
1763 buffer_length = le16_to_cpu(ep->wMaxPacketSize); 1762 buffer_length = le16_to_cpu(ep->wMaxPacketSize);
1764 transfer_buffer = kmalloc(buffer_length, GFP_KERNEL); 1763 transfer_buffer = kmalloc(buffer_length, GFP_KERNEL);
1765 if (!transfer_buffer) 1764 if (!transfer_buffer)
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 69689e79bf79..92115755d98e 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1480,6 +1480,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1480 } 1480 }
1481 } 1481 }
1482}, 1482},
1483{
1484 /* Advanced modes of the Edirol UA-25EX.
1485 * For the standard mode, UA-25EX has ID 0582:00e7, which
1486 * offers only 16-bit PCM at 44.1 kHz and no MIDI.
1487 */
1488 USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e6),
1489 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1490 .vendor_name = "EDIROL",
1491 .product_name = "UA-25EX",
1492 .ifnum = QUIRK_ANY_INTERFACE,
1493 .type = QUIRK_COMPOSITE,
1494 .data = (const struct snd_usb_audio_quirk[]) {
1495 {
1496 .ifnum = 0,
1497 .type = QUIRK_AUDIO_EDIROL_UAXX
1498 },
1499 {
1500 .ifnum = 1,
1501 .type = QUIRK_AUDIO_EDIROL_UAXX
1502 },
1503 {
1504 .ifnum = 2,
1505 .type = QUIRK_AUDIO_EDIROL_UAXX
1506 },
1507 {
1508 .ifnum = -1
1509 }
1510 }
1511 }
1512},
1483 1513
1484/* Guillemot devices */ 1514/* Guillemot devices */
1485{ 1515{
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index b441fe2cd190..73e59f4403a4 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -118,12 +118,11 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
118 void *vaddr; 118 void *vaddr;
119 struct us122l *us122l = area->vm_private_data; 119 struct us122l *us122l = area->vm_private_data;
120 struct usb_stream *s; 120 struct usb_stream *s;
121 int vm_f = VM_FAULT_SIGBUS;
122 121
123 mutex_lock(&us122l->mutex); 122 mutex_lock(&us122l->mutex);
124 s = us122l->sk.s; 123 s = us122l->sk.s;
125 if (!s) 124 if (!s)
126 goto out; 125 goto unlock;
127 126
128 offset = vmf->pgoff << PAGE_SHIFT; 127 offset = vmf->pgoff << PAGE_SHIFT;
129 if (offset < PAGE_ALIGN(s->read_size)) 128 if (offset < PAGE_ALIGN(s->read_size))
@@ -131,7 +130,7 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
131 else { 130 else {
132 offset -= PAGE_ALIGN(s->read_size); 131 offset -= PAGE_ALIGN(s->read_size);
133 if (offset >= PAGE_ALIGN(s->write_size)) 132 if (offset >= PAGE_ALIGN(s->write_size))
134 goto out; 133 goto unlock;
135 134
136 vaddr = us122l->sk.write_page + offset; 135 vaddr = us122l->sk.write_page + offset;
137 } 136 }
@@ -141,9 +140,11 @@ static int usb_stream_hwdep_vm_fault(struct vm_area_struct *area,
141 mutex_unlock(&us122l->mutex); 140 mutex_unlock(&us122l->mutex);
142 141
143 vmf->page = page; 142 vmf->page = page;
144 vm_f = 0; 143
145out: 144 return 0;
146 return vm_f; 145unlock:
146 mutex_unlock(&us122l->mutex);
147 return VM_FAULT_SIGBUS;
147} 148}
148 149
149static void usb_stream_hwdep_vm_close(struct vm_area_struct *area) 150static void usb_stream_hwdep_vm_close(struct vm_area_struct *area)
@@ -588,7 +589,7 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
588 struct us122l *us122l; 589 struct us122l *us122l;
589 struct list_head *p; 590 struct list_head *p;
590 591
591 card = dev_get_drvdata(&intf->dev); 592 card = usb_get_intfdata(intf);
592 if (!card) 593 if (!card)
593 return 0; 594 return 0;
594 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 595 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -614,7 +615,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
614 struct list_head *p; 615 struct list_head *p;
615 int err; 616 int err;
616 617
617 card = dev_get_drvdata(&intf->dev); 618 card = usb_get_intfdata(intf);
618 if (!card) 619 if (!card)
619 return 0; 620 return 0;
620 621
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index ff23cc1ce3b9..70b96355ca4c 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -276,7 +276,8 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
276 } 276 }
277} 277}
278 278
279int usb_stream_prepare_playback(struct usb_stream_kernel *sk, struct urb *inurb) 279static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
280 struct urb *inurb)
280{ 281{
281 struct usb_stream *s = sk->s; 282 struct usb_stream *s = sk->s;
282 struct urb *io; 283 struct urb *io;
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index e5981a630314..11639bd72a51 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -238,7 +238,7 @@ static void i_usX2Y_In04Int(struct urb *urb)
238 send = 0; 238 send = 0;
239 for (j = 0; j < URBS_AsyncSeq && !err; ++j) 239 for (j = 0; j < URBS_AsyncSeq && !err; ++j)
240 if (0 == usX2Y->AS04.urb[j]->status) { 240 if (0 == usX2Y->AS04.urb[j]->status) {
241 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more then 1 p4out is new, 1 gets lost. 241 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
242 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev, 242 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev,
243 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol, 243 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol,
244 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, 244 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
@@ -392,7 +392,7 @@ static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_i
392 void *chip; 392 void *chip;
393 chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id); 393 chip = usX2Y_usb_probe(interface_to_usbdev(intf), intf, id);
394 if (chip) { 394 if (chip) {
395 dev_set_drvdata(&intf->dev, chip); 395 usb_set_intfdata(intf, chip);
396 return 0; 396 return 0;
397 } else 397 } else
398 return -EIO; 398 return -EIO;
@@ -401,7 +401,7 @@ static int snd_usX2Y_probe(struct usb_interface *intf, const struct usb_device_i
401static void snd_usX2Y_disconnect(struct usb_interface *intf) 401static void snd_usX2Y_disconnect(struct usb_interface *intf)
402{ 402{
403 usX2Y_usb_disconnect(interface_to_usbdev(intf), 403 usX2Y_usb_disconnect(interface_to_usbdev(intf),
404 dev_get_drvdata(&intf->dev)); 404 usb_get_intfdata(intf));
405} 405}
406 406
407MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table); 407MODULE_DEVICE_TABLE(usb, snd_usX2Y_usb_id_table);