aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/ALSA-Configuration.txt24
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt33
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt64
-rw-r--r--MAINTAINERS3
-rw-r--r--Makefile2
-rw-r--r--arch/arm/mach-omap2/mcbsp.c5
-rw-r--r--arch/arm/mach-pxa/include/mach/audio.h3
-rw-r--r--arch/arm/plat-omap/dma.c10
-rw-r--r--arch/arm/plat-omap/include/mach/mcbsp.h51
-rw-r--r--arch/arm/plat-omap/mcbsp.c401
-rw-r--r--arch/arm/plat-s3c/include/plat/audio-simtec.h37
-rw-r--r--arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h5
-rw-r--r--arch/ia64/kernel/dma-mapping.c4
-rw-r--r--arch/ia64/lib/ip_fast_csum.S8
-rw-r--r--arch/parisc/kernel/traps.c2
-rw-r--r--arch/powerpc/kernel/power7-pmu.c6
-rw-r--r--arch/powerpc/sysdev/xilinx_intc.c1
-rw-r--r--arch/sparc/kernel/irq_64.c2
-rw-r--r--arch/sparc/kernel/nmi.c2
-rw-r--r--arch/sparc/prom/misc_64.c2
-rw-r--r--arch/sparc/prom/printf.c7
-rw-r--r--arch/x86/kernel/apic/probe_64.c10
-rw-r--r--arch/x86/xen/enlighten.c2
-rw-r--r--block/blk-sysfs.c2
-rw-r--r--crypto/algapi.c11
-rw-r--r--drivers/acpi/acpica/exstorob.c12
-rw-r--r--drivers/acpi/video.c7
-rw-r--r--drivers/ata/ata_piix.c14
-rw-r--r--drivers/block/aoe/aoe.h2
-rw-r--r--drivers/block/aoe/aoeblk.c12
-rw-r--r--drivers/block/aoe/aoedev.c1
-rw-r--r--drivers/char/agp/intel-agp.c8
-rw-r--r--drivers/char/n_tty.c3
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/cpufreq/cpufreq.c95
-rw-r--r--drivers/firewire/core-iso.c4
-rw-r--r--drivers/firewire/ohci.c14
-rw-r--r--drivers/firewire/sbp2.c8
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h7
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c99
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c51
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c11
-rw-r--r--drivers/gpu/drm/i915/intel_display.c87
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c12
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h21
-rw-r--r--drivers/gpu/drm/i915/intel_dvo.c6
-rw-r--r--drivers/gpu/drm/i915/intel_hdmi.c18
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c2
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c13
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c3
-rw-r--r--drivers/gpu/drm/radeon/r300.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_asic.h6
-rw-r--r--drivers/gpu/drm/radeon/rs600.c65
-rw-r--r--drivers/gpu/drm/radeon/rs690.c64
-rw-r--r--drivers/gpu/drm/radeon/rv515.c2
-rw-r--r--drivers/ide/ide-cs.c1
-rw-r--r--drivers/input/keyboard/atkbd.c35
-rw-r--r--drivers/input/serio/i8042-x86ia64io.h8
-rw-r--r--drivers/md/dm-exception-store.c13
-rw-r--r--drivers/md/dm-exception-store.h4
-rw-r--r--drivers/md/dm-log-userspace-base.c39
-rw-r--r--drivers/md/dm-log-userspace-transfer.c6
-rw-r--r--drivers/md/dm-log-userspace-transfer.h2
-rw-r--r--drivers/md/dm-raid1.c8
-rw-r--r--drivers/md/dm-snap-persistent.c88
-rw-r--r--drivers/md/dm-snap.c23
-rw-r--r--drivers/md/dm-stripe.c13
-rw-r--r--drivers/md/dm-table.c51
-rw-r--r--drivers/md/dm.c15
-rw-r--r--drivers/media/dvb/siano/Kconfig40
-rw-r--r--drivers/media/dvb/siano/Makefile9
-rw-r--r--drivers/media/dvb/siano/smsdvb.c44
-rw-r--r--drivers/media/dvb/siano/smssdio.c54
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c44
-rw-r--r--drivers/media/video/em28xx/em28xx.h1
-rw-r--r--drivers/media/video/gspca/Kconfig2
-rw-r--r--drivers/media/video/zr364xx.c2
-rw-r--r--drivers/mtd/devices/m25p80.c2
-rw-r--r--drivers/mtd/nftlcore.c15
-rw-r--r--drivers/net/gianfar.c1
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c120
-rw-r--r--drivers/pci/iov.c23
-rw-r--r--drivers/pci/pci.h13
-rw-r--r--drivers/pci/setup-bus.c4
-rw-r--r--drivers/pci/setup-res.c8
-rw-r--r--drivers/platform/x86/toshiba_acpi.c1
-rw-r--r--fs/autofs4/expire.c2
-rw-r--r--fs/compat.c17
-rw-r--r--fs/exec.c63
-rw-r--r--fs/ext2/namei.c4
-rw-r--r--fs/jffs2/wbuf.c10
-rw-r--r--fs/namei.c22
-rw-r--r--fs/nilfs2/btnode.c2
-rw-r--r--fs/notify/inotify/inotify_user.c20
-rw-r--r--fs/ocfs2/aops.c4
-rw-r--r--fs/ocfs2/dcache.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c2
-rw-r--r--include/crypto/algapi.h1
-rw-r--r--include/crypto/internal/skcipher.h4
-rw-r--r--include/linux/binfmts.h1
-rw-r--r--include/linux/device-mapper.h4
-rw-r--r--include/linux/dm-log-userspace.h13
-rw-r--r--include/linux/lmb.h2
-rw-r--r--include/linux/tty.h4
-rw-r--r--include/linux/workqueue.h15
-rw-r--r--include/net/pkt_sched.h4
-rw-r--r--include/sound/ac97_codec.h9
-rw-r--r--include/sound/core.h13
-rw-r--r--include/sound/info.h4
-rw-r--r--include/sound/memalloc.h6
-rw-r--r--include/sound/pcm.h25
-rw-r--r--include/sound/sh_fsi.h83
-rw-r--r--include/sound/soc-dai.h40
-rw-r--r--include/sound/soc-dapm.h10
-rw-r--r--include/sound/soc.h49
-rw-r--r--include/sound/uda1380.h22
-rw-r--r--include/sound/version.h2
-rw-r--r--include/sound/wm8993.h44
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/perf_counter.c3
-rw-r--r--mm/nommu.c3
-rw-r--r--mm/page_alloc.c6
-rw-r--r--mm/percpu.c15
-rw-r--r--mm/slub.c4
-rw-r--r--net/core/sock.c2
-rw-r--r--net/sched/sch_api.c12
-rw-r--r--net/sched/sch_cbq.c25
-rw-r--r--net/sunrpc/clnt.c1
-rw-r--r--security/integrity/ima/ima_main.c6
-rw-r--r--sound/arm/pxa2xx-ac97.c10
-rw-r--r--sound/arm/pxa2xx-pcm-lib.c3
-rw-r--r--sound/core/Kconfig4
-rw-r--r--sound/core/Makefile2
-rw-r--r--sound/core/control.c34
-rw-r--r--sound/core/info.c8
-rw-r--r--sound/core/init.c8
-rw-r--r--sound/core/memalloc.c4
-rw-r--r--sound/core/oss/mixer_oss.c3
-rw-r--r--sound/core/oss/pcm_oss.c12
-rw-r--r--sound/core/pcm.c26
-rw-r--r--sound/core/pcm_memory.c2
-rw-r--r--sound/core/rawmidi.c2
-rw-r--r--sound/core/seq/oss/seq_oss_midi.c14
-rw-r--r--sound/core/seq/seq_midi.c7
-rw-r--r--sound/drivers/dummy.c700
-rw-r--r--sound/isa/cmi8330.c86
-rw-r--r--sound/oss/midibuf.c7
-rw-r--r--sound/oss/vwsnd.c6
-rw-r--r--sound/pci/Kconfig4
-rw-r--r--sound/pci/ali5451/ali5451.c65
-rw-r--r--sound/pci/azt3328.c1116
-rw-r--r--sound/pci/azt3328.h103
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.h2
-rw-r--r--sound/pci/ctxfi/ct20k2reg.h9
-rw-r--r--sound/pci/ctxfi/ctamixer.c20
-rw-r--r--sound/pci/ctxfi/ctatc.c77
-rw-r--r--sound/pci/ctxfi/ctdaio.c30
-rw-r--r--sound/pci/ctxfi/cthw20k1.c22
-rw-r--r--sound/pci/ctxfi/cthw20k2.c73
-rw-r--r--sound/pci/ctxfi/ctmixer.c8
-rw-r--r--sound/pci/ctxfi/ctpcm.c6
-rw-r--r--sound/pci/ctxfi/ctresource.c4
-rw-r--r--sound/pci/ctxfi/ctsrc.c10
-rw-r--r--sound/pci/ctxfi/ctvmem.c6
-rw-r--r--sound/pci/hda/Kconfig27
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_beep.c4
-rw-r--r--sound/pci/hda/hda_codec.c68
-rw-r--r--sound/pci/hda/hda_codec.h10
-rw-r--r--sound/pci/hda/hda_generic.c18
-rw-r--r--sound/pci/hda/hda_hwdep.c236
-rw-r--r--sound/pci/hda/hda_intel.c74
-rw-r--r--sound/pci/hda/hda_local.h14
-rw-r--r--sound/pci/hda/hda_proc.c7
-rw-r--r--sound/pci/hda/patch_analog.c131
-rw-r--r--sound/pci/hda/patch_atihdmi.c3
-rw-r--r--sound/pci/hda/patch_ca0110.c3
-rw-r--r--sound/pci/hda/patch_cirrus.c1194
-rw-r--r--sound/pci/hda/patch_cmedia.c3
-rw-r--r--sound/pci/hda/patch_conexant.c479
-rw-r--r--sound/pci/hda/patch_intelhdmi.c104
-rw-r--r--sound/pci/hda/patch_nvhdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c4170
-rw-r--r--sound/pci/hda/patch_sigmatel.c1206
-rw-r--r--sound/pci/hda/patch_via.c4
-rw-r--r--sound/pci/ice1712/ice1712.h9
-rw-r--r--sound/pci/ice1712/ice1724.c112
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c46
-rw-r--r--sound/pci/rme9652/hdsp.c39
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile3
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c138
-rw-r--r--sound/soc/au1x/psc-ac97.c129
-rw-r--r--sound/soc/au1x/psc.h1
-rw-r--r--sound/soc/blackfin/Kconfig31
-rw-r--r--sound/soc/blackfin/Makefile8
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c10
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c128
-rw-r--r--sound/soc/blackfin/bf5xx-ad1938.c142
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c16
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c8
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c16
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c330
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.h21
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c343
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h14
-rw-r--r--sound/soc/codecs/Kconfig44
-rw-r--r--sound/soc/codecs/Makefile26
-rw-r--r--sound/soc/codecs/ad1836.c446
-rw-r--r--sound/soc/codecs/ad1836.h64
-rw-r--r--sound/soc/codecs/ad1938.c682
-rw-r--r--sound/soc/codecs/ad1938.h100
-rw-r--r--sound/soc/codecs/ak4535.c16
-rw-r--r--sound/soc/codecs/ak4642.c502
-rw-r--r--sound/soc/codecs/ak4642.h20
-rw-r--r--sound/soc/codecs/cs4270.c27
-rw-r--r--sound/soc/codecs/cx20442.c501
-rw-r--r--sound/soc/codecs/cx20442.h20
-rw-r--r--sound/soc/codecs/max9877.c308
-rw-r--r--sound/soc/codecs/max9877.h37
-rw-r--r--sound/soc/codecs/spdif_transciever.c3
-rw-r--r--sound/soc/codecs/stac9766.c4
-rw-r--r--sound/soc/codecs/tlv320aic3x.c233
-rw-r--r--sound/soc/codecs/tlv320aic3x.h2
-rw-r--r--sound/soc/codecs/twl4030.c260
-rw-r--r--sound/soc/codecs/twl4030.h2
-rw-r--r--sound/soc/codecs/uda134x.c2
-rw-r--r--sound/soc/codecs/uda1380.c313
-rw-r--r--sound/soc/codecs/uda1380.h8
-rw-r--r--sound/soc/codecs/wm8350.c51
-rw-r--r--sound/soc/codecs/wm8400.c26
-rw-r--r--sound/soc/codecs/wm8510.c175
-rw-r--r--sound/soc/codecs/wm8523.c699
-rw-r--r--sound/soc/codecs/wm8523.h160
-rw-r--r--sound/soc/codecs/wm8580.c211
-rw-r--r--sound/soc/codecs/wm8728.c111
-rw-r--r--sound/soc/codecs/wm8731.c218
-rw-r--r--sound/soc/codecs/wm8750.c154
-rw-r--r--sound/soc/codecs/wm8753.c35
-rw-r--r--sound/soc/codecs/wm8776.c744
-rw-r--r--sound/soc/codecs/wm8776.h51
-rw-r--r--sound/soc/codecs/wm8900.c345
-rw-r--r--sound/soc/codecs/wm8903.c267
-rw-r--r--sound/soc/codecs/wm8940.c160
-rw-r--r--sound/soc/codecs/wm8960.c233
-rw-r--r--sound/soc/codecs/wm8961.c1265
-rw-r--r--sound/soc/codecs/wm8961.h866
-rw-r--r--sound/soc/codecs/wm8971.c127
-rw-r--r--sound/soc/codecs/wm8974.c808
-rw-r--r--sound/soc/codecs/wm8974.h99
-rw-r--r--sound/soc/codecs/wm8988.c180
-rw-r--r--sound/soc/codecs/wm8990.c194
-rw-r--r--sound/soc/codecs/wm8993.c1675
-rw-r--r--sound/soc/codecs/wm8993.h2132
-rw-r--r--sound/soc/codecs/wm9081.c317
-rw-r--r--sound/soc/codecs/wm9705.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c743
-rw-r--r--sound/soc/codecs/wm_hubs.h24
-rw-r--r--sound/soc/davinci/Kconfig33
-rw-r--r--sound/soc/davinci/Makefile5
-rw-r--r--sound/soc/davinci/davinci-evm.c140
-rw-r--r--sound/soc/davinci/davinci-i2s.c340
-rw-r--r--sound/soc/davinci/davinci-mcasp.c973
-rw-r--r--sound/soc/davinci/davinci-mcasp.h60
-rw-r--r--sound/soc/davinci/davinci-pcm.c10
-rw-r--r--sound/soc/davinci/davinci-pcm.h19
-rw-r--r--sound/soc/fsl/mpc5200_dma.c17
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c3
-rw-r--r--sound/soc/imx/Kconfig21
-rw-r--r--sound/soc/imx/Makefile10
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.c488
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.h26
-rw-r--r--sound/soc/imx/mx27vis_wm8974.c317
-rw-r--r--sound/soc/imx/mxc-ssi.c868
-rw-r--r--sound/soc/imx/mxc-ssi.h238
-rw-r--r--sound/soc/omap/Kconfig15
-rw-r--r--sound/soc/omap/Makefile4
-rw-r--r--sound/soc/omap/ams-delta.c646
-rw-r--r--sound/soc/omap/n810.c12
-rw-r--r--sound/soc/omap/omap-mcbsp.c123
-rw-r--r--sound/soc/omap/omap-mcbsp.h4
-rw-r--r--sound/soc/omap/omap-pcm.c53
-rw-r--r--sound/soc/omap/omap-pcm.h2
-rw-r--r--sound/soc/omap/sdp3430.c18
-rw-r--r--sound/soc/omap/zoom2.c314
-rw-r--r--sound/soc/pxa/magician.c56
-rw-r--r--sound/soc/pxa/palm27x.c204
-rw-r--r--sound/soc/pxa/pxa-ssp.c77
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c12
-rw-r--r--sound/soc/s3c24xx/Kconfig35
-rw-r--r--sound/soc/s3c24xx/Makefile9
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c498
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c17
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c20
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c5
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.c394
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.h22
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_hermes.c153
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c137
-rw-r--r--sound/soc/s6000/s6105-ipcam.c12
-rw-r--r--sound/soc/sh/Kconfig15
-rw-r--r--sound/soc/sh/Makefile4
-rw-r--r--sound/soc/sh/fsi-ak4642.c107
-rw-r--r--sound/soc/sh/fsi.c1004
-rw-r--r--sound/soc/soc-cache.c218
-rw-r--r--sound/soc/soc-core.c148
-rw-r--r--sound/soc/soc-dapm.c498
-rw-r--r--sound/soc/soc-jack.c24
-rw-r--r--sound/soc/txx9/txx9aclc.c10
-rw-r--r--sound/usb/usbaudio.c4
311 files changed, 31221 insertions, 7355 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt
index 4252697a95d6..ad51c93d41e4 100644
--- a/Documentation/sound/alsa/ALSA-Configuration.txt
+++ b/Documentation/sound/alsa/ALSA-Configuration.txt
@@ -513,6 +513,26 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
513 or input, but you may use this module for any application which 513 or input, but you may use this module for any application which
514 requires a sound card (like RealPlayer). 514 requires a sound card (like RealPlayer).
515 515
516 pcm_devs - Number of PCM devices assigned to each card
517 (default = 1, up to 4)
518 pcm_substreams - Number of PCM substreams assigned to each PCM
519 (default = 8, up to 16)
520 hrtimer - Use hrtimer (=1, default) or system timer (=0)
521 fake_buffer - Fake buffer allocations (default = 1)
522
523 When multiple PCM devices are created, snd-dummy gives different
524 behavior to each PCM device:
525 0 = interleaved with mmap support
526 1 = non-interleaved with mmap support
527 2 = interleaved without mmap
528 3 = non-interleaved without mmap
529
530 As default, snd-dummy drivers doesn't allocate the real buffers
531 but either ignores read/write or mmap a single dummy page to all
532 buffer pages, in order to save the resouces. If your apps need
533 the read/ written buffer data to be consistent, pass fake_buffer=0
534 option.
535
516 The power-management is supported. 536 The power-management is supported.
517 537
518 Module snd-echo3g 538 Module snd-echo3g
@@ -768,6 +788,10 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
768 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples. 788 bdl_pos_adj - Specifies the DMA IRQ timing delay in samples.
769 Passing -1 will make the driver to choose the appropriate 789 Passing -1 will make the driver to choose the appropriate
770 value based on the controller chip. 790 value based on the controller chip.
791 patch - Specifies the early "patch" files to modify the HD-audio
792 setup before initializing the codecs. This option is
793 available only when CONFIG_SND_HDA_PATCH_LOADER=y is set.
794 See HD-Audio.txt for details.
771 795
772 [Single (global) options] 796 [Single (global) options]
773 single_cmd - Use single immediate commands to communicate with 797 single_cmd - Use single immediate commands to communicate with
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index 939a3dd58148..97eebd63bedc 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -114,8 +114,8 @@ ALC662/663/272
114 samsung-nc10 Samsung NC10 mini notebook 114 samsung-nc10 Samsung NC10 mini notebook
115 auto auto-config reading BIOS (default) 115 auto auto-config reading BIOS (default)
116 116
117ALC882/885 117ALC882/883/885/888/889
118========== 118======================
119 3stack-dig 3-jack with SPDIF I/O 119 3stack-dig 3-jack with SPDIF I/O
120 6stack-dig 6-jack digital with SPDIF I/O 120 6stack-dig 6-jack digital with SPDIF I/O
121 arima Arima W820Di1 121 arima Arima W820Di1
@@ -127,12 +127,8 @@ ALC882/885
127 mbp3 Macbook Pro rev3 127 mbp3 Macbook Pro rev3
128 imac24 iMac 24'' with jack detection 128 imac24 iMac 24'' with jack detection
129 w2jc ASUS W2JC 129 w2jc ASUS W2JC
130 auto auto-config reading BIOS (default) 130 3stack-2ch-dig 3-jack with SPDIF I/O (ALC883)
131 131 alc883-6stack-dig 6-jack digital with SPDIF I/O (ALC883)
132ALC883/888
133==========
134 3stack-dig 3-jack with SPDIF I/O
135 6stack-dig 6-jack digital with SPDIF I/O
136 3stack-6ch 3-jack 6-channel 132 3stack-6ch 3-jack 6-channel
137 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O 133 3stack-6ch-dig 3-jack 6-channel with SPDIF I/O
138 6stack-dig-demo 6-jack digital for Intel demo board 134 6stack-dig-demo 6-jack digital for Intel demo board
@@ -140,6 +136,7 @@ ALC883/888
140 acer-aspire Acer Aspire 9810 136 acer-aspire Acer Aspire 9810
141 acer-aspire-4930g Acer Aspire 4930G 137 acer-aspire-4930g Acer Aspire 4930G
142 acer-aspire-6530g Acer Aspire 6530G 138 acer-aspire-6530g Acer Aspire 6530G
139 acer-aspire-7730g Acer Aspire 7730G
143 acer-aspire-8930g Acer Aspire 8930G 140 acer-aspire-8930g Acer Aspire 8930G
144 medion Medion Laptops 141 medion Medion Laptops
145 medion-md2 Medion MD2 142 medion-md2 Medion MD2
@@ -155,10 +152,13 @@ ALC883/888
155 3stack-hp HP machines with 3stack (Lucknow, Samba boards) 152 3stack-hp HP machines with 3stack (Lucknow, Samba boards)
156 6stack-dell Dell machines with 6stack (Inspiron 530) 153 6stack-dell Dell machines with 6stack (Inspiron 530)
157 mitac Mitac 8252D 154 mitac Mitac 8252D
155 clevo-m540r Clevo M540R (6ch + digital)
158 clevo-m720 Clevo M720 laptop series 156 clevo-m720 Clevo M720 laptop series
159 fujitsu-pi2515 Fujitsu AMILO Pi2515 157 fujitsu-pi2515 Fujitsu AMILO Pi2515
160 fujitsu-xa3530 Fujitsu AMILO XA3530 158 fujitsu-xa3530 Fujitsu AMILO XA3530
161 3stack-6ch-intel Intel DG33* boards 159 3stack-6ch-intel Intel DG33* boards
160 intel-alc889a Intel IbexPeak with ALC889A
161 intel-x58 Intel DX58 with ALC889
162 asus-p5q ASUS P5Q-EM boards 162 asus-p5q ASUS P5Q-EM boards
163 mb31 MacBook 3,1 163 mb31 MacBook 3,1
164 sony-vaio-tt Sony VAIO TT 164 sony-vaio-tt Sony VAIO TT
@@ -229,7 +229,7 @@ AD1984
229====== 229======
230 basic default configuration 230 basic default configuration
231 thinkpad Lenovo Thinkpad T61/X61 231 thinkpad Lenovo Thinkpad T61/X61
232 dell Dell T3400 232 dell_desktop Dell T3400
233 233
234AD1986A 234AD1986A
235======= 235=======
@@ -258,6 +258,7 @@ Conexant 5045
258 laptop-micsense Laptop with Mic sense (old model fujitsu) 258 laptop-micsense Laptop with Mic sense (old model fujitsu)
259 laptop-hpmicsense Laptop with HP and Mic senses 259 laptop-hpmicsense Laptop with HP and Mic senses
260 benq Benq R55E 260 benq Benq R55E
261 laptop-hp530 HP 530 laptop
261 test for testing/debugging purpose, almost all controls 262 test for testing/debugging purpose, almost all controls
262 can be adjusted. Appearing only when compiled with 263 can be adjusted. Appearing only when compiled with
263 $CONFIG_SND_DEBUG=y 264 $CONFIG_SND_DEBUG=y
@@ -278,9 +279,16 @@ Conexant 5051
278 hp-dv6736 HP dv6736 279 hp-dv6736 HP dv6736
279 lenovo-x200 Lenovo X200 laptop 280 lenovo-x200 Lenovo X200 laptop
280 281
282Conexant 5066
283=============
284 laptop Basic Laptop config (default)
285 dell-laptop Dell laptops
286 olpc-xo-1_5 OLPC XO 1.5
287
281STAC9200 288STAC9200
282======== 289========
283 ref Reference board 290 ref Reference board
291 oqo OQO Model 2
284 dell-d21 Dell (unknown) 292 dell-d21 Dell (unknown)
285 dell-d22 Dell (unknown) 293 dell-d22 Dell (unknown)
286 dell-d23 Dell (unknown) 294 dell-d23 Dell (unknown)
@@ -368,10 +376,12 @@ STAC92HD73*
368=========== 376===========
369 ref Reference board 377 ref Reference board
370 no-jd BIOS setup but without jack-detection 378 no-jd BIOS setup but without jack-detection
379 intel Intel DG45* mobos
371 dell-m6-amic Dell desktops/laptops with analog mics 380 dell-m6-amic Dell desktops/laptops with analog mics
372 dell-m6-dmic Dell desktops/laptops with digital mics 381 dell-m6-dmic Dell desktops/laptops with digital mics
373 dell-m6 Dell desktops/laptops with both type of mics 382 dell-m6 Dell desktops/laptops with both type of mics
374 dell-eq Dell desktops/laptops 383 dell-eq Dell desktops/laptops
384 alienware Alienware M17x
375 auto BIOS setup (default) 385 auto BIOS setup (default)
376 386
377STAC92HD83* 387STAC92HD83*
@@ -385,3 +395,8 @@ STAC9872
385======== 395========
386 vaio VAIO laptop without SPDIF 396 vaio VAIO laptop without SPDIF
387 auto BIOS setup (default) 397 auto BIOS setup (default)
398
399Cirrus Logic CS4206/4207
400========================
401 mbp55 MacBook Pro 5,5
402 auto BIOS setup (default)
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 71ac995b1915..7b8a5f947d1d 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -139,6 +139,10 @@ The driver checks PCI SSID and looks through the static configuration
139table until any matching entry is found. If you have a new machine, 139table until any matching entry is found. If you have a new machine,
140you may see a message like below: 140you may see a message like below:
141------------------------------------------------------------------------ 141------------------------------------------------------------------------
142 hda_codec: ALC880: BIOS auto-probing.
143------------------------------------------------------------------------
144Meanwhile, in the earlier versions, you would see a message like:
145------------------------------------------------------------------------
142 hda_codec: Unknown model for ALC880, trying auto-probe from BIOS... 146 hda_codec: Unknown model for ALC880, trying auto-probe from BIOS...
143------------------------------------------------------------------------ 147------------------------------------------------------------------------
144Even if you see such a message, DON'T PANIC. Take a deep breath and 148Even if you see such a message, DON'T PANIC. Take a deep breath and
@@ -403,6 +407,66 @@ re-configure based on that state, run like below:
403------------------------------------------------------------------------ 407------------------------------------------------------------------------
404 408
405 409
410Early Patching
411~~~~~~~~~~~~~~
412When CONFIG_SND_HDA_PATCH_LOADER=y is set, you can pass a "patch" as a
413firmware file for modifying the HD-audio setup before initializing the
414codec. This can work basically like the reconfiguration via sysfs in
415the above, but it does it before the first codec configuration.
416
417A patch file is a plain text file which looks like below:
418
419------------------------------------------------------------------------
420 [codec]
421 0x12345678 0xabcd1234 2
422
423 [model]
424 auto
425
426 [pincfg]
427 0x12 0x411111f0
428
429 [verb]
430 0x20 0x500 0x03
431 0x20 0x400 0xff
432
433 [hint]
434 hp_detect = yes
435------------------------------------------------------------------------
436
437The file needs to have a line `[codec]`. The next line should contain
438three numbers indicating the codec vendor-id (0x12345678 in the
439example), the codec subsystem-id (0xabcd1234) and the address (2) of
440the codec. The rest patch entries are applied to this specified codec
441until another codec entry is given.
442
443The `[model]` line allows to change the model name of the each codec.
444In the example above, it will be changed to model=auto.
445Note that this overrides the module option.
446
447After the `[pincfg]` line, the contents are parsed as the initial
448default pin-configurations just like `user_pin_configs` sysfs above.
449The values can be shown in user_pin_configs sysfs file, too.
450
451Similarly, the lines after `[verb]` are parsed as `init_verbs`
452sysfs entries, and the lines after `[hint]` are parsed as `hints`
453sysfs entries, respectively.
454
455The hd-audio driver reads the file via request_firmware(). Thus,
456a patch file has to be located on the appropriate firmware path,
457typically, /lib/firmware. For example, when you pass the option
458`patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be
459present.
460
461The patch module option is specific to each card instance, and you
462need to give one file name for each instance, separated by commas.
463For example, if you have two cards, one for an on-board analog and one
464for an HDMI video board, you may pass patch option like below:
465------------------------------------------------------------------------
466 options snd-hda-intel patch=on-board-patch,hdmi-patch
467------------------------------------------------------------------------
468
469
406Power-Saving 470Power-Saving
407~~~~~~~~~~~~ 471~~~~~~~~~~~~
408The power-saving is a kind of auto-suspend of the device. When the 472The power-saving is a kind of auto-suspend of the device. When the
diff --git a/MAINTAINERS b/MAINTAINERS
index 60299a9a7adb..8dca9d89c6c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2239,8 +2239,7 @@ S: Maintained
2239F: drivers/media/video/gspca/pac207.c 2239F: drivers/media/video/gspca/pac207.c
2240 2240
2241GSPCA SN9C20X SUBDRIVER 2241GSPCA SN9C20X SUBDRIVER
2242P: Brian Johnson 2242M: Brian Johnson <brijohn@gmail.com>
2243M: brijohn@gmail.com
2244L: linux-media@vger.kernel.org 2243L: linux-media@vger.kernel.org
2245T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git 2244T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git
2246S: Maintained 2245S: Maintained
diff --git a/Makefile b/Makefile
index 25c615e57302..60de4ef31254 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 2 1VERSION = 2
2PATCHLEVEL = 6 2PATCHLEVEL = 6
3SUBLEVEL = 31 3SUBLEVEL = 31
4EXTRAVERSION = -rc8 4EXTRAVERSION =
5NAME = Man-Eating Seals of Antiquity 5NAME = Man-Eating Seals of Antiquity
6 6
7# *DOCUMENTATION* 7# *DOCUMENTATION*
diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c
index 99b6e1546311..0447d26d454b 100644
--- a/arch/arm/mach-omap2/mcbsp.c
+++ b/arch/arm/mach-omap2/mcbsp.c
@@ -128,6 +128,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
128 .rx_irq = INT_24XX_MCBSP1_IRQ_RX, 128 .rx_irq = INT_24XX_MCBSP1_IRQ_RX,
129 .tx_irq = INT_24XX_MCBSP1_IRQ_TX, 129 .tx_irq = INT_24XX_MCBSP1_IRQ_TX,
130 .ops = &omap2_mcbsp_ops, 130 .ops = &omap2_mcbsp_ops,
131 .buffer_size = 0x6F,
131 }, 132 },
132 { 133 {
133 .phys_base = OMAP34XX_MCBSP2_BASE, 134 .phys_base = OMAP34XX_MCBSP2_BASE,
@@ -136,6 +137,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
136 .rx_irq = INT_24XX_MCBSP2_IRQ_RX, 137 .rx_irq = INT_24XX_MCBSP2_IRQ_RX,
137 .tx_irq = INT_24XX_MCBSP2_IRQ_TX, 138 .tx_irq = INT_24XX_MCBSP2_IRQ_TX,
138 .ops = &omap2_mcbsp_ops, 139 .ops = &omap2_mcbsp_ops,
140 .buffer_size = 0x3FF,
139 }, 141 },
140 { 142 {
141 .phys_base = OMAP34XX_MCBSP3_BASE, 143 .phys_base = OMAP34XX_MCBSP3_BASE,
@@ -144,6 +146,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
144 .rx_irq = INT_24XX_MCBSP3_IRQ_RX, 146 .rx_irq = INT_24XX_MCBSP3_IRQ_RX,
145 .tx_irq = INT_24XX_MCBSP3_IRQ_TX, 147 .tx_irq = INT_24XX_MCBSP3_IRQ_TX,
146 .ops = &omap2_mcbsp_ops, 148 .ops = &omap2_mcbsp_ops,
149 .buffer_size = 0x6F,
147 }, 150 },
148 { 151 {
149 .phys_base = OMAP34XX_MCBSP4_BASE, 152 .phys_base = OMAP34XX_MCBSP4_BASE,
@@ -152,6 +155,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
152 .rx_irq = INT_24XX_MCBSP4_IRQ_RX, 155 .rx_irq = INT_24XX_MCBSP4_IRQ_RX,
153 .tx_irq = INT_24XX_MCBSP4_IRQ_TX, 156 .tx_irq = INT_24XX_MCBSP4_IRQ_TX,
154 .ops = &omap2_mcbsp_ops, 157 .ops = &omap2_mcbsp_ops,
158 .buffer_size = 0x6F,
155 }, 159 },
156 { 160 {
157 .phys_base = OMAP34XX_MCBSP5_BASE, 161 .phys_base = OMAP34XX_MCBSP5_BASE,
@@ -160,6 +164,7 @@ static struct omap_mcbsp_platform_data omap34xx_mcbsp_pdata[] = {
160 .rx_irq = INT_24XX_MCBSP5_IRQ_RX, 164 .rx_irq = INT_24XX_MCBSP5_IRQ_RX,
161 .tx_irq = INT_24XX_MCBSP5_IRQ_TX, 165 .tx_irq = INT_24XX_MCBSP5_IRQ_TX,
162 .ops = &omap2_mcbsp_ops, 166 .ops = &omap2_mcbsp_ops,
167 .buffer_size = 0x6F,
163 }, 168 },
164}; 169};
165#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata) 170#define OMAP34XX_MCBSP_PDATA_SZ ARRAY_SIZE(omap34xx_mcbsp_pdata)
diff --git a/arch/arm/mach-pxa/include/mach/audio.h b/arch/arm/mach-pxa/include/mach/audio.h
index 16eb02552d5d..a3449e35a6f5 100644
--- a/arch/arm/mach-pxa/include/mach/audio.h
+++ b/arch/arm/mach-pxa/include/mach/audio.h
@@ -3,10 +3,12 @@
3 3
4#include <sound/core.h> 4#include <sound/core.h>
5#include <sound/pcm.h> 5#include <sound/pcm.h>
6#include <sound/ac97_codec.h>
6 7
7/* 8/*
8 * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95) 9 * @reset_gpio: AC97 reset gpio (normally gpio113 or gpio95)
9 * a -1 value means no gpio will be used for reset 10 * a -1 value means no gpio will be used for reset
11 * @codec_pdata: AC97 codec platform_data
10 12
11 * reset_gpio should only be specified for pxa27x CPUs where a silicon 13 * reset_gpio should only be specified for pxa27x CPUs where a silicon
12 * bug prevents correct operation of the reset line. If not specified, 14 * bug prevents correct operation of the reset line. If not specified,
@@ -20,6 +22,7 @@ typedef struct {
20 void (*resume)(void *); 22 void (*resume)(void *);
21 void *priv; 23 void *priv;
22 int reset_gpio; 24 int reset_gpio;
25 void *codec_pdata[AC97_BUS_MAX_DEVICES];
23} pxa2xx_audio_ops_t; 26} pxa2xx_audio_ops_t;
24 27
25extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops); 28extern void pxa_set_ac97_info(pxa2xx_audio_ops_t *ops);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index e3ac94f09006..9b00f4cbc903 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -1127,6 +1127,11 @@ int omap_dma_running(void)
1127void omap_dma_link_lch(int lch_head, int lch_queue) 1127void omap_dma_link_lch(int lch_head, int lch_queue)
1128{ 1128{
1129 if (omap_dma_in_1510_mode()) { 1129 if (omap_dma_in_1510_mode()) {
1130 if (lch_head == lch_queue) {
1131 dma_write(dma_read(CCR(lch_head)) | (3 << 8),
1132 CCR(lch_head));
1133 return;
1134 }
1130 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); 1135 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
1131 BUG(); 1136 BUG();
1132 return; 1137 return;
@@ -1149,6 +1154,11 @@ EXPORT_SYMBOL(omap_dma_link_lch);
1149void omap_dma_unlink_lch(int lch_head, int lch_queue) 1154void omap_dma_unlink_lch(int lch_head, int lch_queue)
1150{ 1155{
1151 if (omap_dma_in_1510_mode()) { 1156 if (omap_dma_in_1510_mode()) {
1157 if (lch_head == lch_queue) {
1158 dma_write(dma_read(CCR(lch_head)) & ~(3 << 8),
1159 CCR(lch_head));
1160 return;
1161 }
1152 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n"); 1162 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
1153 BUG(); 1163 BUG();
1154 return; 1164 return;
diff --git a/arch/arm/plat-omap/include/mach/mcbsp.h b/arch/arm/plat-omap/include/mach/mcbsp.h
index bb154ea76769..63a3f254af7b 100644
--- a/arch/arm/plat-omap/include/mach/mcbsp.h
+++ b/arch/arm/plat-omap/include/mach/mcbsp.h
@@ -134,6 +134,11 @@
134#define OMAP_MCBSP_REG_XCERG 0x74 134#define OMAP_MCBSP_REG_XCERG 0x74
135#define OMAP_MCBSP_REG_XCERH 0x78 135#define OMAP_MCBSP_REG_XCERH 0x78
136#define OMAP_MCBSP_REG_SYSCON 0x8C 136#define OMAP_MCBSP_REG_SYSCON 0x8C
137#define OMAP_MCBSP_REG_THRSH2 0x90
138#define OMAP_MCBSP_REG_THRSH1 0x94
139#define OMAP_MCBSP_REG_IRQST 0xA0
140#define OMAP_MCBSP_REG_IRQEN 0xA4
141#define OMAP_MCBSP_REG_WAKEUPEN 0xA8
137#define OMAP_MCBSP_REG_XCCR 0xAC 142#define OMAP_MCBSP_REG_XCCR 0xAC
138#define OMAP_MCBSP_REG_RCCR 0xB0 143#define OMAP_MCBSP_REG_RCCR 0xB0
139 144
@@ -249,8 +254,27 @@
249#define RDISABLE 0x0001 254#define RDISABLE 0x0001
250 255
251/********************** McBSP SYSCONFIG bit definitions ********************/ 256/********************** McBSP SYSCONFIG bit definitions ********************/
257#define CLOCKACTIVITY(value) ((value)<<8)
258#define SIDLEMODE(value) ((value)<<3)
259#define ENAWAKEUP 0x0004
252#define SOFTRST 0x0002 260#define SOFTRST 0x0002
253 261
262/********************** McBSP DMA operating modes **************************/
263#define MCBSP_DMA_MODE_ELEMENT 0
264#define MCBSP_DMA_MODE_THRESHOLD 1
265#define MCBSP_DMA_MODE_FRAME 2
266
267/********************** McBSP WAKEUPEN bit definitions *********************/
268#define XEMPTYEOFEN 0x4000
269#define XRDYEN 0x0400
270#define XEOFEN 0x0200
271#define XFSXEN 0x0100
272#define XSYNCERREN 0x0080
273#define RRDYEN 0x0008
274#define REOFEN 0x0004
275#define RFSREN 0x0002
276#define RSYNCERREN 0x0001
277
254/* we don't do multichannel for now */ 278/* we don't do multichannel for now */
255struct omap_mcbsp_reg_cfg { 279struct omap_mcbsp_reg_cfg {
256 u16 spcr2; 280 u16 spcr2;
@@ -344,6 +368,9 @@ struct omap_mcbsp_platform_data {
344 u8 dma_rx_sync, dma_tx_sync; 368 u8 dma_rx_sync, dma_tx_sync;
345 u16 rx_irq, tx_irq; 369 u16 rx_irq, tx_irq;
346 struct omap_mcbsp_ops *ops; 370 struct omap_mcbsp_ops *ops;
371#ifdef CONFIG_ARCH_OMAP34XX
372 u16 buffer_size;
373#endif
347}; 374};
348 375
349struct omap_mcbsp { 376struct omap_mcbsp {
@@ -377,6 +404,11 @@ struct omap_mcbsp {
377 struct omap_mcbsp_platform_data *pdata; 404 struct omap_mcbsp_platform_data *pdata;
378 struct clk *iclk; 405 struct clk *iclk;
379 struct clk *fclk; 406 struct clk *fclk;
407#ifdef CONFIG_ARCH_OMAP34XX
408 int dma_op_mode;
409 u16 max_tx_thres;
410 u16 max_rx_thres;
411#endif
380}; 412};
381extern struct omap_mcbsp **mcbsp_ptr; 413extern struct omap_mcbsp **mcbsp_ptr;
382extern int omap_mcbsp_count; 414extern int omap_mcbsp_count;
@@ -385,10 +417,25 @@ int omap_mcbsp_init(void);
385void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config, 417void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
386 int size); 418 int size);
387void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config); 419void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config);
420#ifdef CONFIG_ARCH_OMAP34XX
421void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold);
422void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold);
423u16 omap_mcbsp_get_max_tx_threshold(unsigned int id);
424u16 omap_mcbsp_get_max_rx_threshold(unsigned int id);
425int omap_mcbsp_get_dma_op_mode(unsigned int id);
426#else
427static inline void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
428{ }
429static inline void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
430{ }
431static inline u16 omap_mcbsp_get_max_tx_threshold(unsigned int id) { return 0; }
432static inline u16 omap_mcbsp_get_max_rx_threshold(unsigned int id) { return 0; }
433static inline int omap_mcbsp_get_dma_op_mode(unsigned int id) { return 0; }
434#endif
388int omap_mcbsp_request(unsigned int id); 435int omap_mcbsp_request(unsigned int id);
389void omap_mcbsp_free(unsigned int id); 436void omap_mcbsp_free(unsigned int id);
390void omap_mcbsp_start(unsigned int id); 437void omap_mcbsp_start(unsigned int id, int tx, int rx);
391void omap_mcbsp_stop(unsigned int id); 438void omap_mcbsp_stop(unsigned int id, int tx, int rx);
392void omap_mcbsp_xmit_word(unsigned int id, u32 word); 439void omap_mcbsp_xmit_word(unsigned int id, u32 word);
393u32 omap_mcbsp_recv_word(unsigned int id); 440u32 omap_mcbsp_recv_word(unsigned int id);
394 441
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
index efa0e0111f38..8dc7927906f1 100644
--- a/arch/arm/plat-omap/mcbsp.c
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -198,6 +198,170 @@ void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg *config)
198} 198}
199EXPORT_SYMBOL(omap_mcbsp_config); 199EXPORT_SYMBOL(omap_mcbsp_config);
200 200
201#ifdef CONFIG_ARCH_OMAP34XX
202/*
203 * omap_mcbsp_set_tx_threshold configures how to deal
204 * with transmit threshold. the threshold value and handler can be
205 * configure in here.
206 */
207void omap_mcbsp_set_tx_threshold(unsigned int id, u16 threshold)
208{
209 struct omap_mcbsp *mcbsp;
210 void __iomem *io_base;
211
212 if (!cpu_is_omap34xx())
213 return;
214
215 if (!omap_mcbsp_check_valid_id(id)) {
216 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
217 return;
218 }
219 mcbsp = id_to_mcbsp_ptr(id);
220 io_base = mcbsp->io_base;
221
222 OMAP_MCBSP_WRITE(io_base, THRSH2, threshold);
223}
224EXPORT_SYMBOL(omap_mcbsp_set_tx_threshold);
225
226/*
227 * omap_mcbsp_set_rx_threshold configures how to deal
228 * with receive threshold. the threshold value and handler can be
229 * configure in here.
230 */
231void omap_mcbsp_set_rx_threshold(unsigned int id, u16 threshold)
232{
233 struct omap_mcbsp *mcbsp;
234 void __iomem *io_base;
235
236 if (!cpu_is_omap34xx())
237 return;
238
239 if (!omap_mcbsp_check_valid_id(id)) {
240 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
241 return;
242 }
243 mcbsp = id_to_mcbsp_ptr(id);
244 io_base = mcbsp->io_base;
245
246 OMAP_MCBSP_WRITE(io_base, THRSH1, threshold);
247}
248EXPORT_SYMBOL(omap_mcbsp_set_rx_threshold);
249
250/*
251 * omap_mcbsp_get_max_tx_thres just return the current configured
252 * maximum threshold for transmission
253 */
254u16 omap_mcbsp_get_max_tx_threshold(unsigned int id)
255{
256 struct omap_mcbsp *mcbsp;
257
258 if (!omap_mcbsp_check_valid_id(id)) {
259 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
260 return -ENODEV;
261 }
262 mcbsp = id_to_mcbsp_ptr(id);
263
264 return mcbsp->max_tx_thres;
265}
266EXPORT_SYMBOL(omap_mcbsp_get_max_tx_threshold);
267
268/*
269 * omap_mcbsp_get_max_rx_thres just return the current configured
270 * maximum threshold for reception
271 */
272u16 omap_mcbsp_get_max_rx_threshold(unsigned int id)
273{
274 struct omap_mcbsp *mcbsp;
275
276 if (!omap_mcbsp_check_valid_id(id)) {
277 printk(KERN_ERR "%s: Invalid id (%d)\n", __func__, id + 1);
278 return -ENODEV;
279 }
280 mcbsp = id_to_mcbsp_ptr(id);
281
282 return mcbsp->max_rx_thres;
283}
284EXPORT_SYMBOL(omap_mcbsp_get_max_rx_threshold);
285
286/*
287 * omap_mcbsp_get_dma_op_mode just return the current configured
288 * operating mode for the mcbsp channel
289 */
290int omap_mcbsp_get_dma_op_mode(unsigned int id)
291{
292 struct omap_mcbsp *mcbsp;
293 int dma_op_mode;
294
295 if (!omap_mcbsp_check_valid_id(id)) {
296 printk(KERN_ERR "%s: Invalid id (%u)\n", __func__, id + 1);
297 return -ENODEV;
298 }
299 mcbsp = id_to_mcbsp_ptr(id);
300
301 spin_lock_irq(&mcbsp->lock);
302 dma_op_mode = mcbsp->dma_op_mode;
303 spin_unlock_irq(&mcbsp->lock);
304
305 return dma_op_mode;
306}
307EXPORT_SYMBOL(omap_mcbsp_get_dma_op_mode);
308
309static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp)
310{
311 /*
312 * Enable wakup behavior, smart idle and all wakeups
313 * REVISIT: some wakeups may be unnecessary
314 */
315 if (cpu_is_omap34xx()) {
316 u16 syscon;
317
318 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
319 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
320
321 spin_lock_irq(&mcbsp->lock);
322 if (mcbsp->dma_op_mode == MCBSP_DMA_MODE_THRESHOLD) {
323 syscon |= (ENAWAKEUP | SIDLEMODE(0x02) |
324 CLOCKACTIVITY(0x02));
325 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN,
326 XRDYEN | RRDYEN);
327 } else {
328 syscon |= SIDLEMODE(0x01);
329 }
330 spin_unlock_irq(&mcbsp->lock);
331
332 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
333 }
334}
335
336static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp)
337{
338 /*
339 * Disable wakup behavior, smart idle and all wakeups
340 */
341 if (cpu_is_omap34xx()) {
342 u16 syscon;
343
344 syscon = OMAP_MCBSP_READ(mcbsp->io_base, SYSCON);
345 syscon &= ~(ENAWAKEUP | SIDLEMODE(0x03) | CLOCKACTIVITY(0x03));
346 /*
347 * HW bug workaround - If no_idle mode is taken, we need to
348 * go to smart_idle before going to always_idle, or the
349 * device will not hit retention anymore.
350 */
351 syscon |= SIDLEMODE(0x02);
352 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
353
354 syscon &= ~(SIDLEMODE(0x03));
355 OMAP_MCBSP_WRITE(mcbsp->io_base, SYSCON, syscon);
356
357 OMAP_MCBSP_WRITE(mcbsp->io_base, WAKEUPEN, 0);
358 }
359}
360#else
361static inline void omap34xx_mcbsp_request(struct omap_mcbsp *mcbsp) {}
362static inline void omap34xx_mcbsp_free(struct omap_mcbsp *mcbsp) {}
363#endif
364
201/* 365/*
202 * We can choose between IRQ based or polled IO. 366 * We can choose between IRQ based or polled IO.
203 * This needs to be called before omap_mcbsp_request(). 367 * This needs to be called before omap_mcbsp_request().
@@ -257,6 +421,9 @@ int omap_mcbsp_request(unsigned int id)
257 clk_enable(mcbsp->iclk); 421 clk_enable(mcbsp->iclk);
258 clk_enable(mcbsp->fclk); 422 clk_enable(mcbsp->fclk);
259 423
424 /* Do procedure specific to omap34xx arch, if applicable */
425 omap34xx_mcbsp_request(mcbsp);
426
260 /* 427 /*
261 * Make sure that transmitter, receiver and sample-rate generator are 428 * Make sure that transmitter, receiver and sample-rate generator are
262 * not running before activating IRQs. 429 * not running before activating IRQs.
@@ -305,6 +472,9 @@ void omap_mcbsp_free(unsigned int id)
305 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free) 472 if (mcbsp->pdata && mcbsp->pdata->ops && mcbsp->pdata->ops->free)
306 mcbsp->pdata->ops->free(id); 473 mcbsp->pdata->ops->free(id);
307 474
475 /* Do procedure specific to omap34xx arch, if applicable */
476 omap34xx_mcbsp_free(mcbsp);
477
308 clk_disable(mcbsp->fclk); 478 clk_disable(mcbsp->fclk);
309 clk_disable(mcbsp->iclk); 479 clk_disable(mcbsp->iclk);
310 480
@@ -328,14 +498,15 @@ void omap_mcbsp_free(unsigned int id)
328EXPORT_SYMBOL(omap_mcbsp_free); 498EXPORT_SYMBOL(omap_mcbsp_free);
329 499
330/* 500/*
331 * Here we start the McBSP, by enabling the sample 501 * Here we start the McBSP, by enabling transmitter, receiver or both.
332 * generator, both transmitter and receivers, 502 * If no transmitter or receiver is active prior calling, then sample-rate
333 * and the frame sync. 503 * generator and frame sync are started.
334 */ 504 */
335void omap_mcbsp_start(unsigned int id) 505void omap_mcbsp_start(unsigned int id, int tx, int rx)
336{ 506{
337 struct omap_mcbsp *mcbsp; 507 struct omap_mcbsp *mcbsp;
338 void __iomem *io_base; 508 void __iomem *io_base;
509 int idle;
339 u16 w; 510 u16 w;
340 511
341 if (!omap_mcbsp_check_valid_id(id)) { 512 if (!omap_mcbsp_check_valid_id(id)) {
@@ -348,32 +519,58 @@ void omap_mcbsp_start(unsigned int id)
348 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7; 519 mcbsp->rx_word_length = (OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7;
349 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7; 520 mcbsp->tx_word_length = (OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7;
350 521
351 /* Start the sample generator */ 522 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
352 w = OMAP_MCBSP_READ(io_base, SPCR2); 523 OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
353 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6)); 524
525 if (idle) {
526 /* Start the sample generator */
527 w = OMAP_MCBSP_READ(io_base, SPCR2);
528 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
529 }
354 530
355 /* Enable transmitter and receiver */ 531 /* Enable transmitter and receiver */
532 tx &= 1;
356 w = OMAP_MCBSP_READ(io_base, SPCR2); 533 w = OMAP_MCBSP_READ(io_base, SPCR2);
357 OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1); 534 OMAP_MCBSP_WRITE(io_base, SPCR2, w | tx);
358 535
536 rx &= 1;
359 w = OMAP_MCBSP_READ(io_base, SPCR1); 537 w = OMAP_MCBSP_READ(io_base, SPCR1);
360 OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1); 538 OMAP_MCBSP_WRITE(io_base, SPCR1, w | rx);
361 539
362 udelay(100); 540 /*
541 * Worst case: CLKSRG*2 = 8000khz: (1/8000) * 2 * 2 usec
542 * REVISIT: 100us may give enough time for two CLKSRG, however
543 * due to some unknown PM related, clock gating etc. reason it
544 * is now at 500us.
545 */
546 udelay(500);
363 547
364 /* Start frame sync */ 548 if (idle) {
365 w = OMAP_MCBSP_READ(io_base, SPCR2); 549 /* Start frame sync */
366 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7)); 550 w = OMAP_MCBSP_READ(io_base, SPCR2);
551 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
552 }
553
554 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
555 /* Release the transmitter and receiver */
556 w = OMAP_MCBSP_READ(io_base, XCCR);
557 w &= ~(tx ? XDISABLE : 0);
558 OMAP_MCBSP_WRITE(io_base, XCCR, w);
559 w = OMAP_MCBSP_READ(io_base, RCCR);
560 w &= ~(rx ? RDISABLE : 0);
561 OMAP_MCBSP_WRITE(io_base, RCCR, w);
562 }
367 563
368 /* Dump McBSP Regs */ 564 /* Dump McBSP Regs */
369 omap_mcbsp_dump_reg(id); 565 omap_mcbsp_dump_reg(id);
370} 566}
371EXPORT_SYMBOL(omap_mcbsp_start); 567EXPORT_SYMBOL(omap_mcbsp_start);
372 568
373void omap_mcbsp_stop(unsigned int id) 569void omap_mcbsp_stop(unsigned int id, int tx, int rx)
374{ 570{
375 struct omap_mcbsp *mcbsp; 571 struct omap_mcbsp *mcbsp;
376 void __iomem *io_base; 572 void __iomem *io_base;
573 int idle;
377 u16 w; 574 u16 w;
378 575
379 if (!omap_mcbsp_check_valid_id(id)) { 576 if (!omap_mcbsp_check_valid_id(id)) {
@@ -385,16 +582,33 @@ void omap_mcbsp_stop(unsigned int id)
385 io_base = mcbsp->io_base; 582 io_base = mcbsp->io_base;
386 583
387 /* Reset transmitter */ 584 /* Reset transmitter */
585 tx &= 1;
586 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
587 w = OMAP_MCBSP_READ(io_base, XCCR);
588 w |= (tx ? XDISABLE : 0);
589 OMAP_MCBSP_WRITE(io_base, XCCR, w);
590 }
388 w = OMAP_MCBSP_READ(io_base, SPCR2); 591 w = OMAP_MCBSP_READ(io_base, SPCR2);
389 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1)); 592 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~tx);
390 593
391 /* Reset receiver */ 594 /* Reset receiver */
595 rx &= 1;
596 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
597 w = OMAP_MCBSP_READ(io_base, RCCR);
598 w |= (tx ? RDISABLE : 0);
599 OMAP_MCBSP_WRITE(io_base, RCCR, w);
600 }
392 w = OMAP_MCBSP_READ(io_base, SPCR1); 601 w = OMAP_MCBSP_READ(io_base, SPCR1);
393 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1)); 602 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~rx);
394 603
395 /* Reset the sample rate generator */ 604 idle = !((OMAP_MCBSP_READ(io_base, SPCR2) |
396 w = OMAP_MCBSP_READ(io_base, SPCR2); 605 OMAP_MCBSP_READ(io_base, SPCR1)) & 1);
397 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6)); 606
607 if (idle) {
608 /* Reset the sample rate generator */
609 w = OMAP_MCBSP_READ(io_base, SPCR2);
610 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
611 }
398} 612}
399EXPORT_SYMBOL(omap_mcbsp_stop); 613EXPORT_SYMBOL(omap_mcbsp_stop);
400 614
@@ -883,6 +1097,149 @@ void omap_mcbsp_set_spi_mode(unsigned int id,
883} 1097}
884EXPORT_SYMBOL(omap_mcbsp_set_spi_mode); 1098EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
885 1099
1100#ifdef CONFIG_ARCH_OMAP34XX
1101#define max_thres(m) (mcbsp->pdata->buffer_size)
1102#define valid_threshold(m, val) ((val) <= max_thres(m))
1103#define THRESHOLD_PROP_BUILDER(prop) \
1104static ssize_t prop##_show(struct device *dev, \
1105 struct device_attribute *attr, char *buf) \
1106{ \
1107 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
1108 \
1109 return sprintf(buf, "%u\n", mcbsp->prop); \
1110} \
1111 \
1112static ssize_t prop##_store(struct device *dev, \
1113 struct device_attribute *attr, \
1114 const char *buf, size_t size) \
1115{ \
1116 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev); \
1117 unsigned long val; \
1118 int status; \
1119 \
1120 status = strict_strtoul(buf, 0, &val); \
1121 if (status) \
1122 return status; \
1123 \
1124 if (!valid_threshold(mcbsp, val)) \
1125 return -EDOM; \
1126 \
1127 mcbsp->prop = val; \
1128 return size; \
1129} \
1130 \
1131static DEVICE_ATTR(prop, 0644, prop##_show, prop##_store);
1132
1133THRESHOLD_PROP_BUILDER(max_tx_thres);
1134THRESHOLD_PROP_BUILDER(max_rx_thres);
1135
1136static const char *dma_op_modes[] = {
1137 "element", "threshold", "frame",
1138};
1139
1140static ssize_t dma_op_mode_show(struct device *dev,
1141 struct device_attribute *attr, char *buf)
1142{
1143 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1144 int dma_op_mode, i = 0;
1145 ssize_t len = 0;
1146 const char * const *s;
1147
1148 spin_lock_irq(&mcbsp->lock);
1149 dma_op_mode = mcbsp->dma_op_mode;
1150 spin_unlock_irq(&mcbsp->lock);
1151
1152 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++) {
1153 if (dma_op_mode == i)
1154 len += sprintf(buf + len, "[%s] ", *s);
1155 else
1156 len += sprintf(buf + len, "%s ", *s);
1157 }
1158 len += sprintf(buf + len, "\n");
1159
1160 return len;
1161}
1162
1163static ssize_t dma_op_mode_store(struct device *dev,
1164 struct device_attribute *attr,
1165 const char *buf, size_t size)
1166{
1167 struct omap_mcbsp *mcbsp = dev_get_drvdata(dev);
1168 const char * const *s;
1169 int i = 0;
1170
1171 for (s = &dma_op_modes[i]; i < ARRAY_SIZE(dma_op_modes); s++, i++)
1172 if (sysfs_streq(buf, *s))
1173 break;
1174
1175 if (i == ARRAY_SIZE(dma_op_modes))
1176 return -EINVAL;
1177
1178 spin_lock_irq(&mcbsp->lock);
1179 if (!mcbsp->free) {
1180 size = -EBUSY;
1181 goto unlock;
1182 }
1183 mcbsp->dma_op_mode = i;
1184
1185unlock:
1186 spin_unlock_irq(&mcbsp->lock);
1187
1188 return size;
1189}
1190
1191static DEVICE_ATTR(dma_op_mode, 0644, dma_op_mode_show, dma_op_mode_store);
1192
1193static const struct attribute *additional_attrs[] = {
1194 &dev_attr_max_tx_thres.attr,
1195 &dev_attr_max_rx_thres.attr,
1196 &dev_attr_dma_op_mode.attr,
1197 NULL,
1198};
1199
1200static const struct attribute_group additional_attr_group = {
1201 .attrs = (struct attribute **)additional_attrs,
1202};
1203
1204static inline int __devinit omap_additional_add(struct device *dev)
1205{
1206 return sysfs_create_group(&dev->kobj, &additional_attr_group);
1207}
1208
1209static inline void __devexit omap_additional_remove(struct device *dev)
1210{
1211 sysfs_remove_group(&dev->kobj, &additional_attr_group);
1212}
1213
1214static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp)
1215{
1216 mcbsp->dma_op_mode = MCBSP_DMA_MODE_ELEMENT;
1217 if (cpu_is_omap34xx()) {
1218 mcbsp->max_tx_thres = max_thres(mcbsp);
1219 mcbsp->max_rx_thres = max_thres(mcbsp);
1220 /*
1221 * REVISIT: Set dmap_op_mode to THRESHOLD as default
1222 * for mcbsp2 instances.
1223 */
1224 if (omap_additional_add(mcbsp->dev))
1225 dev_warn(mcbsp->dev,
1226 "Unable to create additional controls\n");
1227 } else {
1228 mcbsp->max_tx_thres = -EINVAL;
1229 mcbsp->max_rx_thres = -EINVAL;
1230 }
1231}
1232
1233static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp)
1234{
1235 if (cpu_is_omap34xx())
1236 omap_additional_remove(mcbsp->dev);
1237}
1238#else
1239static inline void __devinit omap34xx_device_init(struct omap_mcbsp *mcbsp) {}
1240static inline void __devexit omap34xx_device_exit(struct omap_mcbsp *mcbsp) {}
1241#endif /* CONFIG_ARCH_OMAP34XX */
1242
886/* 1243/*
887 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510. 1244 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
888 * 730 has only 2 McBSP, and both of them are MPU peripherals. 1245 * 730 has only 2 McBSP, and both of them are MPU peripherals.
@@ -953,6 +1310,10 @@ static int __devinit omap_mcbsp_probe(struct platform_device *pdev)
953 mcbsp->dev = &pdev->dev; 1310 mcbsp->dev = &pdev->dev;
954 mcbsp_ptr[id] = mcbsp; 1311 mcbsp_ptr[id] = mcbsp;
955 platform_set_drvdata(pdev, mcbsp); 1312 platform_set_drvdata(pdev, mcbsp);
1313
1314 /* Initialize mcbsp properties for OMAP34XX if needed / applicable */
1315 omap34xx_device_init(mcbsp);
1316
956 return 0; 1317 return 0;
957 1318
958err_fclk: 1319err_fclk:
@@ -976,6 +1337,8 @@ static int __devexit omap_mcbsp_remove(struct platform_device *pdev)
976 mcbsp->pdata->ops->free) 1337 mcbsp->pdata->ops->free)
977 mcbsp->pdata->ops->free(mcbsp->id); 1338 mcbsp->pdata->ops->free(mcbsp->id);
978 1339
1340 omap34xx_device_exit(mcbsp);
1341
979 clk_disable(mcbsp->fclk); 1342 clk_disable(mcbsp->fclk);
980 clk_disable(mcbsp->iclk); 1343 clk_disable(mcbsp->iclk);
981 clk_put(mcbsp->fclk); 1344 clk_put(mcbsp->fclk);
diff --git a/arch/arm/plat-s3c/include/plat/audio-simtec.h b/arch/arm/plat-s3c/include/plat/audio-simtec.h
new file mode 100644
index 000000000000..0f440b9168db
--- /dev/null
+++ b/arch/arm/plat-s3c/include/plat/audio-simtec.h
@@ -0,0 +1,37 @@
1/* arch/arm/plat-s3c/include/plat/audio-simtec.h
2 *
3 * Copyright 2008 Simtec Electronics
4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk>
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 * Simtec Audio support.
12*/
13
14/**
15 * struct s3c24xx_audio_simtec_pdata - platform data for simtec audio
16 * @use_mpllin: Select codec clock from MPLLin
17 * @output_cdclk: Need to output CDCLK to the codec
18 * @have_mic: Set if we have a MIC socket
19 * @have_lout: Set if we have a LineOut socket
20 * @amp_gpio: GPIO pin to enable the AMP
21 * @amp_gain: Option GPIO to control AMP gain
22 */
23struct s3c24xx_audio_simtec_pdata {
24 unsigned int use_mpllin:1;
25 unsigned int output_cdclk:1;
26
27 unsigned int have_mic:1;
28 unsigned int have_lout:1;
29
30 int amp_gpio;
31 int amp_gain[2];
32
33 void (*startup)(void);
34};
35
36extern int simtec_audio_add(const char *codec_name,
37 struct s3c24xx_audio_simtec_pdata *pdata);
diff --git a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
index 0fad7571030e..07659dad1748 100644
--- a/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
+++ b/arch/arm/plat-s3c/include/plat/regs-s3c2412-iis.h
@@ -33,6 +33,11 @@
33#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) 33#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1)
34#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) 34#define S3C2412_IISCON_IIS_ACTIVE (1 << 0)
35 35
36#define S3C64XX_IISMOD_BLC_16BIT (0 << 13)
37#define S3C64XX_IISMOD_BLC_8BIT (1 << 13)
38#define S3C64XX_IISMOD_BLC_24BIT (2 << 13)
39#define S3C64XX_IISMOD_BLC_MASK (3 << 13)
40
36#define S3C64XX_IISMOD_IMS_PCLK (0 << 10) 41#define S3C64XX_IISMOD_IMS_PCLK (0 << 10)
37#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10) 42#define S3C64XX_IISMOD_IMS_SYSMUX (1 << 10)
38 43
diff --git a/arch/ia64/kernel/dma-mapping.c b/arch/ia64/kernel/dma-mapping.c
index 39a3cd0a4173..f2c1600da097 100644
--- a/arch/ia64/kernel/dma-mapping.c
+++ b/arch/ia64/kernel/dma-mapping.c
@@ -10,7 +10,9 @@ EXPORT_SYMBOL(dma_ops);
10 10
11static int __init dma_init(void) 11static int __init dma_init(void)
12{ 12{
13 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES); 13 dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
14
15 return 0;
14} 16}
15fs_initcall(dma_init); 17fs_initcall(dma_init);
16 18
diff --git a/arch/ia64/lib/ip_fast_csum.S b/arch/ia64/lib/ip_fast_csum.S
index 1f86aeb2c948..620d9dc5220f 100644
--- a/arch/ia64/lib/ip_fast_csum.S
+++ b/arch/ia64/lib/ip_fast_csum.S
@@ -96,20 +96,22 @@ END(ip_fast_csum)
96GLOBAL_ENTRY(csum_ipv6_magic) 96GLOBAL_ENTRY(csum_ipv6_magic)
97 ld4 r20=[in0],4 97 ld4 r20=[in0],4
98 ld4 r21=[in1],4 98 ld4 r21=[in1],4
99 dep r15=in3,in2,32,16 99 zxt4 in2=in2
100 ;; 100 ;;
101 ld4 r22=[in0],4 101 ld4 r22=[in0],4
102 ld4 r23=[in1],4 102 ld4 r23=[in1],4
103 mux1 r15=r15,@rev 103 dep r15=in3,in2,32,16
104 ;; 104 ;;
105 ld4 r24=[in0],4 105 ld4 r24=[in0],4
106 ld4 r25=[in1],4 106 ld4 r25=[in1],4
107 shr.u r15=r15,16 107 mux1 r15=r15,@rev
108 add r16=r20,r21 108 add r16=r20,r21
109 add r17=r22,r23 109 add r17=r22,r23
110 zxt4 in4=in4
110 ;; 111 ;;
111 ld4 r26=[in0],4 112 ld4 r26=[in0],4
112 ld4 r27=[in1],4 113 ld4 r27=[in1],4
114 shr.u r15=r15,16
113 add r18=r24,r25 115 add r18=r24,r25
114 add r8=r16,r17 116 add r8=r16,r17
115 ;; 117 ;;
diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c
index 528f0ff9b273..8b58bf0b7d5a 100644
--- a/arch/parisc/kernel/traps.c
+++ b/arch/parisc/kernel/traps.c
@@ -532,7 +532,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs)
532 /* Kill the user process later */ 532 /* Kill the user process later */
533 regs->iaoq[0] = 0 | 3; 533 regs->iaoq[0] = 0 | 3;
534 regs->iaoq[1] = regs->iaoq[0] + 4; 534 regs->iaoq[1] = regs->iaoq[0] + 4;
535 regs->iasq[0] = regs->iasq[0] = regs->sr[7]; 535 regs->iasq[0] = regs->iasq[1] = regs->sr[7];
536 regs->gr[0] &= ~PSW_B; 536 regs->gr[0] &= ~PSW_B;
537 return; 537 return;
538 } 538 }
diff --git a/arch/powerpc/kernel/power7-pmu.c b/arch/powerpc/kernel/power7-pmu.c
index 388cf57ad827..018d094d92f9 100644
--- a/arch/powerpc/kernel/power7-pmu.c
+++ b/arch/powerpc/kernel/power7-pmu.c
@@ -317,7 +317,7 @@ static int power7_generic_events[] = {
317 */ 317 */
318static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = { 318static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
319 [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */ 319 [C(L1D)] = { /* RESULT_ACCESS RESULT_MISS */
320 [C(OP_READ)] = { 0x400f0, 0xc880 }, 320 [C(OP_READ)] = { 0xc880, 0x400f0 },
321 [C(OP_WRITE)] = { 0, 0x300f0 }, 321 [C(OP_WRITE)] = { 0, 0x300f0 },
322 [C(OP_PREFETCH)] = { 0xd8b8, 0 }, 322 [C(OP_PREFETCH)] = { 0xd8b8, 0 },
323 }, 323 },
@@ -327,8 +327,8 @@ static int power7_cache_events[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
327 [C(OP_PREFETCH)] = { 0x408a, 0 }, 327 [C(OP_PREFETCH)] = { 0x408a, 0 },
328 }, 328 },
329 [C(LL)] = { /* RESULT_ACCESS RESULT_MISS */ 329 [C(LL)] = { /* RESULT_ACCESS RESULT_MISS */
330 [C(OP_READ)] = { 0x6080, 0x6084 }, 330 [C(OP_READ)] = { 0x16080, 0x26080 },
331 [C(OP_WRITE)] = { 0x6082, 0x6086 }, 331 [C(OP_WRITE)] = { 0x16082, 0x26082 },
332 [C(OP_PREFETCH)] = { 0, 0 }, 332 [C(OP_PREFETCH)] = { 0, 0 },
333 }, 333 },
334 [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */ 334 [C(DTLB)] = { /* RESULT_ACCESS RESULT_MISS */
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 3ee1fd37bbfc..40edad520770 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -234,7 +234,6 @@ static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
234 generic_handle_irq(cascade_irq); 234 generic_handle_irq(cascade_irq);
235 235
236 /* Let xilinx_intc end the interrupt */ 236 /* Let xilinx_intc end the interrupt */
237 desc->chip->ack(irq);
238 desc->chip->unmask(irq); 237 desc->chip->unmask(irq);
239} 238}
240 239
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index f0ee79055409..8daab33fc17d 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -886,7 +886,7 @@ void notrace init_irqwork_curcpu(void)
886 * Therefore you cannot make any OBP calls, not even prom_printf, 886 * Therefore you cannot make any OBP calls, not even prom_printf,
887 * from these two routines. 887 * from these two routines.
888 */ 888 */
889static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask) 889static void __cpuinit notrace register_one_mondo(unsigned long paddr, unsigned long type, unsigned long qmask)
890{ 890{
891 unsigned long num_entries = (qmask + 1) / 64; 891 unsigned long num_entries = (qmask + 1) / 64;
892 unsigned long status; 892 unsigned long status;
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c
index 2c0cc72d295b..b75bf502cd42 100644
--- a/arch/sparc/kernel/nmi.c
+++ b/arch/sparc/kernel/nmi.c
@@ -103,7 +103,7 @@ notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs)
103 } 103 }
104 if (!touched && __get_cpu_var(last_irq_sum) == sum) { 104 if (!touched && __get_cpu_var(last_irq_sum) == sum) {
105 local_inc(&__get_cpu_var(alert_counter)); 105 local_inc(&__get_cpu_var(alert_counter));
106 if (local_read(&__get_cpu_var(alert_counter)) == 5 * nmi_hz) 106 if (local_read(&__get_cpu_var(alert_counter)) == 30 * nmi_hz)
107 die_nmi("BUG: NMI Watchdog detected LOCKUP", 107 die_nmi("BUG: NMI Watchdog detected LOCKUP",
108 regs, panic_on_timeout); 108 regs, panic_on_timeout);
109 } else { 109 } else {
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index eedffb4fec2d..39fc6af21b7c 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -88,7 +88,7 @@ void prom_cmdline(void)
88/* Drop into the prom, but completely terminate the program. 88/* Drop into the prom, but completely terminate the program.
89 * No chance of continuing. 89 * No chance of continuing.
90 */ 90 */
91void prom_halt(void) 91void notrace prom_halt(void)
92{ 92{
93#ifdef CONFIG_SUN_LDOMS 93#ifdef CONFIG_SUN_LDOMS
94 if (ldom_domaining_enabled) 94 if (ldom_domaining_enabled)
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index 660943ee4c2a..ca869266b9f3 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -14,14 +14,14 @@
14 */ 14 */
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/compiler.h>
17 18
18#include <asm/openprom.h> 19#include <asm/openprom.h>
19#include <asm/oplib.h> 20#include <asm/oplib.h>
20 21
21static char ppbuf[1024]; 22static char ppbuf[1024];
22 23
23void 24void notrace prom_write(const char *buf, unsigned int n)
24prom_write(const char *buf, unsigned int n)
25{ 25{
26 char ch; 26 char ch;
27 27
@@ -33,8 +33,7 @@ prom_write(const char *buf, unsigned int n)
33 } 33 }
34} 34}
35 35
36void 36void notrace prom_printf(const char *fmt, ...)
37prom_printf(const char *fmt, ...)
38{ 37{
39 va_list args; 38 va_list args;
40 int i; 39 int i;
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c
index bc3e880f9b82..fcec2f1d34a1 100644
--- a/arch/x86/kernel/apic/probe_64.c
+++ b/arch/x86/kernel/apic/probe_64.c
@@ -44,6 +44,11 @@ static struct apic *apic_probe[] __initdata = {
44 NULL, 44 NULL,
45}; 45};
46 46
47static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
48{
49 return hard_smp_processor_id() >> index_msb;
50}
51
47/* 52/*
48 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. 53 * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode.
49 */ 54 */
@@ -69,6 +74,11 @@ void __init default_setup_apic_routing(void)
69 printk(KERN_INFO "Setting APIC routing to %s\n", apic->name); 74 printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
70 } 75 }
71 76
77 if (is_vsmp_box()) {
78 /* need to update phys_pkg_id */
79 apic->phys_pkg_id = apicid_phys_pkg_id;
80 }
81
72 /* 82 /*
73 * Now that apic routing model is selected, configure the 83 * Now that apic routing model is selected, configure the
74 * fault handling for intr remapping. 84 * fault handling for intr remapping.
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index e90540a46a0b..eb33aaa8415d 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -215,6 +215,7 @@ static __init void xen_init_cpuid_mask(void)
215 (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 215 (1 << X86_FEATURE_ACPI)); /* disable ACPI */
216 216
217 ax = 1; 217 ax = 1;
218 cx = 0;
218 xen_cpuid(&ax, &bx, &cx, &dx); 219 xen_cpuid(&ax, &bx, &cx, &dx);
219 220
220 /* cpuid claims we support xsave; try enabling it to see what happens */ 221 /* cpuid claims we support xsave; try enabling it to see what happens */
@@ -1059,6 +1060,7 @@ asmlinkage void __init xen_start_kernel(void)
1059 /* set up basic CPUID stuff */ 1060 /* set up basic CPUID stuff */
1060 cpu_detect(&new_cpu_data); 1061 cpu_detect(&new_cpu_data);
1061 new_cpu_data.hard_math = 1; 1062 new_cpu_data.hard_math = 1;
1063 new_cpu_data.wp_works_ok = 1;
1062 new_cpu_data.x86_capability[0] = cpuid_edx(1); 1064 new_cpu_data.x86_capability[0] = cpuid_edx(1);
1063#endif 1065#endif
1064 1066
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 418d63619680..d3aa2aadb3e0 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -133,7 +133,7 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
133 return -EINVAL; 133 return -EINVAL;
134 134
135 spin_lock_irq(q->queue_lock); 135 spin_lock_irq(q->queue_lock);
136 blk_queue_max_sectors(q, max_sectors_kb << 1); 136 q->limits.max_sectors = max_sectors_kb << 1;
137 spin_unlock_irq(q->queue_lock); 137 spin_unlock_irq(q->queue_lock);
138 138
139 return ret; 139 return ret;
diff --git a/crypto/algapi.c b/crypto/algapi.c
index 56c62e2858d5..df0863d56995 100644
--- a/crypto/algapi.c
+++ b/crypto/algapi.c
@@ -692,7 +692,7 @@ out:
692} 692}
693EXPORT_SYMBOL_GPL(crypto_enqueue_request); 693EXPORT_SYMBOL_GPL(crypto_enqueue_request);
694 694
695struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue) 695void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset)
696{ 696{
697 struct list_head *request; 697 struct list_head *request;
698 698
@@ -707,7 +707,14 @@ struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
707 request = queue->list.next; 707 request = queue->list.next;
708 list_del(request); 708 list_del(request);
709 709
710 return list_entry(request, struct crypto_async_request, list); 710 return (char *)list_entry(request, struct crypto_async_request, list) -
711 offset;
712}
713EXPORT_SYMBOL_GPL(__crypto_dequeue_request);
714
715struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue)
716{
717 return __crypto_dequeue_request(queue, 0);
711} 718}
712EXPORT_SYMBOL_GPL(crypto_dequeue_request); 719EXPORT_SYMBOL_GPL(crypto_dequeue_request);
713 720
diff --git a/drivers/acpi/acpica/exstorob.c b/drivers/acpi/acpica/exstorob.c
index 67340cc70142..257706e7734f 100644
--- a/drivers/acpi/acpica/exstorob.c
+++ b/drivers/acpi/acpica/exstorob.c
@@ -70,6 +70,12 @@ acpi_ex_store_buffer_to_buffer(union acpi_operand_object *source_desc,
70 70
71 ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc); 71 ACPI_FUNCTION_TRACE_PTR(ex_store_buffer_to_buffer, source_desc);
72 72
73 /* If Source and Target are the same, just return */
74
75 if (source_desc == target_desc) {
76 return_ACPI_STATUS(AE_OK);
77 }
78
73 /* We know that source_desc is a buffer by now */ 79 /* We know that source_desc is a buffer by now */
74 80
75 buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer); 81 buffer = ACPI_CAST_PTR(u8, source_desc->buffer.pointer);
@@ -161,6 +167,12 @@ acpi_ex_store_string_to_string(union acpi_operand_object *source_desc,
161 167
162 ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc); 168 ACPI_FUNCTION_TRACE_PTR(ex_store_string_to_string, source_desc);
163 169
170 /* If Source and Target are the same, just return */
171
172 if (source_desc == target_desc) {
173 return_ACPI_STATUS(AE_OK);
174 }
175
164 /* We know that source_desc is a string by now */ 176 /* We know that source_desc is a string by now */
165 177
166 buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer); 178 buffer = ACPI_CAST_PTR(u8, source_desc->string.pointer);
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 8851315ce858..60ea984c84a0 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -2004,8 +2004,11 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
2004 status = acpi_remove_notify_handler(device->dev->handle, 2004 status = acpi_remove_notify_handler(device->dev->handle,
2005 ACPI_DEVICE_NOTIFY, 2005 ACPI_DEVICE_NOTIFY,
2006 acpi_video_device_notify); 2006 acpi_video_device_notify);
2007 sysfs_remove_link(&device->backlight->dev.kobj, "device"); 2007 if (device->backlight) {
2008 backlight_device_unregister(device->backlight); 2008 sysfs_remove_link(&device->backlight->dev.kobj, "device");
2009 backlight_device_unregister(device->backlight);
2010 device->backlight = NULL;
2011 }
2009 if (device->cdev) { 2012 if (device->cdev) {
2010 sysfs_remove_link(&device->dev->dev.kobj, 2013 sysfs_remove_link(&device->dev->dev.kobj,
2011 "thermal_cooling"); 2014 "thermal_cooling");
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 56b8a3ff1286..9ac4e378992e 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -664,6 +664,8 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
664 return ata_sff_prereset(link, deadline); 664 return ata_sff_prereset(link, deadline);
665} 665}
666 666
667static DEFINE_SPINLOCK(piix_lock);
668
667/** 669/**
668 * piix_set_piomode - Initialize host controller PATA PIO timings 670 * piix_set_piomode - Initialize host controller PATA PIO timings
669 * @ap: Port whose timings we are configuring 671 * @ap: Port whose timings we are configuring
@@ -677,8 +679,9 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
677 679
678static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev) 680static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
679{ 681{
680 unsigned int pio = adev->pio_mode - XFER_PIO_0;
681 struct pci_dev *dev = to_pci_dev(ap->host->dev); 682 struct pci_dev *dev = to_pci_dev(ap->host->dev);
683 unsigned long flags;
684 unsigned int pio = adev->pio_mode - XFER_PIO_0;
682 unsigned int is_slave = (adev->devno != 0); 685 unsigned int is_slave = (adev->devno != 0);
683 unsigned int master_port= ap->port_no ? 0x42 : 0x40; 686 unsigned int master_port= ap->port_no ? 0x42 : 0x40;
684 unsigned int slave_port = 0x44; 687 unsigned int slave_port = 0x44;
@@ -708,6 +711,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
708 if (adev->class == ATA_DEV_ATA) 711 if (adev->class == ATA_DEV_ATA)
709 control |= 4; /* PPE enable */ 712 control |= 4; /* PPE enable */
710 713
714 spin_lock_irqsave(&piix_lock, flags);
715
711 /* PIO configuration clears DTE unconditionally. It will be 716 /* PIO configuration clears DTE unconditionally. It will be
712 * programmed in set_dmamode which is guaranteed to be called 717 * programmed in set_dmamode which is guaranteed to be called
713 * after set_piomode if any DMA mode is available. 718 * after set_piomode if any DMA mode is available.
@@ -747,6 +752,8 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
747 udma_enable &= ~(1 << (2 * ap->port_no + adev->devno)); 752 udma_enable &= ~(1 << (2 * ap->port_no + adev->devno));
748 pci_write_config_byte(dev, 0x48, udma_enable); 753 pci_write_config_byte(dev, 0x48, udma_enable);
749 } 754 }
755
756 spin_unlock_irqrestore(&piix_lock, flags);
750} 757}
751 758
752/** 759/**
@@ -764,6 +771,7 @@ static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev)
764static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich) 771static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, int isich)
765{ 772{
766 struct pci_dev *dev = to_pci_dev(ap->host->dev); 773 struct pci_dev *dev = to_pci_dev(ap->host->dev);
774 unsigned long flags;
767 u8 master_port = ap->port_no ? 0x42 : 0x40; 775 u8 master_port = ap->port_no ? 0x42 : 0x40;
768 u16 master_data; 776 u16 master_data;
769 u8 speed = adev->dma_mode; 777 u8 speed = adev->dma_mode;
@@ -777,6 +785,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
777 { 2, 1 }, 785 { 2, 1 },
778 { 2, 3 }, }; 786 { 2, 3 }, };
779 787
788 spin_lock_irqsave(&piix_lock, flags);
789
780 pci_read_config_word(dev, master_port, &master_data); 790 pci_read_config_word(dev, master_port, &master_data);
781 if (ap->udma_mask) 791 if (ap->udma_mask)
782 pci_read_config_byte(dev, 0x48, &udma_enable); 792 pci_read_config_byte(dev, 0x48, &udma_enable);
@@ -867,6 +877,8 @@ static void do_pata_set_dmamode(struct ata_port *ap, struct ata_device *adev, in
867 /* Don't scribble on 0x48 if the controller does not support UDMA */ 877 /* Don't scribble on 0x48 if the controller does not support UDMA */
868 if (ap->udma_mask) 878 if (ap->udma_mask)
869 pci_write_config_byte(dev, 0x48, udma_enable); 879 pci_write_config_byte(dev, 0x48, udma_enable);
880
881 spin_unlock_irqrestore(&piix_lock, flags);
870} 882}
871 883
872/** 884/**
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h
index 5e41e6dd657b..db195abad698 100644
--- a/drivers/block/aoe/aoe.h
+++ b/drivers/block/aoe/aoe.h
@@ -155,7 +155,7 @@ struct aoedev {
155 u16 fw_ver; /* version of blade's firmware */ 155 u16 fw_ver; /* version of blade's firmware */
156 struct work_struct work;/* disk create work struct */ 156 struct work_struct work;/* disk create work struct */
157 struct gendisk *gd; 157 struct gendisk *gd;
158 struct request_queue blkq; 158 struct request_queue *blkq;
159 struct hd_geometry geo; 159 struct hd_geometry geo;
160 sector_t ssize; 160 sector_t ssize;
161 struct timer_list timer; 161 struct timer_list timer;
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index 2307a271bdc9..1e15889c4b98 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -264,9 +264,12 @@ aoeblk_gdalloc(void *vp)
264 goto err_disk; 264 goto err_disk;
265 } 265 }
266 266
267 blk_queue_make_request(&d->blkq, aoeblk_make_request); 267 d->blkq = blk_alloc_queue(GFP_KERNEL);
268 if (bdi_init(&d->blkq.backing_dev_info)) 268 if (!d->blkq)
269 goto err_mempool; 269 goto err_mempool;
270 blk_queue_make_request(d->blkq, aoeblk_make_request);
271 if (bdi_init(&d->blkq->backing_dev_info))
272 goto err_blkq;
270 spin_lock_irqsave(&d->lock, flags); 273 spin_lock_irqsave(&d->lock, flags);
271 gd->major = AOE_MAJOR; 274 gd->major = AOE_MAJOR;
272 gd->first_minor = d->sysminor * AOE_PARTITIONS; 275 gd->first_minor = d->sysminor * AOE_PARTITIONS;
@@ -276,7 +279,7 @@ aoeblk_gdalloc(void *vp)
276 snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", 279 snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d",
277 d->aoemajor, d->aoeminor); 280 d->aoemajor, d->aoeminor);
278 281
279 gd->queue = &d->blkq; 282 gd->queue = d->blkq;
280 d->gd = gd; 283 d->gd = gd;
281 d->flags &= ~DEVFL_GDALLOC; 284 d->flags &= ~DEVFL_GDALLOC;
282 d->flags |= DEVFL_UP; 285 d->flags |= DEVFL_UP;
@@ -287,6 +290,9 @@ aoeblk_gdalloc(void *vp)
287 aoedisk_add_sysfs(d); 290 aoedisk_add_sysfs(d);
288 return; 291 return;
289 292
293err_blkq:
294 blk_cleanup_queue(d->blkq);
295 d->blkq = NULL;
290err_mempool: 296err_mempool:
291 mempool_destroy(d->bufpool); 297 mempool_destroy(d->bufpool);
292err_disk: 298err_disk:
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c
index eeea477d9601..fa67027789aa 100644
--- a/drivers/block/aoe/aoedev.c
+++ b/drivers/block/aoe/aoedev.c
@@ -113,6 +113,7 @@ aoedev_freedev(struct aoedev *d)
113 if (d->bufpool) 113 if (d->bufpool)
114 mempool_destroy(d->bufpool); 114 mempool_destroy(d->bufpool);
115 skbpoolfree(d); 115 skbpoolfree(d);
116 blk_cleanup_queue(d->blkq);
116 kfree(d); 117 kfree(d);
117} 118}
118 119
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 8c9d50db5c3a..c58557790585 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -49,6 +49,7 @@
49#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040 49#define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040
50#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 50#define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042
51#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 51#define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044
52#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062
52#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 53#define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046
53 54
54/* cover 915 and 945 variants */ 55/* cover 915 and 945 variants */
@@ -81,7 +82,8 @@
81 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ 82 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \
82 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ 83 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \
83 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ 84 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \
84 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB) 85 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \
86 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB)
85 87
86extern int agp_memory_reserved; 88extern int agp_memory_reserved;
87 89
@@ -1216,6 +1218,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
1216 case PCI_DEVICE_ID_INTEL_G41_HB: 1218 case PCI_DEVICE_ID_INTEL_G41_HB:
1217 case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: 1219 case PCI_DEVICE_ID_INTEL_IGDNG_D_HB:
1218 case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: 1220 case PCI_DEVICE_ID_INTEL_IGDNG_M_HB:
1221 case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB:
1219 *gtt_offset = *gtt_size = MB(2); 1222 *gtt_offset = *gtt_size = MB(2);
1220 break; 1223 break;
1221 default: 1224 default:
@@ -2195,6 +2198,8 @@ static const struct intel_driver_description {
2195 "IGDNG/D", NULL, &intel_i965_driver }, 2198 "IGDNG/D", NULL, &intel_i965_driver },
2196 { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, 2199 { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
2197 "IGDNG/M", NULL, &intel_i965_driver }, 2200 "IGDNG/M", NULL, &intel_i965_driver },
2201 { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0,
2202 "IGDNG/MA", NULL, &intel_i965_driver },
2198 { 0, 0, 0, NULL, NULL, NULL } 2203 { 0, 0, 0, NULL, NULL, NULL }
2199}; 2204};
2200 2205
@@ -2398,6 +2403,7 @@ static struct pci_device_id agp_intel_pci_table[] = {
2398 ID(PCI_DEVICE_ID_INTEL_G41_HB), 2403 ID(PCI_DEVICE_ID_INTEL_G41_HB),
2399 ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), 2404 ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB),
2400 ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), 2405 ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB),
2406 ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB),
2401 { } 2407 { }
2402}; 2408};
2403 2409
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 973be2f44195..4e28b35024ec 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -300,8 +300,7 @@ static int do_output_char(unsigned char c, struct tty_struct *tty, int space)
300 if (space < 2) 300 if (space < 2)
301 return -1; 301 return -1;
302 tty->canon_column = tty->column = 0; 302 tty->canon_column = tty->column = 0;
303 tty_put_char(tty, '\r'); 303 tty->ops->write(tty, "\r\n", 2);
304 tty_put_char(tty, c);
305 return 2; 304 return 2;
306 } 305 }
307 tty->canon_column = tty->column; 306 tty->canon_column = tty->column;
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index d083c73d784a..b33d6688e910 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -109,21 +109,13 @@ static int pty_space(struct tty_struct *to)
109 * the other side of the pty/tty pair. 109 * the other side of the pty/tty pair.
110 */ 110 */
111 111
112static int pty_write(struct tty_struct *tty, const unsigned char *buf, 112static int pty_write(struct tty_struct *tty, const unsigned char *buf, int c)
113 int count)
114{ 113{
115 struct tty_struct *to = tty->link; 114 struct tty_struct *to = tty->link;
116 int c;
117 115
118 if (tty->stopped) 116 if (tty->stopped)
119 return 0; 117 return 0;
120 118
121 /* This isn't locked but our 8K is quite sloppy so no
122 big deal */
123
124 c = pty_space(to);
125 if (c > count)
126 c = count;
127 if (c > 0) { 119 if (c > 0) {
128 /* Stuff the data into the input queue of the other end */ 120 /* Stuff the data into the input queue of the other end */
129 c = tty_insert_flip_string(to, buf, c); 121 c = tty_insert_flip_string(to, buf, c);
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index fd69086d08d5..2968ed6a9c49 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1250,20 +1250,11 @@ static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg)
1250{ 1250{
1251 int ret = 0; 1251 int ret = 0;
1252 1252
1253#ifdef __powerpc__
1254 int cpu = sysdev->id; 1253 int cpu = sysdev->id;
1255 unsigned int cur_freq = 0;
1256 struct cpufreq_policy *cpu_policy; 1254 struct cpufreq_policy *cpu_policy;
1257 1255
1258 dprintk("suspending cpu %u\n", cpu); 1256 dprintk("suspending cpu %u\n", cpu);
1259 1257
1260 /*
1261 * This whole bogosity is here because Powerbooks are made of fail.
1262 * No sane platform should need any of the code below to be run.
1263 * (it's entirely the wrong thing to do, as driver->get may
1264 * reenable interrupts on some architectures).
1265 */
1266
1267 if (!cpu_online(cpu)) 1258 if (!cpu_online(cpu))
1268 return 0; 1259 return 0;
1269 1260
@@ -1282,47 +1273,13 @@ static int cpufreq_suspend(struct sys_device *sysdev, pm_message_t pmsg)
1282 1273
1283 if (cpufreq_driver->suspend) { 1274 if (cpufreq_driver->suspend) {
1284 ret = cpufreq_driver->suspend(cpu_policy, pmsg); 1275 ret = cpufreq_driver->suspend(cpu_policy, pmsg);
1285 if (ret) { 1276 if (ret)
1286 printk(KERN_ERR "cpufreq: suspend failed in ->suspend " 1277 printk(KERN_ERR "cpufreq: suspend failed in ->suspend "
1287 "step on CPU %u\n", cpu_policy->cpu); 1278 "step on CPU %u\n", cpu_policy->cpu);
1288 goto out;
1289 }
1290 }
1291
1292 if (cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)
1293 goto out;
1294
1295 if (cpufreq_driver->get)
1296 cur_freq = cpufreq_driver->get(cpu_policy->cpu);
1297
1298 if (!cur_freq || !cpu_policy->cur) {
1299 printk(KERN_ERR "cpufreq: suspend failed to assert current "
1300 "frequency is what timing core thinks it is.\n");
1301 goto out;
1302 }
1303
1304 if (unlikely(cur_freq != cpu_policy->cur)) {
1305 struct cpufreq_freqs freqs;
1306
1307 if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
1308 dprintk("Warning: CPU frequency is %u, "
1309 "cpufreq assumed %u kHz.\n",
1310 cur_freq, cpu_policy->cur);
1311
1312 freqs.cpu = cpu;
1313 freqs.old = cpu_policy->cur;
1314 freqs.new = cur_freq;
1315
1316 srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
1317 CPUFREQ_SUSPENDCHANGE, &freqs);
1318 adjust_jiffies(CPUFREQ_SUSPENDCHANGE, &freqs);
1319
1320 cpu_policy->cur = cur_freq;
1321 } 1279 }
1322 1280
1323out: 1281out:
1324 cpufreq_cpu_put(cpu_policy); 1282 cpufreq_cpu_put(cpu_policy);
1325#endif /* __powerpc__ */
1326 return ret; 1283 return ret;
1327} 1284}
1328 1285
@@ -1330,24 +1287,21 @@ out:
1330 * cpufreq_resume - restore proper CPU frequency handling after resume 1287 * cpufreq_resume - restore proper CPU frequency handling after resume
1331 * 1288 *
1332 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume()) 1289 * 1.) resume CPUfreq hardware support (cpufreq_driver->resume())
1333 * 2.) if ->target and !CPUFREQ_CONST_LOOPS: verify we're in sync 1290 * 2.) schedule call cpufreq_update_policy() ASAP as interrupts are
1334 * 3.) schedule call cpufreq_update_policy() ASAP as interrupts are 1291 * restored. It will verify that the current freq is in sync with
1335 * restored. 1292 * what we believe it to be. This is a bit later than when it
1293 * should be, but nonethteless it's better than calling
1294 * cpufreq_driver->get() here which might re-enable interrupts...
1336 */ 1295 */
1337static int cpufreq_resume(struct sys_device *sysdev) 1296static int cpufreq_resume(struct sys_device *sysdev)
1338{ 1297{
1339 int ret = 0; 1298 int ret = 0;
1340 1299
1341#ifdef __powerpc__
1342 int cpu = sysdev->id; 1300 int cpu = sysdev->id;
1343 struct cpufreq_policy *cpu_policy; 1301 struct cpufreq_policy *cpu_policy;
1344 1302
1345 dprintk("resuming cpu %u\n", cpu); 1303 dprintk("resuming cpu %u\n", cpu);
1346 1304
1347 /* As with the ->suspend method, all the code below is
1348 * only necessary because Powerbooks suck.
1349 * See commit 42d4dc3f4e1e for jokes. */
1350
1351 if (!cpu_online(cpu)) 1305 if (!cpu_online(cpu))
1352 return 0; 1306 return 0;
1353 1307
@@ -1373,45 +1327,10 @@ static int cpufreq_resume(struct sys_device *sysdev)
1373 } 1327 }
1374 } 1328 }
1375 1329
1376 if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
1377 unsigned int cur_freq = 0;
1378
1379 if (cpufreq_driver->get)
1380 cur_freq = cpufreq_driver->get(cpu_policy->cpu);
1381
1382 if (!cur_freq || !cpu_policy->cur) {
1383 printk(KERN_ERR "cpufreq: resume failed to assert "
1384 "current frequency is what timing core "
1385 "thinks it is.\n");
1386 goto out;
1387 }
1388
1389 if (unlikely(cur_freq != cpu_policy->cur)) {
1390 struct cpufreq_freqs freqs;
1391
1392 if (!(cpufreq_driver->flags & CPUFREQ_PM_NO_WARN))
1393 dprintk("Warning: CPU frequency "
1394 "is %u, cpufreq assumed %u kHz.\n",
1395 cur_freq, cpu_policy->cur);
1396
1397 freqs.cpu = cpu;
1398 freqs.old = cpu_policy->cur;
1399 freqs.new = cur_freq;
1400
1401 srcu_notifier_call_chain(
1402 &cpufreq_transition_notifier_list,
1403 CPUFREQ_RESUMECHANGE, &freqs);
1404 adjust_jiffies(CPUFREQ_RESUMECHANGE, &freqs);
1405
1406 cpu_policy->cur = cur_freq;
1407 }
1408 }
1409
1410out:
1411 schedule_work(&cpu_policy->update); 1330 schedule_work(&cpu_policy->update);
1331
1412fail: 1332fail:
1413 cpufreq_cpu_put(cpu_policy); 1333 cpufreq_cpu_put(cpu_policy);
1414#endif /* __powerpc__ */
1415 return ret; 1334 return ret;
1416} 1335}
1417 1336
diff --git a/drivers/firewire/core-iso.c b/drivers/firewire/core-iso.c
index 110e731f5574..1c0b504a42f3 100644
--- a/drivers/firewire/core-iso.c
+++ b/drivers/firewire/core-iso.c
@@ -196,7 +196,7 @@ static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
196 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, 196 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
197 irm_id, generation, SCODE_100, 197 irm_id, generation, SCODE_100,
198 CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE, 198 CSR_REGISTER_BASE + CSR_BANDWIDTH_AVAILABLE,
199 data, sizeof(data))) { 199 data, 8)) {
200 case RCODE_GENERATION: 200 case RCODE_GENERATION:
201 /* A generation change frees all bandwidth. */ 201 /* A generation change frees all bandwidth. */
202 return allocate ? -EAGAIN : bandwidth; 202 return allocate ? -EAGAIN : bandwidth;
@@ -233,7 +233,7 @@ static int manage_channel(struct fw_card *card, int irm_id, int generation,
233 data[1] = old ^ c; 233 data[1] = old ^ c;
234 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP, 234 switch (fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
235 irm_id, generation, SCODE_100, 235 irm_id, generation, SCODE_100,
236 offset, data, sizeof(data))) { 236 offset, data, 8)) {
237 case RCODE_GENERATION: 237 case RCODE_GENERATION:
238 /* A generation change frees all channels. */ 238 /* A generation change frees all channels. */
239 return allocate ? -EAGAIN : i; 239 return allocate ? -EAGAIN : i;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index ecddd11b797a..76b321bb73f9 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -34,6 +34,7 @@
34#include <linux/module.h> 34#include <linux/module.h>
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/pci_ids.h>
37#include <linux/spinlock.h> 38#include <linux/spinlock.h>
38#include <linux/string.h> 39#include <linux/string.h>
39 40
@@ -2372,6 +2373,9 @@ static void ohci_pmac_off(struct pci_dev *dev)
2372#define ohci_pmac_off(dev) 2373#define ohci_pmac_off(dev)
2373#endif /* CONFIG_PPC_PMAC */ 2374#endif /* CONFIG_PPC_PMAC */
2374 2375
2376#define PCI_VENDOR_ID_AGERE PCI_VENDOR_ID_ATT
2377#define PCI_DEVICE_ID_AGERE_FW643 0x5901
2378
2375static int __devinit pci_probe(struct pci_dev *dev, 2379static int __devinit pci_probe(struct pci_dev *dev,
2376 const struct pci_device_id *ent) 2380 const struct pci_device_id *ent)
2377{ 2381{
@@ -2422,6 +2426,16 @@ static int __devinit pci_probe(struct pci_dev *dev,
2422 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; 2426 version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff;
2423 ohci->use_dualbuffer = version >= OHCI_VERSION_1_1; 2427 ohci->use_dualbuffer = version >= OHCI_VERSION_1_1;
2424 2428
2429 /* dual-buffer mode is broken if more than one IR context is active */
2430 if (dev->vendor == PCI_VENDOR_ID_AGERE &&
2431 dev->device == PCI_DEVICE_ID_AGERE_FW643)
2432 ohci->use_dualbuffer = false;
2433
2434 /* dual-buffer mode is broken */
2435 if (dev->vendor == PCI_VENDOR_ID_RICOH &&
2436 dev->device == PCI_DEVICE_ID_RICOH_R5C832)
2437 ohci->use_dualbuffer = false;
2438
2425/* x86-32 currently doesn't use highmem for dma_alloc_coherent */ 2439/* x86-32 currently doesn't use highmem for dma_alloc_coherent */
2426#if !defined(CONFIG_X86_32) 2440#if !defined(CONFIG_X86_32)
2427 /* dual-buffer mode is broken with descriptor addresses above 2G */ 2441 /* dual-buffer mode is broken with descriptor addresses above 2G */
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 8d51568ee143..e5df822a8130 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -456,12 +456,12 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request,
456 } 456 }
457 spin_unlock_irqrestore(&card->lock, flags); 457 spin_unlock_irqrestore(&card->lock, flags);
458 458
459 if (&orb->link != &lu->orb_list) 459 if (&orb->link != &lu->orb_list) {
460 orb->callback(orb, &status); 460 orb->callback(orb, &status);
461 else 461 kref_put(&orb->kref, free_orb);
462 } else {
462 fw_error("status write for unknown orb\n"); 463 fw_error("status write for unknown orb\n");
463 464 }
464 kref_put(&orb->kref, free_orb);
465 465
466 fw_send_response(card, request, RCODE_COMPLETE); 466 fw_send_response(card, request, RCODE_COMPLETE);
467} 467}
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 7537f57d8a87..5b4f87e55621 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -222,6 +222,7 @@ typedef struct drm_i915_private {
222 unsigned int edp_support:1; 222 unsigned int edp_support:1;
223 int lvds_ssc_freq; 223 int lvds_ssc_freq;
224 224
225 int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */
225 struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ 226 struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */
226 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ 227 int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
227 int num_fence_regs; /* 8 on pre-965, 16 otherwise */ 228 int num_fence_regs; /* 8 on pre-965, 16 otherwise */
@@ -384,6 +385,9 @@ typedef struct drm_i915_private {
384 */ 385 */
385 struct list_head inactive_list; 386 struct list_head inactive_list;
386 387
388 /** LRU list of objects with fence regs on them. */
389 struct list_head fence_list;
390
387 /** 391 /**
388 * List of breadcrumbs associated with GPU requests currently 392 * List of breadcrumbs associated with GPU requests currently
389 * outstanding. 393 * outstanding.
@@ -451,6 +455,9 @@ struct drm_i915_gem_object {
451 /** This object's place on the active/flushing/inactive lists */ 455 /** This object's place on the active/flushing/inactive lists */
452 struct list_head list; 456 struct list_head list;
453 457
458 /** This object's place on the fenced object LRU */
459 struct list_head fence_list;
460
454 /** 461 /**
455 * This is set if the object is on the active or flushing lists 462 * This is set if the object is on the active or flushing lists
456 * (has pending rendering), and is not set if it's on inactive (ready 463 * (has pending rendering), and is not set if it's on inactive (ready
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 140bee142fc2..80e5ba490dc2 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -978,6 +978,7 @@ int
978i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, 978i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
979 struct drm_file *file_priv) 979 struct drm_file *file_priv)
980{ 980{
981 struct drm_i915_private *dev_priv = dev->dev_private;
981 struct drm_i915_gem_set_domain *args = data; 982 struct drm_i915_gem_set_domain *args = data;
982 struct drm_gem_object *obj; 983 struct drm_gem_object *obj;
983 uint32_t read_domains = args->read_domains; 984 uint32_t read_domains = args->read_domains;
@@ -1010,8 +1011,18 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1010 obj, obj->size, read_domains, write_domain); 1011 obj, obj->size, read_domains, write_domain);
1011#endif 1012#endif
1012 if (read_domains & I915_GEM_DOMAIN_GTT) { 1013 if (read_domains & I915_GEM_DOMAIN_GTT) {
1014 struct drm_i915_gem_object *obj_priv = obj->driver_private;
1015
1013 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); 1016 ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0);
1014 1017
1018 /* Update the LRU on the fence for the CPU access that's
1019 * about to occur.
1020 */
1021 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
1022 list_move_tail(&obj_priv->fence_list,
1023 &dev_priv->mm.fence_list);
1024 }
1025
1015 /* Silently promote "you're not bound, there was nothing to do" 1026 /* Silently promote "you're not bound, there was nothing to do"
1016 * to success, since the client was just asking us to 1027 * to success, since the client was just asking us to
1017 * make sure everything was done. 1028 * make sure everything was done.
@@ -1155,8 +1166,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1155 } 1166 }
1156 1167
1157 /* Need a new fence register? */ 1168 /* Need a new fence register? */
1158 if (obj_priv->fence_reg == I915_FENCE_REG_NONE && 1169 if (obj_priv->tiling_mode != I915_TILING_NONE) {
1159 obj_priv->tiling_mode != I915_TILING_NONE) {
1160 ret = i915_gem_object_get_fence_reg(obj); 1170 ret = i915_gem_object_get_fence_reg(obj);
1161 if (ret) { 1171 if (ret) {
1162 mutex_unlock(&dev->struct_mutex); 1172 mutex_unlock(&dev->struct_mutex);
@@ -2208,6 +2218,12 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
2208 struct drm_i915_gem_object *old_obj_priv = NULL; 2218 struct drm_i915_gem_object *old_obj_priv = NULL;
2209 int i, ret, avail; 2219 int i, ret, avail;
2210 2220
2221 /* Just update our place in the LRU if our fence is getting used. */
2222 if (obj_priv->fence_reg != I915_FENCE_REG_NONE) {
2223 list_move_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
2224 return 0;
2225 }
2226
2211 switch (obj_priv->tiling_mode) { 2227 switch (obj_priv->tiling_mode) {
2212 case I915_TILING_NONE: 2228 case I915_TILING_NONE:
2213 WARN(1, "allocating a fence for non-tiled object?\n"); 2229 WARN(1, "allocating a fence for non-tiled object?\n");
@@ -2229,7 +2245,6 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
2229 } 2245 }
2230 2246
2231 /* First try to find a free reg */ 2247 /* First try to find a free reg */
2232try_again:
2233 avail = 0; 2248 avail = 0;
2234 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { 2249 for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) {
2235 reg = &dev_priv->fence_regs[i]; 2250 reg = &dev_priv->fence_regs[i];
@@ -2243,63 +2258,62 @@ try_again:
2243 2258
2244 /* None available, try to steal one or wait for a user to finish */ 2259 /* None available, try to steal one or wait for a user to finish */
2245 if (i == dev_priv->num_fence_regs) { 2260 if (i == dev_priv->num_fence_regs) {
2246 uint32_t seqno = dev_priv->mm.next_gem_seqno; 2261 struct drm_gem_object *old_obj = NULL;
2247 2262
2248 if (avail == 0) 2263 if (avail == 0)
2249 return -ENOSPC; 2264 return -ENOSPC;
2250 2265
2251 for (i = dev_priv->fence_reg_start; 2266 list_for_each_entry(old_obj_priv, &dev_priv->mm.fence_list,
2252 i < dev_priv->num_fence_regs; i++) { 2267 fence_list) {
2253 uint32_t this_seqno; 2268 old_obj = old_obj_priv->obj;
2254
2255 reg = &dev_priv->fence_regs[i];
2256 old_obj_priv = reg->obj->driver_private;
2257 2269
2258 if (old_obj_priv->pin_count) 2270 if (old_obj_priv->pin_count)
2259 continue; 2271 continue;
2260 2272
2273 /* Take a reference, as otherwise the wait_rendering
2274 * below may cause the object to get freed out from
2275 * under us.
2276 */
2277 drm_gem_object_reference(old_obj);
2278
2261 /* i915 uses fences for GPU access to tiled buffers */ 2279 /* i915 uses fences for GPU access to tiled buffers */
2262 if (IS_I965G(dev) || !old_obj_priv->active) 2280 if (IS_I965G(dev) || !old_obj_priv->active)
2263 break; 2281 break;
2264 2282
2265 /* find the seqno of the first available fence */ 2283 /* This brings the object to the head of the LRU if it
2266 this_seqno = old_obj_priv->last_rendering_seqno; 2284 * had been written to. The only way this should
2267 if (this_seqno != 0 && 2285 * result in us waiting longer than the expected
2268 reg->obj->write_domain == 0 && 2286 * optimal amount of time is if there was a
2269 i915_seqno_passed(seqno, this_seqno)) 2287 * fence-using buffer later that was read-only.
2270 seqno = this_seqno; 2288 */
2271 } 2289 i915_gem_object_flush_gpu_write_domain(old_obj);
2272 2290 ret = i915_gem_object_wait_rendering(old_obj);
2273 /* 2291 if (ret != 0) {
2274 * Now things get ugly... we have to wait for one of the 2292 drm_gem_object_unreference(old_obj);
2275 * objects to finish before trying again. 2293 return ret;
2276 */
2277 if (i == dev_priv->num_fence_regs) {
2278 if (seqno == dev_priv->mm.next_gem_seqno) {
2279 i915_gem_flush(dev,
2280 I915_GEM_GPU_DOMAINS,
2281 I915_GEM_GPU_DOMAINS);
2282 seqno = i915_add_request(dev, NULL,
2283 I915_GEM_GPU_DOMAINS);
2284 if (seqno == 0)
2285 return -ENOMEM;
2286 } 2294 }
2287 2295
2288 ret = i915_wait_request(dev, seqno); 2296 break;
2289 if (ret)
2290 return ret;
2291 goto try_again;
2292 } 2297 }
2293 2298
2294 /* 2299 /*
2295 * Zap this virtual mapping so we can set up a fence again 2300 * Zap this virtual mapping so we can set up a fence again
2296 * for this object next time we need it. 2301 * for this object next time we need it.
2297 */ 2302 */
2298 i915_gem_release_mmap(reg->obj); 2303 i915_gem_release_mmap(old_obj);
2304
2305 i = old_obj_priv->fence_reg;
2306 reg = &dev_priv->fence_regs[i];
2307
2299 old_obj_priv->fence_reg = I915_FENCE_REG_NONE; 2308 old_obj_priv->fence_reg = I915_FENCE_REG_NONE;
2309 list_del_init(&old_obj_priv->fence_list);
2310
2311 drm_gem_object_unreference(old_obj);
2300 } 2312 }
2301 2313
2302 obj_priv->fence_reg = i; 2314 obj_priv->fence_reg = i;
2315 list_add_tail(&obj_priv->fence_list, &dev_priv->mm.fence_list);
2316
2303 reg->obj = obj; 2317 reg->obj = obj;
2304 2318
2305 if (IS_I965G(dev)) 2319 if (IS_I965G(dev))
@@ -2342,6 +2356,7 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj)
2342 2356
2343 dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL; 2357 dev_priv->fence_regs[obj_priv->fence_reg].obj = NULL;
2344 obj_priv->fence_reg = I915_FENCE_REG_NONE; 2358 obj_priv->fence_reg = I915_FENCE_REG_NONE;
2359 list_del_init(&obj_priv->fence_list);
2345} 2360}
2346 2361
2347/** 2362/**
@@ -3595,9 +3610,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3595 * Pre-965 chips need a fence register set up in order to 3610 * Pre-965 chips need a fence register set up in order to
3596 * properly handle tiled surfaces. 3611 * properly handle tiled surfaces.
3597 */ 3612 */
3598 if (!IS_I965G(dev) && 3613 if (!IS_I965G(dev) && obj_priv->tiling_mode != I915_TILING_NONE) {
3599 obj_priv->fence_reg == I915_FENCE_REG_NONE &&
3600 obj_priv->tiling_mode != I915_TILING_NONE) {
3601 ret = i915_gem_object_get_fence_reg(obj); 3614 ret = i915_gem_object_get_fence_reg(obj);
3602 if (ret != 0) { 3615 if (ret != 0) {
3603 if (ret != -EBUSY && ret != -ERESTARTSYS) 3616 if (ret != -EBUSY && ret != -ERESTARTSYS)
@@ -3806,6 +3819,7 @@ int i915_gem_init_object(struct drm_gem_object *obj)
3806 obj_priv->obj = obj; 3819 obj_priv->obj = obj;
3807 obj_priv->fence_reg = I915_FENCE_REG_NONE; 3820 obj_priv->fence_reg = I915_FENCE_REG_NONE;
3808 INIT_LIST_HEAD(&obj_priv->list); 3821 INIT_LIST_HEAD(&obj_priv->list);
3822 INIT_LIST_HEAD(&obj_priv->fence_list);
3809 3823
3810 return 0; 3824 return 0;
3811} 3825}
@@ -4218,15 +4232,11 @@ int
4218i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, 4232i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
4219 struct drm_file *file_priv) 4233 struct drm_file *file_priv)
4220{ 4234{
4221 int ret;
4222
4223 if (drm_core_check_feature(dev, DRIVER_MODESET)) 4235 if (drm_core_check_feature(dev, DRIVER_MODESET))
4224 return 0; 4236 return 0;
4225 4237
4226 ret = i915_gem_idle(dev);
4227 drm_irq_uninstall(dev); 4238 drm_irq_uninstall(dev);
4228 4239 return i915_gem_idle(dev);
4229 return ret;
4230} 4240}
4231 4241
4232void 4242void
@@ -4253,6 +4263,7 @@ i915_gem_load(struct drm_device *dev)
4253 INIT_LIST_HEAD(&dev_priv->mm.flushing_list); 4263 INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
4254 INIT_LIST_HEAD(&dev_priv->mm.inactive_list); 4264 INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
4255 INIT_LIST_HEAD(&dev_priv->mm.request_list); 4265 INIT_LIST_HEAD(&dev_priv->mm.request_list);
4266 INIT_LIST_HEAD(&dev_priv->mm.fence_list);
4256 INIT_DELAYED_WORK(&dev_priv->mm.retire_work, 4267 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
4257 i915_gem_retire_work_handler); 4268 i915_gem_retire_work_handler);
4258 dev_priv->mm.next_gem_seqno = 1; 4269 dev_priv->mm.next_gem_seqno = 1;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 300aee3296c2..f806fcc54e09 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -59,6 +59,16 @@ find_section(struct bdb_header *bdb, int section_id)
59 return NULL; 59 return NULL;
60} 60}
61 61
62static u16
63get_blocksize(void *p)
64{
65 u16 *block_ptr, block_size;
66
67 block_ptr = (u16 *)((char *)p - 2);
68 block_size = *block_ptr;
69 return block_size;
70}
71
62static void 72static void
63fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode, 73fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,
64 struct lvds_dvo_timing *dvo_timing) 74 struct lvds_dvo_timing *dvo_timing)
@@ -215,6 +225,41 @@ parse_general_features(struct drm_i915_private *dev_priv,
215} 225}
216 226
217static void 227static void
228parse_general_definitions(struct drm_i915_private *dev_priv,
229 struct bdb_header *bdb)
230{
231 struct bdb_general_definitions *general;
232 const int crt_bus_map_table[] = {
233 GPIOB,
234 GPIOA,
235 GPIOC,
236 GPIOD,
237 GPIOE,
238 GPIOF,
239 };
240
241 /* Set sensible defaults in case we can't find the general block
242 or it is the wrong chipset */
243 dev_priv->crt_ddc_bus = -1;
244
245 general = find_section(bdb, BDB_GENERAL_DEFINITIONS);
246 if (general) {
247 u16 block_size = get_blocksize(general);
248 if (block_size >= sizeof(*general)) {
249 int bus_pin = general->crt_ddc_gmbus_pin;
250 DRM_DEBUG("crt_ddc_bus_pin: %d\n", bus_pin);
251 if ((bus_pin >= 1) && (bus_pin <= 6)) {
252 dev_priv->crt_ddc_bus =
253 crt_bus_map_table[bus_pin-1];
254 }
255 } else {
256 DRM_DEBUG("BDB_GD too small (%d). Invalid.\n",
257 block_size);
258 }
259 }
260}
261
262static void
218parse_sdvo_device_mapping(struct drm_i915_private *dev_priv, 263parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
219 struct bdb_header *bdb) 264 struct bdb_header *bdb)
220{ 265{
@@ -222,7 +267,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
222 struct bdb_general_definitions *p_defs; 267 struct bdb_general_definitions *p_defs;
223 struct child_device_config *p_child; 268 struct child_device_config *p_child;
224 int i, child_device_num, count; 269 int i, child_device_num, count;
225 u16 block_size, *block_ptr; 270 u16 block_size;
226 271
227 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS); 272 p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);
228 if (!p_defs) { 273 if (!p_defs) {
@@ -240,8 +285,7 @@ parse_sdvo_device_mapping(struct drm_i915_private *dev_priv,
240 return; 285 return;
241 } 286 }
242 /* get the block size of general definitions */ 287 /* get the block size of general definitions */
243 block_ptr = (u16 *)((char *)p_defs - 2); 288 block_size = get_blocksize(p_defs);
244 block_size = *block_ptr;
245 /* get the number of child device */ 289 /* get the number of child device */
246 child_device_num = (block_size - sizeof(*p_defs)) / 290 child_device_num = (block_size - sizeof(*p_defs)) /
247 sizeof(*p_child); 291 sizeof(*p_child);
@@ -362,6 +406,7 @@ intel_init_bios(struct drm_device *dev)
362 406
363 /* Grab useful general definitions */ 407 /* Grab useful general definitions */
364 parse_general_features(dev_priv, bdb); 408 parse_general_features(dev_priv, bdb);
409 parse_general_definitions(dev_priv, bdb);
365 parse_lfp_panel_data(dev_priv, bdb); 410 parse_lfp_panel_data(dev_priv, bdb);
366 parse_sdvo_panel_data(dev_priv, bdb); 411 parse_sdvo_panel_data(dev_priv, bdb);
367 parse_sdvo_device_mapping(dev_priv, bdb); 412 parse_sdvo_device_mapping(dev_priv, bdb);
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 4cf8e2e88a40..590f81c8f594 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -508,6 +508,7 @@ void intel_crt_init(struct drm_device *dev)
508{ 508{
509 struct drm_connector *connector; 509 struct drm_connector *connector;
510 struct intel_output *intel_output; 510 struct intel_output *intel_output;
511 struct drm_i915_private *dev_priv = dev->dev_private;
511 u32 i2c_reg; 512 u32 i2c_reg;
512 513
513 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL); 514 intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
@@ -527,8 +528,12 @@ void intel_crt_init(struct drm_device *dev)
527 /* Set up the DDC bus. */ 528 /* Set up the DDC bus. */
528 if (IS_IGDNG(dev)) 529 if (IS_IGDNG(dev))
529 i2c_reg = PCH_GPIOA; 530 i2c_reg = PCH_GPIOA;
530 else 531 else {
531 i2c_reg = GPIOA; 532 i2c_reg = GPIOA;
533 /* Use VBT information for CRT DDC if available */
534 if (dev_priv->crt_ddc_bus != -1)
535 i2c_reg = dev_priv->crt_ddc_bus;
536 }
532 intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A"); 537 intel_output->ddc_bus = intel_i2c_create(dev, i2c_reg, "CRTDDC_A");
533 if (!intel_output->ddc_bus) { 538 if (!intel_output->ddc_bus) {
534 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration " 539 dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
@@ -537,6 +542,10 @@ void intel_crt_init(struct drm_device *dev)
537 } 542 }
538 543
539 intel_output->type = INTEL_OUTPUT_ANALOG; 544 intel_output->type = INTEL_OUTPUT_ANALOG;
545 intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
546 (1 << INTEL_ANALOG_CLONE_BIT) |
547 (1 << INTEL_SDVO_LVDS_CLONE_BIT);
548 intel_output->crtc_mask = (1 << 0) | (1 << 1);
540 connector->interlace_allowed = 0; 549 connector->interlace_allowed = 0;
541 connector->doublescan_allowed = 0; 550 connector->doublescan_allowed = 0;
542 551
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d6fce2133413..748ed50c55ca 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -666,7 +666,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
666 intel_clock_t clock; 666 intel_clock_t clock;
667 int err = target; 667 int err = target;
668 668
669 if (IS_I9XX(dev) && intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && 669 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
670 (I915_READ(LVDS)) != 0) { 670 (I915_READ(LVDS)) != 0) {
671 /* 671 /*
672 * For LVDS, if the panel is on, just rely on its current 672 * For LVDS, if the panel is on, just rely on its current
@@ -2005,7 +2005,21 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock,
2005 return; 2005 return;
2006} 2006}
2007 2007
2008const static int latency_ns = 3000; /* default for non-igd platforms */ 2008/*
2009 * Latency for FIFO fetches is dependent on several factors:
2010 * - memory configuration (speed, channels)
2011 * - chipset
2012 * - current MCH state
2013 * It can be fairly high in some situations, so here we assume a fairly
2014 * pessimal value. It's a tradeoff between extra memory fetches (if we
2015 * set this value too high, the FIFO will fetch frequently to stay full)
2016 * and power consumption (set it too low to save power and we might see
2017 * FIFO underruns and display "flicker").
2018 *
2019 * A value of 5us seems to be a good balance; safe for very low end
2020 * platforms but not overly aggressive on lower latency configs.
2021 */
2022const static int latency_ns = 5000;
2009 2023
2010static int intel_get_fifo_size(struct drm_device *dev, int plane) 2024static int intel_get_fifo_size(struct drm_device *dev, int plane)
2011{ 2025{
@@ -2396,7 +2410,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
2396 if (is_sdvo) { 2410 if (is_sdvo) {
2397 dpll |= DPLL_DVO_HIGH_SPEED; 2411 dpll |= DPLL_DVO_HIGH_SPEED;
2398 sdvo_pixel_multiply = adjusted_mode->clock / mode->clock; 2412 sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;
2399 if (IS_I945G(dev) || IS_I945GM(dev)) 2413 if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
2400 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; 2414 dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
2401 else if (IS_IGDNG(dev)) 2415 else if (IS_IGDNG(dev))
2402 dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT; 2416 dpll |= (sdvo_pixel_multiply - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
@@ -3170,7 +3184,7 @@ static int intel_connector_clones(struct drm_device *dev, int type_mask)
3170 3184
3171 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 3185 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3172 struct intel_output *intel_output = to_intel_output(connector); 3186 struct intel_output *intel_output = to_intel_output(connector);
3173 if (type_mask & (1 << intel_output->type)) 3187 if (type_mask & intel_output->clone_mask)
3174 index_mask |= (1 << entry); 3188 index_mask |= (1 << entry);
3175 entry++; 3189 entry++;
3176 } 3190 }
@@ -3218,30 +3232,30 @@ static void intel_setup_outputs(struct drm_device *dev)
3218 intel_dp_init(dev, PCH_DP_D); 3232 intel_dp_init(dev, PCH_DP_D);
3219 3233
3220 } else if (IS_I9XX(dev)) { 3234 } else if (IS_I9XX(dev)) {
3221 int found; 3235 bool found = false;
3222 u32 reg;
3223 3236
3224 if (I915_READ(SDVOB) & SDVO_DETECTED) { 3237 if (I915_READ(SDVOB) & SDVO_DETECTED) {
3225 found = intel_sdvo_init(dev, SDVOB); 3238 found = intel_sdvo_init(dev, SDVOB);
3226 if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) 3239 if (!found && SUPPORTS_INTEGRATED_HDMI(dev))
3227 intel_hdmi_init(dev, SDVOB); 3240 intel_hdmi_init(dev, SDVOB);
3241
3228 if (!found && SUPPORTS_INTEGRATED_DP(dev)) 3242 if (!found && SUPPORTS_INTEGRATED_DP(dev))
3229 intel_dp_init(dev, DP_B); 3243 intel_dp_init(dev, DP_B);
3230 } 3244 }
3231 3245
3232 /* Before G4X SDVOC doesn't have its own detect register */ 3246 /* Before G4X SDVOC doesn't have its own detect register */
3233 if (IS_G4X(dev))
3234 reg = SDVOC;
3235 else
3236 reg = SDVOB;
3237 3247
3238 if (I915_READ(reg) & SDVO_DETECTED) { 3248 if (I915_READ(SDVOB) & SDVO_DETECTED)
3239 found = intel_sdvo_init(dev, SDVOC); 3249 found = intel_sdvo_init(dev, SDVOC);
3240 if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) 3250
3251 if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) {
3252
3253 if (SUPPORTS_INTEGRATED_HDMI(dev))
3241 intel_hdmi_init(dev, SDVOC); 3254 intel_hdmi_init(dev, SDVOC);
3242 if (!found && SUPPORTS_INTEGRATED_DP(dev)) 3255 if (SUPPORTS_INTEGRATED_DP(dev))
3243 intel_dp_init(dev, DP_C); 3256 intel_dp_init(dev, DP_C);
3244 } 3257 }
3258
3245 if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED)) 3259 if (SUPPORTS_INTEGRATED_DP(dev) && (I915_READ(DP_D) & DP_DETECTED))
3246 intel_dp_init(dev, DP_D); 3260 intel_dp_init(dev, DP_D);
3247 } else 3261 } else
@@ -3253,51 +3267,10 @@ static void intel_setup_outputs(struct drm_device *dev)
3253 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 3267 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
3254 struct intel_output *intel_output = to_intel_output(connector); 3268 struct intel_output *intel_output = to_intel_output(connector);
3255 struct drm_encoder *encoder = &intel_output->enc; 3269 struct drm_encoder *encoder = &intel_output->enc;
3256 int crtc_mask = 0, clone_mask = 0;
3257 3270
3258 /* valid crtcs */ 3271 encoder->possible_crtcs = intel_output->crtc_mask;
3259 switch(intel_output->type) { 3272 encoder->possible_clones = intel_connector_clones(dev,
3260 case INTEL_OUTPUT_HDMI: 3273 intel_output->clone_mask);
3261 crtc_mask = ((1 << 0)|
3262 (1 << 1));
3263 clone_mask = ((1 << INTEL_OUTPUT_HDMI));
3264 break;
3265 case INTEL_OUTPUT_DVO:
3266 case INTEL_OUTPUT_SDVO:
3267 crtc_mask = ((1 << 0)|
3268 (1 << 1));
3269 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
3270 (1 << INTEL_OUTPUT_DVO) |
3271 (1 << INTEL_OUTPUT_SDVO));
3272 break;
3273 case INTEL_OUTPUT_ANALOG:
3274 crtc_mask = ((1 << 0)|
3275 (1 << 1));
3276 clone_mask = ((1 << INTEL_OUTPUT_ANALOG) |
3277 (1 << INTEL_OUTPUT_DVO) |
3278 (1 << INTEL_OUTPUT_SDVO));
3279 break;
3280 case INTEL_OUTPUT_LVDS:
3281 crtc_mask = (1 << 1);
3282 clone_mask = (1 << INTEL_OUTPUT_LVDS);
3283 break;
3284 case INTEL_OUTPUT_TVOUT:
3285 crtc_mask = ((1 << 0) |
3286 (1 << 1));
3287 clone_mask = (1 << INTEL_OUTPUT_TVOUT);
3288 break;
3289 case INTEL_OUTPUT_DISPLAYPORT:
3290 crtc_mask = ((1 << 0) |
3291 (1 << 1));
3292 clone_mask = (1 << INTEL_OUTPUT_DISPLAYPORT);
3293 break;
3294 case INTEL_OUTPUT_EDP:
3295 crtc_mask = (1 << 1);
3296 clone_mask = (1 << INTEL_OUTPUT_EDP);
3297 break;
3298 }
3299 encoder->possible_crtcs = crtc_mask;
3300 encoder->possible_clones = intel_connector_clones(dev, clone_mask);
3301 } 3274 }
3302} 3275}
3303 3276
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a6ff15ac548a..2b914d732076 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -1254,6 +1254,18 @@ intel_dp_init(struct drm_device *dev, int output_reg)
1254 else 1254 else
1255 intel_output->type = INTEL_OUTPUT_DISPLAYPORT; 1255 intel_output->type = INTEL_OUTPUT_DISPLAYPORT;
1256 1256
1257 if (output_reg == DP_B)
1258 intel_output->clone_mask = (1 << INTEL_DP_B_CLONE_BIT);
1259 else if (output_reg == DP_C)
1260 intel_output->clone_mask = (1 << INTEL_DP_C_CLONE_BIT);
1261 else if (output_reg == DP_D)
1262 intel_output->clone_mask = (1 << INTEL_DP_D_CLONE_BIT);
1263
1264 if (IS_eDP(intel_output)) {
1265 intel_output->crtc_mask = (1 << 1);
1266 intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT);
1267 } else
1268 intel_output->crtc_mask = (1 << 0) | (1 << 1);
1257 connector->interlace_allowed = true; 1269 connector->interlace_allowed = true;
1258 connector->doublescan_allowed = 0; 1270 connector->doublescan_allowed = 0;
1259 1271
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d6f92ea1b553..26a6227c15fe 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -57,6 +57,25 @@
57#define INTEL_OUTPUT_DISPLAYPORT 7 57#define INTEL_OUTPUT_DISPLAYPORT 7
58#define INTEL_OUTPUT_EDP 8 58#define INTEL_OUTPUT_EDP 8
59 59
60/* Intel Pipe Clone Bit */
61#define INTEL_HDMIB_CLONE_BIT 1
62#define INTEL_HDMIC_CLONE_BIT 2
63#define INTEL_HDMID_CLONE_BIT 3
64#define INTEL_HDMIE_CLONE_BIT 4
65#define INTEL_HDMIF_CLONE_BIT 5
66#define INTEL_SDVO_NON_TV_CLONE_BIT 6
67#define INTEL_SDVO_TV_CLONE_BIT 7
68#define INTEL_SDVO_LVDS_CLONE_BIT 8
69#define INTEL_ANALOG_CLONE_BIT 9
70#define INTEL_TV_CLONE_BIT 10
71#define INTEL_DP_B_CLONE_BIT 11
72#define INTEL_DP_C_CLONE_BIT 12
73#define INTEL_DP_D_CLONE_BIT 13
74#define INTEL_LVDS_CLONE_BIT 14
75#define INTEL_DVO_TMDS_CLONE_BIT 15
76#define INTEL_DVO_LVDS_CLONE_BIT 16
77#define INTEL_EDP_CLONE_BIT 17
78
60#define INTEL_DVO_CHIP_NONE 0 79#define INTEL_DVO_CHIP_NONE 0
61#define INTEL_DVO_CHIP_LVDS 1 80#define INTEL_DVO_CHIP_LVDS 1
62#define INTEL_DVO_CHIP_TMDS 2 81#define INTEL_DVO_CHIP_TMDS 2
@@ -86,6 +105,8 @@ struct intel_output {
86 bool needs_tv_clock; 105 bool needs_tv_clock;
87 void *dev_priv; 106 void *dev_priv;
88 void (*hot_plug)(struct intel_output *); 107 void (*hot_plug)(struct intel_output *);
108 int crtc_mask;
109 int clone_mask;
89}; 110};
90 111
91struct intel_crtc { 112struct intel_crtc {
diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c
index 13bff20930e8..a4d2606de778 100644
--- a/drivers/gpu/drm/i915/intel_dvo.c
+++ b/drivers/gpu/drm/i915/intel_dvo.c
@@ -435,14 +435,20 @@ void intel_dvo_init(struct drm_device *dev)
435 continue; 435 continue;
436 436
437 intel_output->type = INTEL_OUTPUT_DVO; 437 intel_output->type = INTEL_OUTPUT_DVO;
438 intel_output->crtc_mask = (1 << 0) | (1 << 1);
438 switch (dvo->type) { 439 switch (dvo->type) {
439 case INTEL_DVO_CHIP_TMDS: 440 case INTEL_DVO_CHIP_TMDS:
441 intel_output->clone_mask =
442 (1 << INTEL_DVO_TMDS_CLONE_BIT) |
443 (1 << INTEL_ANALOG_CLONE_BIT);
440 drm_connector_init(dev, connector, 444 drm_connector_init(dev, connector,
441 &intel_dvo_connector_funcs, 445 &intel_dvo_connector_funcs,
442 DRM_MODE_CONNECTOR_DVII); 446 DRM_MODE_CONNECTOR_DVII);
443 encoder_type = DRM_MODE_ENCODER_TMDS; 447 encoder_type = DRM_MODE_ENCODER_TMDS;
444 break; 448 break;
445 case INTEL_DVO_CHIP_LVDS: 449 case INTEL_DVO_CHIP_LVDS:
450 intel_output->clone_mask =
451 (1 << INTEL_DVO_LVDS_CLONE_BIT);
446 drm_connector_init(dev, connector, 452 drm_connector_init(dev, connector,
447 &intel_dvo_connector_funcs, 453 &intel_dvo_connector_funcs,
448 DRM_MODE_CONNECTOR_LVDS); 454 DRM_MODE_CONNECTOR_LVDS);
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
index 1842290cded3..fa304e136010 100644
--- a/drivers/gpu/drm/i915/intel_hdmi.c
+++ b/drivers/gpu/drm/i915/intel_hdmi.c
@@ -230,22 +230,28 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg)
230 230
231 connector->interlace_allowed = 0; 231 connector->interlace_allowed = 0;
232 connector->doublescan_allowed = 0; 232 connector->doublescan_allowed = 0;
233 intel_output->crtc_mask = (1 << 0) | (1 << 1);
233 234
234 /* Set up the DDC bus. */ 235 /* Set up the DDC bus. */
235 if (sdvox_reg == SDVOB) 236 if (sdvox_reg == SDVOB) {
237 intel_output->clone_mask = (1 << INTEL_HDMIB_CLONE_BIT);
236 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB"); 238 intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "HDMIB");
237 else if (sdvox_reg == SDVOC) 239 } else if (sdvox_reg == SDVOC) {
240 intel_output->clone_mask = (1 << INTEL_HDMIC_CLONE_BIT);
238 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC"); 241 intel_output->ddc_bus = intel_i2c_create(dev, GPIOD, "HDMIC");
239 else if (sdvox_reg == HDMIB) 242 } else if (sdvox_reg == HDMIB) {
243 intel_output->clone_mask = (1 << INTEL_HDMID_CLONE_BIT);
240 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE, 244 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOE,
241 "HDMIB"); 245 "HDMIB");
242 else if (sdvox_reg == HDMIC) 246 } else if (sdvox_reg == HDMIC) {
247 intel_output->clone_mask = (1 << INTEL_HDMIE_CLONE_BIT);
243 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD, 248 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOD,
244 "HDMIC"); 249 "HDMIC");
245 else if (sdvox_reg == HDMID) 250 } else if (sdvox_reg == HDMID) {
251 intel_output->clone_mask = (1 << INTEL_HDMIF_CLONE_BIT);
246 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF, 252 intel_output->ddc_bus = intel_i2c_create(dev, PCH_GPIOF,
247 "HDMID"); 253 "HDMID");
248 254 }
249 if (!intel_output->ddc_bus) 255 if (!intel_output->ddc_bus)
250 goto err_connector; 256 goto err_connector;
251 257
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 3f445a80c552..8df02ef89261 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -916,6 +916,8 @@ void intel_lvds_init(struct drm_device *dev)
916 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); 916 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
917 intel_output->type = INTEL_OUTPUT_LVDS; 917 intel_output->type = INTEL_OUTPUT_LVDS;
918 918
919 intel_output->clone_mask = (1 << INTEL_LVDS_CLONE_BIT);
920 intel_output->crtc_mask = (1 << 1);
919 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); 921 drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
920 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); 922 drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
921 connector->display_info.subpixel_order = SubPixelHorizontalRGB; 923 connector->display_info.subpixel_order = SubPixelHorizontalRGB;
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index 5371d9332554..d3b74ba62b4a 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -1458,7 +1458,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output)
1458 (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) 1458 (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1))
1459 caps++; 1459 caps++;
1460 if (sdvo_priv->caps.output_flags & 1460 if (sdvo_priv->caps.output_flags &
1461 (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) 1461 (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1))
1462 caps++; 1462 caps++;
1463 if (sdvo_priv->caps.output_flags & 1463 if (sdvo_priv->caps.output_flags &
1464 (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) 1464 (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1))
@@ -1967,6 +1967,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
1967 intel_sdvo_set_colorimetry(intel_output, 1967 intel_sdvo_set_colorimetry(intel_output,
1968 SDVO_COLORIMETRY_RGB256); 1968 SDVO_COLORIMETRY_RGB256);
1969 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; 1969 connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
1970 intel_output->clone_mask =
1971 (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
1972 (1 << INTEL_ANALOG_CLONE_BIT);
1970 } 1973 }
1971 } else if (flags & SDVO_OUTPUT_SVID0) { 1974 } else if (flags & SDVO_OUTPUT_SVID0) {
1972 1975
@@ -1975,11 +1978,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
1975 connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; 1978 connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO;
1976 sdvo_priv->is_tv = true; 1979 sdvo_priv->is_tv = true;
1977 intel_output->needs_tv_clock = true; 1980 intel_output->needs_tv_clock = true;
1981 intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT;
1978 } else if (flags & SDVO_OUTPUT_RGB0) { 1982 } else if (flags & SDVO_OUTPUT_RGB0) {
1979 1983
1980 sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; 1984 sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0;
1981 encoder->encoder_type = DRM_MODE_ENCODER_DAC; 1985 encoder->encoder_type = DRM_MODE_ENCODER_DAC;
1982 connector->connector_type = DRM_MODE_CONNECTOR_VGA; 1986 connector->connector_type = DRM_MODE_CONNECTOR_VGA;
1987 intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) |
1988 (1 << INTEL_ANALOG_CLONE_BIT);
1983 } else if (flags & SDVO_OUTPUT_RGB1) { 1989 } else if (flags & SDVO_OUTPUT_RGB1) {
1984 1990
1985 sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; 1991 sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1;
@@ -1991,12 +1997,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
1991 encoder->encoder_type = DRM_MODE_ENCODER_LVDS; 1997 encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
1992 connector->connector_type = DRM_MODE_CONNECTOR_LVDS; 1998 connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
1993 sdvo_priv->is_lvds = true; 1999 sdvo_priv->is_lvds = true;
2000 intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
2001 (1 << INTEL_SDVO_LVDS_CLONE_BIT);
1994 } else if (flags & SDVO_OUTPUT_LVDS1) { 2002 } else if (flags & SDVO_OUTPUT_LVDS1) {
1995 2003
1996 sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; 2004 sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1;
1997 encoder->encoder_type = DRM_MODE_ENCODER_LVDS; 2005 encoder->encoder_type = DRM_MODE_ENCODER_LVDS;
1998 connector->connector_type = DRM_MODE_CONNECTOR_LVDS; 2006 connector->connector_type = DRM_MODE_CONNECTOR_LVDS;
1999 sdvo_priv->is_lvds = true; 2007 sdvo_priv->is_lvds = true;
2008 intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) |
2009 (1 << INTEL_SDVO_LVDS_CLONE_BIT);
2000 } else { 2010 } else {
2001 2011
2002 unsigned char bytes[2]; 2012 unsigned char bytes[2];
@@ -2009,6 +2019,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags)
2009 bytes[0], bytes[1]); 2019 bytes[0], bytes[1]);
2010 ret = false; 2020 ret = false;
2011 } 2021 }
2022 intel_output->crtc_mask = (1 << 0) | (1 << 1);
2012 2023
2013 if (ret && registered) 2024 if (ret && registered)
2014 ret = drm_sysfs_connector_add(connector) == 0 ? true : false; 2025 ret = drm_sysfs_connector_add(connector) == 0 ? true : false;
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index da4ab4dc1630..5b1c9e9fdba0 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1718,6 +1718,7 @@ intel_tv_init(struct drm_device *dev)
1718 if (!intel_output) { 1718 if (!intel_output) {
1719 return; 1719 return;
1720 } 1720 }
1721
1721 connector = &intel_output->base; 1722 connector = &intel_output->base;
1722 1723
1723 drm_connector_init(dev, connector, &intel_tv_connector_funcs, 1724 drm_connector_init(dev, connector, &intel_tv_connector_funcs,
@@ -1729,6 +1730,8 @@ intel_tv_init(struct drm_device *dev)
1729 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); 1730 drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
1730 tv_priv = (struct intel_tv_priv *)(intel_output + 1); 1731 tv_priv = (struct intel_tv_priv *)(intel_output + 1);
1731 intel_output->type = INTEL_OUTPUT_TVOUT; 1732 intel_output->type = INTEL_OUTPUT_TVOUT;
1733 intel_output->crtc_mask = (1 << 0) | (1 << 1);
1734 intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT);
1732 intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); 1735 intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
1733 intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); 1736 intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
1734 intel_output->dev_priv = tv_priv; 1737 intel_output->dev_priv = tv_priv;
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 053f4ec397f7..051bca6e3a4f 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -995,7 +995,7 @@ static const unsigned r300_reg_safe_bm[159] = {
995 0x00000000, 0x00000000, 0x00000000, 0x00000000, 995 0x00000000, 0x00000000, 0x00000000, 0x00000000,
996 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, 996 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
997 0x00000000, 0x00000000, 0x00000000, 0x00000000, 997 0x00000000, 0x00000000, 0x00000000, 0x00000000,
998 0x0003FC01, 0xFFFFFFF8, 0xFE800B19, 998 0x0003FC01, 0xFFFFFCF8, 0xFF800B19,
999}; 999};
1000 1000
1001static int r300_packet0_check(struct radeon_cs_parser *p, 1001static int r300_packet0_check(struct radeon_cs_parser *p,
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h
index 7ca6c13569b5..93d8f8889302 100644
--- a/drivers/gpu/drm/radeon/radeon_asic.h
+++ b/drivers/gpu/drm/radeon/radeon_asic.h
@@ -266,6 +266,7 @@ static struct radeon_asic rs400_asic = {
266/* 266/*
267 * rs600. 267 * rs600.
268 */ 268 */
269int rs600_init(struct radeon_device *dev);
269void rs600_errata(struct radeon_device *rdev); 270void rs600_errata(struct radeon_device *rdev);
270void rs600_vram_info(struct radeon_device *rdev); 271void rs600_vram_info(struct radeon_device *rdev);
271int rs600_mc_init(struct radeon_device *rdev); 272int rs600_mc_init(struct radeon_device *rdev);
@@ -281,7 +282,7 @@ uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg);
281void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 282void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
282void rs600_bandwidth_update(struct radeon_device *rdev); 283void rs600_bandwidth_update(struct radeon_device *rdev);
283static struct radeon_asic rs600_asic = { 284static struct radeon_asic rs600_asic = {
284 .init = &r300_init, 285 .init = &rs600_init,
285 .errata = &rs600_errata, 286 .errata = &rs600_errata,
286 .vram_info = &rs600_vram_info, 287 .vram_info = &rs600_vram_info,
287 .gpu_reset = &r300_gpu_reset, 288 .gpu_reset = &r300_gpu_reset,
@@ -316,7 +317,6 @@ static struct radeon_asic rs600_asic = {
316/* 317/*
317 * rs690,rs740 318 * rs690,rs740
318 */ 319 */
319int rs690_init(struct radeon_device *rdev);
320void rs690_errata(struct radeon_device *rdev); 320void rs690_errata(struct radeon_device *rdev);
321void rs690_vram_info(struct radeon_device *rdev); 321void rs690_vram_info(struct radeon_device *rdev);
322int rs690_mc_init(struct radeon_device *rdev); 322int rs690_mc_init(struct radeon_device *rdev);
@@ -325,7 +325,7 @@ uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg);
325void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); 325void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v);
326void rs690_bandwidth_update(struct radeon_device *rdev); 326void rs690_bandwidth_update(struct radeon_device *rdev);
327static struct radeon_asic rs690_asic = { 327static struct radeon_asic rs690_asic = {
328 .init = &rs690_init, 328 .init = &rs600_init,
329 .errata = &rs690_errata, 329 .errata = &rs690_errata,
330 .vram_info = &rs690_vram_info, 330 .vram_info = &rs690_vram_info,
331 .gpu_reset = &r300_gpu_reset, 331 .gpu_reset = &r300_gpu_reset,
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 7e8ce983a908..02fd11aad6a2 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -409,3 +409,68 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
409 ((reg) & RS600_MC_ADDR_MASK)); 409 ((reg) & RS600_MC_ADDR_MASK));
410 WREG32(RS600_MC_DATA, v); 410 WREG32(RS600_MC_DATA, v);
411} 411}
412
413static const unsigned rs600_reg_safe_bm[219] = {
414 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
415 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
416 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
417 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
418 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
419 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
420 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
421 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
422 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
423 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
424 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF,
425 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF,
426 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
427 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
428 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F,
429 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
430 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000,
431 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF,
432 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
433 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
434 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
435 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
436 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
437 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
438 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
439 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
440 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
441 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
442 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
443 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
444 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
445 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
446 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF,
447 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF,
448 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000,
449 0x00000000, 0x0000C100, 0x00000000, 0x00000000,
450 0x00000000, 0x00000000, 0x00000000, 0x00000000,
451 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF,
452 0x00000000, 0x00000000, 0x00000000, 0x00000000,
453 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF,
454 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
455 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
456 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
457 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
458 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
459 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
460 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
461 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
462 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
463 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
464 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
465 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
466 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
467 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
468 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
469};
470
471int rs600_init(struct radeon_device *rdev)
472{
473 rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm;
474 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm);
475 return 0;
476}
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index bc6b7c5339bc..879882533e45 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -653,67 +653,3 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
653 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); 653 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
654} 654}
655 655
656static const unsigned rs690_reg_safe_bm[219] = {
657 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
658 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
659 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
660 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
661 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
662 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
663 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
664 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
665 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
666 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
667 0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF,
668 0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF,
669 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
670 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
671 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F,
672 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
673 0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000,
674 0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF,
675 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
676 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
677 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
678 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
679 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
680 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
681 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
682 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
683 0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
684 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
685 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
686 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
687 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
688 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
689 0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
690 0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF,
691 0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
692 0x00000000,0x0000C100,0x00000000,0x00000000,
693 0x00000000,0x00000000,0x00000000,0x00000000,
694 0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF,
695 0x00000000,0x00000000,0x00000000,0x00000000,
696 0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF,
697 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
698 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
699 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
700 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
701 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
702 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
703 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
704 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
705 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
706 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
707 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
708 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
709 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
710 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
711 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
712};
713
714int rs690_init(struct radeon_device *rdev)
715{
716 rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm;
717 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm);
718 return 0;
719}
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 31a7f668ae5a..0566fb67e460 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -508,7 +508,7 @@ static const unsigned r500_reg_safe_bm[219] = {
508 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 508 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
509 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, 509 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF,
510 0x00000000, 0x00000000, 0x00000000, 0x00000000, 510 0x00000000, 0x00000000, 0x00000000, 0x00000000,
511 0x0003FC01, 0x3FFFFCF8, 0xFE800B19, 0xFFFFFFFF, 511 0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF,
512 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 512 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
513 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 513 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
514 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 514 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index 527908ff298c..063b933d864a 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -408,6 +408,7 @@ static struct pcmcia_device_id ide_ids[] = {
408 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), 408 PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9),
409 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), 409 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591),
410 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), 410 PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728),
411 PCMCIA_DEVICE_PROD_ID12("CNF ", "CD-ROM", 0x46d7db81, 0x66536591),
411 PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), 412 PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591),
412 PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), 413 PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4),
413 PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), 414 PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde),
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 95fe0452dae4..6c6a09b1c0fe 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -880,6 +880,14 @@ static unsigned int atkbd_hp_zv6100_forced_release_keys[] = {
880}; 880};
881 881
882/* 882/*
883 * Perform fixup for HP (Compaq) Presario R4000 R4100 R4200 that don't generate
884 * release for their volume buttons
885 */
886static unsigned int atkbd_hp_r4000_forced_release_keys[] = {
887 0xae, 0xb0, -1U
888};
889
890/*
883 * Samsung NC10,NC20 with Fn+F? key release not working 891 * Samsung NC10,NC20 with Fn+F? key release not working
884 */ 892 */
885static unsigned int atkbd_samsung_forced_release_keys[] = { 893static unsigned int atkbd_samsung_forced_release_keys[] = {
@@ -1537,6 +1545,33 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
1537 .driver_data = atkbd_hp_zv6100_forced_release_keys, 1545 .driver_data = atkbd_hp_zv6100_forced_release_keys,
1538 }, 1546 },
1539 { 1547 {
1548 .ident = "HP Presario R4000",
1549 .matches = {
1550 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1551 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"),
1552 },
1553 .callback = atkbd_setup_forced_release,
1554 .driver_data = atkbd_hp_r4000_forced_release_keys,
1555 },
1556 {
1557 .ident = "HP Presario R4100",
1558 .matches = {
1559 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1560 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"),
1561 },
1562 .callback = atkbd_setup_forced_release,
1563 .driver_data = atkbd_hp_r4000_forced_release_keys,
1564 },
1565 {
1566 .ident = "HP Presario R4200",
1567 .matches = {
1568 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1569 DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"),
1570 },
1571 .callback = atkbd_setup_forced_release,
1572 .driver_data = atkbd_hp_r4000_forced_release_keys,
1573 },
1574 {
1540 .ident = "Inventec Symphony", 1575 .ident = "Inventec Symphony",
1541 .matches = { 1576 .matches = {
1542 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), 1577 DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
index ae04d8a494e5..ccbf23ece8e3 100644
--- a/drivers/input/serio/i8042-x86ia64io.h
+++ b/drivers/input/serio/i8042-x86ia64io.h
@@ -382,6 +382,14 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
382 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"), 382 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro1510"),
383 }, 383 },
384 }, 384 },
385 {
386 .ident = "Acer Aspire 5536",
387 .matches = {
388 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
389 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5536"),
390 DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
391 },
392 },
385 { } 393 { }
386}; 394};
387 395
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index 3710ff88fc10..556acff3952f 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -171,6 +171,14 @@ static int set_chunk_size(struct dm_exception_store *store,
171 */ 171 */
172 chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9); 172 chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
173 173
174 return dm_exception_store_set_chunk_size(store, chunk_size_ulong,
175 error);
176}
177
178int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
179 unsigned long chunk_size_ulong,
180 char **error)
181{
174 /* Check chunk_size is a power of 2 */ 182 /* Check chunk_size is a power of 2 */
175 if (!is_power_of_2(chunk_size_ulong)) { 183 if (!is_power_of_2(chunk_size_ulong)) {
176 *error = "Chunk size is not a power of 2"; 184 *error = "Chunk size is not a power of 2";
@@ -183,6 +191,11 @@ static int set_chunk_size(struct dm_exception_store *store,
183 return -EINVAL; 191 return -EINVAL;
184 } 192 }
185 193
194 if (chunk_size_ulong > INT_MAX >> SECTOR_SHIFT) {
195 *error = "Chunk size is too high";
196 return -EINVAL;
197 }
198
186 store->chunk_size = chunk_size_ulong; 199 store->chunk_size = chunk_size_ulong;
187 store->chunk_mask = chunk_size_ulong - 1; 200 store->chunk_mask = chunk_size_ulong - 1;
188 store->chunk_shift = ffs(chunk_size_ulong) - 1; 201 store->chunk_shift = ffs(chunk_size_ulong) - 1;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index 2442c8c07898..812c71872ba0 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -168,6 +168,10 @@ static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
168int dm_exception_store_type_register(struct dm_exception_store_type *type); 168int dm_exception_store_type_register(struct dm_exception_store_type *type);
169int dm_exception_store_type_unregister(struct dm_exception_store_type *type); 169int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
170 170
171int dm_exception_store_set_chunk_size(struct dm_exception_store *store,
172 unsigned long chunk_size_ulong,
173 char **error);
174
171int dm_exception_store_create(struct dm_target *ti, int argc, char **argv, 175int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
172 unsigned *args_used, 176 unsigned *args_used,
173 struct dm_exception_store **store); 177 struct dm_exception_store **store);
diff --git a/drivers/md/dm-log-userspace-base.c b/drivers/md/dm-log-userspace-base.c
index e69b96560997..6e186b1a062d 100644
--- a/drivers/md/dm-log-userspace-base.c
+++ b/drivers/md/dm-log-userspace-base.c
@@ -21,6 +21,7 @@ struct log_c {
21 struct dm_target *ti; 21 struct dm_target *ti;
22 uint32_t region_size; 22 uint32_t region_size;
23 region_t region_count; 23 region_t region_count;
24 uint64_t luid;
24 char uuid[DM_UUID_LEN]; 25 char uuid[DM_UUID_LEN];
25 26
26 char *usr_argv_str; 27 char *usr_argv_str;
@@ -63,7 +64,7 @@ static int userspace_do_request(struct log_c *lc, const char *uuid,
63 * restored. 64 * restored.
64 */ 65 */
65retry: 66retry:
66 r = dm_consult_userspace(uuid, request_type, data, 67 r = dm_consult_userspace(uuid, lc->luid, request_type, data,
67 data_size, rdata, rdata_size); 68 data_size, rdata, rdata_size);
68 69
69 if (r != -ESRCH) 70 if (r != -ESRCH)
@@ -74,14 +75,15 @@ retry:
74 set_current_state(TASK_INTERRUPTIBLE); 75 set_current_state(TASK_INTERRUPTIBLE);
75 schedule_timeout(2*HZ); 76 schedule_timeout(2*HZ);
76 DMWARN("Attempting to contact userspace log server..."); 77 DMWARN("Attempting to contact userspace log server...");
77 r = dm_consult_userspace(uuid, DM_ULOG_CTR, lc->usr_argv_str, 78 r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_CTR,
79 lc->usr_argv_str,
78 strlen(lc->usr_argv_str) + 1, 80 strlen(lc->usr_argv_str) + 1,
79 NULL, NULL); 81 NULL, NULL);
80 if (!r) 82 if (!r)
81 break; 83 break;
82 } 84 }
83 DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete"); 85 DMINFO("Reconnected to userspace log server... DM_ULOG_CTR complete");
84 r = dm_consult_userspace(uuid, DM_ULOG_RESUME, NULL, 86 r = dm_consult_userspace(uuid, lc->luid, DM_ULOG_RESUME, NULL,
85 0, NULL, NULL); 87 0, NULL, NULL);
86 if (!r) 88 if (!r)
87 goto retry; 89 goto retry;
@@ -111,10 +113,9 @@ static int build_constructor_string(struct dm_target *ti,
111 return -ENOMEM; 113 return -ENOMEM;
112 } 114 }
113 115
114 for (i = 0, str_size = 0; i < argc; i++) 116 str_size = sprintf(str, "%llu", (unsigned long long)ti->len);
115 str_size += sprintf(str + str_size, "%s ", argv[i]); 117 for (i = 0; i < argc; i++)
116 str_size += sprintf(str + str_size, "%llu", 118 str_size += sprintf(str + str_size, " %s", argv[i]);
117 (unsigned long long)ti->len);
118 119
119 *ctr_str = str; 120 *ctr_str = str;
120 return str_size; 121 return str_size;
@@ -154,6 +155,9 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
154 return -ENOMEM; 155 return -ENOMEM;
155 } 156 }
156 157
158 /* The ptr value is sufficient for local unique id */
159 lc->luid = (uint64_t)lc;
160
157 lc->ti = ti; 161 lc->ti = ti;
158 162
159 if (strlen(argv[0]) > (DM_UUID_LEN - 1)) { 163 if (strlen(argv[0]) > (DM_UUID_LEN - 1)) {
@@ -173,7 +177,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
173 } 177 }
174 178
175 /* Send table string */ 179 /* Send table string */
176 r = dm_consult_userspace(lc->uuid, DM_ULOG_CTR, 180 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_CTR,
177 ctr_str, str_size, NULL, NULL); 181 ctr_str, str_size, NULL, NULL);
178 182
179 if (r == -ESRCH) { 183 if (r == -ESRCH) {
@@ -183,7 +187,7 @@ static int userspace_ctr(struct dm_dirty_log *log, struct dm_target *ti,
183 187
184 /* Since the region size does not change, get it now */ 188 /* Since the region size does not change, get it now */
185 rdata_size = sizeof(rdata); 189 rdata_size = sizeof(rdata);
186 r = dm_consult_userspace(lc->uuid, DM_ULOG_GET_REGION_SIZE, 190 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_GET_REGION_SIZE,
187 NULL, 0, (char *)&rdata, &rdata_size); 191 NULL, 0, (char *)&rdata, &rdata_size);
188 192
189 if (r) { 193 if (r) {
@@ -212,7 +216,7 @@ static void userspace_dtr(struct dm_dirty_log *log)
212 int r; 216 int r;
213 struct log_c *lc = log->context; 217 struct log_c *lc = log->context;
214 218
215 r = dm_consult_userspace(lc->uuid, DM_ULOG_DTR, 219 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_DTR,
216 NULL, 0, 220 NULL, 0,
217 NULL, NULL); 221 NULL, NULL);
218 222
@@ -227,7 +231,7 @@ static int userspace_presuspend(struct dm_dirty_log *log)
227 int r; 231 int r;
228 struct log_c *lc = log->context; 232 struct log_c *lc = log->context;
229 233
230 r = dm_consult_userspace(lc->uuid, DM_ULOG_PRESUSPEND, 234 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_PRESUSPEND,
231 NULL, 0, 235 NULL, 0,
232 NULL, NULL); 236 NULL, NULL);
233 237
@@ -239,7 +243,7 @@ static int userspace_postsuspend(struct dm_dirty_log *log)
239 int r; 243 int r;
240 struct log_c *lc = log->context; 244 struct log_c *lc = log->context;
241 245
242 r = dm_consult_userspace(lc->uuid, DM_ULOG_POSTSUSPEND, 246 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_POSTSUSPEND,
243 NULL, 0, 247 NULL, 0,
244 NULL, NULL); 248 NULL, NULL);
245 249
@@ -252,7 +256,7 @@ static int userspace_resume(struct dm_dirty_log *log)
252 struct log_c *lc = log->context; 256 struct log_c *lc = log->context;
253 257
254 lc->in_sync_hint = 0; 258 lc->in_sync_hint = 0;
255 r = dm_consult_userspace(lc->uuid, DM_ULOG_RESUME, 259 r = dm_consult_userspace(lc->uuid, lc->luid, DM_ULOG_RESUME,
256 NULL, 0, 260 NULL, 0,
257 NULL, NULL); 261 NULL, NULL);
258 262
@@ -561,6 +565,7 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
561 char *result, unsigned maxlen) 565 char *result, unsigned maxlen)
562{ 566{
563 int r = 0; 567 int r = 0;
568 char *table_args;
564 size_t sz = (size_t)maxlen; 569 size_t sz = (size_t)maxlen;
565 struct log_c *lc = log->context; 570 struct log_c *lc = log->context;
566 571
@@ -577,8 +582,12 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type,
577 break; 582 break;
578 case STATUSTYPE_TABLE: 583 case STATUSTYPE_TABLE:
579 sz = 0; 584 sz = 0;
580 DMEMIT("%s %u %s %s", log->type->name, lc->usr_argc + 1, 585 table_args = strstr(lc->usr_argv_str, " ");
581 lc->uuid, lc->usr_argv_str); 586 BUG_ON(!table_args); /* There will always be a ' ' */
587 table_args++;
588
589 DMEMIT("%s %u %s %s ", log->type->name, lc->usr_argc,
590 lc->uuid, table_args);
582 break; 591 break;
583 } 592 }
584 return (r) ? 0 : (int)sz; 593 return (r) ? 0 : (int)sz;
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index 8ce74d95ae4d..ba0edad2d048 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -147,7 +147,8 @@ static void cn_ulog_callback(void *data)
147 147
148/** 148/**
149 * dm_consult_userspace 149 * dm_consult_userspace
150 * @uuid: log's uuid (must be DM_UUID_LEN in size) 150 * @uuid: log's universal unique identifier (must be DM_UUID_LEN in size)
151 * @luid: log's local unique identifier
151 * @request_type: found in include/linux/dm-log-userspace.h 152 * @request_type: found in include/linux/dm-log-userspace.h
152 * @data: data to tx to the server 153 * @data: data to tx to the server
153 * @data_size: size of data in bytes 154 * @data_size: size of data in bytes
@@ -163,7 +164,7 @@ static void cn_ulog_callback(void *data)
163 * 164 *
164 * Returns: 0 on success, -EXXX on failure 165 * Returns: 0 on success, -EXXX on failure
165 **/ 166 **/
166int dm_consult_userspace(const char *uuid, int request_type, 167int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
167 char *data, size_t data_size, 168 char *data, size_t data_size,
168 char *rdata, size_t *rdata_size) 169 char *rdata, size_t *rdata_size)
169{ 170{
@@ -190,6 +191,7 @@ resend:
190 191
191 memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); 192 memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size);
192 memcpy(tfr->uuid, uuid, DM_UUID_LEN); 193 memcpy(tfr->uuid, uuid, DM_UUID_LEN);
194 tfr->luid = luid;
193 tfr->seq = dm_ulog_seq++; 195 tfr->seq = dm_ulog_seq++;
194 196
195 /* 197 /*
diff --git a/drivers/md/dm-log-userspace-transfer.h b/drivers/md/dm-log-userspace-transfer.h
index c26d8e4e2710..04ee874f9153 100644
--- a/drivers/md/dm-log-userspace-transfer.h
+++ b/drivers/md/dm-log-userspace-transfer.h
@@ -11,7 +11,7 @@
11 11
12int dm_ulog_tfr_init(void); 12int dm_ulog_tfr_init(void);
13void dm_ulog_tfr_exit(void); 13void dm_ulog_tfr_exit(void);
14int dm_consult_userspace(const char *uuid, int request_type, 14int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
15 char *data, size_t data_size, 15 char *data, size_t data_size,
16 char *rdata, size_t *rdata_size); 16 char *rdata, size_t *rdata_size);
17 17
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 9726577cde49..33f179e66bf5 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -648,7 +648,13 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
648 */ 648 */
649 dm_rh_inc_pending(ms->rh, &sync); 649 dm_rh_inc_pending(ms->rh, &sync);
650 dm_rh_inc_pending(ms->rh, &nosync); 650 dm_rh_inc_pending(ms->rh, &nosync);
651 ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0; 651
652 /*
653 * If the flush fails on a previous call and succeeds here,
654 * we must not reset the log_failure variable. We need
655 * userspace interaction to do that.
656 */
657 ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;
652 658
653 /* 659 /*
654 * Dispatch io. 660 * Dispatch io.
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 6e3fe4f14934..d5b2e08750d5 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -106,6 +106,13 @@ struct pstore {
106 void *zero_area; 106 void *zero_area;
107 107
108 /* 108 /*
109 * An area used for header. The header can be written
110 * concurrently with metadata (when invalidating the snapshot),
111 * so it needs a separate buffer.
112 */
113 void *header_area;
114
115 /*
109 * Used to keep track of which metadata area the data in 116 * Used to keep track of which metadata area the data in
110 * 'chunk' refers to. 117 * 'chunk' refers to.
111 */ 118 */
@@ -148,16 +155,27 @@ static int alloc_area(struct pstore *ps)
148 */ 155 */
149 ps->area = vmalloc(len); 156 ps->area = vmalloc(len);
150 if (!ps->area) 157 if (!ps->area)
151 return r; 158 goto err_area;
152 159
153 ps->zero_area = vmalloc(len); 160 ps->zero_area = vmalloc(len);
154 if (!ps->zero_area) { 161 if (!ps->zero_area)
155 vfree(ps->area); 162 goto err_zero_area;
156 return r;
157 }
158 memset(ps->zero_area, 0, len); 163 memset(ps->zero_area, 0, len);
159 164
165 ps->header_area = vmalloc(len);
166 if (!ps->header_area)
167 goto err_header_area;
168
160 return 0; 169 return 0;
170
171err_header_area:
172 vfree(ps->zero_area);
173
174err_zero_area:
175 vfree(ps->area);
176
177err_area:
178 return r;
161} 179}
162 180
163static void free_area(struct pstore *ps) 181static void free_area(struct pstore *ps)
@@ -169,6 +187,10 @@ static void free_area(struct pstore *ps)
169 if (ps->zero_area) 187 if (ps->zero_area)
170 vfree(ps->zero_area); 188 vfree(ps->zero_area);
171 ps->zero_area = NULL; 189 ps->zero_area = NULL;
190
191 if (ps->header_area)
192 vfree(ps->header_area);
193 ps->header_area = NULL;
172} 194}
173 195
174struct mdata_req { 196struct mdata_req {
@@ -188,7 +210,8 @@ static void do_metadata(struct work_struct *work)
188/* 210/*
189 * Read or write a chunk aligned and sized block of data from a device. 211 * Read or write a chunk aligned and sized block of data from a device.
190 */ 212 */
191static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata) 213static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
214 int metadata)
192{ 215{
193 struct dm_io_region where = { 216 struct dm_io_region where = {
194 .bdev = ps->store->cow->bdev, 217 .bdev = ps->store->cow->bdev,
@@ -198,7 +221,7 @@ static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
198 struct dm_io_request io_req = { 221 struct dm_io_request io_req = {
199 .bi_rw = rw, 222 .bi_rw = rw,
200 .mem.type = DM_IO_VMA, 223 .mem.type = DM_IO_VMA,
201 .mem.ptr.vma = ps->area, 224 .mem.ptr.vma = area,
202 .client = ps->io_client, 225 .client = ps->io_client,
203 .notify.fn = NULL, 226 .notify.fn = NULL,
204 }; 227 };
@@ -240,7 +263,7 @@ static int area_io(struct pstore *ps, int rw)
240 263
241 chunk = area_location(ps, ps->current_area); 264 chunk = area_location(ps, ps->current_area);
242 265
243 r = chunk_io(ps, chunk, rw, 0); 266 r = chunk_io(ps, ps->area, chunk, rw, 0);
244 if (r) 267 if (r)
245 return r; 268 return r;
246 269
@@ -254,20 +277,7 @@ static void zero_memory_area(struct pstore *ps)
254 277
255static int zero_disk_area(struct pstore *ps, chunk_t area) 278static int zero_disk_area(struct pstore *ps, chunk_t area)
256{ 279{
257 struct dm_io_region where = { 280 return chunk_io(ps, ps->zero_area, area_location(ps, area), WRITE, 0);
258 .bdev = ps->store->cow->bdev,
259 .sector = ps->store->chunk_size * area_location(ps, area),
260 .count = ps->store->chunk_size,
261 };
262 struct dm_io_request io_req = {
263 .bi_rw = WRITE,
264 .mem.type = DM_IO_VMA,
265 .mem.ptr.vma = ps->zero_area,
266 .client = ps->io_client,
267 .notify.fn = NULL,
268 };
269
270 return dm_io(&io_req, 1, &where, NULL);
271} 281}
272 282
273static int read_header(struct pstore *ps, int *new_snapshot) 283static int read_header(struct pstore *ps, int *new_snapshot)
@@ -276,6 +286,7 @@ static int read_header(struct pstore *ps, int *new_snapshot)
276 struct disk_header *dh; 286 struct disk_header *dh;
277 chunk_t chunk_size; 287 chunk_t chunk_size;
278 int chunk_size_supplied = 1; 288 int chunk_size_supplied = 1;
289 char *chunk_err;
279 290
280 /* 291 /*
281 * Use default chunk size (or hardsect_size, if larger) if none supplied 292 * Use default chunk size (or hardsect_size, if larger) if none supplied
@@ -297,11 +308,11 @@ static int read_header(struct pstore *ps, int *new_snapshot)
297 if (r) 308 if (r)
298 return r; 309 return r;
299 310
300 r = chunk_io(ps, 0, READ, 1); 311 r = chunk_io(ps, ps->header_area, 0, READ, 1);
301 if (r) 312 if (r)
302 goto bad; 313 goto bad;
303 314
304 dh = (struct disk_header *) ps->area; 315 dh = ps->header_area;
305 316
306 if (le32_to_cpu(dh->magic) == 0) { 317 if (le32_to_cpu(dh->magic) == 0) {
307 *new_snapshot = 1; 318 *new_snapshot = 1;
@@ -319,20 +330,25 @@ static int read_header(struct pstore *ps, int *new_snapshot)
319 ps->version = le32_to_cpu(dh->version); 330 ps->version = le32_to_cpu(dh->version);
320 chunk_size = le32_to_cpu(dh->chunk_size); 331 chunk_size = le32_to_cpu(dh->chunk_size);
321 332
322 if (!chunk_size_supplied || ps->store->chunk_size == chunk_size) 333 if (ps->store->chunk_size == chunk_size)
323 return 0; 334 return 0;
324 335
325 DMWARN("chunk size %llu in device metadata overrides " 336 if (chunk_size_supplied)
326 "table chunk size of %llu.", 337 DMWARN("chunk size %llu in device metadata overrides "
327 (unsigned long long)chunk_size, 338 "table chunk size of %llu.",
328 (unsigned long long)ps->store->chunk_size); 339 (unsigned long long)chunk_size,
340 (unsigned long long)ps->store->chunk_size);
329 341
330 /* We had a bogus chunk_size. Fix stuff up. */ 342 /* We had a bogus chunk_size. Fix stuff up. */
331 free_area(ps); 343 free_area(ps);
332 344
333 ps->store->chunk_size = chunk_size; 345 r = dm_exception_store_set_chunk_size(ps->store, chunk_size,
334 ps->store->chunk_mask = chunk_size - 1; 346 &chunk_err);
335 ps->store->chunk_shift = ffs(chunk_size) - 1; 347 if (r) {
348 DMERR("invalid on-disk chunk size %llu: %s.",
349 (unsigned long long)chunk_size, chunk_err);
350 return r;
351 }
336 352
337 r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size), 353 r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
338 ps->io_client); 354 ps->io_client);
@@ -351,15 +367,15 @@ static int write_header(struct pstore *ps)
351{ 367{
352 struct disk_header *dh; 368 struct disk_header *dh;
353 369
354 memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT); 370 memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT);
355 371
356 dh = (struct disk_header *) ps->area; 372 dh = ps->header_area;
357 dh->magic = cpu_to_le32(SNAP_MAGIC); 373 dh->magic = cpu_to_le32(SNAP_MAGIC);
358 dh->valid = cpu_to_le32(ps->valid); 374 dh->valid = cpu_to_le32(ps->valid);
359 dh->version = cpu_to_le32(ps->version); 375 dh->version = cpu_to_le32(ps->version);
360 dh->chunk_size = cpu_to_le32(ps->store->chunk_size); 376 dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
361 377
362 return chunk_io(ps, 0, WRITE, 1); 378 return chunk_io(ps, ps->header_area, 0, WRITE, 1);
363} 379}
364 380
365/* 381/*
@@ -679,6 +695,8 @@ static int persistent_ctr(struct dm_exception_store *store,
679 ps->valid = 1; 695 ps->valid = 1;
680 ps->version = SNAPSHOT_DISK_VERSION; 696 ps->version = SNAPSHOT_DISK_VERSION;
681 ps->area = NULL; 697 ps->area = NULL;
698 ps->zero_area = NULL;
699 ps->header_area = NULL;
682 ps->next_free = 2; /* skipping the header and first area */ 700 ps->next_free = 2; /* skipping the header and first area */
683 ps->current_committed = 0; 701 ps->current_committed = 0;
684 702
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index d573165cd2b7..57f1bf7f3b7a 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1176,6 +1176,15 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
1176 return 0; 1176 return 0;
1177} 1177}
1178 1178
1179static int snapshot_iterate_devices(struct dm_target *ti,
1180 iterate_devices_callout_fn fn, void *data)
1181{
1182 struct dm_snapshot *snap = ti->private;
1183
1184 return fn(ti, snap->origin, 0, ti->len, data);
1185}
1186
1187
1179/*----------------------------------------------------------------- 1188/*-----------------------------------------------------------------
1180 * Origin methods 1189 * Origin methods
1181 *---------------------------------------------------------------*/ 1190 *---------------------------------------------------------------*/
@@ -1410,20 +1419,29 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result,
1410 return 0; 1419 return 0;
1411} 1420}
1412 1421
1422static int origin_iterate_devices(struct dm_target *ti,
1423 iterate_devices_callout_fn fn, void *data)
1424{
1425 struct dm_dev *dev = ti->private;
1426
1427 return fn(ti, dev, 0, ti->len, data);
1428}
1429
1413static struct target_type origin_target = { 1430static struct target_type origin_target = {
1414 .name = "snapshot-origin", 1431 .name = "snapshot-origin",
1415 .version = {1, 6, 0}, 1432 .version = {1, 7, 0},
1416 .module = THIS_MODULE, 1433 .module = THIS_MODULE,
1417 .ctr = origin_ctr, 1434 .ctr = origin_ctr,
1418 .dtr = origin_dtr, 1435 .dtr = origin_dtr,
1419 .map = origin_map, 1436 .map = origin_map,
1420 .resume = origin_resume, 1437 .resume = origin_resume,
1421 .status = origin_status, 1438 .status = origin_status,
1439 .iterate_devices = origin_iterate_devices,
1422}; 1440};
1423 1441
1424static struct target_type snapshot_target = { 1442static struct target_type snapshot_target = {
1425 .name = "snapshot", 1443 .name = "snapshot",
1426 .version = {1, 6, 0}, 1444 .version = {1, 7, 0},
1427 .module = THIS_MODULE, 1445 .module = THIS_MODULE,
1428 .ctr = snapshot_ctr, 1446 .ctr = snapshot_ctr,
1429 .dtr = snapshot_dtr, 1447 .dtr = snapshot_dtr,
@@ -1431,6 +1449,7 @@ static struct target_type snapshot_target = {
1431 .end_io = snapshot_end_io, 1449 .end_io = snapshot_end_io,
1432 .resume = snapshot_resume, 1450 .resume = snapshot_resume,
1433 .status = snapshot_status, 1451 .status = snapshot_status,
1452 .iterate_devices = snapshot_iterate_devices,
1434}; 1453};
1435 1454
1436static int __init dm_snapshot_init(void) 1455static int __init dm_snapshot_init(void)
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 4e0e5937e42a..3e563d251733 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -329,9 +329,19 @@ static int stripe_iterate_devices(struct dm_target *ti,
329 return ret; 329 return ret;
330} 330}
331 331
332static void stripe_io_hints(struct dm_target *ti,
333 struct queue_limits *limits)
334{
335 struct stripe_c *sc = ti->private;
336 unsigned chunk_size = (sc->chunk_mask + 1) << 9;
337
338 blk_limits_io_min(limits, chunk_size);
339 limits->io_opt = chunk_size * sc->stripes;
340}
341
332static struct target_type stripe_target = { 342static struct target_type stripe_target = {
333 .name = "striped", 343 .name = "striped",
334 .version = {1, 2, 0}, 344 .version = {1, 3, 0},
335 .module = THIS_MODULE, 345 .module = THIS_MODULE,
336 .ctr = stripe_ctr, 346 .ctr = stripe_ctr,
337 .dtr = stripe_dtr, 347 .dtr = stripe_dtr,
@@ -339,6 +349,7 @@ static struct target_type stripe_target = {
339 .end_io = stripe_end_io, 349 .end_io = stripe_end_io,
340 .status = stripe_status, 350 .status = stripe_status,
341 .iterate_devices = stripe_iterate_devices, 351 .iterate_devices = stripe_iterate_devices,
352 .io_hints = stripe_io_hints,
342}; 353};
343 354
344int __init dm_stripe_init(void) 355int __init dm_stripe_init(void)
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index d952b3441913..1a6cb3c7822e 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -343,10 +343,10 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md)
343} 343}
344 344
345/* 345/*
346 * If possible, this checks an area of a destination device is valid. 346 * If possible, this checks an area of a destination device is invalid.
347 */ 347 */
348static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev, 348static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
349 sector_t start, sector_t len, void *data) 349 sector_t start, sector_t len, void *data)
350{ 350{
351 struct queue_limits *limits = data; 351 struct queue_limits *limits = data;
352 struct block_device *bdev = dev->bdev; 352 struct block_device *bdev = dev->bdev;
@@ -357,36 +357,40 @@ static int device_area_is_valid(struct dm_target *ti, struct dm_dev *dev,
357 char b[BDEVNAME_SIZE]; 357 char b[BDEVNAME_SIZE];
358 358
359 if (!dev_size) 359 if (!dev_size)
360 return 1; 360 return 0;
361 361
362 if ((start >= dev_size) || (start + len > dev_size)) { 362 if ((start >= dev_size) || (start + len > dev_size)) {
363 DMWARN("%s: %s too small for target", 363 DMWARN("%s: %s too small for target: "
364 dm_device_name(ti->table->md), bdevname(bdev, b)); 364 "start=%llu, len=%llu, dev_size=%llu",
365 return 0; 365 dm_device_name(ti->table->md), bdevname(bdev, b),
366 (unsigned long long)start,
367 (unsigned long long)len,
368 (unsigned long long)dev_size);
369 return 1;
366 } 370 }
367 371
368 if (logical_block_size_sectors <= 1) 372 if (logical_block_size_sectors <= 1)
369 return 1; 373 return 0;
370 374
371 if (start & (logical_block_size_sectors - 1)) { 375 if (start & (logical_block_size_sectors - 1)) {
372 DMWARN("%s: start=%llu not aligned to h/w " 376 DMWARN("%s: start=%llu not aligned to h/w "
373 "logical block size %hu of %s", 377 "logical block size %u of %s",
374 dm_device_name(ti->table->md), 378 dm_device_name(ti->table->md),
375 (unsigned long long)start, 379 (unsigned long long)start,
376 limits->logical_block_size, bdevname(bdev, b)); 380 limits->logical_block_size, bdevname(bdev, b));
377 return 0; 381 return 1;
378 } 382 }
379 383
380 if (len & (logical_block_size_sectors - 1)) { 384 if (len & (logical_block_size_sectors - 1)) {
381 DMWARN("%s: len=%llu not aligned to h/w " 385 DMWARN("%s: len=%llu not aligned to h/w "
382 "logical block size %hu of %s", 386 "logical block size %u of %s",
383 dm_device_name(ti->table->md), 387 dm_device_name(ti->table->md),
384 (unsigned long long)len, 388 (unsigned long long)len,
385 limits->logical_block_size, bdevname(bdev, b)); 389 limits->logical_block_size, bdevname(bdev, b));
386 return 0; 390 return 1;
387 } 391 }
388 392
389 return 1; 393 return 0;
390} 394}
391 395
392/* 396/*
@@ -496,8 +500,15 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
496 } 500 }
497 501
498 if (blk_stack_limits(limits, &q->limits, start << 9) < 0) 502 if (blk_stack_limits(limits, &q->limits, start << 9) < 0)
499 DMWARN("%s: target device %s is misaligned", 503 DMWARN("%s: target device %s is misaligned: "
500 dm_device_name(ti->table->md), bdevname(bdev, b)); 504 "physical_block_size=%u, logical_block_size=%u, "
505 "alignment_offset=%u, start=%llu",
506 dm_device_name(ti->table->md), bdevname(bdev, b),
507 q->limits.physical_block_size,
508 q->limits.logical_block_size,
509 q->limits.alignment_offset,
510 (unsigned long long) start << 9);
511
501 512
502 /* 513 /*
503 * Check if merge fn is supported. 514 * Check if merge fn is supported.
@@ -698,7 +709,7 @@ static int validate_hardware_logical_block_alignment(struct dm_table *table,
698 709
699 if (remaining) { 710 if (remaining) {
700 DMWARN("%s: table line %u (start sect %llu len %llu) " 711 DMWARN("%s: table line %u (start sect %llu len %llu) "
701 "not aligned to h/w logical block size %hu", 712 "not aligned to h/w logical block size %u",
702 dm_device_name(table->md), i, 713 dm_device_name(table->md), i,
703 (unsigned long long) ti->begin, 714 (unsigned long long) ti->begin,
704 (unsigned long long) ti->len, 715 (unsigned long long) ti->len,
@@ -996,12 +1007,16 @@ int dm_calculate_queue_limits(struct dm_table *table,
996 ti->type->iterate_devices(ti, dm_set_device_limits, 1007 ti->type->iterate_devices(ti, dm_set_device_limits,
997 &ti_limits); 1008 &ti_limits);
998 1009
1010 /* Set I/O hints portion of queue limits */
1011 if (ti->type->io_hints)
1012 ti->type->io_hints(ti, &ti_limits);
1013
999 /* 1014 /*
1000 * Check each device area is consistent with the target's 1015 * Check each device area is consistent with the target's
1001 * overall queue limits. 1016 * overall queue limits.
1002 */ 1017 */
1003 if (!ti->type->iterate_devices(ti, device_area_is_valid, 1018 if (ti->type->iterate_devices(ti, device_area_is_invalid,
1004 &ti_limits)) 1019 &ti_limits))
1005 return -EINVAL; 1020 return -EINVAL;
1006 1021
1007combine_limits: 1022combine_limits:
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8a311ea0d441..b4845b14740d 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -738,16 +738,22 @@ static void rq_completed(struct mapped_device *md, int run_queue)
738 dm_put(md); 738 dm_put(md);
739} 739}
740 740
741static void free_rq_clone(struct request *clone)
742{
743 struct dm_rq_target_io *tio = clone->end_io_data;
744
745 blk_rq_unprep_clone(clone);
746 free_rq_tio(tio);
747}
748
741static void dm_unprep_request(struct request *rq) 749static void dm_unprep_request(struct request *rq)
742{ 750{
743 struct request *clone = rq->special; 751 struct request *clone = rq->special;
744 struct dm_rq_target_io *tio = clone->end_io_data;
745 752
746 rq->special = NULL; 753 rq->special = NULL;
747 rq->cmd_flags &= ~REQ_DONTPREP; 754 rq->cmd_flags &= ~REQ_DONTPREP;
748 755
749 blk_rq_unprep_clone(clone); 756 free_rq_clone(clone);
750 free_rq_tio(tio);
751} 757}
752 758
753/* 759/*
@@ -825,8 +831,7 @@ static void dm_end_request(struct request *clone, int error)
825 rq->sense_len = clone->sense_len; 831 rq->sense_len = clone->sense_len;
826 } 832 }
827 833
828 BUG_ON(clone->bio); 834 free_rq_clone(clone);
829 free_rq_tio(tio);
830 835
831 blk_end_request_all(rq, error); 836 blk_end_request_all(rq, error);
832 837
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig
index 88847d1dcbb5..8c1aed77ea30 100644
--- a/drivers/media/dvb/siano/Kconfig
+++ b/drivers/media/dvb/siano/Kconfig
@@ -2,25 +2,33 @@
2# Siano Mobile Silicon Digital TV device configuration 2# Siano Mobile Silicon Digital TV device configuration
3# 3#
4 4
5config DVB_SIANO_SMS1XXX 5config SMS_SIANO_MDTV
6 tristate "Siano SMS1XXX USB dongle support" 6 tristate "Siano SMS1xxx based MDTV receiver"
7 depends on DVB_CORE && USB && INPUT 7 depends on DVB_CORE && INPUT
8 ---help--- 8 ---help---
9 Choose Y here if you have a USB dongle with a SMS1XXX chipset. 9 Choose Y or M here if you have MDTV receiver with a Siano chipset.
10 10
11 To compile this driver as a module, choose M here: the 11 To compile this driver as a module, choose M here
12 module will be called sms1xxx. 12 (The module will be called smsmdtv).
13 13
14config DVB_SIANO_SMS1XXX_SMS_IDS 14 Further documentation on this driver can be found on the WWW
15 bool "Enable support for Siano Mobile Silicon default USB IDs" 15 at http://www.siano-ms.com/
16 depends on DVB_SIANO_SMS1XXX 16
17 default y 17if SMS_SIANO_MDTV
18 ---help--- 18menu "Siano module components"
19 Choose Y here if you have a USB dongle with a SMS1XXX chipset
20 that uses Siano Mobile Silicon's default usb vid:pid.
21 19
22 Choose N here if you would prefer to use Siano's external driver. 20# Hardware interfaces support
23 21
24 Further documentation on this driver can be found on the WWW at 22config SMS_USB_DRV
25 <http://www.siano-ms.com/>. 23 tristate "USB interface support"
24 depends on DVB_CORE && USB
25 ---help---
26 Choose if you would like to have Siano's support for USB interface
26 27
28config SMS_SDIO_DRV
29 tristate "SDIO interface support"
30 depends on DVB_CORE && MMC
31 ---help---
32 Choose if you would like to have Siano's support for SDIO interface
33endmenu
34endif # SMS_SIANO_MDTV
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
index c6644d909433..c54140b5ab5a 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/dvb/siano/Makefile
@@ -1,8 +1,9 @@
1sms1xxx-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
2 1
3obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o 2smsmdtv-objs := smscoreapi.o sms-cards.o smsendian.o smsir.o
4obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o 3
5obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o 4obj-$(CONFIG_SMS_SIANO_MDTV) += smsmdtv.o smsdvb.o
5obj-$(CONFIG_SMS_USB_DRV) += smsusb.o
6obj-$(CONFIG_SMS_SDIO_DRV) += smssdio.o
6 7
7EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 8EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
8 9
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 3ee1c3902c56..266033ae2784 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -325,6 +325,16 @@ static int smsdvb_sendrequest_and_wait(struct smsdvb_client_t *client,
325 0 : -ETIME; 325 0 : -ETIME;
326} 326}
327 327
328static inline int led_feedback(struct smsdvb_client_t *client)
329{
330 if (client->fe_status & FE_HAS_LOCK)
331 return sms_board_led_feedback(client->coredev,
332 (client->sms_stat_dvb.ReceptionData.BER
333 == 0) ? SMS_LED_HI : SMS_LED_LO);
334 else
335 return sms_board_led_feedback(client->coredev, SMS_LED_OFF);
336}
337
328static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat) 338static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
329{ 339{
330 struct smsdvb_client_t *client; 340 struct smsdvb_client_t *client;
@@ -332,6 +342,8 @@ static int smsdvb_read_status(struct dvb_frontend *fe, fe_status_t *stat)
332 342
333 *stat = client->fe_status; 343 *stat = client->fe_status;
334 344
345 led_feedback(client);
346
335 return 0; 347 return 0;
336} 348}
337 349
@@ -342,6 +354,8 @@ static int smsdvb_read_ber(struct dvb_frontend *fe, u32 *ber)
342 354
343 *ber = client->sms_stat_dvb.ReceptionData.BER; 355 *ber = client->sms_stat_dvb.ReceptionData.BER;
344 356
357 led_feedback(client);
358
345 return 0; 359 return 0;
346} 360}
347 361
@@ -359,6 +373,8 @@ static int smsdvb_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
359 (client->sms_stat_dvb.ReceptionData.InBandPwr 373 (client->sms_stat_dvb.ReceptionData.InBandPwr
360 + 95) * 3 / 2; 374 + 95) * 3 / 2;
361 375
376 led_feedback(client);
377
362 return 0; 378 return 0;
363} 379}
364 380
@@ -369,6 +385,8 @@ static int smsdvb_read_snr(struct dvb_frontend *fe, u16 *snr)
369 385
370 *snr = client->sms_stat_dvb.ReceptionData.SNR; 386 *snr = client->sms_stat_dvb.ReceptionData.SNR;
371 387
388 led_feedback(client);
389
372 return 0; 390 return 0;
373} 391}
374 392
@@ -379,6 +397,8 @@ static int smsdvb_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
379 397
380 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets; 398 *ucblocks = client->sms_stat_dvb.ReceptionData.ErrorTSPackets;
381 399
400 led_feedback(client);
401
382 return 0; 402 return 0;
383} 403}
384 404
@@ -404,6 +424,8 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
404 u32 Data[3]; 424 u32 Data[3];
405 } Msg; 425 } Msg;
406 426
427 int ret;
428
407 client->fe_status = FE_HAS_SIGNAL; 429 client->fe_status = FE_HAS_SIGNAL;
408 client->event_fe_state = -1; 430 client->event_fe_state = -1;
409 client->event_unc_state = -1; 431 client->event_unc_state = -1;
@@ -426,6 +448,23 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
426 case BANDWIDTH_AUTO: return -EOPNOTSUPP; 448 case BANDWIDTH_AUTO: return -EOPNOTSUPP;
427 default: return -EINVAL; 449 default: return -EINVAL;
428 } 450 }
451 /* Disable LNA, if any. An error is returned if no LNA is present */
452 ret = sms_board_lna_control(client->coredev, 0);
453 if (ret == 0) {
454 fe_status_t status;
455
456 /* tune with LNA off at first */
457 ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
458 &client->tune_done);
459
460 smsdvb_read_status(fe, &status);
461
462 if (status & FE_HAS_LOCK)
463 return ret;
464
465 /* previous tune didnt lock - enable LNA and tune again */
466 sms_board_lna_control(client->coredev, 1);
467 }
429 468
430 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg), 469 return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
431 &client->tune_done); 470 &client->tune_done);
@@ -451,6 +490,8 @@ static int smsdvb_init(struct dvb_frontend *fe)
451 struct smsdvb_client_t *client = 490 struct smsdvb_client_t *client =
452 container_of(fe, struct smsdvb_client_t, frontend); 491 container_of(fe, struct smsdvb_client_t, frontend);
453 492
493 sms_board_power(client->coredev, 1);
494
454 sms_board_dvb3_event(client, DVB3_EVENT_INIT); 495 sms_board_dvb3_event(client, DVB3_EVENT_INIT);
455 return 0; 496 return 0;
456} 497}
@@ -460,6 +501,9 @@ static int smsdvb_sleep(struct dvb_frontend *fe)
460 struct smsdvb_client_t *client = 501 struct smsdvb_client_t *client =
461 container_of(fe, struct smsdvb_client_t, frontend); 502 container_of(fe, struct smsdvb_client_t, frontend);
462 503
504 sms_board_led_feedback(client->coredev, SMS_LED_OFF);
505 sms_board_power(client->coredev, 0);
506
463 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP); 507 sms_board_dvb3_event(client, DVB3_EVENT_SLEEP);
464 508
465 return 0; 509 return 0;
diff --git a/drivers/media/dvb/siano/smssdio.c b/drivers/media/dvb/siano/smssdio.c
index dfaa49a53f32..d1d652e7f890 100644
--- a/drivers/media/dvb/siano/smssdio.c
+++ b/drivers/media/dvb/siano/smssdio.c
@@ -46,6 +46,7 @@
46 46
47#define SMSSDIO_DATA 0x00 47#define SMSSDIO_DATA 0x00
48#define SMSSDIO_INT 0x04 48#define SMSSDIO_INT 0x04
49#define SMSSDIO_BLOCK_SIZE 128
49 50
50static const struct sdio_device_id smssdio_ids[] = { 51static const struct sdio_device_id smssdio_ids[] = {
51 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR), 52 {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
@@ -85,7 +86,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
85 sdio_claim_host(smsdev->func); 86 sdio_claim_host(smsdev->func);
86 87
87 while (size >= smsdev->func->cur_blksize) { 88 while (size >= smsdev->func->cur_blksize) {
88 ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1); 89 ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
90 buffer, smsdev->func->cur_blksize);
89 if (ret) 91 if (ret)
90 goto out; 92 goto out;
91 93
@@ -94,8 +96,8 @@ static int smssdio_sendrequest(void *context, void *buffer, size_t size)
94 } 96 }
95 97
96 if (size) { 98 if (size) {
97 ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA, 99 ret = sdio_memcpy_toio(smsdev->func, SMSSDIO_DATA,
98 buffer, size); 100 buffer, size);
99 } 101 }
100 102
101out: 103out:
@@ -125,23 +127,23 @@ static void smssdio_interrupt(struct sdio_func *func)
125 */ 127 */
126 isr = sdio_readb(func, SMSSDIO_INT, &ret); 128 isr = sdio_readb(func, SMSSDIO_INT, &ret);
127 if (ret) { 129 if (ret) {
128 dev_err(&smsdev->func->dev, 130 sms_err("Unable to read interrupt register!\n");
129 "Unable to read interrupt register!\n");
130 return; 131 return;
131 } 132 }
132 133
133 if (smsdev->split_cb == NULL) { 134 if (smsdev->split_cb == NULL) {
134 cb = smscore_getbuffer(smsdev->coredev); 135 cb = smscore_getbuffer(smsdev->coredev);
135 if (!cb) { 136 if (!cb) {
136 dev_err(&smsdev->func->dev, 137 sms_err("Unable to allocate data buffer!\n");
137 "Unable to allocate data buffer!\n");
138 return; 138 return;
139 } 139 }
140 140
141 ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1); 141 ret = sdio_memcpy_fromio(smsdev->func,
142 cb->p,
143 SMSSDIO_DATA,
144 SMSSDIO_BLOCK_SIZE);
142 if (ret) { 145 if (ret) {
143 dev_err(&smsdev->func->dev, 146 sms_err("Error %d reading initial block!\n", ret);
144 "Error %d reading initial block!\n", ret);
145 return; 147 return;
146 } 148 }
147 149
@@ -152,7 +154,10 @@ static void smssdio_interrupt(struct sdio_func *func)
152 return; 154 return;
153 } 155 }
154 156
155 size = hdr->msgLength - smsdev->func->cur_blksize; 157 if (hdr->msgLength > smsdev->func->cur_blksize)
158 size = hdr->msgLength - smsdev->func->cur_blksize;
159 else
160 size = 0;
156 } else { 161 } else {
157 cb = smsdev->split_cb; 162 cb = smsdev->split_cb;
158 hdr = cb->p; 163 hdr = cb->p;
@@ -162,23 +167,24 @@ static void smssdio_interrupt(struct sdio_func *func)
162 smsdev->split_cb = NULL; 167 smsdev->split_cb = NULL;
163 } 168 }
164 169
165 if (hdr->msgLength > smsdev->func->cur_blksize) { 170 if (size) {
166 void *buffer; 171 void *buffer;
167 172
168 size = ALIGN(size, 128); 173 buffer = cb->p + (hdr->msgLength - size);
169 buffer = cb->p + hdr->msgLength; 174 size = ALIGN(size, SMSSDIO_BLOCK_SIZE);
170 175
171 BUG_ON(smsdev->func->cur_blksize != 128); 176 BUG_ON(smsdev->func->cur_blksize != SMSSDIO_BLOCK_SIZE);
172 177
173 /* 178 /*
174 * First attempt to transfer all of it in one go... 179 * First attempt to transfer all of it in one go...
175 */ 180 */
176 ret = sdio_read_blocks(smsdev->func, buffer, 181 ret = sdio_memcpy_fromio(smsdev->func,
177 SMSSDIO_DATA, size / 128); 182 buffer,
183 SMSSDIO_DATA,
184 size);
178 if (ret && ret != -EINVAL) { 185 if (ret && ret != -EINVAL) {
179 smscore_putbuffer(smsdev->coredev, cb); 186 smscore_putbuffer(smsdev->coredev, cb);
180 dev_err(&smsdev->func->dev, 187 sms_err("Error %d reading data from card!\n", ret);
181 "Error %d reading data from card!\n", ret);
182 return; 188 return;
183 } 189 }
184 190
@@ -191,12 +197,12 @@ static void smssdio_interrupt(struct sdio_func *func)
191 */ 197 */
192 if (ret == -EINVAL) { 198 if (ret == -EINVAL) {
193 while (size) { 199 while (size) {
194 ret = sdio_read_blocks(smsdev->func, 200 ret = sdio_memcpy_fromio(smsdev->func,
195 buffer, SMSSDIO_DATA, 1); 201 buffer, SMSSDIO_DATA,
202 smsdev->func->cur_blksize);
196 if (ret) { 203 if (ret) {
197 smscore_putbuffer(smsdev->coredev, cb); 204 smscore_putbuffer(smsdev->coredev, cb);
198 dev_err(&smsdev->func->dev, 205 sms_err("Error %d reading "
199 "Error %d reading "
200 "data from card!\n", ret); 206 "data from card!\n", ret);
201 return; 207 return;
202 } 208 }
@@ -269,7 +275,7 @@ static int smssdio_probe(struct sdio_func *func,
269 if (ret) 275 if (ret)
270 goto release; 276 goto release;
271 277
272 ret = sdio_set_block_size(func, 128); 278 ret = sdio_set_block_size(func, SMSSDIO_BLOCK_SIZE);
273 if (ret) 279 if (ret)
274 goto disable; 280 goto disable;
275 281
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index ed281f565945..1c2e544eda73 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1730,6 +1730,25 @@ static inline void em28xx_set_model(struct em28xx *dev)
1730 EM28XX_I2C_FREQ_100_KHZ; 1730 EM28XX_I2C_FREQ_100_KHZ;
1731} 1731}
1732 1732
1733
1734/* FIXME: Should be replaced by a proper mt9m111 driver */
1735static int em28xx_initialize_mt9m111(struct em28xx *dev)
1736{
1737 int i;
1738 unsigned char regs[][3] = {
1739 { 0x0d, 0x00, 0x01, }, /* reset and use defaults */
1740 { 0x0d, 0x00, 0x00, },
1741 { 0x0a, 0x00, 0x21, },
1742 { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */
1743 };
1744
1745 for (i = 0; i < ARRAY_SIZE(regs); i++)
1746 i2c_master_send(&dev->i2c_client, &regs[i][0], 3);
1747
1748 return 0;
1749}
1750
1751
1733/* FIXME: Should be replaced by a proper mt9m001 driver */ 1752/* FIXME: Should be replaced by a proper mt9m001 driver */
1734static int em28xx_initialize_mt9m001(struct em28xx *dev) 1753static int em28xx_initialize_mt9m001(struct em28xx *dev)
1735{ 1754{
@@ -1758,7 +1777,7 @@ static int em28xx_initialize_mt9m001(struct em28xx *dev)
1758 1777
1759/* HINT method: webcam I2C chips 1778/* HINT method: webcam I2C chips
1760 * 1779 *
1761 * This method work for webcams with Micron sensors 1780 * This method works for webcams with Micron sensors
1762 */ 1781 */
1763static int em28xx_hint_sensor(struct em28xx *dev) 1782static int em28xx_hint_sensor(struct em28xx *dev)
1764{ 1783{
@@ -1804,6 +1823,23 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1804 dev->vinctl = 0x00; 1823 dev->vinctl = 0x00;
1805 1824
1806 break; 1825 break;
1826
1827 case 0x143a: /* MT9M111 as found in the ECS G200 */
1828 dev->model = EM2750_BOARD_UNKNOWN;
1829 em28xx_set_model(dev);
1830
1831 sensor_name = "mt9m111";
1832 dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ;
1833 dev->em28xx_sensor = EM28XX_MT9M111;
1834 em28xx_initialize_mt9m111(dev);
1835 dev->sensor_xres = 640;
1836 dev->sensor_yres = 512;
1837
1838 dev->vinmode = 0x0a;
1839 dev->vinctl = 0x00;
1840
1841 break;
1842
1807 case 0x8431: 1843 case 0x8431:
1808 dev->model = EM2750_BOARD_UNKNOWN; 1844 dev->model = EM2750_BOARD_UNKNOWN;
1809 em28xx_set_model(dev); 1845 em28xx_set_model(dev);
@@ -1820,7 +1856,7 @@ static int em28xx_hint_sensor(struct em28xx *dev)
1820 1856
1821 break; 1857 break;
1822 default: 1858 default:
1823 printk("Unknown Micron Sensor 0x%04x\n", be16_to_cpu(version)); 1859 printk("Unknown Micron Sensor 0x%04x\n", version);
1824 return -EINVAL; 1860 return -EINVAL;
1825 } 1861 }
1826 1862
@@ -2346,7 +2382,9 @@ void em28xx_card_setup(struct em28xx *dev)
2346 } 2382 }
2347 2383
2348 em28xx_tuner_setup(dev); 2384 em28xx_tuner_setup(dev);
2349 em28xx_ir_init(dev); 2385
2386 if(!disable_ir)
2387 em28xx_ir_init(dev);
2350} 2388}
2351 2389
2352 2390
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 8c2dc38bca9f..a2add61f7d59 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -367,6 +367,7 @@ enum em28xx_sensor {
367 EM28XX_NOSENSOR = 0, 367 EM28XX_NOSENSOR = 0,
368 EM28XX_MT9V011, 368 EM28XX_MT9V011,
369 EM28XX_MT9M001, 369 EM28XX_MT9M001,
370 EM28XX_MT9M111,
370}; 371};
371 372
372enum em28xx_adecoder { 373enum em28xx_adecoder {
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 34f46f2bc040..e994dcac43ff 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -114,7 +114,7 @@ config USB_GSPCA_SN9C20X
114 114
115config USB_GSPCA_SN9C20X_EVDEV 115config USB_GSPCA_SN9C20X_EVDEV
116 bool "Enable evdev support" 116 bool "Enable evdev support"
117 depends on USB_GSPCA_SN9C20X 117 depends on USB_GSPCA_SN9C20X && INPUT
118 ---help--- 118 ---help---
119 Say Y here in order to enable evdev support for sn9c20x webcam button. 119 Say Y here in order to enable evdev support for sn9c20x webcam button.
120 120
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index fc976f42f432..2622a6e63da1 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -695,7 +695,7 @@ static int zr364xx_release(struct file *file)
695 for (i = 0; i < 2; i++) { 695 for (i = 0; i < 2; i++) {
696 err = 696 err =
697 send_control_msg(udev, 1, init[cam->method][i].value, 697 send_control_msg(udev, 1, init[cam->method][i].value,
698 0, init[i][cam->method].bytes, 698 0, init[cam->method][i].bytes,
699 init[cam->method][i].size); 699 init[cam->method][i].size);
700 if (err < 0) { 700 if (err < 0) {
701 dev_err(&udev->dev, "error during release sequence\n"); 701 dev_err(&udev->dev, "error during release sequence\n");
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index ae5fe91867e1..10ed195c0c1c 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -736,7 +736,7 @@ static int __devinit m25p_probe(struct spi_device *spi)
736 flash->partitioned = 1; 736 flash->partitioned = 1;
737 return add_mtd_partitions(&flash->mtd, parts, nr_parts); 737 return add_mtd_partitions(&flash->mtd, parts, nr_parts);
738 } 738 }
739 } else if (data->nr_parts) 739 } else if (data && data->nr_parts)
740 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n", 740 dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
741 data->nr_parts, data->name); 741 data->nr_parts, data->name);
742 742
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index fb86cacd5bdb..1002e1882996 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -135,16 +135,17 @@ static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
135int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len, 135int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
136 size_t *retlen, uint8_t *buf) 136 size_t *retlen, uint8_t *buf)
137{ 137{
138 loff_t mask = mtd->writesize - 1;
138 struct mtd_oob_ops ops; 139 struct mtd_oob_ops ops;
139 int res; 140 int res;
140 141
141 ops.mode = MTD_OOB_PLACE; 142 ops.mode = MTD_OOB_PLACE;
142 ops.ooboffs = offs & (mtd->writesize - 1); 143 ops.ooboffs = offs & mask;
143 ops.ooblen = len; 144 ops.ooblen = len;
144 ops.oobbuf = buf; 145 ops.oobbuf = buf;
145 ops.datbuf = NULL; 146 ops.datbuf = NULL;
146 147
147 res = mtd->read_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 148 res = mtd->read_oob(mtd, offs & ~mask, &ops);
148 *retlen = ops.oobretlen; 149 *retlen = ops.oobretlen;
149 return res; 150 return res;
150} 151}
@@ -155,16 +156,17 @@ int nftl_read_oob(struct mtd_info *mtd, loff_t offs, size_t len,
155int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len, 156int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
156 size_t *retlen, uint8_t *buf) 157 size_t *retlen, uint8_t *buf)
157{ 158{
159 loff_t mask = mtd->writesize - 1;
158 struct mtd_oob_ops ops; 160 struct mtd_oob_ops ops;
159 int res; 161 int res;
160 162
161 ops.mode = MTD_OOB_PLACE; 163 ops.mode = MTD_OOB_PLACE;
162 ops.ooboffs = offs & (mtd->writesize - 1); 164 ops.ooboffs = offs & mask;
163 ops.ooblen = len; 165 ops.ooblen = len;
164 ops.oobbuf = buf; 166 ops.oobbuf = buf;
165 ops.datbuf = NULL; 167 ops.datbuf = NULL;
166 168
167 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 169 res = mtd->write_oob(mtd, offs & ~mask, &ops);
168 *retlen = ops.oobretlen; 170 *retlen = ops.oobretlen;
169 return res; 171 return res;
170} 172}
@@ -177,17 +179,18 @@ int nftl_write_oob(struct mtd_info *mtd, loff_t offs, size_t len,
177static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len, 179static int nftl_write(struct mtd_info *mtd, loff_t offs, size_t len,
178 size_t *retlen, uint8_t *buf, uint8_t *oob) 180 size_t *retlen, uint8_t *buf, uint8_t *oob)
179{ 181{
182 loff_t mask = mtd->writesize - 1;
180 struct mtd_oob_ops ops; 183 struct mtd_oob_ops ops;
181 int res; 184 int res;
182 185
183 ops.mode = MTD_OOB_PLACE; 186 ops.mode = MTD_OOB_PLACE;
184 ops.ooboffs = offs; 187 ops.ooboffs = offs & mask;
185 ops.ooblen = mtd->oobsize; 188 ops.ooblen = mtd->oobsize;
186 ops.oobbuf = oob; 189 ops.oobbuf = oob;
187 ops.datbuf = buf; 190 ops.datbuf = buf;
188 ops.len = len; 191 ops.len = len;
189 192
190 res = mtd->write_oob(mtd, offs & ~(mtd->writesize - 1), &ops); 193 res = mtd->write_oob(mtd, offs & ~mask, &ops);
191 *retlen = ops.retlen; 194 *retlen = ops.retlen;
192 return res; 195 return res;
193} 196}
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index e212f2c5448b..a00ec639c380 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -491,6 +491,7 @@ static int gfar_remove(struct of_device *ofdev)
491 491
492 dev_set_drvdata(&ofdev->dev, NULL); 492 dev_set_drvdata(&ofdev->dev, NULL);
493 493
494 unregister_netdev(priv->ndev);
494 iounmap(priv->regs); 495 iounmap(priv->regs);
495 free_netdev(priv->ndev); 496 free_netdev(priv->ndev);
496 497
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 6dcac73b4d29..f593fbbb4e52 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -2874,45 +2874,27 @@ static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,
2874 return 0; 2874 return 0;
2875} 2875}
2876 2876
2877static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, 2877static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,
2878 u32 src_phys, u32 dest_address, u32 length) 2878 int nr, u32 dest_address, u32 len)
2879{ 2879{
2880 u32 bytes_left = length; 2880 int ret, i;
2881 u32 src_offset = 0; 2881 u32 size;
2882 u32 dest_offset = 0; 2882
2883 int status = 0;
2884 IPW_DEBUG_FW(">> \n"); 2883 IPW_DEBUG_FW(">> \n");
2885 IPW_DEBUG_FW_INFO("src_phys=0x%x dest_address=0x%x length=0x%x\n", 2884 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",
2886 src_phys, dest_address, length); 2885 nr, dest_address, len);
2887 while (bytes_left > CB_MAX_LENGTH) { 2886
2888 status = ipw_fw_dma_add_command_block(priv, 2887 for (i = 0; i < nr; i++) {
2889 src_phys + src_offset, 2888 size = min_t(u32, len - i * CB_MAX_LENGTH, CB_MAX_LENGTH);
2890 dest_address + 2889 ret = ipw_fw_dma_add_command_block(priv, src_address[i],
2891 dest_offset, 2890 dest_address +
2892 CB_MAX_LENGTH, 0, 0); 2891 i * CB_MAX_LENGTH, size,
2893 if (status) { 2892 0, 0);
2893 if (ret) {
2894 IPW_DEBUG_FW_INFO(": Failed\n"); 2894 IPW_DEBUG_FW_INFO(": Failed\n");
2895 return -1; 2895 return -1;
2896 } else 2896 } else
2897 IPW_DEBUG_FW_INFO(": Added new cb\n"); 2897 IPW_DEBUG_FW_INFO(": Added new cb\n");
2898
2899 src_offset += CB_MAX_LENGTH;
2900 dest_offset += CB_MAX_LENGTH;
2901 bytes_left -= CB_MAX_LENGTH;
2902 }
2903
2904 /* add the buffer tail */
2905 if (bytes_left > 0) {
2906 status =
2907 ipw_fw_dma_add_command_block(priv, src_phys + src_offset,
2908 dest_address + dest_offset,
2909 bytes_left, 0, 0);
2910 if (status) {
2911 IPW_DEBUG_FW_INFO(": Failed on the buffer tail\n");
2912 return -1;
2913 } else
2914 IPW_DEBUG_FW_INFO
2915 (": Adding new cb - the buffer tail\n");
2916 } 2898 }
2917 2899
2918 IPW_DEBUG_FW("<< \n"); 2900 IPW_DEBUG_FW("<< \n");
@@ -3160,59 +3142,91 @@ static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)
3160 3142
3161static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len) 3143static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
3162{ 3144{
3163 int rc = -1; 3145 int ret = -1;
3164 int offset = 0; 3146 int offset = 0;
3165 struct fw_chunk *chunk; 3147 struct fw_chunk *chunk;
3166 dma_addr_t shared_phys; 3148 int total_nr = 0;
3167 u8 *shared_virt; 3149 int i;
3150 struct pci_pool *pool;
3151 u32 *virts[CB_NUMBER_OF_ELEMENTS_SMALL];
3152 dma_addr_t phys[CB_NUMBER_OF_ELEMENTS_SMALL];
3168 3153
3169 IPW_DEBUG_TRACE("<< : \n"); 3154 IPW_DEBUG_TRACE("<< : \n");
3170 shared_virt = pci_alloc_consistent(priv->pci_dev, len, &shared_phys);
3171 3155
3172 if (!shared_virt) 3156 pool = pci_pool_create("ipw2200", priv->pci_dev, CB_MAX_LENGTH, 0, 0);
3157 if (!pool) {
3158 IPW_ERROR("pci_pool_create failed\n");
3173 return -ENOMEM; 3159 return -ENOMEM;
3174 3160 }
3175 memmove(shared_virt, data, len);
3176 3161
3177 /* Start the Dma */ 3162 /* Start the Dma */
3178 rc = ipw_fw_dma_enable(priv); 3163 ret = ipw_fw_dma_enable(priv);
3179 3164
3180 /* the DMA is already ready this would be a bug. */ 3165 /* the DMA is already ready this would be a bug. */
3181 BUG_ON(priv->sram_desc.last_cb_index > 0); 3166 BUG_ON(priv->sram_desc.last_cb_index > 0);
3182 3167
3183 do { 3168 do {
3169 u32 chunk_len;
3170 u8 *start;
3171 int size;
3172 int nr = 0;
3173
3184 chunk = (struct fw_chunk *)(data + offset); 3174 chunk = (struct fw_chunk *)(data + offset);
3185 offset += sizeof(struct fw_chunk); 3175 offset += sizeof(struct fw_chunk);
3176 chunk_len = le32_to_cpu(chunk->length);
3177 start = data + offset;
3178
3179 nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;
3180 for (i = 0; i < nr; i++) {
3181 virts[total_nr] = pci_pool_alloc(pool, GFP_KERNEL,
3182 &phys[total_nr]);
3183 if (!virts[total_nr]) {
3184 ret = -ENOMEM;
3185 goto out;
3186 }
3187 size = min_t(u32, chunk_len - i * CB_MAX_LENGTH,
3188 CB_MAX_LENGTH);
3189 memcpy(virts[total_nr], start, size);
3190 start += size;
3191 total_nr++;
3192 /* We don't support fw chunk larger than 64*8K */
3193 BUG_ON(total_nr > CB_NUMBER_OF_ELEMENTS_SMALL);
3194 }
3195
3186 /* build DMA packet and queue up for sending */ 3196 /* build DMA packet and queue up for sending */
3187 /* dma to chunk->address, the chunk->length bytes from data + 3197 /* dma to chunk->address, the chunk->length bytes from data +
3188 * offeset*/ 3198 * offeset*/
3189 /* Dma loading */ 3199 /* Dma loading */
3190 rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset, 3200 ret = ipw_fw_dma_add_buffer(priv, &phys[total_nr - nr],
3191 le32_to_cpu(chunk->address), 3201 nr, le32_to_cpu(chunk->address),
3192 le32_to_cpu(chunk->length)); 3202 chunk_len);
3193 if (rc) { 3203 if (ret) {
3194 IPW_DEBUG_INFO("dmaAddBuffer Failed\n"); 3204 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
3195 goto out; 3205 goto out;
3196 } 3206 }
3197 3207
3198 offset += le32_to_cpu(chunk->length); 3208 offset += chunk_len;
3199 } while (offset < len); 3209 } while (offset < len);
3200 3210
3201 /* Run the DMA and wait for the answer */ 3211 /* Run the DMA and wait for the answer */
3202 rc = ipw_fw_dma_kick(priv); 3212 ret = ipw_fw_dma_kick(priv);
3203 if (rc) { 3213 if (ret) {
3204 IPW_ERROR("dmaKick Failed\n"); 3214 IPW_ERROR("dmaKick Failed\n");
3205 goto out; 3215 goto out;
3206 } 3216 }
3207 3217
3208 rc = ipw_fw_dma_wait(priv); 3218 ret = ipw_fw_dma_wait(priv);
3209 if (rc) { 3219 if (ret) {
3210 IPW_ERROR("dmaWaitSync Failed\n"); 3220 IPW_ERROR("dmaWaitSync Failed\n");
3211 goto out; 3221 goto out;
3212 } 3222 }
3213 out: 3223 out:
3214 pci_free_consistent(priv->pci_dev, len, shared_virt, shared_phys); 3224 for (i = 0; i < total_nr; i++)
3215 return rc; 3225 pci_pool_free(pool, virts[i], phys[i]);
3226
3227 pci_pool_destroy(pool);
3228
3229 return ret;
3216} 3230}
3217 3231
3218/* stop nic */ 3232/* stop nic */
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
index e3a87210e947..e03fe98f0619 100644
--- a/drivers/pci/iov.c
+++ b/drivers/pci/iov.c
@@ -598,6 +598,29 @@ int pci_iov_resource_bar(struct pci_dev *dev, int resno,
598} 598}
599 599
600/** 600/**
601 * pci_sriov_resource_alignment - get resource alignment for VF BAR
602 * @dev: the PCI device
603 * @resno: the resource number
604 *
605 * Returns the alignment of the VF BAR found in the SR-IOV capability.
606 * This is not the same as the resource size which is defined as
607 * the VF BAR size multiplied by the number of VFs. The alignment
608 * is just the VF BAR size.
609 */
610int pci_sriov_resource_alignment(struct pci_dev *dev, int resno)
611{
612 struct resource tmp;
613 enum pci_bar_type type;
614 int reg = pci_iov_resource_bar(dev, resno, &type);
615
616 if (!reg)
617 return 0;
618
619 __pci_read_base(dev, type, &tmp, reg);
620 return resource_alignment(&tmp);
621}
622
623/**
601 * pci_restore_iov_state - restore the state of the IOV capability 624 * pci_restore_iov_state - restore the state of the IOV capability
602 * @dev: the PCI device 625 * @dev: the PCI device
603 */ 626 */
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f73bcbedf37c..5ff4d25bf0e9 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -243,6 +243,7 @@ extern int pci_iov_init(struct pci_dev *dev);
243extern void pci_iov_release(struct pci_dev *dev); 243extern void pci_iov_release(struct pci_dev *dev);
244extern int pci_iov_resource_bar(struct pci_dev *dev, int resno, 244extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
245 enum pci_bar_type *type); 245 enum pci_bar_type *type);
246extern int pci_sriov_resource_alignment(struct pci_dev *dev, int resno);
246extern void pci_restore_iov_state(struct pci_dev *dev); 247extern void pci_restore_iov_state(struct pci_dev *dev);
247extern int pci_iov_bus_range(struct pci_bus *bus); 248extern int pci_iov_bus_range(struct pci_bus *bus);
248 249
@@ -298,4 +299,16 @@ static inline int pci_ats_enabled(struct pci_dev *dev)
298} 299}
299#endif /* CONFIG_PCI_IOV */ 300#endif /* CONFIG_PCI_IOV */
300 301
302static inline int pci_resource_alignment(struct pci_dev *dev,
303 struct resource *res)
304{
305#ifdef CONFIG_PCI_IOV
306 int resno = res - dev->resource;
307
308 if (resno >= PCI_IOV_RESOURCES && resno <= PCI_IOV_RESOURCE_END)
309 return pci_sriov_resource_alignment(dev, resno);
310#endif
311 return resource_alignment(res);
312}
313
301#endif /* DRIVERS_PCI_H */ 314#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index b636e245445d..7c443b4583ab 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -25,7 +25,7 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/cache.h> 26#include <linux/cache.h>
27#include <linux/slab.h> 27#include <linux/slab.h>
28 28#include "pci.h"
29 29
30static void pbus_assign_resources_sorted(const struct pci_bus *bus) 30static void pbus_assign_resources_sorted(const struct pci_bus *bus)
31{ 31{
@@ -384,7 +384,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long
384 continue; 384 continue;
385 r_size = resource_size(r); 385 r_size = resource_size(r);
386 /* For bridges size != alignment */ 386 /* For bridges size != alignment */
387 align = resource_alignment(r); 387 align = pci_resource_alignment(dev, r);
388 order = __ffs(align) - 20; 388 order = __ffs(align) - 20;
389 if (order > 11) { 389 if (order > 11) {
390 dev_warn(&dev->dev, "BAR %d bad alignment %llx: " 390 dev_warn(&dev->dev, "BAR %d bad alignment %llx: "
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 1898c7b47907..88cdd1a937d6 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -144,7 +144,7 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev,
144 144
145 size = resource_size(res); 145 size = resource_size(res);
146 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM; 146 min = (res->flags & IORESOURCE_IO) ? PCIBIOS_MIN_IO : PCIBIOS_MIN_MEM;
147 align = resource_alignment(res); 147 align = pci_resource_alignment(dev, res);
148 148
149 /* First, try exact prefetching match.. */ 149 /* First, try exact prefetching match.. */
150 ret = pci_bus_alloc_resource(bus, res, size, align, min, 150 ret = pci_bus_alloc_resource(bus, res, size, align, min,
@@ -178,7 +178,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno)
178 struct pci_bus *bus; 178 struct pci_bus *bus;
179 int ret; 179 int ret;
180 180
181 align = resource_alignment(res); 181 align = pci_resource_alignment(dev, res);
182 if (!align) { 182 if (!align) {
183 dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus " 183 dev_info(&dev->dev, "BAR %d: can't allocate resource (bogus "
184 "alignment) %pR flags %#lx\n", 184 "alignment) %pR flags %#lx\n",
@@ -259,7 +259,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
259 if (!(r->flags) || r->parent) 259 if (!(r->flags) || r->parent)
260 continue; 260 continue;
261 261
262 r_align = resource_alignment(r); 262 r_align = pci_resource_alignment(dev, r);
263 if (!r_align) { 263 if (!r_align) {
264 dev_warn(&dev->dev, "BAR %d: bogus alignment " 264 dev_warn(&dev->dev, "BAR %d: bogus alignment "
265 "%pR flags %#lx\n", 265 "%pR flags %#lx\n",
@@ -271,7 +271,7 @@ void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
271 struct resource_list *ln = list->next; 271 struct resource_list *ln = list->next;
272 272
273 if (ln) 273 if (ln)
274 align = resource_alignment(ln->res); 274 align = pci_resource_alignment(ln->dev, ln->res);
275 275
276 if (r_align > align) { 276 if (r_align > align) {
277 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); 277 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 81d31ea507d1..51c0a8bee414 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -335,6 +335,7 @@ static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
335 if (hci_result != HCI_SUCCESS) { 335 if (hci_result != HCI_SUCCESS) {
336 /* Can't do anything useful */ 336 /* Can't do anything useful */
337 mutex_unlock(&dev->mutex); 337 mutex_unlock(&dev->mutex);
338 return;
338 } 339 }
339 340
340 new_rfk_state = value; 341 new_rfk_state = value;
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index aa39ae83f019..3da18d453488 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -77,7 +77,7 @@ static int autofs4_mount_busy(struct vfsmount *mnt, struct dentry *dentry)
77 } 77 }
78 78
79 /* Update the expiry counter if fs is busy */ 79 /* Update the expiry counter if fs is busy */
80 if (!may_umount_tree(mnt)) { 80 if (!may_umount_tree(path.mnt)) {
81 struct autofs_info *ino = autofs4_dentry_ino(top); 81 struct autofs_info *ino = autofs4_dentry_ino(top);
82 ino->last_used = jiffies; 82 ino->last_used = jiffies;
83 goto done; 83 goto done;
diff --git a/fs/compat.c b/fs/compat.c
index 94502dab972a..6d6f98fe64a0 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1485,20 +1485,15 @@ int compat_do_execve(char * filename,
1485 if (!bprm) 1485 if (!bprm)
1486 goto out_files; 1486 goto out_files;
1487 1487
1488 retval = -ERESTARTNOINTR; 1488 retval = prepare_bprm_creds(bprm);
1489 if (mutex_lock_interruptible(&current->cred_guard_mutex)) 1489 if (retval)
1490 goto out_free; 1490 goto out_free;
1491 current->in_execve = 1;
1492
1493 retval = -ENOMEM;
1494 bprm->cred = prepare_exec_creds();
1495 if (!bprm->cred)
1496 goto out_unlock;
1497 1491
1498 retval = check_unsafe_exec(bprm); 1492 retval = check_unsafe_exec(bprm);
1499 if (retval < 0) 1493 if (retval < 0)
1500 goto out_unlock; 1494 goto out_free;
1501 clear_in_exec = retval; 1495 clear_in_exec = retval;
1496 current->in_execve = 1;
1502 1497
1503 file = open_exec(filename); 1498 file = open_exec(filename);
1504 retval = PTR_ERR(file); 1499 retval = PTR_ERR(file);
@@ -1547,7 +1542,6 @@ int compat_do_execve(char * filename,
1547 /* execve succeeded */ 1542 /* execve succeeded */
1548 current->fs->in_exec = 0; 1543 current->fs->in_exec = 0;
1549 current->in_execve = 0; 1544 current->in_execve = 0;
1550 mutex_unlock(&current->cred_guard_mutex);
1551 acct_update_integrals(current); 1545 acct_update_integrals(current);
1552 free_bprm(bprm); 1546 free_bprm(bprm);
1553 if (displaced) 1547 if (displaced)
@@ -1567,10 +1561,7 @@ out_file:
1567out_unmark: 1561out_unmark:
1568 if (clear_in_exec) 1562 if (clear_in_exec)
1569 current->fs->in_exec = 0; 1563 current->fs->in_exec = 0;
1570
1571out_unlock:
1572 current->in_execve = 0; 1564 current->in_execve = 0;
1573 mutex_unlock(&current->cred_guard_mutex);
1574 1565
1575out_free: 1566out_free:
1576 free_bprm(bprm); 1567 free_bprm(bprm);
diff --git a/fs/exec.c b/fs/exec.c
index fb4f3cdda78c..172ceb6edde4 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1016,6 +1016,35 @@ out:
1016EXPORT_SYMBOL(flush_old_exec); 1016EXPORT_SYMBOL(flush_old_exec);
1017 1017
1018/* 1018/*
1019 * Prepare credentials and lock ->cred_guard_mutex.
1020 * install_exec_creds() commits the new creds and drops the lock.
1021 * Or, if exec fails before, free_bprm() should release ->cred and
1022 * and unlock.
1023 */
1024int prepare_bprm_creds(struct linux_binprm *bprm)
1025{
1026 if (mutex_lock_interruptible(&current->cred_guard_mutex))
1027 return -ERESTARTNOINTR;
1028
1029 bprm->cred = prepare_exec_creds();
1030 if (likely(bprm->cred))
1031 return 0;
1032
1033 mutex_unlock(&current->cred_guard_mutex);
1034 return -ENOMEM;
1035}
1036
1037void free_bprm(struct linux_binprm *bprm)
1038{
1039 free_arg_pages(bprm);
1040 if (bprm->cred) {
1041 mutex_unlock(&current->cred_guard_mutex);
1042 abort_creds(bprm->cred);
1043 }
1044 kfree(bprm);
1045}
1046
1047/*
1019 * install the new credentials for this executable 1048 * install the new credentials for this executable
1020 */ 1049 */
1021void install_exec_creds(struct linux_binprm *bprm) 1050void install_exec_creds(struct linux_binprm *bprm)
@@ -1024,12 +1053,13 @@ void install_exec_creds(struct linux_binprm *bprm)
1024 1053
1025 commit_creds(bprm->cred); 1054 commit_creds(bprm->cred);
1026 bprm->cred = NULL; 1055 bprm->cred = NULL;
1027 1056 /*
1028 /* cred_guard_mutex must be held at least to this point to prevent 1057 * cred_guard_mutex must be held at least to this point to prevent
1029 * ptrace_attach() from altering our determination of the task's 1058 * ptrace_attach() from altering our determination of the task's
1030 * credentials; any time after this it may be unlocked */ 1059 * credentials; any time after this it may be unlocked.
1031 1060 */
1032 security_bprm_committed_creds(bprm); 1061 security_bprm_committed_creds(bprm);
1062 mutex_unlock(&current->cred_guard_mutex);
1033} 1063}
1034EXPORT_SYMBOL(install_exec_creds); 1064EXPORT_SYMBOL(install_exec_creds);
1035 1065
@@ -1246,14 +1276,6 @@ int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
1246 1276
1247EXPORT_SYMBOL(search_binary_handler); 1277EXPORT_SYMBOL(search_binary_handler);
1248 1278
1249void free_bprm(struct linux_binprm *bprm)
1250{
1251 free_arg_pages(bprm);
1252 if (bprm->cred)
1253 abort_creds(bprm->cred);
1254 kfree(bprm);
1255}
1256
1257/* 1279/*
1258 * sys_execve() executes a new program. 1280 * sys_execve() executes a new program.
1259 */ 1281 */
@@ -1277,20 +1299,15 @@ int do_execve(char * filename,
1277 if (!bprm) 1299 if (!bprm)
1278 goto out_files; 1300 goto out_files;
1279 1301
1280 retval = -ERESTARTNOINTR; 1302 retval = prepare_bprm_creds(bprm);
1281 if (mutex_lock_interruptible(&current->cred_guard_mutex)) 1303 if (retval)
1282 goto out_free; 1304 goto out_free;
1283 current->in_execve = 1;
1284
1285 retval = -ENOMEM;
1286 bprm->cred = prepare_exec_creds();
1287 if (!bprm->cred)
1288 goto out_unlock;
1289 1305
1290 retval = check_unsafe_exec(bprm); 1306 retval = check_unsafe_exec(bprm);
1291 if (retval < 0) 1307 if (retval < 0)
1292 goto out_unlock; 1308 goto out_free;
1293 clear_in_exec = retval; 1309 clear_in_exec = retval;
1310 current->in_execve = 1;
1294 1311
1295 file = open_exec(filename); 1312 file = open_exec(filename);
1296 retval = PTR_ERR(file); 1313 retval = PTR_ERR(file);
@@ -1340,7 +1357,6 @@ int do_execve(char * filename,
1340 /* execve succeeded */ 1357 /* execve succeeded */
1341 current->fs->in_exec = 0; 1358 current->fs->in_exec = 0;
1342 current->in_execve = 0; 1359 current->in_execve = 0;
1343 mutex_unlock(&current->cred_guard_mutex);
1344 acct_update_integrals(current); 1360 acct_update_integrals(current);
1345 free_bprm(bprm); 1361 free_bprm(bprm);
1346 if (displaced) 1362 if (displaced)
@@ -1360,10 +1376,7 @@ out_file:
1360out_unmark: 1376out_unmark:
1361 if (clear_in_exec) 1377 if (clear_in_exec)
1362 current->fs->in_exec = 0; 1378 current->fs->in_exec = 0;
1363
1364out_unlock:
1365 current->in_execve = 0; 1379 current->in_execve = 0;
1366 mutex_unlock(&current->cred_guard_mutex);
1367 1380
1368out_free: 1381out_free:
1369 free_bprm(bprm); 1382 free_bprm(bprm);
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index e1dedb0f7873..78d9b925fc94 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -362,6 +362,10 @@ static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
362 if (dir_de) { 362 if (dir_de) {
363 if (old_dir != new_dir) 363 if (old_dir != new_dir)
364 ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0); 364 ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
365 else {
366 kunmap(dir_page);
367 page_cache_release(dir_page);
368 }
365 inode_dec_link_count(old_dir); 369 inode_dec_link_count(old_dir);
366 } 370 }
367 return 0; 371 return 0;
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index d9a721e6db70..5ef7bac265e5 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -1268,10 +1268,20 @@ int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
1268 if (!c->wbuf) 1268 if (!c->wbuf)
1269 return -ENOMEM; 1269 return -ENOMEM;
1270 1270
1271#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
1272 c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1273 if (!c->wbuf_verify) {
1274 kfree(c->wbuf);
1275 return -ENOMEM;
1276 }
1277#endif
1271 return 0; 1278 return 0;
1272} 1279}
1273 1280
1274void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) { 1281void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
1282#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
1283 kfree(c->wbuf_verify);
1284#endif
1275 kfree(c->wbuf); 1285 kfree(c->wbuf);
1276} 1286}
1277 1287
diff --git a/fs/namei.c b/fs/namei.c
index f3c5b278895a..1f13751693a5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1542,28 +1542,31 @@ int may_open(struct path *path, int acc_mode, int flag)
1542 * An append-only file must be opened in append mode for writing. 1542 * An append-only file must be opened in append mode for writing.
1543 */ 1543 */
1544 if (IS_APPEND(inode)) { 1544 if (IS_APPEND(inode)) {
1545 error = -EPERM;
1545 if ((flag & FMODE_WRITE) && !(flag & O_APPEND)) 1546 if ((flag & FMODE_WRITE) && !(flag & O_APPEND))
1546 return -EPERM; 1547 goto err_out;
1547 if (flag & O_TRUNC) 1548 if (flag & O_TRUNC)
1548 return -EPERM; 1549 goto err_out;
1549 } 1550 }
1550 1551
1551 /* O_NOATIME can only be set by the owner or superuser */ 1552 /* O_NOATIME can only be set by the owner or superuser */
1552 if (flag & O_NOATIME) 1553 if (flag & O_NOATIME)
1553 if (!is_owner_or_cap(inode)) 1554 if (!is_owner_or_cap(inode)) {
1554 return -EPERM; 1555 error = -EPERM;
1556 goto err_out;
1557 }
1555 1558
1556 /* 1559 /*
1557 * Ensure there are no outstanding leases on the file. 1560 * Ensure there are no outstanding leases on the file.
1558 */ 1561 */
1559 error = break_lease(inode, flag); 1562 error = break_lease(inode, flag);
1560 if (error) 1563 if (error)
1561 return error; 1564 goto err_out;
1562 1565
1563 if (flag & O_TRUNC) { 1566 if (flag & O_TRUNC) {
1564 error = get_write_access(inode); 1567 error = get_write_access(inode);
1565 if (error) 1568 if (error)
1566 return error; 1569 goto err_out;
1567 1570
1568 /* 1571 /*
1569 * Refuse to truncate files with mandatory locks held on them. 1572 * Refuse to truncate files with mandatory locks held on them.
@@ -1581,12 +1584,17 @@ int may_open(struct path *path, int acc_mode, int flag)
1581 } 1584 }
1582 put_write_access(inode); 1585 put_write_access(inode);
1583 if (error) 1586 if (error)
1584 return error; 1587 goto err_out;
1585 } else 1588 } else
1586 if (flag & FMODE_WRITE) 1589 if (flag & FMODE_WRITE)
1587 vfs_dq_init(inode); 1590 vfs_dq_init(inode);
1588 1591
1589 return 0; 1592 return 0;
1593err_out:
1594 ima_counts_put(path, acc_mode ?
1595 acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) :
1596 ACC_MODE(flag) & (MAY_READ | MAY_WRITE));
1597 return error;
1590} 1598}
1591 1599
1592/* 1600/*
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index 7e0b61be212e..c668bca579c1 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -209,6 +209,7 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
209 * We cannot call radix_tree_preload for the kernels older 209 * We cannot call radix_tree_preload for the kernels older
210 * than 2.6.23, because it is not exported for modules. 210 * than 2.6.23, because it is not exported for modules.
211 */ 211 */
212retry:
212 err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); 213 err = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM);
213 if (err) 214 if (err)
214 goto failed_unlock; 215 goto failed_unlock;
@@ -219,7 +220,6 @@ int nilfs_btnode_prepare_change_key(struct address_space *btnc,
219 (unsigned long long)oldkey, 220 (unsigned long long)oldkey,
220 (unsigned long long)newkey); 221 (unsigned long long)newkey);
221 222
222retry:
223 spin_lock_irq(&btnc->tree_lock); 223 spin_lock_irq(&btnc->tree_lock);
224 err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page); 224 err = radix_tree_insert(&btnc->page_tree, newkey, obh->b_page);
225 spin_unlock_irq(&btnc->tree_lock); 225 spin_unlock_irq(&btnc->tree_lock);
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 0e781bc88d1e..dcd2040d330c 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -154,7 +154,8 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
154 154
155 event = fsnotify_peek_notify_event(group); 155 event = fsnotify_peek_notify_event(group);
156 156
157 event_size += roundup(event->name_len, event_size); 157 if (event->name_len)
158 event_size += roundup(event->name_len + 1, event_size);
158 159
159 if (event_size > count) 160 if (event_size > count)
160 return ERR_PTR(-EINVAL); 161 return ERR_PTR(-EINVAL);
@@ -180,7 +181,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
180 struct fsnotify_event_private_data *fsn_priv; 181 struct fsnotify_event_private_data *fsn_priv;
181 struct inotify_event_private_data *priv; 182 struct inotify_event_private_data *priv;
182 size_t event_size = sizeof(struct inotify_event); 183 size_t event_size = sizeof(struct inotify_event);
183 size_t name_len; 184 size_t name_len = 0;
184 185
185 /* we get the inotify watch descriptor from the event private data */ 186 /* we get the inotify watch descriptor from the event private data */
186 spin_lock(&event->lock); 187 spin_lock(&event->lock);
@@ -196,10 +197,12 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
196 inotify_free_event_priv(fsn_priv); 197 inotify_free_event_priv(fsn_priv);
197 } 198 }
198 199
199 /* round up event->name_len so it is a multiple of event_size 200 /*
201 * round up event->name_len so it is a multiple of event_size
200 * plus an extra byte for the terminating '\0'. 202 * plus an extra byte for the terminating '\0'.
201 */ 203 */
202 name_len = roundup(event->name_len + 1, event_size); 204 if (event->name_len)
205 name_len = roundup(event->name_len + 1, event_size);
203 inotify_event.len = name_len; 206 inotify_event.len = name_len;
204 207
205 inotify_event.mask = inotify_mask_to_arg(event->mask); 208 inotify_event.mask = inotify_mask_to_arg(event->mask);
@@ -325,8 +328,9 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
325 list_for_each_entry(holder, &group->notification_list, event_list) { 328 list_for_each_entry(holder, &group->notification_list, event_list) {
326 event = holder->event; 329 event = holder->event;
327 send_len += sizeof(struct inotify_event); 330 send_len += sizeof(struct inotify_event);
328 send_len += roundup(event->name_len, 331 if (event->name_len)
329 sizeof(struct inotify_event)); 332 send_len += roundup(event->name_len + 1,
333 sizeof(struct inotify_event));
330 } 334 }
331 mutex_unlock(&group->notification_mutex); 335 mutex_unlock(&group->notification_mutex);
332 ret = put_user(send_len, (int __user *) p); 336 ret = put_user(send_len, (int __user *) p);
@@ -587,6 +591,10 @@ retry:
587 /* match the ref from fsnotify_init_markentry() */ 591 /* match the ref from fsnotify_init_markentry() */
588 fsnotify_put_mark(&tmp_ientry->fsn_entry); 592 fsnotify_put_mark(&tmp_ientry->fsn_entry);
589 593
594 /* if this mark added a new event update the group mask */
595 if (mask & ~group->mask)
596 fsnotify_recalc_group_mask(group);
597
590out_err: 598out_err:
591 if (ret < 0) 599 if (ret < 0)
592 kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry); 600 kmem_cache_free(inotify_inode_mark_cachep, tmp_ientry);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index b401654011a2..8a1e61545f41 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1747,8 +1747,8 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
1747 * we know zeros will only be needed in the first and/or last cluster. 1747 * we know zeros will only be needed in the first and/or last cluster.
1748 */ 1748 */
1749 if (clusters_to_alloc || extents_to_split || 1749 if (clusters_to_alloc || extents_to_split ||
1750 wc->w_desc[0].c_needs_zero || 1750 (wc->w_clen && (wc->w_desc[0].c_needs_zero ||
1751 wc->w_desc[wc->w_clen - 1].c_needs_zero) 1751 wc->w_desc[wc->w_clen - 1].c_needs_zero)))
1752 cluster_of_pages = 1; 1752 cluster_of_pages = 1;
1753 else 1753 else
1754 cluster_of_pages = 0; 1754 cluster_of_pages = 0;
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 2f28b7de2c8d..b4957c7d9fe2 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -85,6 +85,17 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
85 goto bail; 85 goto bail;
86 } 86 }
87 87
88 /*
89 * If the last lookup failed to create dentry lock, let us
90 * redo it.
91 */
92 if (!dentry->d_fsdata) {
93 mlog(0, "Inode %llu doesn't have dentry lock, "
94 "returning false\n",
95 (unsigned long long)OCFS2_I(inode)->ip_blkno);
96 goto bail;
97 }
98
88 ret = 1; 99 ret = 1;
89 100
90bail: 101bail:
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 0882d166239a..eafcc7c18706 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -619,7 +619,7 @@ xfs_file_compat_ioctl(
619 case XFS_IOC_GETVERSION_32: 619 case XFS_IOC_GETVERSION_32:
620 cmd = _NATIVE_IOC(cmd, long); 620 cmd = _NATIVE_IOC(cmd, long);
621 return xfs_file_ioctl(filp, cmd, p); 621 return xfs_file_ioctl(filp, cmd, p);
622 case XFS_IOC_SWAPEXT: { 622 case XFS_IOC_SWAPEXT_32: {
623 struct xfs_swapext sxp; 623 struct xfs_swapext sxp;
624 struct compat_xfs_swapext __user *sxu = arg; 624 struct compat_xfs_swapext __user *sxu = arg;
625 625
diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
index 010545436efa..5a2bd1cc9656 100644
--- a/include/crypto/algapi.h
+++ b/include/crypto/algapi.h
@@ -137,6 +137,7 @@ struct crypto_instance *crypto_alloc_instance(const char *name,
137void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen); 137void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
138int crypto_enqueue_request(struct crypto_queue *queue, 138int crypto_enqueue_request(struct crypto_queue *queue,
139 struct crypto_async_request *request); 139 struct crypto_async_request *request);
140void *__crypto_dequeue_request(struct crypto_queue *queue, unsigned int offset);
140struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue); 141struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
141int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm); 142int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);
142 143
diff --git a/include/crypto/internal/skcipher.h b/include/crypto/internal/skcipher.h
index 2ba42cd7d6aa..3a748a6bf772 100644
--- a/include/crypto/internal/skcipher.h
+++ b/include/crypto/internal/skcipher.h
@@ -79,8 +79,8 @@ static inline int skcipher_enqueue_givcrypt(
79static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt( 79static inline struct skcipher_givcrypt_request *skcipher_dequeue_givcrypt(
80 struct crypto_queue *queue) 80 struct crypto_queue *queue)
81{ 81{
82 return container_of(ablkcipher_dequeue_request(queue), 82 return __crypto_dequeue_request(
83 struct skcipher_givcrypt_request, creq); 83 queue, offsetof(struct skcipher_givcrypt_request, creq.base));
84} 84}
85 85
86static inline void *skcipher_givcrypt_reqctx( 86static inline void *skcipher_givcrypt_reqctx(
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h
index 61ee18c1bdb4..2046b5b8af48 100644
--- a/include/linux/binfmts.h
+++ b/include/linux/binfmts.h
@@ -117,6 +117,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
117 int executable_stack); 117 int executable_stack);
118extern int bprm_mm_init(struct linux_binprm *bprm); 118extern int bprm_mm_init(struct linux_binprm *bprm);
119extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); 119extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm);
120extern int prepare_bprm_creds(struct linux_binprm *bprm);
120extern void install_exec_creds(struct linux_binprm *bprm); 121extern void install_exec_creds(struct linux_binprm *bprm);
121extern void do_coredump(long signr, int exit_code, struct pt_regs *regs); 122extern void do_coredump(long signr, int exit_code, struct pt_regs *regs);
122extern int set_binfmt(struct linux_binfmt *new); 123extern int set_binfmt(struct linux_binfmt *new);
diff --git a/include/linux/device-mapper.h b/include/linux/device-mapper.h
index 655e7721580a..df7607e6dce8 100644
--- a/include/linux/device-mapper.h
+++ b/include/linux/device-mapper.h
@@ -91,6 +91,9 @@ typedef int (*dm_iterate_devices_fn) (struct dm_target *ti,
91 iterate_devices_callout_fn fn, 91 iterate_devices_callout_fn fn,
92 void *data); 92 void *data);
93 93
94typedef void (*dm_io_hints_fn) (struct dm_target *ti,
95 struct queue_limits *limits);
96
94/* 97/*
95 * Returns: 98 * Returns:
96 * 0: The target can handle the next I/O immediately. 99 * 0: The target can handle the next I/O immediately.
@@ -151,6 +154,7 @@ struct target_type {
151 dm_merge_fn merge; 154 dm_merge_fn merge;
152 dm_busy_fn busy; 155 dm_busy_fn busy;
153 dm_iterate_devices_fn iterate_devices; 156 dm_iterate_devices_fn iterate_devices;
157 dm_io_hints_fn io_hints;
154 158
155 /* For internal device-mapper use. */ 159 /* For internal device-mapper use. */
156 struct list_head list; 160 struct list_head list;
diff --git a/include/linux/dm-log-userspace.h b/include/linux/dm-log-userspace.h
index 642e3017b51f..8a1f972c0fe9 100644
--- a/include/linux/dm-log-userspace.h
+++ b/include/linux/dm-log-userspace.h
@@ -371,7 +371,18 @@
371 (DM_ULOG_REQUEST_MASK & (request_type)) 371 (DM_ULOG_REQUEST_MASK & (request_type))
372 372
373struct dm_ulog_request { 373struct dm_ulog_request {
374 char uuid[DM_UUID_LEN]; /* Ties a request to a specific mirror log */ 374 /*
375 * The local unique identifier (luid) and the universally unique
376 * identifier (uuid) are used to tie a request to a specific
377 * mirror log. A single machine log could probably make due with
378 * just the 'luid', but a cluster-aware log must use the 'uuid' and
379 * the 'luid'. The uuid is what is required for node to node
380 * communication concerning a particular log, but the 'luid' helps
381 * differentiate between logs that are being swapped and have the
382 * same 'uuid'. (Think "live" and "inactive" device-mapper tables.)
383 */
384 uint64_t luid;
385 char uuid[DM_UUID_LEN];
375 char padding[7]; /* Padding because DM_UUID_LEN = 129 */ 386 char padding[7]; /* Padding because DM_UUID_LEN = 129 */
376 387
377 int32_t error; /* Used to report back processing errors */ 388 int32_t error; /* Used to report back processing errors */
diff --git a/include/linux/lmb.h b/include/linux/lmb.h
index c46c89505dac..2442e3f3d033 100644
--- a/include/linux/lmb.h
+++ b/include/linux/lmb.h
@@ -51,7 +51,7 @@ extern u64 __init lmb_alloc_base(u64 size,
51extern u64 __init __lmb_alloc_base(u64 size, 51extern u64 __init __lmb_alloc_base(u64 size,
52 u64 align, u64 max_addr); 52 u64 align, u64 max_addr);
53extern u64 __init lmb_phys_mem_size(void); 53extern u64 __init lmb_phys_mem_size(void);
54extern u64 __init lmb_end_of_DRAM(void); 54extern u64 lmb_end_of_DRAM(void);
55extern void __init lmb_enforce_memory_limit(u64 memory_limit); 55extern void __init lmb_enforce_memory_limit(u64 memory_limit);
56extern int __init lmb_is_reserved(u64 addr); 56extern int __init lmb_is_reserved(u64 addr);
57extern int lmb_find(struct lmb_property *res); 57extern int lmb_find(struct lmb_property *res);
diff --git a/include/linux/tty.h b/include/linux/tty.h
index e8c6c9136c97..0d3974f59c53 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -23,7 +23,7 @@
23 */ 23 */
24#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */ 24#define NR_UNIX98_PTY_DEFAULT 4096 /* Default maximum for Unix98 ptys */
25#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */ 25#define NR_UNIX98_PTY_MAX (1 << MINORBITS) /* Absolute limit */
26#define NR_LDISCS 19 26#define NR_LDISCS 20
27 27
28/* line disciplines */ 28/* line disciplines */
29#define N_TTY 0 29#define N_TTY 0
@@ -47,6 +47,8 @@
47#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */ 47#define N_SLCAN 17 /* Serial / USB serial CAN Adaptors */
48#define N_PPS 18 /* Pulse per Second */ 48#define N_PPS 18 /* Pulse per Second */
49 49
50#define N_V253 19 /* Codec control over voice modem */
51
50/* 52/*
51 * This character is the same as _POSIX_VDISABLE: it cannot be used as 53 * This character is the same as _POSIX_VDISABLE: it cannot be used as
52 * a c_cc[] character, but indicates that a particular special character 54 * a c_cc[] character, but indicates that a particular special character
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 13e1adf55c4c..6273fa97b527 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -240,6 +240,21 @@ static inline int cancel_delayed_work(struct delayed_work *work)
240 return ret; 240 return ret;
241} 241}
242 242
243/*
244 * Like above, but uses del_timer() instead of del_timer_sync(). This means,
245 * if it returns 0 the timer function may be running and the queueing is in
246 * progress.
247 */
248static inline int __cancel_delayed_work(struct delayed_work *work)
249{
250 int ret;
251
252 ret = del_timer(&work->timer);
253 if (ret)
254 work_clear_pending(&work->work);
255 return ret;
256}
257
243extern int cancel_delayed_work_sync(struct delayed_work *work); 258extern int cancel_delayed_work_sync(struct delayed_work *work);
244 259
245/* Obsolete. use cancel_delayed_work_sync() */ 260/* Obsolete. use cancel_delayed_work_sync() */
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 7eafb8d54470..82a3191375f5 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -61,8 +61,8 @@ psched_tdiff_bounded(psched_time_t tv1, psched_time_t tv2, psched_time_t bound)
61} 61}
62 62
63struct qdisc_watchdog { 63struct qdisc_watchdog {
64 struct tasklet_hrtimer timer; 64 struct hrtimer timer;
65 struct Qdisc *qdisc; 65 struct Qdisc *qdisc;
66}; 66};
67 67
68extern void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc); 68extern void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc);
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h
index 251fc1cd5002..3dae3f799b9b 100644
--- a/include/sound/ac97_codec.h
+++ b/include/sound/ac97_codec.h
@@ -32,6 +32,9 @@
32#include "control.h" 32#include "control.h"
33#include "info.h" 33#include "info.h"
34 34
35/* maximum number of devices on the AC97 bus */
36#define AC97_BUS_MAX_DEVICES 4
37
35/* 38/*
36 * AC'97 codec registers 39 * AC'97 codec registers
37 */ 40 */
@@ -642,4 +645,10 @@ int snd_ac97_pcm_double_rate_rules(struct snd_pcm_runtime *runtime);
642/* ad hoc AC97 device driver access */ 645/* ad hoc AC97 device driver access */
643extern struct bus_type ac97_bus_type; 646extern struct bus_type ac97_bus_type;
644 647
648/* AC97 platform_data adding function */
649static inline void snd_ac97_dev_add_pdata(struct snd_ac97 *ac97, void *data)
650{
651 ac97->dev.platform_data = data;
652}
653
645#endif /* __SOUND_AC97_CODEC_H */ 654#endif /* __SOUND_AC97_CODEC_H */
diff --git a/include/sound/core.h b/include/sound/core.h
index 309cb9659a05..f545efcf03f2 100644
--- a/include/sound/core.h
+++ b/include/sound/core.h
@@ -93,15 +93,6 @@ struct snd_device {
93 93
94#define snd_device(n) list_entry(n, struct snd_device, list) 94#define snd_device(n) list_entry(n, struct snd_device, list)
95 95
96/* monitor files for graceful shutdown (hotplug) */
97
98struct snd_monitor_file {
99 struct file *file;
100 const struct file_operations *disconnected_f_op;
101 struct list_head shutdown_list; /* still need to shutdown */
102 struct list_head list; /* link of monitor files */
103};
104
105/* main structure for soundcard */ 96/* main structure for soundcard */
106 97
107struct snd_card { 98struct snd_card {
@@ -311,9 +302,7 @@ int snd_component_add(struct snd_card *card, const char *component);
311int snd_card_file_add(struct snd_card *card, struct file *file); 302int snd_card_file_add(struct snd_card *card, struct file *file);
312int snd_card_file_remove(struct snd_card *card, struct file *file); 303int snd_card_file_remove(struct snd_card *card, struct file *file);
313 304
314#ifndef snd_card_set_dev
315#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr)) 305#define snd_card_set_dev(card, devptr) ((card)->dev = (devptr))
316#endif
317 306
318/* device.c */ 307/* device.c */
319 308
@@ -438,12 +427,10 @@ static inline int __snd_bug_on(int cond)
438 427
439/* for easier backward-porting */ 428/* for easier backward-porting */
440#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE) 429#if defined(CONFIG_GAMEPORT) || defined(CONFIG_GAMEPORT_MODULE)
441#ifndef gameport_set_dev_parent
442#define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev)) 430#define gameport_set_dev_parent(gp,xdev) ((gp)->dev.parent = (xdev))
443#define gameport_set_port_data(gp,r) ((gp)->port_data = (r)) 431#define gameport_set_port_data(gp,r) ((gp)->port_data = (r))
444#define gameport_get_port_data(gp) (gp)->port_data 432#define gameport_get_port_data(gp) (gp)->port_data
445#endif 433#endif
446#endif
447 434
448/* PCI quirk list helper */ 435/* PCI quirk list helper */
449struct snd_pci_quirk { 436struct snd_pci_quirk {
diff --git a/include/sound/info.h b/include/sound/info.h
index 7c2ee1a21b00..112e8949e1a7 100644
--- a/include/sound/info.h
+++ b/include/sound/info.h
@@ -110,13 +110,13 @@ void snd_card_info_read_oss(struct snd_info_buffer *buffer);
110static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {} 110static inline void snd_card_info_read_oss(struct snd_info_buffer *buffer) {}
111#endif 111#endif
112 112
113int snd_iprintf(struct snd_info_buffer *buffer, char *fmt, ...) \ 113int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...) \
114 __attribute__ ((format (printf, 2, 3))); 114 __attribute__ ((format (printf, 2, 3)));
115int snd_info_init(void); 115int snd_info_init(void);
116int snd_info_done(void); 116int snd_info_done(void);
117 117
118int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len); 118int snd_info_get_line(struct snd_info_buffer *buffer, char *line, int len);
119char *snd_info_get_str(char *dest, char *src, int len); 119const char *snd_info_get_str(char *dest, const char *src, int len);
120struct snd_info_entry *snd_info_create_module_entry(struct module *module, 120struct snd_info_entry *snd_info_create_module_entry(struct module *module,
121 const char *name, 121 const char *name,
122 struct snd_info_entry *parent); 122 struct snd_info_entry *parent);
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index 7ccce94a5255..c42506212649 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -47,7 +47,11 @@ struct snd_dma_device {
47#define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */ 47#define SNDRV_DMA_TYPE_UNKNOWN 0 /* not defined */
48#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */ 48#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
49#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */ 49#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
50#ifdef CONFIG_SND_DMA_SGBUF
50#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */ 51#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
52#else
53#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
54#endif
51 55
52/* 56/*
53 * info for buffer allocation 57 * info for buffer allocation
@@ -60,6 +64,7 @@ struct snd_dma_buffer {
60 void *private_data; /* private for allocator; don't touch */ 64 void *private_data; /* private for allocator; don't touch */
61}; 65};
62 66
67#ifdef CONFIG_SND_DMA_SGBUF
63/* 68/*
64 * Scatter-Gather generic device pages 69 * Scatter-Gather generic device pages
65 */ 70 */
@@ -107,6 +112,7 @@ static inline void *snd_sgbuf_get_ptr(struct snd_sg_buf *sgbuf, size_t offset)
107{ 112{
108 return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE; 113 return sgbuf->table[offset >> PAGE_SHIFT].buf + offset % PAGE_SIZE;
109} 114}
115#endif /* CONFIG_SND_DMA_SGBUF */
110 116
111/* allocate/release a buffer */ 117/* allocate/release a buffer */
112int snd_dma_alloc_pages(int type, struct device *dev, size_t size, 118int snd_dma_alloc_pages(int type, struct device *dev, size_t size,
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 23893523dc8c..de6d981de5d6 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -902,6 +902,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
902int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size); 902int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
903int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream); 903int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
904 904
905#ifdef CONFIG_SND_DMA_SGBUF
905/* 906/*
906 * SG-buffer handling 907 * SG-buffer handling
907 */ 908 */
@@ -927,6 +928,28 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
927unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, 928unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
928 unsigned int ofs, unsigned int size); 929 unsigned int ofs, unsigned int size);
929 930
931#else /* !SND_DMA_SGBUF */
932/*
933 * fake using a continuous buffer
934 */
935static inline dma_addr_t
936snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
937{
938 return substream->runtime->dma_addr + ofs;
939}
940
941static inline void *
942snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
943{
944 return substream->runtime->dma_area + ofs;
945}
946
947#define snd_pcm_sgbuf_ops_page NULL
948
949#define snd_pcm_sgbuf_get_chunk_size(subs, ofs, size) (size)
950
951#endif /* SND_DMA_SGBUF */
952
930/* handle mmap counter - PCM mmap callback should handle this counter properly */ 953/* handle mmap counter - PCM mmap callback should handle this counter properly */
931static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) 954static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
932{ 955{
@@ -965,4 +988,6 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
965 988
966#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime) 989#define PCM_RUNTIME_CHECK(sub) snd_BUG_ON(!(sub) || !(sub)->runtime)
967 990
991const char *snd_pcm_format_name(snd_pcm_format_t format);
992
968#endif /* __SOUND_PCM_H */ 993#endif /* __SOUND_PCM_H */
diff --git a/include/sound/sh_fsi.h b/include/sound/sh_fsi.h
new file mode 100644
index 000000000000..c0227361a876
--- /dev/null
+++ b/include/sound/sh_fsi.h
@@ -0,0 +1,83 @@
1#ifndef __SOUND_FSI_H
2#define __SOUND_FSI_H
3
4/*
5 * Fifo-attached Serial Interface (FSI) support for SH7724
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Kuninori Morimoto <morimoto.kuninori@renesas.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/* flags format
16
17 * 0xABCDEEFF
18 *
19 * A: channel size for TDM (input)
20 * B: channel size for TDM (ooutput)
21 * C: inversion
22 * D: mode
23 * E: input format
24 * F: output format
25 */
26
27#include <linux/clk.h>
28#include <sound/soc.h>
29
30/* TDM channel */
31#define SH_FSI_SET_CH_I(x) ((x & 0xF) << 28)
32#define SH_FSI_SET_CH_O(x) ((x & 0xF) << 24)
33
34#define SH_FSI_CH_IMASK 0xF0000000
35#define SH_FSI_CH_OMASK 0x0F000000
36#define SH_FSI_GET_CH_I(x) ((x & SH_FSI_CH_IMASK) >> 28)
37#define SH_FSI_GET_CH_O(x) ((x & SH_FSI_CH_OMASK) >> 24)
38
39/* clock inversion */
40#define SH_FSI_INVERSION_MASK 0x00F00000
41#define SH_FSI_LRM_INV (1 << 20)
42#define SH_FSI_BRM_INV (1 << 21)
43#define SH_FSI_LRS_INV (1 << 22)
44#define SH_FSI_BRS_INV (1 << 23)
45
46/* mode */
47#define SH_FSI_MODE_MASK 0x000F0000
48#define SH_FSI_IN_SLAVE_MODE (1 << 16) /* default master mode */
49#define SH_FSI_OUT_SLAVE_MODE (1 << 17) /* default master mode */
50
51/* DI format */
52#define SH_FSI_FMT_MASK 0x000000FF
53#define SH_FSI_IFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 8)
54#define SH_FSI_OFMT(x) (((SH_FSI_FMT_ ## x) & SH_FSI_FMT_MASK) << 0)
55#define SH_FSI_GET_IFMT(x) ((x >> 8) & SH_FSI_FMT_MASK)
56#define SH_FSI_GET_OFMT(x) ((x >> 0) & SH_FSI_FMT_MASK)
57
58#define SH_FSI_FMT_MONO (1 << 0)
59#define SH_FSI_FMT_MONO_DELAY (1 << 1)
60#define SH_FSI_FMT_PCM (1 << 2)
61#define SH_FSI_FMT_I2S (1 << 3)
62#define SH_FSI_FMT_TDM (1 << 4)
63#define SH_FSI_FMT_TDM_DELAY (1 << 5)
64
65#define SH_FSI_IFMT_TDM_CH(x) \
66 (SH_FSI_IFMT(TDM) | SH_FSI_SET_CH_I(x))
67#define SH_FSI_IFMT_TDM_DELAY_CH(x) \
68 (SH_FSI_IFMT(TDM_DELAY) | SH_FSI_SET_CH_I(x))
69
70#define SH_FSI_OFMT_TDM_CH(x) \
71 (SH_FSI_OFMT(TDM) | SH_FSI_SET_CH_O(x))
72#define SH_FSI_OFMT_TDM_DELAY_CH(x) \
73 (SH_FSI_OFMT(TDM_DELAY) | SH_FSI_SET_CH_O(x))
74
75struct sh_fsi_platform_info {
76 unsigned long porta_flags;
77 unsigned long portb_flags;
78};
79
80extern struct snd_soc_dai fsi_soc_dai[2];
81extern struct snd_soc_platform fsi_soc_platform;
82
83#endif /* __SOUND_FSI_H */
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 352d7eee9b6d..97ca9af414dc 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -27,8 +27,8 @@ struct snd_pcm_substream;
27#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ 27#define SND_SOC_DAIFMT_I2S 0 /* I2S mode */
28#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */ 28#define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */
29#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ 29#define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */
30#define SND_SOC_DAIFMT_DSP_A 3 /* L data msb after FRM LRC */ 30#define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */
31#define SND_SOC_DAIFMT_DSP_B 4 /* L data msb during FRM LRC */ 31#define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */
32#define SND_SOC_DAIFMT_AC97 5 /* AC97 */ 32#define SND_SOC_DAIFMT_AC97 5 /* AC97 */
33 33
34/* left and right justified also known as MSB and LSB respectively */ 34/* left and right justified also known as MSB and LSB respectively */
@@ -38,7 +38,7 @@ struct snd_pcm_substream;
38/* 38/*
39 * DAI Clock gating. 39 * DAI Clock gating.
40 * 40 *
41 * DAI bit clocks can be be gated (disabled) when not the DAI is not 41 * DAI bit clocks can be be gated (disabled) when the DAI is not
42 * sending or receiving PCM data in a frame. This can be used to save power. 42 * sending or receiving PCM data in a frame. This can be used to save power.
43 */ 43 */
44#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ 44#define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */
@@ -51,21 +51,21 @@ struct snd_pcm_substream;
51 * format. 51 * format.
52 */ 52 */
53#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ 53#define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */
54#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal bclk + inv frm */ 54#define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */
55#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert bclk + nor frm */ 55#define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */
56#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert bclk + frm */ 56#define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */
57 57
58/* 58/*
59 * DAI hardware clock masters. 59 * DAI hardware clock masters.
60 * 60 *
61 * This is wrt the codec, the inverse is true for the interface 61 * This is wrt the codec, the inverse is true for the interface
62 * i.e. if the codec is clk and frm master then the interface is 62 * i.e. if the codec is clk and FRM master then the interface is
63 * clk and frame slave. 63 * clk and frame slave.
64 */ 64 */
65#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */ 65#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */
66#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */ 66#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */
67#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ 67#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
68#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */ 68#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */
69 69
70#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f 70#define SND_SOC_DAIFMT_FORMAT_MASK 0x000f
71#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 71#define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0
@@ -78,7 +78,13 @@ struct snd_pcm_substream;
78#define SND_SOC_CLOCK_IN 0 78#define SND_SOC_CLOCK_IN 0
79#define SND_SOC_CLOCK_OUT 1 79#define SND_SOC_CLOCK_OUT 1
80 80
81#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\ 81#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S8 |\
82 SNDRV_PCM_FMTBIT_S16_LE |\
83 SNDRV_PCM_FMTBIT_S16_BE |\
84 SNDRV_PCM_FMTBIT_S20_3LE |\
85 SNDRV_PCM_FMTBIT_S20_3BE |\
86 SNDRV_PCM_FMTBIT_S24_3LE |\
87 SNDRV_PCM_FMTBIT_S24_3BE |\
82 SNDRV_PCM_FMTBIT_S32_LE |\ 88 SNDRV_PCM_FMTBIT_S32_LE |\
83 SNDRV_PCM_FMTBIT_S32_BE) 89 SNDRV_PCM_FMTBIT_S32_BE)
84 90
@@ -106,7 +112,7 @@ int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
106int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt); 112int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
107 113
108int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 114int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
109 unsigned int mask, int slots); 115 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width);
110 116
111int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate); 117int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
112 118
@@ -116,12 +122,12 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
116/* 122/*
117 * Digital Audio Interface. 123 * Digital Audio Interface.
118 * 124 *
119 * Describes the Digital Audio Interface in terms of it's ALSA, DAI and AC97 125 * Describes the Digital Audio Interface in terms of its ALSA, DAI and AC97
120 * operations an capabilities. Codec and platfom drivers will register a this 126 * operations and capabilities. Codec and platform drivers will register this
121 * structure for every DAI they have. 127 * structure for every DAI they have.
122 * 128 *
123 * This structure covers the clocking, formating and ALSA operations for each 129 * This structure covers the clocking, formating and ALSA operations for each
124 * interface a 130 * interface.
125 */ 131 */
126struct snd_soc_dai_ops { 132struct snd_soc_dai_ops {
127 /* 133 /*
@@ -140,7 +146,8 @@ struct snd_soc_dai_ops {
140 */ 146 */
141 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt); 147 int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
142 int (*set_tdm_slot)(struct snd_soc_dai *dai, 148 int (*set_tdm_slot)(struct snd_soc_dai *dai,
143 unsigned int mask, int slots); 149 unsigned int tx_mask, unsigned int rx_mask,
150 int slots, int slot_width);
144 int (*set_tristate)(struct snd_soc_dai *dai, int tristate); 151 int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
145 152
146 /* 153 /*
@@ -179,6 +186,7 @@ struct snd_soc_dai {
179 int ac97_control; 186 int ac97_control;
180 187
181 struct device *dev; 188 struct device *dev;
189 void *ac97_pdata; /* platform_data for the ac97 codec */
182 190
183 /* DAI callbacks */ 191 /* DAI callbacks */
184 int (*probe)(struct platform_device *pdev, 192 int (*probe)(struct platform_device *pdev,
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index ec8a45f9a069..c1410e3191e3 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -137,6 +137,12 @@
137 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD} 137 .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD}
138 138
139/* stream domain */ 139/* stream domain */
140#define SND_SOC_DAPM_AIF_IN(wname, stname, wslot, wreg, wshift, winvert) \
141{ .id = snd_soc_dapm_aif_in, .name = wname, .sname = stname, \
142 .reg = wreg, .shift = wshift, .invert = winvert }
143#define SND_SOC_DAPM_AIF_OUT(wname, stname, wslot, wreg, wshift, winvert) \
144{ .id = snd_soc_dapm_aif_out, .name = wname, .sname = stname, \
145 .reg = wreg, .shift = wshift, .invert = winvert }
140#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \ 146#define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \
141{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ 147{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \
142 .shift = wshift, .invert = winvert} 148 .shift = wshift, .invert = winvert}
@@ -279,9 +285,11 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
279/* dapm events */ 285/* dapm events */
280int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, 286int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream,
281 int event); 287 int event);
288void snd_soc_dapm_shutdown(struct snd_soc_device *socdev);
282 289
283/* dapm sys fs - used by the core */ 290/* dapm sys fs - used by the core */
284int snd_soc_dapm_sys_add(struct device *dev); 291int snd_soc_dapm_sys_add(struct device *dev);
292void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec);
285 293
286/* dapm audio pin control and status */ 294/* dapm audio pin control and status */
287int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); 295int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin);
@@ -311,6 +319,8 @@ enum snd_soc_dapm_type {
311 snd_soc_dapm_pre, /* machine specific pre widget - exec first */ 319 snd_soc_dapm_pre, /* machine specific pre widget - exec first */
312 snd_soc_dapm_post, /* machine specific post widget - exec last */ 320 snd_soc_dapm_post, /* machine specific post widget - exec last */
313 snd_soc_dapm_supply, /* power/clock supply */ 321 snd_soc_dapm_supply, /* power/clock supply */
322 snd_soc_dapm_aif_in, /* audio interface input */
323 snd_soc_dapm_aif_out, /* audio interface output */
314}; 324};
315 325
316/* 326/*
diff --git a/include/sound/soc.h b/include/sound/soc.h
index cf6111d72b17..475cb7ed6bec 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -135,6 +135,28 @@
135 .info = snd_soc_info_volsw, \ 135 .info = snd_soc_info_volsw, \
136 .get = xhandler_get, .put = xhandler_put, \ 136 .get = xhandler_get, .put = xhandler_put, \
137 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } 137 .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) }
138#define SOC_DOUBLE_EXT_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert,\
139 xhandler_get, xhandler_put, tlv_array) \
140{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
141 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
142 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
143 .tlv.p = (tlv_array), \
144 .info = snd_soc_info_volsw, \
145 .get = xhandler_get, .put = xhandler_put, \
146 .private_value = (unsigned long)&(struct soc_mixer_control) \
147 {.reg = xreg, .shift = shift_left, .rshift = shift_right, \
148 .max = xmax, .invert = xinvert} }
149#define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\
150 xhandler_get, xhandler_put, tlv_array) \
151{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
152 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
153 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
154 .tlv.p = (tlv_array), \
155 .info = snd_soc_info_volsw_2r, \
156 .get = xhandler_get, .put = xhandler_put, \
157 .private_value = (unsigned long)&(struct soc_mixer_control) \
158 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
159 .max = xmax, .invert = xinvert} }
138#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ 160#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
139{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 161{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
140 .info = snd_soc_info_bool_ext, \ 162 .info = snd_soc_info_bool_ext, \
@@ -183,14 +205,28 @@ struct snd_soc_jack_gpio;
183#endif 205#endif
184 206
185typedef int (*hw_write_t)(void *,const char* ,int); 207typedef int (*hw_write_t)(void *,const char* ,int);
186typedef int (*hw_read_t)(void *,char* ,int);
187 208
188extern struct snd_ac97_bus_ops soc_ac97_ops; 209extern struct snd_ac97_bus_ops soc_ac97_ops;
189 210
211enum snd_soc_control_type {
212 SND_SOC_CUSTOM,
213 SND_SOC_I2C,
214 SND_SOC_SPI,
215};
216
190int snd_soc_register_platform(struct snd_soc_platform *platform); 217int snd_soc_register_platform(struct snd_soc_platform *platform);
191void snd_soc_unregister_platform(struct snd_soc_platform *platform); 218void snd_soc_unregister_platform(struct snd_soc_platform *platform);
192int snd_soc_register_codec(struct snd_soc_codec *codec); 219int snd_soc_register_codec(struct snd_soc_codec *codec);
193void snd_soc_unregister_codec(struct snd_soc_codec *codec); 220void snd_soc_unregister_codec(struct snd_soc_codec *codec);
221int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg);
222int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
223 int addr_bits, int data_bits,
224 enum snd_soc_control_type control);
225
226#ifdef CONFIG_PM
227int snd_soc_suspend_device(struct device *dev);
228int snd_soc_resume_device(struct device *dev);
229#endif
194 230
195/* pcm <-> DAI connect */ 231/* pcm <-> DAI connect */
196void snd_soc_free_pcms(struct snd_soc_device *socdev); 232void snd_soc_free_pcms(struct snd_soc_device *socdev);
@@ -216,9 +252,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
216 252
217/* codec register bit access */ 253/* codec register bit access */
218int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 254int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
219 unsigned short mask, unsigned short value); 255 unsigned int mask, unsigned int value);
220int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, 256int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
221 unsigned short mask, unsigned short value); 257 unsigned int mask, unsigned int value);
222 258
223int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, 259int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
224 struct snd_ac97_bus_ops *ops, int num); 260 struct snd_ac97_bus_ops *ops, int num);
@@ -356,8 +392,10 @@ struct snd_soc_codec {
356 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); 392 int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
357 int (*display_register)(struct snd_soc_codec *, char *, 393 int (*display_register)(struct snd_soc_codec *, char *,
358 size_t, unsigned int); 394 size_t, unsigned int);
395 int (*volatile_register)(unsigned int);
396 int (*readable_register)(unsigned int);
359 hw_write_t hw_write; 397 hw_write_t hw_write;
360 hw_read_t hw_read; 398 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int);
361 void *reg_cache; 399 void *reg_cache;
362 short reg_cache_size; 400 short reg_cache_size;
363 short reg_cache_step; 401 short reg_cache_step;
@@ -369,8 +407,6 @@ struct snd_soc_codec {
369 enum snd_soc_bias_level bias_level; 407 enum snd_soc_bias_level bias_level;
370 enum snd_soc_bias_level suspend_bias_level; 408 enum snd_soc_bias_level suspend_bias_level;
371 struct delayed_work delayed_work; 409 struct delayed_work delayed_work;
372 struct list_head up_list;
373 struct list_head down_list;
374 410
375 /* codec DAI's */ 411 /* codec DAI's */
376 struct snd_soc_dai *dai; 412 struct snd_soc_dai *dai;
@@ -379,6 +415,7 @@ struct snd_soc_codec {
379#ifdef CONFIG_DEBUG_FS 415#ifdef CONFIG_DEBUG_FS
380 struct dentry *debugfs_reg; 416 struct dentry *debugfs_reg;
381 struct dentry *debugfs_pop_time; 417 struct dentry *debugfs_pop_time;
418 struct dentry *debugfs_dapm;
382#endif 419#endif
383}; 420};
384 421
diff --git a/include/sound/uda1380.h b/include/sound/uda1380.h
new file mode 100644
index 000000000000..381319c7000c
--- /dev/null
+++ b/include/sound/uda1380.h
@@ -0,0 +1,22 @@
1/*
2 * UDA1380 ALSA SoC Codec driver
3 *
4 * Copyright 2009 Philipp Zabel
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __UDA1380_H
12#define __UDA1380_H
13
14struct uda1380_platform_data {
15 int gpio_power;
16 int gpio_reset;
17 int dac_clk;
18#define UDA1380_DAC_CLK_SYSCLK 0
19#define UDA1380_DAC_CLK_WSPLL 1
20};
21
22#endif /* __UDA1380_H */
diff --git a/include/sound/version.h b/include/sound/version.h
index 456f1359e1c0..22939142dd23 100644
--- a/include/sound/version.h
+++ b/include/sound/version.h
@@ -1,3 +1,3 @@
1/* include/version.h */ 1/* include/version.h */
2#define CONFIG_SND_VERSION "1.0.20" 2#define CONFIG_SND_VERSION "1.0.21"
3#define CONFIG_SND_DATE "" 3#define CONFIG_SND_DATE ""
diff --git a/include/sound/wm8993.h b/include/sound/wm8993.h
new file mode 100644
index 000000000000..9c661f2f8cda
--- /dev/null
+++ b/include/sound/wm8993.h
@@ -0,0 +1,44 @@
1/*
2 * linux/sound/wm8993.h -- Platform data for WM8993
3 *
4 * Copyright 2009 Wolfson Microelectronics. PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_SND_WM8993_H
12#define __LINUX_SND_WM8993_H
13
14/* Note that EQ1 only contains the enable/disable bit so will be
15 ignored but is included for simplicity.
16 */
17struct wm8993_retune_mobile_setting {
18 const char *name;
19 unsigned int rate;
20 u16 config[24];
21};
22
23struct wm8993_platform_data {
24 struct wm8993_retune_mobile_setting *retune_configs;
25 int num_retune_configs;
26
27 /* LINEOUT can be differential or single ended */
28 unsigned int lineout1_diff:1;
29 unsigned int lineout2_diff:1;
30
31 /* Common mode feedback */
32 unsigned int lineout1fb:1;
33 unsigned int lineout2fb:1;
34
35 /* Microphone biases: 0=0.9*AVDD1 1=0.65*AVVD1 */
36 unsigned int micbias1_lvl:1;
37 unsigned int micbias2_lvl:1;
38
39 /* Jack detect threashold levels, see datasheet for values */
40 unsigned int jd_scthr:2;
41 unsigned int jd_thr:2;
42};
43
44#endif
diff --git a/kernel/module.c b/kernel/module.c
index eccb561dd8a3..2d537186191f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1274,6 +1274,10 @@ static void add_notes_attrs(struct module *mod, unsigned int nsect,
1274 struct module_notes_attrs *notes_attrs; 1274 struct module_notes_attrs *notes_attrs;
1275 struct bin_attribute *nattr; 1275 struct bin_attribute *nattr;
1276 1276
1277 /* failed to create section attributes, so can't create notes */
1278 if (!mod->sect_attrs)
1279 return;
1280
1277 /* Count notes sections and allocate structures. */ 1281 /* Count notes sections and allocate structures. */
1278 notes = 0; 1282 notes = 0;
1279 for (i = 0; i < nsect; i++) 1283 for (i = 0; i < nsect; i++)
@@ -2355,8 +2359,7 @@ static noinline struct module *load_module(void __user *umod,
2355 if (err < 0) 2359 if (err < 0)
2356 goto unlink; 2360 goto unlink;
2357 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs); 2361 add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2358 if (mod->sect_attrs) 2362 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2359 add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
2360 2363
2361 /* Get rid of temporary copy */ 2364 /* Get rid of temporary copy */
2362 vfree(hdr); 2365 vfree(hdr);
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index f274e1959885..d7cbc579fc80 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -50,7 +50,7 @@ static atomic_t nr_task_counters __read_mostly;
50 * 1 - disallow cpu counters to unpriv 50 * 1 - disallow cpu counters to unpriv
51 * 2 - disallow kernel profiling to unpriv 51 * 2 - disallow kernel profiling to unpriv
52 */ 52 */
53int sysctl_perf_counter_paranoid __read_mostly; 53int sysctl_perf_counter_paranoid __read_mostly = 1;
54 54
55static inline bool perf_paranoid_cpu(void) 55static inline bool perf_paranoid_cpu(void)
56{ 56{
@@ -4066,6 +4066,7 @@ perf_counter_alloc(struct perf_counter_attr *attr,
4066 hwc->sample_period = attr->sample_period; 4066 hwc->sample_period = attr->sample_period;
4067 if (attr->freq && attr->sample_freq) 4067 if (attr->freq && attr->sample_freq)
4068 hwc->sample_period = 1; 4068 hwc->sample_period = 1;
4069 hwc->last_period = hwc->sample_period;
4069 4070
4070 atomic64_set(&hwc->period_left, hwc->sample_period); 4071 atomic64_set(&hwc->period_left, hwc->sample_period);
4071 4072
diff --git a/mm/nommu.c b/mm/nommu.c
index 4bde489ec431..66e81e7e9fe9 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1352,6 +1352,7 @@ unsigned long do_mmap_pgoff(struct file *file,
1352 } 1352 }
1353 1353
1354 vma->vm_region = region; 1354 vma->vm_region = region;
1355 add_nommu_region(region);
1355 1356
1356 /* set up the mapping */ 1357 /* set up the mapping */
1357 if (file && vma->vm_flags & VM_SHARED) 1358 if (file && vma->vm_flags & VM_SHARED)
@@ -1361,8 +1362,6 @@ unsigned long do_mmap_pgoff(struct file *file,
1361 if (ret < 0) 1362 if (ret < 0)
1362 goto error_put_region; 1363 goto error_put_region;
1363 1364
1364 add_nommu_region(region);
1365
1366 /* okay... we have a mapping; now we have to register it */ 1365 /* okay... we have a mapping; now we have to register it */
1367 result = vma->vm_start; 1366 result = vma->vm_start;
1368 1367
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5cc986eb9f6f..a0de15f46987 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -817,13 +817,15 @@ __rmqueue_fallback(struct zone *zone, int order, int start_migratetype)
817 * agressive about taking ownership of free pages 817 * agressive about taking ownership of free pages
818 */ 818 */
819 if (unlikely(current_order >= (pageblock_order >> 1)) || 819 if (unlikely(current_order >= (pageblock_order >> 1)) ||
820 start_migratetype == MIGRATE_RECLAIMABLE) { 820 start_migratetype == MIGRATE_RECLAIMABLE ||
821 page_group_by_mobility_disabled) {
821 unsigned long pages; 822 unsigned long pages;
822 pages = move_freepages_block(zone, page, 823 pages = move_freepages_block(zone, page,
823 start_migratetype); 824 start_migratetype);
824 825
825 /* Claim the whole block if over half of it is free */ 826 /* Claim the whole block if over half of it is free */
826 if (pages >= (1 << (pageblock_order-1))) 827 if (pages >= (1 << (pageblock_order-1)) ||
828 page_group_by_mobility_disabled)
827 set_pageblock_migratetype(page, 829 set_pageblock_migratetype(page,
828 start_migratetype); 830 start_migratetype);
829 831
diff --git a/mm/percpu.c b/mm/percpu.c
index 5fe37842e0ea..3311c8919f37 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -197,7 +197,12 @@ static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk,
197static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk, 197static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk,
198 int page_idx) 198 int page_idx)
199{ 199{
200 return *pcpu_chunk_pagep(chunk, 0, page_idx) != NULL; 200 /*
201 * Any possible cpu id can be used here, so there's no need to
202 * worry about preemption or cpu hotplug.
203 */
204 return *pcpu_chunk_pagep(chunk, raw_smp_processor_id(),
205 page_idx) != NULL;
201} 206}
202 207
203/* set the pointer to a chunk in a page struct */ 208/* set the pointer to a chunk in a page struct */
@@ -297,6 +302,14 @@ static struct pcpu_chunk *pcpu_chunk_addr_search(void *addr)
297 return pcpu_first_chunk; 302 return pcpu_first_chunk;
298 } 303 }
299 304
305 /*
306 * The address is relative to unit0 which might be unused and
307 * thus unmapped. Offset the address to the unit space of the
308 * current processor before looking it up in the vmalloc
309 * space. Note that any possible cpu id can be used here, so
310 * there's no need to worry about preemption or cpu hotplug.
311 */
312 addr += raw_smp_processor_id() * pcpu_unit_size;
300 return pcpu_get_page_chunk(vmalloc_to_page(addr)); 313 return pcpu_get_page_chunk(vmalloc_to_page(addr));
301} 314}
302 315
diff --git a/mm/slub.c b/mm/slub.c
index b9f1491a58a1..b6276753626e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2594,8 +2594,6 @@ static inline int kmem_cache_close(struct kmem_cache *s)
2594 */ 2594 */
2595void kmem_cache_destroy(struct kmem_cache *s) 2595void kmem_cache_destroy(struct kmem_cache *s)
2596{ 2596{
2597 if (s->flags & SLAB_DESTROY_BY_RCU)
2598 rcu_barrier();
2599 down_write(&slub_lock); 2597 down_write(&slub_lock);
2600 s->refcount--; 2598 s->refcount--;
2601 if (!s->refcount) { 2599 if (!s->refcount) {
@@ -2606,6 +2604,8 @@ void kmem_cache_destroy(struct kmem_cache *s)
2606 "still has objects.\n", s->name, __func__); 2604 "still has objects.\n", s->name, __func__);
2607 dump_stack(); 2605 dump_stack();
2608 } 2606 }
2607 if (s->flags & SLAB_DESTROY_BY_RCU)
2608 rcu_barrier();
2609 sysfs_slab_remove(s); 2609 sysfs_slab_remove(s);
2610 } else 2610 } else
2611 up_write(&slub_lock); 2611 up_write(&slub_lock);
diff --git a/net/core/sock.c b/net/core/sock.c
index bbb25be7ddfe..76334228ed1c 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1025,6 +1025,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
1025 sk->sk_prot = sk->sk_prot_creator = prot; 1025 sk->sk_prot = sk->sk_prot_creator = prot;
1026 sock_lock_init(sk); 1026 sock_lock_init(sk);
1027 sock_net_set(sk, get_net(net)); 1027 sock_net_set(sk, get_net(net));
1028 atomic_set(&sk->sk_wmem_alloc, 1);
1028 } 1029 }
1029 1030
1030 return sk; 1031 return sk;
@@ -1872,7 +1873,6 @@ void sock_init_data(struct socket *sock, struct sock *sk)
1872 */ 1873 */
1873 smp_wmb(); 1874 smp_wmb();
1874 atomic_set(&sk->sk_refcnt, 1); 1875 atomic_set(&sk->sk_refcnt, 1);
1875 atomic_set(&sk->sk_wmem_alloc, 1);
1876 atomic_set(&sk->sk_drops, 0); 1876 atomic_set(&sk->sk_drops, 0);
1877} 1877}
1878EXPORT_SYMBOL(sock_init_data); 1878EXPORT_SYMBOL(sock_init_data);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 92e6f3a52c13..fdb694e9f759 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -458,7 +458,7 @@ EXPORT_SYMBOL(qdisc_warn_nonwc);
458static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer) 458static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
459{ 459{
460 struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog, 460 struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
461 timer.timer); 461 timer);
462 462
463 wd->qdisc->flags &= ~TCQ_F_THROTTLED; 463 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
464 __netif_schedule(qdisc_root(wd->qdisc)); 464 __netif_schedule(qdisc_root(wd->qdisc));
@@ -468,8 +468,8 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
468 468
469void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc) 469void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc)
470{ 470{
471 tasklet_hrtimer_init(&wd->timer, qdisc_watchdog, 471 hrtimer_init(&wd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
472 CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 472 wd->timer.function = qdisc_watchdog;
473 wd->qdisc = qdisc; 473 wd->qdisc = qdisc;
474} 474}
475EXPORT_SYMBOL(qdisc_watchdog_init); 475EXPORT_SYMBOL(qdisc_watchdog_init);
@@ -485,13 +485,13 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
485 wd->qdisc->flags |= TCQ_F_THROTTLED; 485 wd->qdisc->flags |= TCQ_F_THROTTLED;
486 time = ktime_set(0, 0); 486 time = ktime_set(0, 0);
487 time = ktime_add_ns(time, PSCHED_TICKS2NS(expires)); 487 time = ktime_add_ns(time, PSCHED_TICKS2NS(expires));
488 tasklet_hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS); 488 hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS);
489} 489}
490EXPORT_SYMBOL(qdisc_watchdog_schedule); 490EXPORT_SYMBOL(qdisc_watchdog_schedule);
491 491
492void qdisc_watchdog_cancel(struct qdisc_watchdog *wd) 492void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
493{ 493{
494 tasklet_hrtimer_cancel(&wd->timer); 494 hrtimer_cancel(&wd->timer);
495 wd->qdisc->flags &= ~TCQ_F_THROTTLED; 495 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
496} 496}
497EXPORT_SYMBOL(qdisc_watchdog_cancel); 497EXPORT_SYMBOL(qdisc_watchdog_cancel);
@@ -1456,6 +1456,8 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1456 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); 1456 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
1457 tcm = NLMSG_DATA(nlh); 1457 tcm = NLMSG_DATA(nlh);
1458 tcm->tcm_family = AF_UNSPEC; 1458 tcm->tcm_family = AF_UNSPEC;
1459 tcm->tcm__pad1 = 0;
1460 tcm->tcm__pad2 = 0;
1459 tcm->tcm_ifindex = qdisc_dev(q)->ifindex; 1461 tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
1460 tcm->tcm_parent = q->handle; 1462 tcm->tcm_parent = q->handle;
1461 tcm->tcm_handle = q->handle; 1463 tcm->tcm_handle = q->handle;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 149b0405c5ec..d5798e17a832 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -163,7 +163,7 @@ struct cbq_sched_data
163 psched_time_t now_rt; /* Cached real time */ 163 psched_time_t now_rt; /* Cached real time */
164 unsigned pmask; 164 unsigned pmask;
165 165
166 struct tasklet_hrtimer delay_timer; 166 struct hrtimer delay_timer;
167 struct qdisc_watchdog watchdog; /* Watchdog timer, 167 struct qdisc_watchdog watchdog; /* Watchdog timer,
168 started when CBQ has 168 started when CBQ has
169 backlog, but cannot 169 backlog, but cannot
@@ -503,8 +503,6 @@ static void cbq_ovl_delay(struct cbq_class *cl)
503 cl->undertime = q->now + delay; 503 cl->undertime = q->now + delay;
504 504
505 if (delay > 0) { 505 if (delay > 0) {
506 struct hrtimer *ht;
507
508 sched += delay + cl->penalty; 506 sched += delay + cl->penalty;
509 cl->penalized = sched; 507 cl->penalized = sched;
510 cl->cpriority = TC_CBQ_MAXPRIO; 508 cl->cpriority = TC_CBQ_MAXPRIO;
@@ -512,12 +510,12 @@ static void cbq_ovl_delay(struct cbq_class *cl)
512 510
513 expires = ktime_set(0, 0); 511 expires = ktime_set(0, 0);
514 expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched)); 512 expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
515 ht = &q->delay_timer.timer; 513 if (hrtimer_try_to_cancel(&q->delay_timer) &&
516 if (hrtimer_try_to_cancel(ht) && 514 ktime_to_ns(ktime_sub(
517 ktime_to_ns(ktime_sub(hrtimer_get_expires(ht), 515 hrtimer_get_expires(&q->delay_timer),
518 expires)) > 0) 516 expires)) > 0)
519 hrtimer_set_expires(ht, expires); 517 hrtimer_set_expires(&q->delay_timer, expires);
520 hrtimer_restart(ht); 518 hrtimer_restart(&q->delay_timer);
521 cl->delayed = 1; 519 cl->delayed = 1;
522 cl->xstats.overactions++; 520 cl->xstats.overactions++;
523 return; 521 return;
@@ -593,7 +591,7 @@ static psched_tdiff_t cbq_undelay_prio(struct cbq_sched_data *q, int prio,
593static enum hrtimer_restart cbq_undelay(struct hrtimer *timer) 591static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
594{ 592{
595 struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data, 593 struct cbq_sched_data *q = container_of(timer, struct cbq_sched_data,
596 delay_timer.timer); 594 delay_timer);
597 struct Qdisc *sch = q->watchdog.qdisc; 595 struct Qdisc *sch = q->watchdog.qdisc;
598 psched_time_t now; 596 psched_time_t now;
599 psched_tdiff_t delay = 0; 597 psched_tdiff_t delay = 0;
@@ -623,7 +621,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
623 621
624 time = ktime_set(0, 0); 622 time = ktime_set(0, 0);
625 time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay)); 623 time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
626 tasklet_hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS); 624 hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
627 } 625 }
628 626
629 sch->flags &= ~TCQ_F_THROTTLED; 627 sch->flags &= ~TCQ_F_THROTTLED;
@@ -1216,7 +1214,7 @@ cbq_reset(struct Qdisc* sch)
1216 q->tx_class = NULL; 1214 q->tx_class = NULL;
1217 q->tx_borrowed = NULL; 1215 q->tx_borrowed = NULL;
1218 qdisc_watchdog_cancel(&q->watchdog); 1216 qdisc_watchdog_cancel(&q->watchdog);
1219 tasklet_hrtimer_cancel(&q->delay_timer); 1217 hrtimer_cancel(&q->delay_timer);
1220 q->toplevel = TC_CBQ_MAXLEVEL; 1218 q->toplevel = TC_CBQ_MAXLEVEL;
1221 q->now = psched_get_time(); 1219 q->now = psched_get_time();
1222 q->now_rt = q->now; 1220 q->now_rt = q->now;
@@ -1399,8 +1397,7 @@ static int cbq_init(struct Qdisc *sch, struct nlattr *opt)
1399 q->link.minidle = -0x7FFFFFFF; 1397 q->link.minidle = -0x7FFFFFFF;
1400 1398
1401 qdisc_watchdog_init(&q->watchdog, sch); 1399 qdisc_watchdog_init(&q->watchdog, sch);
1402 tasklet_hrtimer_init(&q->delay_timer, cbq_undelay, 1400 hrtimer_init(&q->delay_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1403 CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
1404 q->delay_timer.function = cbq_undelay; 1401 q->delay_timer.function = cbq_undelay;
1405 q->toplevel = TC_CBQ_MAXLEVEL; 1402 q->toplevel = TC_CBQ_MAXLEVEL;
1406 q->now = psched_get_time(); 1403 q->now = psched_get_time();
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index ebfcf9b89909..df1039f077c2 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -937,6 +937,7 @@ static inline void
937rpc_task_force_reencode(struct rpc_task *task) 937rpc_task_force_reencode(struct rpc_task *task)
938{ 938{
939 task->tk_rqstp->rq_snd_buf.len = 0; 939 task->tk_rqstp->rq_snd_buf.len = 0;
940 task->tk_rqstp->rq_bytes_sent = 0;
940} 941}
941 942
942static inline void 943static inline void
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 4732f5e5d127..b85e61bcf246 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -249,7 +249,11 @@ void ima_counts_put(struct path *path, int mask)
249 struct inode *inode = path->dentry->d_inode; 249 struct inode *inode = path->dentry->d_inode;
250 struct ima_iint_cache *iint; 250 struct ima_iint_cache *iint;
251 251
252 if (!ima_initialized || !S_ISREG(inode->i_mode)) 252 /* The inode may already have been freed, freeing the iint
253 * with it. Verify the inode is not NULL before dereferencing
254 * it.
255 */
256 if (!ima_initialized || !inode || !S_ISREG(inode->i_mode))
253 return; 257 return;
254 iint = ima_iint_find_insert_get(inode); 258 iint = ima_iint_find_insert_get(inode);
255 if (!iint) 259 if (!iint)
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index c570ebd9d177..4e34d19ddbc0 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -170,6 +170,13 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
170 struct snd_ac97_bus *ac97_bus; 170 struct snd_ac97_bus *ac97_bus;
171 struct snd_ac97_template ac97_template; 171 struct snd_ac97_template ac97_template;
172 int ret; 172 int ret;
173 pxa2xx_audio_ops_t *pdata = dev->dev.platform_data;
174
175 if (dev->id >= 0) {
176 dev_err(&dev->dev, "PXA2xx has only one AC97 port.\n");
177 ret = -ENXIO;
178 goto err_dev;
179 }
173 180
174 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 181 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
175 THIS_MODULE, 0, &card); 182 THIS_MODULE, 0, &card);
@@ -200,6 +207,8 @@ static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
200 snprintf(card->longname, sizeof(card->longname), 207 snprintf(card->longname, sizeof(card->longname),
201 "%s (%s)", dev->dev.driver->name, card->mixername); 208 "%s (%s)", dev->dev.driver->name, card->mixername);
202 209
210 if (pdata && pdata->codec_pdata[0])
211 snd_ac97_dev_add_pdata(ac97_bus->codec[0], pdata->codec_pdata[0]);
203 snd_card_set_dev(card, &dev->dev); 212 snd_card_set_dev(card, &dev->dev);
204 ret = snd_card_register(card); 213 ret = snd_card_register(card);
205 if (ret == 0) { 214 if (ret == 0) {
@@ -212,6 +221,7 @@ err_remove:
212err: 221err:
213 if (card) 222 if (card)
214 snd_card_free(card); 223 snd_card_free(card);
224err_dev:
215 return ret; 225 return ret;
216} 226}
217 227
diff --git a/sound/arm/pxa2xx-pcm-lib.c b/sound/arm/pxa2xx-pcm-lib.c
index 6205f37d547c..743ac6a29065 100644
--- a/sound/arm/pxa2xx-pcm-lib.c
+++ b/sound/arm/pxa2xx-pcm-lib.c
@@ -136,6 +136,9 @@ int __pxa2xx_pcm_prepare(struct snd_pcm_substream *substream)
136{ 136{
137 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data; 137 struct pxa2xx_runtime_data *prtd = substream->runtime->private_data;
138 138
139 if (!prtd || !prtd->params)
140 return 0;
141
139 DCSR(prtd->dma_ch) &= ~DCSR_RUN; 142 DCSR(prtd->dma_ch) &= ~DCSR_RUN;
140 DCSR(prtd->dma_ch) = 0; 143 DCSR(prtd->dma_ch) = 0;
141 DCMD(prtd->dma_ch) = 0; 144 DCMD(prtd->dma_ch) = 0;
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 6061fb5f4e1c..c15682a2f9db 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -206,4 +206,8 @@ config SND_PCM_XRUN_DEBUG
206config SND_VMASTER 206config SND_VMASTER
207 bool 207 bool
208 208
209config SND_DMA_SGBUF
210 def_bool y
211 depends on X86
212
209source "sound/core/seq/Kconfig" 213source "sound/core/seq/Kconfig"
diff --git a/sound/core/Makefile b/sound/core/Makefile
index 4229052e7b91..350a08d277f4 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -13,7 +13,7 @@ snd-pcm-objs := pcm.o pcm_native.o pcm_lib.o pcm_timer.o pcm_misc.o \
13 pcm_memory.o 13 pcm_memory.o
14 14
15snd-page-alloc-y := memalloc.o 15snd-page-alloc-y := memalloc.o
16snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o 16snd-page-alloc-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
17 17
18snd-rawmidi-objs := rawmidi.o 18snd-rawmidi-objs := rawmidi.o
19snd-timer-objs := timer.o 19snd-timer-objs := timer.o
diff --git a/sound/core/control.c b/sound/core/control.c
index 17b8d47a5cd0..a8b7fabe645e 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -414,7 +414,7 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
414EXPORT_SYMBOL(snd_ctl_remove_id); 414EXPORT_SYMBOL(snd_ctl_remove_id);
415 415
416/** 416/**
417 * snd_ctl_remove_unlocked_id - remove the unlocked control of the given id and release it 417 * snd_ctl_remove_user_ctl - remove and release the unlocked user control
418 * @file: active control handle 418 * @file: active control handle
419 * @id: the control id to remove 419 * @id: the control id to remove
420 * 420 *
@@ -423,8 +423,8 @@ EXPORT_SYMBOL(snd_ctl_remove_id);
423 * 423 *
424 * Returns 0 if successful, or a negative error code on failure. 424 * Returns 0 if successful, or a negative error code on failure.
425 */ 425 */
426static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file, 426static int snd_ctl_remove_user_ctl(struct snd_ctl_file * file,
427 struct snd_ctl_elem_id *id) 427 struct snd_ctl_elem_id *id)
428{ 428{
429 struct snd_card *card = file->card; 429 struct snd_card *card = file->card;
430 struct snd_kcontrol *kctl; 430 struct snd_kcontrol *kctl;
@@ -433,15 +433,23 @@ static int snd_ctl_remove_unlocked_id(struct snd_ctl_file * file,
433 down_write(&card->controls_rwsem); 433 down_write(&card->controls_rwsem);
434 kctl = snd_ctl_find_id(card, id); 434 kctl = snd_ctl_find_id(card, id);
435 if (kctl == NULL) { 435 if (kctl == NULL) {
436 up_write(&card->controls_rwsem); 436 ret = -ENOENT;
437 return -ENOENT; 437 goto error;
438 }
439 if (!(kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_USER)) {
440 ret = -EINVAL;
441 goto error;
438 } 442 }
439 for (idx = 0; idx < kctl->count; idx++) 443 for (idx = 0; idx < kctl->count; idx++)
440 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) { 444 if (kctl->vd[idx].owner != NULL && kctl->vd[idx].owner != file) {
441 up_write(&card->controls_rwsem); 445 ret = -EBUSY;
442 return -EBUSY; 446 goto error;
443 } 447 }
444 ret = snd_ctl_remove(card, kctl); 448 ret = snd_ctl_remove(card, kctl);
449 if (ret < 0)
450 goto error;
451 card->user_ctl_count--;
452error:
445 up_write(&card->controls_rwsem); 453 up_write(&card->controls_rwsem);
446 return ret; 454 return ret;
447} 455}
@@ -951,7 +959,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
951 959
952 if (card->user_ctl_count >= MAX_USER_CONTROLS) 960 if (card->user_ctl_count >= MAX_USER_CONTROLS)
953 return -ENOMEM; 961 return -ENOMEM;
954 if (info->count > 1024) 962 if (info->count < 1)
955 return -EINVAL; 963 return -EINVAL;
956 access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE : 964 access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
957 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE| 965 (info->access & (SNDRV_CTL_ELEM_ACCESS_READWRITE|
@@ -1052,18 +1060,10 @@ static int snd_ctl_elem_remove(struct snd_ctl_file *file,
1052 struct snd_ctl_elem_id __user *_id) 1060 struct snd_ctl_elem_id __user *_id)
1053{ 1061{
1054 struct snd_ctl_elem_id id; 1062 struct snd_ctl_elem_id id;
1055 int err;
1056 1063
1057 if (copy_from_user(&id, _id, sizeof(id))) 1064 if (copy_from_user(&id, _id, sizeof(id)))
1058 return -EFAULT; 1065 return -EFAULT;
1059 err = snd_ctl_remove_unlocked_id(file, &id); 1066 return snd_ctl_remove_user_ctl(file, &id);
1060 if (! err) {
1061 struct snd_card *card = file->card;
1062 down_write(&card->controls_rwsem);
1063 card->user_ctl_count--;
1064 up_write(&card->controls_rwsem);
1065 }
1066 return err;
1067} 1067}
1068 1068
1069static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr) 1069static int snd_ctl_subscribe_events(struct snd_ctl_file *file, int __user *ptr)
diff --git a/sound/core/info.c b/sound/core/info.c
index 35df614f6c55..d749a0d394a7 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -88,12 +88,10 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
88 char *nbuf; 88 char *nbuf;
89 89
90 nsize = PAGE_ALIGN(nsize); 90 nsize = PAGE_ALIGN(nsize);
91 nbuf = kmalloc(nsize, GFP_KERNEL); 91 nbuf = krealloc(buffer->buffer, nsize, GFP_KERNEL);
92 if (! nbuf) 92 if (! nbuf)
93 return -ENOMEM; 93 return -ENOMEM;
94 94
95 memcpy(nbuf, buffer->buffer, buffer->len);
96 kfree(buffer->buffer);
97 buffer->buffer = nbuf; 95 buffer->buffer = nbuf;
98 buffer->len = nsize; 96 buffer->len = nsize;
99 return 0; 97 return 0;
@@ -108,7 +106,7 @@ static int resize_info_buffer(struct snd_info_buffer *buffer,
108 * 106 *
109 * Returns the size of output string. 107 * Returns the size of output string.
110 */ 108 */
111int snd_iprintf(struct snd_info_buffer *buffer, char *fmt,...) 109int snd_iprintf(struct snd_info_buffer *buffer, const char *fmt, ...)
112{ 110{
113 va_list args; 111 va_list args;
114 int len, res; 112 int len, res;
@@ -727,7 +725,7 @@ EXPORT_SYMBOL(snd_info_get_line);
727 * Returns the updated pointer of the original string so that 725 * Returns the updated pointer of the original string so that
728 * it can be used for the next call. 726 * it can be used for the next call.
729 */ 727 */
730char *snd_info_get_str(char *dest, char *src, int len) 728const char *snd_info_get_str(char *dest, const char *src, int len)
731{ 729{
732 int c; 730 int c;
733 731
diff --git a/sound/core/init.c b/sound/core/init.c
index d5d40d78c409..ec4a50ce5656 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -31,6 +31,14 @@
31#include <sound/control.h> 31#include <sound/control.h>
32#include <sound/info.h> 32#include <sound/info.h>
33 33
34/* monitor files for graceful shutdown (hotplug) */
35struct snd_monitor_file {
36 struct file *file;
37 const struct file_operations *disconnected_f_op;
38 struct list_head shutdown_list; /* still need to shutdown */
39 struct list_head list; /* link of monitor files */
40};
41
34static DEFINE_SPINLOCK(shutdown_lock); 42static DEFINE_SPINLOCK(shutdown_lock);
35static LIST_HEAD(shutdown_files); 43static LIST_HEAD(shutdown_files);
36 44
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 1b3534d67686..9e92441f9b78 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -199,6 +199,8 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
199 case SNDRV_DMA_TYPE_DEV: 199 case SNDRV_DMA_TYPE_DEV:
200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr); 200 dmab->area = snd_malloc_dev_pages(device, size, &dmab->addr);
201 break; 201 break;
202#endif
203#ifdef CONFIG_SND_DMA_SGBUF
202 case SNDRV_DMA_TYPE_DEV_SG: 204 case SNDRV_DMA_TYPE_DEV_SG:
203 snd_malloc_sgbuf_pages(device, size, dmab, NULL); 205 snd_malloc_sgbuf_pages(device, size, dmab, NULL);
204 break; 206 break;
@@ -269,6 +271,8 @@ void snd_dma_free_pages(struct snd_dma_buffer *dmab)
269 case SNDRV_DMA_TYPE_DEV: 271 case SNDRV_DMA_TYPE_DEV:
270 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 272 snd_free_dev_pages(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
271 break; 273 break;
274#endif
275#ifdef CONFIG_SND_DMA_SGBUF
272 case SNDRV_DMA_TYPE_DEV_SG: 276 case SNDRV_DMA_TYPE_DEV_SG:
273 snd_free_sgbuf_pages(dmab); 277 snd_free_sgbuf_pages(dmab);
274 break; 278 break;
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index 5dcd8a526970..772423889eb3 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -1154,7 +1154,8 @@ static void snd_mixer_oss_proc_write(struct snd_info_entry *entry,
1154 struct snd_info_buffer *buffer) 1154 struct snd_info_buffer *buffer)
1155{ 1155{
1156 struct snd_mixer_oss *mixer = entry->private_data; 1156 struct snd_mixer_oss *mixer = entry->private_data;
1157 char line[128], str[32], idxstr[16], *cptr; 1157 char line[128], str[32], idxstr[16];
1158 const char *cptr;
1158 int ch, idx; 1159 int ch, idx;
1159 struct snd_mixer_oss_assign_table *tbl; 1160 struct snd_mixer_oss_assign_table *tbl;
1160 struct slot *slot; 1161 struct slot *slot;
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index dbe406b82591..d9c96353121a 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1043,10 +1043,15 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream)
1043 runtime->oss.channels = params_channels(params); 1043 runtime->oss.channels = params_channels(params);
1044 runtime->oss.rate = params_rate(params); 1044 runtime->oss.rate = params_rate(params);
1045 1045
1046 runtime->oss.params = 0;
1047 runtime->oss.prepare = 1;
1048 vfree(runtime->oss.buffer); 1046 vfree(runtime->oss.buffer);
1049 runtime->oss.buffer = vmalloc(runtime->oss.period_bytes); 1047 runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
1048 if (!runtime->oss.buffer) {
1049 err = -ENOMEM;
1050 goto failure;
1051 }
1052
1053 runtime->oss.params = 0;
1054 runtime->oss.prepare = 1;
1050 runtime->oss.buffer_used = 0; 1055 runtime->oss.buffer_used = 0;
1051 if (runtime->dma_area) 1056 if (runtime->dma_area)
1052 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes)); 1057 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
@@ -2836,7 +2841,8 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2836 struct snd_info_buffer *buffer) 2841 struct snd_info_buffer *buffer)
2837{ 2842{
2838 struct snd_pcm_str *pstr = entry->private_data; 2843 struct snd_pcm_str *pstr = entry->private_data;
2839 char line[128], str[32], task_name[32], *ptr; 2844 char line[128], str[32], task_name[32];
2845 const char *ptr;
2840 int idx1; 2846 int idx1;
2841 struct snd_pcm_oss_setup *setup, *setup1, template; 2847 struct snd_pcm_oss_setup *setup, *setup1, template;
2842 2848
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 145931a9ff30..0c1440121c22 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -162,18 +162,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
162 return -ENOIOCTLCMD; 162 return -ENOIOCTLCMD;
163} 163}
164 164
165#ifdef CONFIG_SND_VERBOSE_PROCFS
166
167#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
168#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
169#define READY(v) [SNDRV_PCM_READY_##v] = #v
170#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
171#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
172#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
173#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
174#define START(v) [SNDRV_PCM_START_##v] = #v
175#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v 165#define FORMAT(v) [SNDRV_PCM_FORMAT_##v] = #v
176#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
177 166
178static char *snd_pcm_format_names[] = { 167static char *snd_pcm_format_names[] = {
179 FORMAT(S8), 168 FORMAT(S8),
@@ -216,10 +205,23 @@ static char *snd_pcm_format_names[] = {
216 FORMAT(U18_3BE), 205 FORMAT(U18_3BE),
217}; 206};
218 207
219static const char *snd_pcm_format_name(snd_pcm_format_t format) 208const char *snd_pcm_format_name(snd_pcm_format_t format)
220{ 209{
221 return snd_pcm_format_names[format]; 210 return snd_pcm_format_names[format];
222} 211}
212EXPORT_SYMBOL_GPL(snd_pcm_format_name);
213
214#ifdef CONFIG_SND_VERBOSE_PROCFS
215
216#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
217#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
218#define READY(v) [SNDRV_PCM_READY_##v] = #v
219#define XRUN(v) [SNDRV_PCM_XRUN_##v] = #v
220#define SILENCE(v) [SNDRV_PCM_SILENCE_##v] = #v
221#define TSTAMP(v) [SNDRV_PCM_TSTAMP_##v] = #v
222#define ACCESS(v) [SNDRV_PCM_ACCESS_##v] = #v
223#define START(v) [SNDRV_PCM_START_##v] = #v
224#define SUBFORMAT(v) [SNDRV_PCM_SUBFORMAT_##v] = #v
223 225
224static char *snd_pcm_stream_names[] = { 226static char *snd_pcm_stream_names[] = {
225 STREAM(PLAYBACK), 227 STREAM(PLAYBACK),
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index a6d42808828c..caa7796bc2f5 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -304,6 +304,7 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
304 304
305EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all); 305EXPORT_SYMBOL(snd_pcm_lib_preallocate_pages_for_all);
306 306
307#ifdef CONFIG_SND_DMA_SGBUF
307/** 308/**
308 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset 309 * snd_pcm_sgbuf_ops_page - get the page struct at the given offset
309 * @substream: the pcm substream instance 310 * @substream: the pcm substream instance
@@ -349,6 +350,7 @@ unsigned int snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
349 return size; 350 return size;
350} 351}
351EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size); 352EXPORT_SYMBOL(snd_pcm_sgbuf_get_chunk_size);
353#endif /* CONFIG_SND_DMA_SGBUF */
352 354
353/** 355/**
354 * snd_pcm_lib_malloc_pages - allocate the DMA buffer 356 * snd_pcm_lib_malloc_pages - allocate the DMA buffer
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 473247c8e6d3..c0adc14c91f0 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -274,7 +274,7 @@ static int open_substream(struct snd_rawmidi *rmidi,
274 return err; 274 return err;
275 substream->opened = 1; 275 substream->opened = 1;
276 if (substream->use_count++ == 0) 276 if (substream->use_count++ == 0)
277 substream->active_sensing = 1; 277 substream->active_sensing = 0;
278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
279 substream->append = 1; 279 substream->append = 1;
280 rmidi->streams[substream->stream].substream_opened++; 280 rmidi->streams[substream->stream].substream_opened++;
diff --git a/sound/core/seq/oss/seq_oss_midi.c b/sound/core/seq/oss/seq_oss_midi.c
index 0a711d2d04f0..9dfb2f77be60 100644
--- a/sound/core/seq/oss/seq_oss_midi.c
+++ b/sound/core/seq/oss/seq_oss_midi.c
@@ -20,6 +20,7 @@
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23#include <sound/asoundef.h>
23#include "seq_oss_midi.h" 24#include "seq_oss_midi.h"
24#include "seq_oss_readq.h" 25#include "seq_oss_readq.h"
25#include "seq_oss_timer.h" 26#include "seq_oss_timer.h"
@@ -476,19 +477,20 @@ snd_seq_oss_midi_reset(struct seq_oss_devinfo *dp, int dev)
476 ev.source.port = dp->port; 477 ev.source.port = dp->port;
477 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) { 478 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_SYNTH) {
478 ev.type = SNDRV_SEQ_EVENT_SENSING; 479 ev.type = SNDRV_SEQ_EVENT_SENSING;
479 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* active sensing */ 480 snd_seq_oss_dispatch(dp, &ev, 0, 0);
480 } 481 }
481 for (c = 0; c < 16; c++) { 482 for (c = 0; c < 16; c++) {
482 ev.type = SNDRV_SEQ_EVENT_CONTROLLER; 483 ev.type = SNDRV_SEQ_EVENT_CONTROLLER;
483 ev.data.control.channel = c; 484 ev.data.control.channel = c;
484 ev.data.control.param = 123; 485 ev.data.control.param = MIDI_CTL_ALL_NOTES_OFF;
485 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* all notes off */ 486 snd_seq_oss_dispatch(dp, &ev, 0, 0);
486 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) { 487 if (dp->seq_mode == SNDRV_SEQ_OSS_MODE_MUSIC) {
487 ev.data.control.param = 121; 488 ev.data.control.param =
488 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* reset all controllers */ 489 MIDI_CTL_RESET_CONTROLLERS;
490 snd_seq_oss_dispatch(dp, &ev, 0, 0);
489 ev.type = SNDRV_SEQ_EVENT_PITCHBEND; 491 ev.type = SNDRV_SEQ_EVENT_PITCHBEND;
490 ev.data.control.value = 0; 492 ev.data.control.value = 0;
491 snd_seq_oss_dispatch(dp, &ev, 0, 0); /* bender off */ 493 snd_seq_oss_dispatch(dp, &ev, 0, 0);
492 } 494 }
493 } 495 }
494 } 496 }
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c
index 4d26146a62cc..ebaf1b541dcd 100644
--- a/sound/core/seq/seq_midi.c
+++ b/sound/core/seq/seq_midi.c
@@ -120,7 +120,8 @@ static int dump_midi(struct snd_rawmidi_substream *substream, const char *buf, i
120 return -EINVAL; 120 return -EINVAL;
121 runtime = substream->runtime; 121 runtime = substream->runtime;
122 if ((tmp = runtime->avail) < count) { 122 if ((tmp = runtime->avail) < count) {
123 snd_printd("warning, output event was lost (count = %i, available = %i)\n", count, tmp); 123 if (printk_ratelimit())
124 snd_printk(KERN_ERR "MIDI output buffer overrun\n");
124 return -ENOMEM; 125 return -ENOMEM;
125 } 126 }
126 if (snd_rawmidi_kernel_write(substream, buf, count) < count) 127 if (snd_rawmidi_kernel_write(substream, buf, count) < count)
@@ -236,6 +237,7 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
236 memset(&params, 0, sizeof(params)); 237 memset(&params, 0, sizeof(params));
237 params.avail_min = 1; 238 params.avail_min = 1;
238 params.buffer_size = output_buffer_size; 239 params.buffer_size = output_buffer_size;
240 params.no_active_sensing = 1;
239 if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) { 241 if ((err = snd_rawmidi_output_params(msynth->output_rfile.output, &params)) < 0) {
240 snd_rawmidi_kernel_release(&msynth->output_rfile); 242 snd_rawmidi_kernel_release(&msynth->output_rfile);
241 return err; 243 return err;
@@ -248,12 +250,9 @@ static int midisynth_use(void *private_data, struct snd_seq_port_subscribe *info
248static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info) 250static int midisynth_unuse(void *private_data, struct snd_seq_port_subscribe *info)
249{ 251{
250 struct seq_midisynth *msynth = private_data; 252 struct seq_midisynth *msynth = private_data;
251 unsigned char buf = 0xff; /* MIDI reset */
252 253
253 if (snd_BUG_ON(!msynth->output_rfile.output)) 254 if (snd_BUG_ON(!msynth->output_rfile.output))
254 return -EINVAL; 255 return -EINVAL;
255 /* sending single MIDI reset message to shut the device up */
256 snd_rawmidi_kernel_write(msynth->output_rfile.output, &buf, 1);
257 snd_rawmidi_drain_output(msynth->output_rfile.output); 256 snd_rawmidi_drain_output(msynth->output_rfile.output);
258 return snd_rawmidi_kernel_release(&msynth->output_rfile); 257 return snd_rawmidi_kernel_release(&msynth->output_rfile);
259} 258}
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 54239d2e0997..6ba066c41d2e 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -25,12 +25,15 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/wait.h> 27#include <linux/wait.h>
28#include <linux/hrtimer.h>
29#include <linux/math64.h>
28#include <linux/moduleparam.h> 30#include <linux/moduleparam.h>
29#include <sound/core.h> 31#include <sound/core.h>
30#include <sound/control.h> 32#include <sound/control.h>
31#include <sound/tlv.h> 33#include <sound/tlv.h>
32#include <sound/pcm.h> 34#include <sound/pcm.h>
33#include <sound/rawmidi.h> 35#include <sound/rawmidi.h>
36#include <sound/info.h>
34#include <sound/initval.h> 37#include <sound/initval.h>
35 38
36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 39MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -39,7 +42,7 @@ MODULE_LICENSE("GPL");
39MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}"); 42MODULE_SUPPORTED_DEVICE("{{ALSA,Dummy soundcard}}");
40 43
41#define MAX_PCM_DEVICES 4 44#define MAX_PCM_DEVICES 4
42#define MAX_PCM_SUBSTREAMS 16 45#define MAX_PCM_SUBSTREAMS 128
43#define MAX_MIDI_DEVICES 2 46#define MAX_MIDI_DEVICES 2
44 47
45#if 0 /* emu10k1 emulation */ 48#if 0 /* emu10k1 emulation */
@@ -148,6 +151,10 @@ static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 0};
148static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 151static int pcm_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
149static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8}; 152static int pcm_substreams[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 8};
150//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2}; 153//static int midi_devs[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 2};
154#ifdef CONFIG_HIGH_RES_TIMERS
155static int hrtimer = 1;
156#endif
157static int fake_buffer = 1;
151 158
152module_param_array(index, int, NULL, 0444); 159module_param_array(index, int, NULL, 0444);
153MODULE_PARM_DESC(index, "Index value for dummy soundcard."); 160MODULE_PARM_DESC(index, "Index value for dummy soundcard.");
@@ -161,6 +168,12 @@ module_param_array(pcm_substreams, int, NULL, 0444);
161MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver."); 168MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver.");
162//module_param_array(midi_devs, int, NULL, 0444); 169//module_param_array(midi_devs, int, NULL, 0444);
163//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver."); 170//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
171module_param(fake_buffer, bool, 0444);
172MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
173#ifdef CONFIG_HIGH_RES_TIMERS
174module_param(hrtimer, bool, 0644);
175MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
176#endif
164 177
165static struct platform_device *devices[SNDRV_CARDS]; 178static struct platform_device *devices[SNDRV_CARDS];
166 179
@@ -171,137 +184,324 @@ static struct platform_device *devices[SNDRV_CARDS];
171#define MIXER_ADDR_CD 4 184#define MIXER_ADDR_CD 4
172#define MIXER_ADDR_LAST 4 185#define MIXER_ADDR_LAST 4
173 186
187struct dummy_timer_ops {
188 int (*create)(struct snd_pcm_substream *);
189 void (*free)(struct snd_pcm_substream *);
190 int (*prepare)(struct snd_pcm_substream *);
191 int (*start)(struct snd_pcm_substream *);
192 int (*stop)(struct snd_pcm_substream *);
193 snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
194};
195
174struct snd_dummy { 196struct snd_dummy {
175 struct snd_card *card; 197 struct snd_card *card;
176 struct snd_pcm *pcm; 198 struct snd_pcm *pcm;
177 spinlock_t mixer_lock; 199 spinlock_t mixer_lock;
178 int mixer_volume[MIXER_ADDR_LAST+1][2]; 200 int mixer_volume[MIXER_ADDR_LAST+1][2];
179 int capture_source[MIXER_ADDR_LAST+1][2]; 201 int capture_source[MIXER_ADDR_LAST+1][2];
202 const struct dummy_timer_ops *timer_ops;
180}; 203};
181 204
182struct snd_dummy_pcm { 205/*
183 struct snd_dummy *dummy; 206 * system timer interface
207 */
208
209struct dummy_systimer_pcm {
184 spinlock_t lock; 210 spinlock_t lock;
185 struct timer_list timer; 211 struct timer_list timer;
186 unsigned int pcm_buffer_size; 212 unsigned long base_time;
187 unsigned int pcm_period_size; 213 unsigned int frac_pos; /* fractional sample position (based HZ) */
188 unsigned int pcm_bps; /* bytes per second */ 214 unsigned int frac_period_rest;
189 unsigned int pcm_hz; /* HZ */ 215 unsigned int frac_buffer_size; /* buffer_size * HZ */
190 unsigned int pcm_irq_pos; /* IRQ position */ 216 unsigned int frac_period_size; /* period_size * HZ */
191 unsigned int pcm_buf_pos; /* position in buffer */ 217 unsigned int rate;
218 int elapsed;
192 struct snd_pcm_substream *substream; 219 struct snd_pcm_substream *substream;
193}; 220};
194 221
195 222static void dummy_systimer_rearm(struct dummy_systimer_pcm *dpcm)
196static inline void snd_card_dummy_pcm_timer_start(struct snd_dummy_pcm *dpcm)
197{ 223{
198 dpcm->timer.expires = 1 + jiffies; 224 dpcm->timer.expires = jiffies +
225 (dpcm->frac_period_rest + dpcm->rate - 1) / dpcm->rate;
199 add_timer(&dpcm->timer); 226 add_timer(&dpcm->timer);
200} 227}
201 228
202static inline void snd_card_dummy_pcm_timer_stop(struct snd_dummy_pcm *dpcm) 229static void dummy_systimer_update(struct dummy_systimer_pcm *dpcm)
203{ 230{
204 del_timer(&dpcm->timer); 231 unsigned long delta;
232
233 delta = jiffies - dpcm->base_time;
234 if (!delta)
235 return;
236 dpcm->base_time += delta;
237 delta *= dpcm->rate;
238 dpcm->frac_pos += delta;
239 while (dpcm->frac_pos >= dpcm->frac_buffer_size)
240 dpcm->frac_pos -= dpcm->frac_buffer_size;
241 while (dpcm->frac_period_rest <= delta) {
242 dpcm->elapsed++;
243 dpcm->frac_period_rest += dpcm->frac_period_size;
244 }
245 dpcm->frac_period_rest -= delta;
205} 246}
206 247
207static int snd_card_dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 248static int dummy_systimer_start(struct snd_pcm_substream *substream)
208{ 249{
209 struct snd_pcm_runtime *runtime = substream->runtime; 250 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
210 struct snd_dummy_pcm *dpcm = runtime->private_data; 251 spin_lock(&dpcm->lock);
211 int err = 0; 252 dpcm->base_time = jiffies;
253 dummy_systimer_rearm(dpcm);
254 spin_unlock(&dpcm->lock);
255 return 0;
256}
212 257
258static int dummy_systimer_stop(struct snd_pcm_substream *substream)
259{
260 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
213 spin_lock(&dpcm->lock); 261 spin_lock(&dpcm->lock);
214 switch (cmd) { 262 del_timer(&dpcm->timer);
215 case SNDRV_PCM_TRIGGER_START:
216 case SNDRV_PCM_TRIGGER_RESUME:
217 snd_card_dummy_pcm_timer_start(dpcm);
218 break;
219 case SNDRV_PCM_TRIGGER_STOP:
220 case SNDRV_PCM_TRIGGER_SUSPEND:
221 snd_card_dummy_pcm_timer_stop(dpcm);
222 break;
223 default:
224 err = -EINVAL;
225 break;
226 }
227 spin_unlock(&dpcm->lock); 263 spin_unlock(&dpcm->lock);
228 return 0; 264 return 0;
229} 265}
230 266
231static int snd_card_dummy_pcm_prepare(struct snd_pcm_substream *substream) 267static int dummy_systimer_prepare(struct snd_pcm_substream *substream)
232{ 268{
233 struct snd_pcm_runtime *runtime = substream->runtime; 269 struct snd_pcm_runtime *runtime = substream->runtime;
234 struct snd_dummy_pcm *dpcm = runtime->private_data; 270 struct dummy_systimer_pcm *dpcm = runtime->private_data;
235 int bps;
236
237 bps = snd_pcm_format_width(runtime->format) * runtime->rate *
238 runtime->channels / 8;
239
240 if (bps <= 0)
241 return -EINVAL;
242
243 dpcm->pcm_bps = bps;
244 dpcm->pcm_hz = HZ;
245 dpcm->pcm_buffer_size = snd_pcm_lib_buffer_bytes(substream);
246 dpcm->pcm_period_size = snd_pcm_lib_period_bytes(substream);
247 dpcm->pcm_irq_pos = 0;
248 dpcm->pcm_buf_pos = 0;
249 271
250 snd_pcm_format_set_silence(runtime->format, runtime->dma_area, 272 dpcm->frac_pos = 0;
251 bytes_to_samples(runtime, runtime->dma_bytes)); 273 dpcm->rate = runtime->rate;
274 dpcm->frac_buffer_size = runtime->buffer_size * HZ;
275 dpcm->frac_period_size = runtime->period_size * HZ;
276 dpcm->frac_period_rest = dpcm->frac_period_size;
277 dpcm->elapsed = 0;
252 278
253 return 0; 279 return 0;
254} 280}
255 281
256static void snd_card_dummy_pcm_timer_function(unsigned long data) 282static void dummy_systimer_callback(unsigned long data)
257{ 283{
258 struct snd_dummy_pcm *dpcm = (struct snd_dummy_pcm *)data; 284 struct dummy_systimer_pcm *dpcm = (struct dummy_systimer_pcm *)data;
259 unsigned long flags; 285 unsigned long flags;
286 int elapsed = 0;
260 287
261 spin_lock_irqsave(&dpcm->lock, flags); 288 spin_lock_irqsave(&dpcm->lock, flags);
262 dpcm->timer.expires = 1 + jiffies; 289 dummy_systimer_update(dpcm);
263 add_timer(&dpcm->timer); 290 dummy_systimer_rearm(dpcm);
264 dpcm->pcm_irq_pos += dpcm->pcm_bps; 291 elapsed = dpcm->elapsed;
265 dpcm->pcm_buf_pos += dpcm->pcm_bps; 292 dpcm->elapsed = 0;
266 dpcm->pcm_buf_pos %= dpcm->pcm_buffer_size * dpcm->pcm_hz; 293 spin_unlock_irqrestore(&dpcm->lock, flags);
267 if (dpcm->pcm_irq_pos >= dpcm->pcm_period_size * dpcm->pcm_hz) { 294 if (elapsed)
268 dpcm->pcm_irq_pos %= dpcm->pcm_period_size * dpcm->pcm_hz; 295 snd_pcm_period_elapsed(dpcm->substream);
269 spin_unlock_irqrestore(&dpcm->lock, flags); 296}
297
298static snd_pcm_uframes_t
299dummy_systimer_pointer(struct snd_pcm_substream *substream)
300{
301 struct dummy_systimer_pcm *dpcm = substream->runtime->private_data;
302 snd_pcm_uframes_t pos;
303
304 spin_lock(&dpcm->lock);
305 dummy_systimer_update(dpcm);
306 pos = dpcm->frac_pos / HZ;
307 spin_unlock(&dpcm->lock);
308 return pos;
309}
310
311static int dummy_systimer_create(struct snd_pcm_substream *substream)
312{
313 struct dummy_systimer_pcm *dpcm;
314
315 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
316 if (!dpcm)
317 return -ENOMEM;
318 substream->runtime->private_data = dpcm;
319 init_timer(&dpcm->timer);
320 dpcm->timer.data = (unsigned long) dpcm;
321 dpcm->timer.function = dummy_systimer_callback;
322 spin_lock_init(&dpcm->lock);
323 dpcm->substream = substream;
324 return 0;
325}
326
327static void dummy_systimer_free(struct snd_pcm_substream *substream)
328{
329 kfree(substream->runtime->private_data);
330}
331
332static struct dummy_timer_ops dummy_systimer_ops = {
333 .create = dummy_systimer_create,
334 .free = dummy_systimer_free,
335 .prepare = dummy_systimer_prepare,
336 .start = dummy_systimer_start,
337 .stop = dummy_systimer_stop,
338 .pointer = dummy_systimer_pointer,
339};
340
341#ifdef CONFIG_HIGH_RES_TIMERS
342/*
343 * hrtimer interface
344 */
345
346struct dummy_hrtimer_pcm {
347 ktime_t base_time;
348 ktime_t period_time;
349 atomic_t running;
350 struct hrtimer timer;
351 struct tasklet_struct tasklet;
352 struct snd_pcm_substream *substream;
353};
354
355static void dummy_hrtimer_pcm_elapsed(unsigned long priv)
356{
357 struct dummy_hrtimer_pcm *dpcm = (struct dummy_hrtimer_pcm *)priv;
358 if (atomic_read(&dpcm->running))
270 snd_pcm_period_elapsed(dpcm->substream); 359 snd_pcm_period_elapsed(dpcm->substream);
271 } else
272 spin_unlock_irqrestore(&dpcm->lock, flags);
273} 360}
274 361
275static snd_pcm_uframes_t snd_card_dummy_pcm_pointer(struct snd_pcm_substream *substream) 362static enum hrtimer_restart dummy_hrtimer_callback(struct hrtimer *timer)
363{
364 struct dummy_hrtimer_pcm *dpcm;
365
366 dpcm = container_of(timer, struct dummy_hrtimer_pcm, timer);
367 if (!atomic_read(&dpcm->running))
368 return HRTIMER_NORESTART;
369 tasklet_schedule(&dpcm->tasklet);
370 hrtimer_forward_now(timer, dpcm->period_time);
371 return HRTIMER_RESTART;
372}
373
374static int dummy_hrtimer_start(struct snd_pcm_substream *substream)
375{
376 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
377
378 dpcm->base_time = hrtimer_cb_get_time(&dpcm->timer);
379 hrtimer_start(&dpcm->timer, dpcm->period_time, HRTIMER_MODE_REL);
380 atomic_set(&dpcm->running, 1);
381 return 0;
382}
383
384static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)
385{
386 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
387
388 atomic_set(&dpcm->running, 0);
389 hrtimer_cancel(&dpcm->timer);
390 return 0;
391}
392
393static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
394{
395 tasklet_kill(&dpcm->tasklet);
396}
397
398static snd_pcm_uframes_t
399dummy_hrtimer_pointer(struct snd_pcm_substream *substream)
276{ 400{
277 struct snd_pcm_runtime *runtime = substream->runtime; 401 struct snd_pcm_runtime *runtime = substream->runtime;
278 struct snd_dummy_pcm *dpcm = runtime->private_data; 402 struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
403 u64 delta;
404 u32 pos;
405
406 delta = ktime_us_delta(hrtimer_cb_get_time(&dpcm->timer),
407 dpcm->base_time);
408 delta = div_u64(delta * runtime->rate + 999999, 1000000);
409 div_u64_rem(delta, runtime->buffer_size, &pos);
410 return pos;
411}
279 412
280 return bytes_to_frames(runtime, dpcm->pcm_buf_pos / dpcm->pcm_hz); 413static int dummy_hrtimer_prepare(struct snd_pcm_substream *substream)
414{
415 struct snd_pcm_runtime *runtime = substream->runtime;
416 struct dummy_hrtimer_pcm *dpcm = runtime->private_data;
417 unsigned int period, rate;
418 long sec;
419 unsigned long nsecs;
420
421 dummy_hrtimer_sync(dpcm);
422 period = runtime->period_size;
423 rate = runtime->rate;
424 sec = period / rate;
425 period %= rate;
426 nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate);
427 dpcm->period_time = ktime_set(sec, nsecs);
428
429 return 0;
281} 430}
282 431
283static struct snd_pcm_hardware snd_card_dummy_playback = 432static int dummy_hrtimer_create(struct snd_pcm_substream *substream)
284{ 433{
285 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 434 struct dummy_hrtimer_pcm *dpcm;
286 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), 435
287 .formats = USE_FORMATS, 436 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
288 .rates = USE_RATE, 437 if (!dpcm)
289 .rate_min = USE_RATE_MIN, 438 return -ENOMEM;
290 .rate_max = USE_RATE_MAX, 439 substream->runtime->private_data = dpcm;
291 .channels_min = USE_CHANNELS_MIN, 440 hrtimer_init(&dpcm->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
292 .channels_max = USE_CHANNELS_MAX, 441 dpcm->timer.function = dummy_hrtimer_callback;
293 .buffer_bytes_max = MAX_BUFFER_SIZE, 442 dpcm->substream = substream;
294 .period_bytes_min = 64, 443 atomic_set(&dpcm->running, 0);
295 .period_bytes_max = MAX_PERIOD_SIZE, 444 tasklet_init(&dpcm->tasklet, dummy_hrtimer_pcm_elapsed,
296 .periods_min = USE_PERIODS_MIN, 445 (unsigned long)dpcm);
297 .periods_max = USE_PERIODS_MAX, 446 return 0;
298 .fifo_size = 0, 447}
448
449static void dummy_hrtimer_free(struct snd_pcm_substream *substream)
450{
451 struct dummy_hrtimer_pcm *dpcm = substream->runtime->private_data;
452 dummy_hrtimer_sync(dpcm);
453 kfree(dpcm);
454}
455
456static struct dummy_timer_ops dummy_hrtimer_ops = {
457 .create = dummy_hrtimer_create,
458 .free = dummy_hrtimer_free,
459 .prepare = dummy_hrtimer_prepare,
460 .start = dummy_hrtimer_start,
461 .stop = dummy_hrtimer_stop,
462 .pointer = dummy_hrtimer_pointer,
299}; 463};
300 464
301static struct snd_pcm_hardware snd_card_dummy_capture = 465#endif /* CONFIG_HIGH_RES_TIMERS */
466
467/*
468 * PCM interface
469 */
470
471static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
302{ 472{
303 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 473 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
304 SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID), 474
475 switch (cmd) {
476 case SNDRV_PCM_TRIGGER_START:
477 case SNDRV_PCM_TRIGGER_RESUME:
478 return dummy->timer_ops->start(substream);
479 case SNDRV_PCM_TRIGGER_STOP:
480 case SNDRV_PCM_TRIGGER_SUSPEND:
481 return dummy->timer_ops->stop(substream);
482 }
483 return -EINVAL;
484}
485
486static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
487{
488 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
489
490 return dummy->timer_ops->prepare(substream);
491}
492
493static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
494{
495 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
496
497 return dummy->timer_ops->pointer(substream);
498}
499
500static struct snd_pcm_hardware dummy_pcm_hardware = {
501 .info = (SNDRV_PCM_INFO_MMAP |
502 SNDRV_PCM_INFO_INTERLEAVED |
503 SNDRV_PCM_INFO_RESUME |
504 SNDRV_PCM_INFO_MMAP_VALID),
305 .formats = USE_FORMATS, 505 .formats = USE_FORMATS,
306 .rates = USE_RATE, 506 .rates = USE_RATE,
307 .rate_min = USE_RATE_MIN, 507 .rate_min = USE_RATE_MIN,
@@ -316,123 +516,152 @@ static struct snd_pcm_hardware snd_card_dummy_capture =
316 .fifo_size = 0, 516 .fifo_size = 0,
317}; 517};
318 518
319static void snd_card_dummy_runtime_free(struct snd_pcm_runtime *runtime) 519static int dummy_pcm_hw_params(struct snd_pcm_substream *substream,
320{ 520 struct snd_pcm_hw_params *hw_params)
321 kfree(runtime->private_data);
322}
323
324static int snd_card_dummy_hw_params(struct snd_pcm_substream *substream,
325 struct snd_pcm_hw_params *hw_params)
326{ 521{
327 return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); 522 if (fake_buffer) {
523 /* runtime->dma_bytes has to be set manually to allow mmap */
524 substream->runtime->dma_bytes = params_buffer_bytes(hw_params);
525 return 0;
526 }
527 return snd_pcm_lib_malloc_pages(substream,
528 params_buffer_bytes(hw_params));
328} 529}
329 530
330static int snd_card_dummy_hw_free(struct snd_pcm_substream *substream) 531static int dummy_pcm_hw_free(struct snd_pcm_substream *substream)
331{ 532{
533 if (fake_buffer)
534 return 0;
332 return snd_pcm_lib_free_pages(substream); 535 return snd_pcm_lib_free_pages(substream);
333} 536}
334 537
335static struct snd_dummy_pcm *new_pcm_stream(struct snd_pcm_substream *substream) 538static int dummy_pcm_open(struct snd_pcm_substream *substream)
336{
337 struct snd_dummy_pcm *dpcm;
338
339 dpcm = kzalloc(sizeof(*dpcm), GFP_KERNEL);
340 if (! dpcm)
341 return dpcm;
342 init_timer(&dpcm->timer);
343 dpcm->timer.data = (unsigned long) dpcm;
344 dpcm->timer.function = snd_card_dummy_pcm_timer_function;
345 spin_lock_init(&dpcm->lock);
346 dpcm->substream = substream;
347 return dpcm;
348}
349
350static int snd_card_dummy_playback_open(struct snd_pcm_substream *substream)
351{ 539{
540 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
352 struct snd_pcm_runtime *runtime = substream->runtime; 541 struct snd_pcm_runtime *runtime = substream->runtime;
353 struct snd_dummy_pcm *dpcm;
354 int err; 542 int err;
355 543
356 if ((dpcm = new_pcm_stream(substream)) == NULL) 544 dummy->timer_ops = &dummy_systimer_ops;
357 return -ENOMEM; 545#ifdef CONFIG_HIGH_RES_TIMERS
358 runtime->private_data = dpcm; 546 if (hrtimer)
359 /* makes the infrastructure responsible for freeing dpcm */ 547 dummy->timer_ops = &dummy_hrtimer_ops;
360 runtime->private_free = snd_card_dummy_runtime_free; 548#endif
361 runtime->hw = snd_card_dummy_playback; 549
550 err = dummy->timer_ops->create(substream);
551 if (err < 0)
552 return err;
553
554 runtime->hw = dummy_pcm_hardware;
362 if (substream->pcm->device & 1) { 555 if (substream->pcm->device & 1) {
363 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; 556 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
364 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; 557 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
365 } 558 }
366 if (substream->pcm->device & 2) 559 if (substream->pcm->device & 2)
367 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID); 560 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
368 err = add_playback_constraints(runtime); 561 SNDRV_PCM_INFO_MMAP_VALID);
369 if (err < 0) 562
563 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
564 err = add_playback_constraints(substream->runtime);
565 else
566 err = add_capture_constraints(substream->runtime);
567 if (err < 0) {
568 dummy->timer_ops->free(substream);
370 return err; 569 return err;
371 570 }
372 return 0; 571 return 0;
373} 572}
374 573
375static int snd_card_dummy_capture_open(struct snd_pcm_substream *substream) 574static int dummy_pcm_close(struct snd_pcm_substream *substream)
376{ 575{
377 struct snd_pcm_runtime *runtime = substream->runtime; 576 struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
378 struct snd_dummy_pcm *dpcm; 577 dummy->timer_ops->free(substream);
379 int err; 578 return 0;
579}
380 580
381 if ((dpcm = new_pcm_stream(substream)) == NULL) 581/*
382 return -ENOMEM; 582 * dummy buffer handling
383 runtime->private_data = dpcm; 583 */
384 /* makes the infrastructure responsible for freeing dpcm */ 584
385 runtime->private_free = snd_card_dummy_runtime_free; 585static void *dummy_page[2];
386 runtime->hw = snd_card_dummy_capture; 586
387 if (substream->pcm->device == 1) { 587static void free_fake_buffer(void)
388 runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED; 588{
389 runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED; 589 if (fake_buffer) {
590 int i;
591 for (i = 0; i < 2; i++)
592 if (dummy_page[i]) {
593 free_page((unsigned long)dummy_page[i]);
594 dummy_page[i] = NULL;
595 }
390 } 596 }
391 if (substream->pcm->device & 2) 597}
392 runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP|SNDRV_PCM_INFO_MMAP_VALID);
393 err = add_capture_constraints(runtime);
394 if (err < 0)
395 return err;
396 598
599static int alloc_fake_buffer(void)
600{
601 int i;
602
603 if (!fake_buffer)
604 return 0;
605 for (i = 0; i < 2; i++) {
606 dummy_page[i] = (void *)get_zeroed_page(GFP_KERNEL);
607 if (!dummy_page[i]) {
608 free_fake_buffer();
609 return -ENOMEM;
610 }
611 }
397 return 0; 612 return 0;
398} 613}
399 614
400static int snd_card_dummy_playback_close(struct snd_pcm_substream *substream) 615static int dummy_pcm_copy(struct snd_pcm_substream *substream,
616 int channel, snd_pcm_uframes_t pos,
617 void __user *dst, snd_pcm_uframes_t count)
401{ 618{
402 return 0; 619 return 0; /* do nothing */
403} 620}
404 621
405static int snd_card_dummy_capture_close(struct snd_pcm_substream *substream) 622static int dummy_pcm_silence(struct snd_pcm_substream *substream,
623 int channel, snd_pcm_uframes_t pos,
624 snd_pcm_uframes_t count)
406{ 625{
407 return 0; 626 return 0; /* do nothing */
627}
628
629static struct page *dummy_pcm_page(struct snd_pcm_substream *substream,
630 unsigned long offset)
631{
632 return virt_to_page(dummy_page[substream->stream]); /* the same page */
408} 633}
409 634
410static struct snd_pcm_ops snd_card_dummy_playback_ops = { 635static struct snd_pcm_ops dummy_pcm_ops = {
411 .open = snd_card_dummy_playback_open, 636 .open = dummy_pcm_open,
412 .close = snd_card_dummy_playback_close, 637 .close = dummy_pcm_close,
413 .ioctl = snd_pcm_lib_ioctl, 638 .ioctl = snd_pcm_lib_ioctl,
414 .hw_params = snd_card_dummy_hw_params, 639 .hw_params = dummy_pcm_hw_params,
415 .hw_free = snd_card_dummy_hw_free, 640 .hw_free = dummy_pcm_hw_free,
416 .prepare = snd_card_dummy_pcm_prepare, 641 .prepare = dummy_pcm_prepare,
417 .trigger = snd_card_dummy_pcm_trigger, 642 .trigger = dummy_pcm_trigger,
418 .pointer = snd_card_dummy_pcm_pointer, 643 .pointer = dummy_pcm_pointer,
419}; 644};
420 645
421static struct snd_pcm_ops snd_card_dummy_capture_ops = { 646static struct snd_pcm_ops dummy_pcm_ops_no_buf = {
422 .open = snd_card_dummy_capture_open, 647 .open = dummy_pcm_open,
423 .close = snd_card_dummy_capture_close, 648 .close = dummy_pcm_close,
424 .ioctl = snd_pcm_lib_ioctl, 649 .ioctl = snd_pcm_lib_ioctl,
425 .hw_params = snd_card_dummy_hw_params, 650 .hw_params = dummy_pcm_hw_params,
426 .hw_free = snd_card_dummy_hw_free, 651 .hw_free = dummy_pcm_hw_free,
427 .prepare = snd_card_dummy_pcm_prepare, 652 .prepare = dummy_pcm_prepare,
428 .trigger = snd_card_dummy_pcm_trigger, 653 .trigger = dummy_pcm_trigger,
429 .pointer = snd_card_dummy_pcm_pointer, 654 .pointer = dummy_pcm_pointer,
655 .copy = dummy_pcm_copy,
656 .silence = dummy_pcm_silence,
657 .page = dummy_pcm_page,
430}; 658};
431 659
432static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device, 660static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
433 int substreams) 661 int substreams)
434{ 662{
435 struct snd_pcm *pcm; 663 struct snd_pcm *pcm;
664 struct snd_pcm_ops *ops;
436 int err; 665 int err;
437 666
438 err = snd_pcm_new(dummy->card, "Dummy PCM", device, 667 err = snd_pcm_new(dummy->card, "Dummy PCM", device,
@@ -440,17 +669,28 @@ static int __devinit snd_card_dummy_pcm(struct snd_dummy *dummy, int device,
440 if (err < 0) 669 if (err < 0)
441 return err; 670 return err;
442 dummy->pcm = pcm; 671 dummy->pcm = pcm;
443 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_dummy_playback_ops); 672 if (fake_buffer)
444 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_dummy_capture_ops); 673 ops = &dummy_pcm_ops_no_buf;
674 else
675 ops = &dummy_pcm_ops;
676 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, ops);
677 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, ops);
445 pcm->private_data = dummy; 678 pcm->private_data = dummy;
446 pcm->info_flags = 0; 679 pcm->info_flags = 0;
447 strcpy(pcm->name, "Dummy PCM"); 680 strcpy(pcm->name, "Dummy PCM");
448 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, 681 if (!fake_buffer) {
449 snd_dma_continuous_data(GFP_KERNEL), 682 snd_pcm_lib_preallocate_pages_for_all(pcm,
450 0, 64*1024); 683 SNDRV_DMA_TYPE_CONTINUOUS,
684 snd_dma_continuous_data(GFP_KERNEL),
685 0, 64*1024);
686 }
451 return 0; 687 return 0;
452} 688}
453 689
690/*
691 * mixer interface
692 */
693
454#define DUMMY_VOLUME(xname, xindex, addr) \ 694#define DUMMY_VOLUME(xname, xindex, addr) \
455{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 695{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
456 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \ 696 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
@@ -581,6 +821,131 @@ static int __devinit snd_card_dummy_new_mixer(struct snd_dummy *dummy)
581 return 0; 821 return 0;
582} 822}
583 823
824#if defined(CONFIG_SND_DEBUG) && defined(CONFIG_PROC_FS)
825/*
826 * proc interface
827 */
828static void print_formats(struct snd_info_buffer *buffer)
829{
830 int i;
831
832 for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
833 if (dummy_pcm_hardware.formats & (1ULL << i))
834 snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
835 }
836}
837
838static void print_rates(struct snd_info_buffer *buffer)
839{
840 static int rates[] = {
841 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
842 64000, 88200, 96000, 176400, 192000,
843 };
844 int i;
845
846 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_CONTINUOUS)
847 snd_iprintf(buffer, " continuous");
848 if (dummy_pcm_hardware.rates & SNDRV_PCM_RATE_KNOT)
849 snd_iprintf(buffer, " knot");
850 for (i = 0; i < ARRAY_SIZE(rates); i++)
851 if (dummy_pcm_hardware.rates & (1 << i))
852 snd_iprintf(buffer, " %d", rates[i]);
853}
854
855#define get_dummy_int_ptr(ofs) \
856 (unsigned int *)((char *)&dummy_pcm_hardware + (ofs))
857#define get_dummy_ll_ptr(ofs) \
858 (unsigned long long *)((char *)&dummy_pcm_hardware + (ofs))
859
860struct dummy_hw_field {
861 const char *name;
862 const char *format;
863 unsigned int offset;
864 unsigned int size;
865};
866#define FIELD_ENTRY(item, fmt) { \
867 .name = #item, \
868 .format = fmt, \
869 .offset = offsetof(struct snd_pcm_hardware, item), \
870 .size = sizeof(dummy_pcm_hardware.item) }
871
872static struct dummy_hw_field fields[] = {
873 FIELD_ENTRY(formats, "%#llx"),
874 FIELD_ENTRY(rates, "%#x"),
875 FIELD_ENTRY(rate_min, "%d"),
876 FIELD_ENTRY(rate_max, "%d"),
877 FIELD_ENTRY(channels_min, "%d"),
878 FIELD_ENTRY(channels_max, "%d"),
879 FIELD_ENTRY(buffer_bytes_max, "%ld"),
880 FIELD_ENTRY(period_bytes_min, "%ld"),
881 FIELD_ENTRY(period_bytes_max, "%ld"),
882 FIELD_ENTRY(periods_min, "%d"),
883 FIELD_ENTRY(periods_max, "%d"),
884};
885
886static void dummy_proc_read(struct snd_info_entry *entry,
887 struct snd_info_buffer *buffer)
888{
889 int i;
890
891 for (i = 0; i < ARRAY_SIZE(fields); i++) {
892 snd_iprintf(buffer, "%s ", fields[i].name);
893 if (fields[i].size == sizeof(int))
894 snd_iprintf(buffer, fields[i].format,
895 *get_dummy_int_ptr(fields[i].offset));
896 else
897 snd_iprintf(buffer, fields[i].format,
898 *get_dummy_ll_ptr(fields[i].offset));
899 if (!strcmp(fields[i].name, "formats"))
900 print_formats(buffer);
901 else if (!strcmp(fields[i].name, "rates"))
902 print_rates(buffer);
903 snd_iprintf(buffer, "\n");
904 }
905}
906
907static void dummy_proc_write(struct snd_info_entry *entry,
908 struct snd_info_buffer *buffer)
909{
910 char line[64];
911
912 while (!snd_info_get_line(buffer, line, sizeof(line))) {
913 char item[20];
914 const char *ptr;
915 unsigned long long val;
916 int i;
917
918 ptr = snd_info_get_str(item, line, sizeof(item));
919 for (i = 0; i < ARRAY_SIZE(fields); i++) {
920 if (!strcmp(item, fields[i].name))
921 break;
922 }
923 if (i >= ARRAY_SIZE(fields))
924 continue;
925 snd_info_get_str(item, ptr, sizeof(item));
926 if (strict_strtoull(item, 0, &val))
927 continue;
928 if (fields[i].size == sizeof(int))
929 *get_dummy_int_ptr(fields[i].offset) = val;
930 else
931 *get_dummy_ll_ptr(fields[i].offset) = val;
932 }
933}
934
935static void __devinit dummy_proc_init(struct snd_dummy *chip)
936{
937 struct snd_info_entry *entry;
938
939 if (!snd_card_proc_new(chip->card, "dummy_pcm", &entry)) {
940 snd_info_set_text_ops(entry, chip, dummy_proc_read);
941 entry->c.text.write = dummy_proc_write;
942 entry->mode |= S_IWUSR;
943 }
944}
945#else
946#define dummy_proc_init(x)
947#endif /* CONFIG_SND_DEBUG && CONFIG_PROC_FS */
948
584static int __devinit snd_dummy_probe(struct platform_device *devptr) 949static int __devinit snd_dummy_probe(struct platform_device *devptr)
585{ 950{
586 struct snd_card *card; 951 struct snd_card *card;
@@ -610,6 +975,8 @@ static int __devinit snd_dummy_probe(struct platform_device *devptr)
610 strcpy(card->shortname, "Dummy"); 975 strcpy(card->shortname, "Dummy");
611 sprintf(card->longname, "Dummy %i", dev + 1); 976 sprintf(card->longname, "Dummy %i", dev + 1);
612 977
978 dummy_proc_init(dummy);
979
613 snd_card_set_dev(card, &devptr->dev); 980 snd_card_set_dev(card, &devptr->dev);
614 981
615 err = snd_card_register(card); 982 err = snd_card_register(card);
@@ -670,6 +1037,7 @@ static void snd_dummy_unregister_all(void)
670 for (i = 0; i < ARRAY_SIZE(devices); ++i) 1037 for (i = 0; i < ARRAY_SIZE(devices); ++i)
671 platform_device_unregister(devices[i]); 1038 platform_device_unregister(devices[i]);
672 platform_driver_unregister(&snd_dummy_driver); 1039 platform_driver_unregister(&snd_dummy_driver);
1040 free_fake_buffer();
673} 1041}
674 1042
675static int __init alsa_card_dummy_init(void) 1043static int __init alsa_card_dummy_init(void)
@@ -680,6 +1048,12 @@ static int __init alsa_card_dummy_init(void)
680 if (err < 0) 1048 if (err < 0)
681 return err; 1049 return err;
682 1050
1051 err = alloc_fake_buffer();
1052 if (err < 0) {
1053 platform_driver_unregister(&snd_dummy_driver);
1054 return err;
1055 }
1056
683 cards = 0; 1057 cards = 0;
684 for (i = 0; i < SNDRV_CARDS; i++) { 1058 for (i = 0; i < SNDRV_CARDS; i++) {
685 struct platform_device *device; 1059 struct platform_device *device;
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c
index 3ee0269e5bd0..02f79d252718 100644
--- a/sound/isa/cmi8330.c
+++ b/sound/isa/cmi8330.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Driver for C-Media's CMI8330 soundcards. 2 * Driver for C-Media's CMI8330 and CMI8329 soundcards.
3 * Copyright (c) by George Talusan <gstalusan@uwaterloo.ca> 3 * Copyright (c) by George Talusan <gstalusan@uwaterloo.ca>
4 * http://www.undergrad.math.uwaterloo.ca/~gstalusa 4 * http://www.undergrad.math.uwaterloo.ca/~gstalusa
5 * 5 *
@@ -35,7 +35,7 @@
35 * 35 *
36 * This card has two mixers and two PCM devices. I've cheesed it such 36 * This card has two mixers and two PCM devices. I've cheesed it such
37 * that recording and playback can be done through the same device. 37 * that recording and playback can be done through the same device.
38 * The driver "magically" routes the capturing to the CMI8330 codec, 38 * The driver "magically" routes the capturing to the AD1848 codec,
39 * and playback to the SB16 codec. This allows for full-duplex mode 39 * and playback to the SB16 codec. This allows for full-duplex mode
40 * to some extent. 40 * to some extent.
41 * The utilities in alsa-utils are aware of both devices, so passing 41 * The utilities in alsa-utils are aware of both devices, so passing
@@ -64,7 +64,7 @@
64/* 64/*
65 */ 65 */
66MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>"); 66MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
67MODULE_DESCRIPTION("C-Media CMI8330"); 67MODULE_DESCRIPTION("C-Media CMI8330/CMI8329");
68MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
69MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}"); 69MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8330,isapnp:{CMI0001,@@@0001,@X@0001}}}");
70 70
@@ -86,38 +86,38 @@ static long mpuport[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
86static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; 86static int mpuirq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
87 87
88module_param_array(index, int, NULL, 0444); 88module_param_array(index, int, NULL, 0444);
89MODULE_PARM_DESC(index, "Index value for CMI8330 soundcard."); 89MODULE_PARM_DESC(index, "Index value for CMI8330/CMI8329 soundcard.");
90module_param_array(id, charp, NULL, 0444); 90module_param_array(id, charp, NULL, 0444);
91MODULE_PARM_DESC(id, "ID string for CMI8330 soundcard."); 91MODULE_PARM_DESC(id, "ID string for CMI8330/CMI8329 soundcard.");
92module_param_array(enable, bool, NULL, 0444); 92module_param_array(enable, bool, NULL, 0444);
93MODULE_PARM_DESC(enable, "Enable CMI8330 soundcard."); 93MODULE_PARM_DESC(enable, "Enable CMI8330/CMI8329 soundcard.");
94#ifdef CONFIG_PNP 94#ifdef CONFIG_PNP
95module_param_array(isapnp, bool, NULL, 0444); 95module_param_array(isapnp, bool, NULL, 0444);
96MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard."); 96MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
97#endif 97#endif
98 98
99module_param_array(sbport, long, NULL, 0444); 99module_param_array(sbport, long, NULL, 0444);
100MODULE_PARM_DESC(sbport, "Port # for CMI8330 SB driver."); 100MODULE_PARM_DESC(sbport, "Port # for CMI8330/CMI8329 SB driver.");
101module_param_array(sbirq, int, NULL, 0444); 101module_param_array(sbirq, int, NULL, 0444);
102MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330 SB driver."); 102MODULE_PARM_DESC(sbirq, "IRQ # for CMI8330/CMI8329 SB driver.");
103module_param_array(sbdma8, int, NULL, 0444); 103module_param_array(sbdma8, int, NULL, 0444);
104MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330 SB driver."); 104MODULE_PARM_DESC(sbdma8, "DMA8 for CMI8330/CMI8329 SB driver.");
105module_param_array(sbdma16, int, NULL, 0444); 105module_param_array(sbdma16, int, NULL, 0444);
106MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330 SB driver."); 106MODULE_PARM_DESC(sbdma16, "DMA16 for CMI8330/CMI8329 SB driver.");
107 107
108module_param_array(wssport, long, NULL, 0444); 108module_param_array(wssport, long, NULL, 0444);
109MODULE_PARM_DESC(wssport, "Port # for CMI8330 WSS driver."); 109MODULE_PARM_DESC(wssport, "Port # for CMI8330/CMI8329 WSS driver.");
110module_param_array(wssirq, int, NULL, 0444); 110module_param_array(wssirq, int, NULL, 0444);
111MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330 WSS driver."); 111MODULE_PARM_DESC(wssirq, "IRQ # for CMI8330/CMI8329 WSS driver.");
112module_param_array(wssdma, int, NULL, 0444); 112module_param_array(wssdma, int, NULL, 0444);
113MODULE_PARM_DESC(wssdma, "DMA for CMI8330 WSS driver."); 113MODULE_PARM_DESC(wssdma, "DMA for CMI8330/CMI8329 WSS driver.");
114 114
115module_param_array(fmport, long, NULL, 0444); 115module_param_array(fmport, long, NULL, 0444);
116MODULE_PARM_DESC(fmport, "FM port # for CMI8330 driver."); 116MODULE_PARM_DESC(fmport, "FM port # for CMI8330/CMI8329 driver.");
117module_param_array(mpuport, long, NULL, 0444); 117module_param_array(mpuport, long, NULL, 0444);
118MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330 driver."); 118MODULE_PARM_DESC(mpuport, "MPU-401 port # for CMI8330/CMI8329 driver.");
119module_param_array(mpuirq, int, NULL, 0444); 119module_param_array(mpuirq, int, NULL, 0444);
120MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330 MPU-401 port."); 120MODULE_PARM_DESC(mpuirq, "IRQ # for CMI8330/CMI8329 MPU-401 port.");
121#ifdef CONFIG_PNP 121#ifdef CONFIG_PNP
122static int isa_registered; 122static int isa_registered;
123static int pnp_registered; 123static int pnp_registered;
@@ -156,6 +156,11 @@ static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
156 156
157typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *); 157typedef int (*snd_pcm_open_callback_t)(struct snd_pcm_substream *);
158 158
159enum card_type {
160 CMI8330,
161 CMI8329
162};
163
159struct snd_cmi8330 { 164struct snd_cmi8330 {
160#ifdef CONFIG_PNP 165#ifdef CONFIG_PNP
161 struct pnp_dev *cap; 166 struct pnp_dev *cap;
@@ -172,11 +177,14 @@ struct snd_cmi8330 {
172 snd_pcm_open_callback_t open; 177 snd_pcm_open_callback_t open;
173 void *private_data; /* sb or wss */ 178 void *private_data; /* sb or wss */
174 } streams[2]; 179 } streams[2];
180
181 enum card_type type;
175}; 182};
176 183
177#ifdef CONFIG_PNP 184#ifdef CONFIG_PNP
178 185
179static struct pnp_card_device_id snd_cmi8330_pnpids[] = { 186static struct pnp_card_device_id snd_cmi8330_pnpids[] = {
187 { .id = "CMI0001", .devs = { { "@X@0001" }, { "@@@0001" }, { "@H@0001" }, { "A@@0001" } } },
180 { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } }, 188 { .id = "CMI0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
181 { .id = "" } 189 { .id = "" }
182}; 190};
@@ -304,7 +312,7 @@ static int __devinit snd_cmi8330_mixer(struct snd_card *card, struct snd_cmi8330
304 unsigned int idx; 312 unsigned int idx;
305 int err; 313 int err;
306 314
307 strcpy(card->mixername, "CMI8330/C3D"); 315 strcpy(card->mixername, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
308 316
309 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) { 317 for (idx = 0; idx < ARRAY_SIZE(snd_cmi8330_controls); idx++) {
310 err = snd_ctl_add(card, 318 err = snd_ctl_add(card,
@@ -329,6 +337,9 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
329 struct pnp_dev *pdev; 337 struct pnp_dev *pdev;
330 int err; 338 int err;
331 339
340 /* CMI8329 has a device with ID A@@0001, CMI8330 does not */
341 acard->type = (id->devs[3].id[0]) ? CMI8329 : CMI8330;
342
332 acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL); 343 acard->cap = pnp_request_card_device(card, id->devs[0].id, NULL);
333 if (acard->cap == NULL) 344 if (acard->cap == NULL)
334 return -EBUSY; 345 return -EBUSY;
@@ -345,38 +356,45 @@ static int __devinit snd_cmi8330_pnp(int dev, struct snd_cmi8330 *acard,
345 356
346 err = pnp_activate_dev(pdev); 357 err = pnp_activate_dev(pdev);
347 if (err < 0) { 358 if (err < 0) {
348 snd_printk(KERN_ERR "CMI8330/C3D PnP configure failure\n"); 359 snd_printk(KERN_ERR "AD1848 PnP configure failure\n");
349 return -EBUSY; 360 return -EBUSY;
350 } 361 }
351 wssport[dev] = pnp_port_start(pdev, 0); 362 wssport[dev] = pnp_port_start(pdev, 0);
352 wssdma[dev] = pnp_dma(pdev, 0); 363 wssdma[dev] = pnp_dma(pdev, 0);
353 wssirq[dev] = pnp_irq(pdev, 0); 364 wssirq[dev] = pnp_irq(pdev, 0);
354 fmport[dev] = pnp_port_start(pdev, 1); 365 if (pnp_port_start(pdev, 1))
366 fmport[dev] = pnp_port_start(pdev, 1);
355 367
356 /* allocate SB16 resources */ 368 /* allocate SB16 resources */
357 pdev = acard->play; 369 pdev = acard->play;
358 370
359 err = pnp_activate_dev(pdev); 371 err = pnp_activate_dev(pdev);
360 if (err < 0) { 372 if (err < 0) {
361 snd_printk(KERN_ERR "CMI8330/C3D (SB16) PnP configure failure\n"); 373 snd_printk(KERN_ERR "SB16 PnP configure failure\n");
362 return -EBUSY; 374 return -EBUSY;
363 } 375 }
364 sbport[dev] = pnp_port_start(pdev, 0); 376 sbport[dev] = pnp_port_start(pdev, 0);
365 sbdma8[dev] = pnp_dma(pdev, 0); 377 sbdma8[dev] = pnp_dma(pdev, 0);
366 sbdma16[dev] = pnp_dma(pdev, 1); 378 sbdma16[dev] = pnp_dma(pdev, 1);
367 sbirq[dev] = pnp_irq(pdev, 0); 379 sbirq[dev] = pnp_irq(pdev, 0);
380 /* On CMI8239, the OPL3 port might be present in SB16 PnP resources */
381 if (fmport[dev] == SNDRV_AUTO_PORT) {
382 if (pnp_port_start(pdev, 1))
383 fmport[dev] = pnp_port_start(pdev, 1);
384 else
385 fmport[dev] = 0x388; /* Or hardwired */
386 }
368 387
369 /* allocate MPU-401 resources */ 388 /* allocate MPU-401 resources */
370 pdev = acard->mpu; 389 pdev = acard->mpu;
371 390
372 err = pnp_activate_dev(pdev); 391 err = pnp_activate_dev(pdev);
373 if (err < 0) { 392 if (err < 0)
374 snd_printk(KERN_ERR 393 snd_printk(KERN_ERR "MPU-401 PnP configure failure: will be disabled\n");
375 "CMI8330/C3D (MPU-401) PnP configure failure\n"); 394 else {
376 return -EBUSY; 395 mpuport[dev] = pnp_port_start(pdev, 0);
396 mpuirq[dev] = pnp_irq(pdev, 0);
377 } 397 }
378 mpuport[dev] = pnp_port_start(pdev, 0);
379 mpuirq[dev] = pnp_irq(pdev, 0);
380 return 0; 398 return 0;
381} 399}
382#endif 400#endif
@@ -430,9 +448,9 @@ static int __devinit snd_cmi8330_pcm(struct snd_card *card, struct snd_cmi8330 *
430 snd_cmi8330_capture_open 448 snd_cmi8330_capture_open
431 }; 449 };
432 450
433 if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0) 451 if ((err = snd_pcm_new(card, (chip->type == CMI8329) ? "CMI8329" : "CMI8330", 0, 1, 1, &pcm)) < 0)
434 return err; 452 return err;
435 strcpy(pcm->name, "CMI8330"); 453 strcpy(pcm->name, (chip->type == CMI8329) ? "CMI8329" : "CMI8330");
436 pcm->private_data = chip; 454 pcm->private_data = chip;
437 455
438 /* SB16 */ 456 /* SB16 */
@@ -527,11 +545,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
527 wssdma[dev], -1, 545 wssdma[dev], -1,
528 WSS_HW_DETECT, 0, &acard->wss); 546 WSS_HW_DETECT, 0, &acard->wss);
529 if (err < 0) { 547 if (err < 0) {
530 snd_printk(KERN_ERR PFX "(CMI8330) device busy??\n"); 548 snd_printk(KERN_ERR PFX "AD1848 device busy??\n");
531 return err; 549 return err;
532 } 550 }
533 if (acard->wss->hardware != WSS_HW_CMI8330) { 551 if (acard->wss->hardware != WSS_HW_CMI8330) {
534 snd_printk(KERN_ERR PFX "(CMI8330) not found during probe\n"); 552 snd_printk(KERN_ERR PFX "AD1848 not found during probe\n");
535 return -ENODEV; 553 return -ENODEV;
536 } 554 }
537 555
@@ -541,11 +559,11 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
541 sbdma8[dev], 559 sbdma8[dev],
542 sbdma16[dev], 560 sbdma16[dev],
543 SB_HW_AUTO, &acard->sb)) < 0) { 561 SB_HW_AUTO, &acard->sb)) < 0) {
544 snd_printk(KERN_ERR PFX "(SB16) device busy??\n"); 562 snd_printk(KERN_ERR PFX "SB16 device busy??\n");
545 return err; 563 return err;
546 } 564 }
547 if (acard->sb->hardware != SB_HW_16) { 565 if (acard->sb->hardware != SB_HW_16) {
548 snd_printk(KERN_ERR PFX "(SB16) not found during probe\n"); 566 snd_printk(KERN_ERR PFX "SB16 not found during probe\n");
549 return err; 567 return err;
550 } 568 }
551 569
@@ -585,8 +603,8 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev)
585 mpuport[dev]); 603 mpuport[dev]);
586 } 604 }
587 605
588 strcpy(card->driver, "CMI8330/C3D"); 606 strcpy(card->driver, (acard->type == CMI8329) ? "CMI8329" : "CMI8330/C3D");
589 strcpy(card->shortname, "C-Media CMI8330/C3D"); 607 strcpy(card->shortname, (acard->type == CMI8329) ? "C-Media CMI8329" : "C-Media CMI8330/C3D");
590 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", 608 sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
591 card->shortname, 609 card->shortname,
592 acard->wss->port, 610 acard->wss->port,
diff --git a/sound/oss/midibuf.c b/sound/oss/midibuf.c
index a40be0cf1d97..782b3b84dac6 100644
--- a/sound/oss/midibuf.c
+++ b/sound/oss/midibuf.c
@@ -127,15 +127,16 @@ static void midi_poll(unsigned long dummy)
127 for (dev = 0; dev < num_midis; dev++) 127 for (dev = 0; dev < num_midis; dev++)
128 if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL) 128 if (midi_devs[dev] != NULL && midi_out_buf[dev] != NULL)
129 { 129 {
130 int ok = 1; 130 while (DATA_AVAIL(midi_out_buf[dev]))
131
132 while (DATA_AVAIL(midi_out_buf[dev]) && ok)
133 { 131 {
132 int ok;
134 int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head]; 133 int c = midi_out_buf[dev]->queue[midi_out_buf[dev]->head];
135 134
136 spin_unlock_irqrestore(&lock,flags);/* Give some time to others */ 135 spin_unlock_irqrestore(&lock,flags);/* Give some time to others */
137 ok = midi_devs[dev]->outputc(dev, c); 136 ok = midi_devs[dev]->outputc(dev, c);
138 spin_lock_irqsave(&lock, flags); 137 spin_lock_irqsave(&lock, flags);
138 if (!ok)
139 break;
139 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE; 140 midi_out_buf[dev]->head = (midi_out_buf[dev]->head + 1) % MAX_QUEUE_SIZE;
140 midi_out_buf[dev]->len--; 141 midi_out_buf[dev]->len--;
141 } 142 }
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 187f72750e8f..6713110bdc75 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -628,7 +628,7 @@ static void li_setup_dma(dma_chan_t *chan,
628 ASSERT(!(buffer_paddr & 0xFF)); 628 ASSERT(!(buffer_paddr & 0xFF));
629 chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8); 629 chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8);
630 630
631 chan->cfgval = (!LI_CCFG_LOCK | 631 chan->cfgval = ((chan->cfgval & ~LI_CCFG_LOCK) |
632 SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) | 632 SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) |
633 desc->direction | 633 desc->direction |
634 mode | 634 mode |
@@ -638,9 +638,9 @@ static void li_setup_dma(dma_chan_t *chan,
638 tmask = 13 - fragshift; /* See Lithium DMA Notes above. */ 638 tmask = 13 - fragshift; /* See Lithium DMA Notes above. */
639 ASSERT(size >= 2 && size <= 7); 639 ASSERT(size >= 2 && size <= 7);
640 ASSERT(tmask >= 1 && tmask <= 7); 640 ASSERT(tmask >= 1 && tmask <= 7);
641 chan->ctlval = (!LI_CCTL_RESET | 641 chan->ctlval = ((chan->ctlval & ~LI_CCTL_RESET) |
642 SHIFT_FIELD(size, LI_CCTL_SIZE) | 642 SHIFT_FIELD(size, LI_CCTL_SIZE) |
643 !LI_CCTL_DMA_ENABLE | 643 (chan->ctlval & ~LI_CCTL_DMA_ENABLE) |
644 SHIFT_FIELD(tmask, LI_CCTL_TMASK) | 644 SHIFT_FIELD(tmask, LI_CCTL_TMASK) |
645 SHIFT_FIELD(0, LI_CCTL_TPTR)); 645 SHIFT_FIELD(0, LI_CCTL_TPTR));
646 646
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 748f6b7d90b7..fb5ee3cc3968 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -135,11 +135,11 @@ config SND_AW2
135 135
136 136
137config SND_AZT3328 137config SND_AZT3328
138 tristate "Aztech AZF3328 / PCI168 (EXPERIMENTAL)" 138 tristate "Aztech AZF3328 / PCI168"
139 depends on EXPERIMENTAL
140 select SND_OPL3_LIB 139 select SND_OPL3_LIB
141 select SND_MPU401_UART 140 select SND_MPU401_UART
142 select SND_PCM 141 select SND_PCM
142 select SND_RAWMIDI
143 help 143 help
144 Say Y here to include support for Aztech AZF3328 (PCI168) 144 Say Y here to include support for Aztech AZF3328 (PCI168)
145 soundcards. 145 soundcards.
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 76d76c08339b..b458d208720b 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -478,45 +478,6 @@ static int snd_ali_reset_5451(struct snd_ali *codec)
478 return 0; 478 return 0;
479} 479}
480 480
481#ifdef CODEC_RESET
482
483static int snd_ali_reset_codec(struct snd_ali *codec)
484{
485 struct pci_dev *pci_dev;
486 unsigned char bVal;
487 unsigned int dwVal;
488 unsigned short wCount, wReg;
489
490 pci_dev = codec->pci_m1533;
491
492 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
493 pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000);
494 udelay(5000);
495 pci_read_config_dword(pci_dev, 0x7c, &dwVal);
496 pci_write_config_dword(pci_dev, 0x7c, dwVal & 0xf7ffffff);
497 udelay(5000);
498
499 bVal = inb(ALI_REG(codec,ALI_SCTRL));
500 bVal |= 0x02;
501 outb(ALI_REG(codec,ALI_SCTRL),bVal);
502 udelay(5000);
503 bVal = inb(ALI_REG(codec,ALI_SCTRL));
504 bVal &= 0xfd;
505 outb(ALI_REG(codec,ALI_SCTRL),bVal);
506 udelay(15000);
507
508 wCount = 200;
509 while (wCount--) {
510 wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN);
511 if ((wReg & 0x000f) == 0x000f)
512 return 0;
513 udelay(5000);
514 }
515 return -1;
516}
517
518#endif
519
520/* 481/*
521 * ALI 5451 Controller 482 * ALI 5451 Controller
522 */ 483 */
@@ -561,22 +522,6 @@ static void snd_ali_disable_address_interrupt(struct snd_ali *codec)
561 outl(gc, ALI_REG(codec, ALI_GC_CIR)); 522 outl(gc, ALI_REG(codec, ALI_GC_CIR));
562} 523}
563 524
564#if 0 /* not used */
565static void snd_ali_enable_voice_irq(struct snd_ali *codec,
566 unsigned int channel)
567{
568 unsigned int mask;
569 struct snd_ali_channel_control *pchregs = &(codec->chregs);
570
571 snd_ali_printk("enable_voice_irq channel=%d\n",channel);
572
573 mask = 1 << (channel & 0x1f);
574 pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten));
575 pchregs->data.ainten |= mask;
576 outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten));
577}
578#endif
579
580static void snd_ali_disable_voice_irq(struct snd_ali *codec, 525static void snd_ali_disable_voice_irq(struct snd_ali *codec,
581 unsigned int channel) 526 unsigned int channel)
582{ 527{
@@ -677,16 +622,6 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel)
677 } 622 }
678} 623}
679 624
680#if 0 /* not used */
681static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel)
682{
683 unsigned int mask = 1 << (channel & 0x1f);
684
685 snd_ali_printk("start_voice: channel=%d\n",channel);
686 outl(mask, ALI_REG(codec,codec->chregs.regs.start));
687}
688#endif
689
690static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) 625static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel)
691{ 626{
692 unsigned int mask = 1 << (channel & 0x1f); 627 unsigned int mask = 1 << (channel & 0x1f);
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index f290bc56178f..8451a0169f32 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005 - 2008 by Andreas Mohr <andi AT lisas.de> 3 * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de>
4 * 4 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -10,6 +10,13 @@
10 * PCI168 A/AP, sub ID 8000 10 * PCI168 A/AP, sub ID 8000
11 * Please give me feedback in case you try my driver with one of these!! 11 * Please give me feedback in case you try my driver with one of these!!
12 * 12 *
13 * Keywords: Windows XP Vista 168nt4-125.zip 168win95-125.zip PCI 168 download
14 * (XP/Vista do not support this card at all but every Linux distribution
15 * has very good support out of the box;
16 * just to make sure that the right people hit this and get to know that,
17 * despite the high level of Internet ignorance - as usual :-P -
18 * about very good support for this card - on Linux!)
19 *
13 * GPL LICENSE 20 * GPL LICENSE
14 * This program is free software; you can redistribute it and/or modify 21 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 22 * it under the terms of the GNU General Public License as published by
@@ -71,10 +78,11 @@
71 * - built-in General DirectX timer having a 20 bits counter 78 * - built-in General DirectX timer having a 20 bits counter
72 * with 1us resolution (see below!) 79 * with 1us resolution (see below!)
73 * - I2S serial output port for external DAC 80 * - I2S serial output port for external DAC
81 * [FIXME: 3.3V or 5V level? maximum rate is 66.2kHz right?]
74 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI 82 * - supports 33MHz PCI spec 2.1, PCI power management 1.0, compliant with ACPI
75 * - supports hardware volume control 83 * - supports hardware volume control
76 * - single chip low cost solution (128 pin QFP) 84 * - single chip low cost solution (128 pin QFP)
77 * - supports programmable Sub-vendor and Sub-system ID 85 * - supports programmable Sub-vendor and Sub-system ID [24C02 SEEPROM chip]
78 * required for Microsoft's logo compliance (FIXME: where?) 86 * required for Microsoft's logo compliance (FIXME: where?)
79 * At least the Trident 4D Wave DX has one bit somewhere 87 * At least the Trident 4D Wave DX has one bit somewhere
80 * to enable writes to PCI subsystem VID registers, that should be it. 88 * to enable writes to PCI subsystem VID registers, that should be it.
@@ -82,6 +90,7 @@
82 * some custom data starting at 0x80. What kind of config settings 90 * some custom data starting at 0x80. What kind of config settings
83 * are located in our extended PCI space anyway?? 91 * are located in our extended PCI space anyway??
84 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms 92 * - PCI168 AP(W) card: power amplifier with 4 Watts/channel at 4 Ohms
93 * [TDA1517P chip]
85 * 94 *
86 * Note that this driver now is actually *better* than the Windows driver, 95 * Note that this driver now is actually *better* than the Windows driver,
87 * since it additionally supports the card's 1MHz DirectX timer - just try 96 * since it additionally supports the card's 1MHz DirectX timer - just try
@@ -146,10 +155,15 @@
146 * to read the Digital Enhanced Game Port. Not sure whether it is fixable. 155 * to read the Digital Enhanced Game Port. Not sure whether it is fixable.
147 * 156 *
148 * TODO 157 * TODO
158 * - use PCI_VDEVICE
159 * - verify driver status on x86_64
160 * - test multi-card driver operation
161 * - (ab)use 1MHz DirectX timer as kernel clocksource
149 * - test MPU401 MIDI playback etc. 162 * - test MPU401 MIDI playback etc.
150 * - add more power micro-management (disable various units of the card 163 * - add more power micro-management (disable various units of the card
151 * as long as they're unused). However this requires more I/O ports which I 164 * as long as they're unused, to improve audio quality and save power).
152 * haven't figured out yet and which thus might not even exist... 165 * However this requires more I/O ports which I haven't figured out yet
166 * and which thus might not even exist...
153 * The standard suspend/resume functionality could probably make use of 167 * The standard suspend/resume functionality could probably make use of
154 * some improvement, too... 168 * some improvement, too...
155 * - figure out what all unknown port bits are responsible for 169 * - figure out what all unknown port bits are responsible for
@@ -185,25 +199,46 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
185#define SUPPORT_GAMEPORT 1 199#define SUPPORT_GAMEPORT 1
186#endif 200#endif
187 201
202/* === Debug settings ===
203 Further diagnostic functionality than the settings below
204 does not need to be provided, since one can easily write a bash script
205 to dump the card's I/O ports (those listed in lspci -v -v):
206 function dump()
207 {
208 local descr=$1; local addr=$2; local count=$3
209
210 echo "${descr}: ${count} @ ${addr}:"
211 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C
212 }
213 and then use something like
214 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
215 "dump codec00 0xa800 32", "dump mixer 0xb800 64", "dump synth 0xbc00 8",
216 possibly within a "while true; do ... sleep 1; done" loop.
217 Tweaking ports could be done using
218 VALSTRING="`printf "%02x" $value`"
219 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null
220*/
221
188#define DEBUG_MISC 0 222#define DEBUG_MISC 0
189#define DEBUG_CALLS 0 223#define DEBUG_CALLS 0
190#define DEBUG_MIXER 0 224#define DEBUG_MIXER 0
191#define DEBUG_PLAY_REC 0 225#define DEBUG_CODEC 0
192#define DEBUG_IO 0 226#define DEBUG_IO 0
193#define DEBUG_TIMER 0 227#define DEBUG_TIMER 0
194#define DEBUG_GAME 0 228#define DEBUG_GAME 0
229#define DEBUG_PM 0
195#define MIXER_TESTING 0 230#define MIXER_TESTING 0
196 231
197#if DEBUG_MISC 232#if DEBUG_MISC
198#define snd_azf3328_dbgmisc(format, args...) printk(KERN_ERR format, ##args) 233#define snd_azf3328_dbgmisc(format, args...) printk(KERN_DEBUG format, ##args)
199#else 234#else
200#define snd_azf3328_dbgmisc(format, args...) 235#define snd_azf3328_dbgmisc(format, args...)
201#endif 236#endif
202 237
203#if DEBUG_CALLS 238#if DEBUG_CALLS
204#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args) 239#define snd_azf3328_dbgcalls(format, args...) printk(format, ##args)
205#define snd_azf3328_dbgcallenter() printk(KERN_ERR "--> %s\n", __func__) 240#define snd_azf3328_dbgcallenter() printk(KERN_DEBUG "--> %s\n", __func__)
206#define snd_azf3328_dbgcallleave() printk(KERN_ERR "<-- %s\n", __func__) 241#define snd_azf3328_dbgcallleave() printk(KERN_DEBUG "<-- %s\n", __func__)
207#else 242#else
208#define snd_azf3328_dbgcalls(format, args...) 243#define snd_azf3328_dbgcalls(format, args...)
209#define snd_azf3328_dbgcallenter() 244#define snd_azf3328_dbgcallenter()
@@ -216,10 +251,10 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
216#define snd_azf3328_dbgmixer(format, args...) 251#define snd_azf3328_dbgmixer(format, args...)
217#endif 252#endif
218 253
219#if DEBUG_PLAY_REC 254#if DEBUG_CODEC
220#define snd_azf3328_dbgplay(format, args...) printk(KERN_DEBUG format, ##args) 255#define snd_azf3328_dbgcodec(format, args...) printk(KERN_DEBUG format, ##args)
221#else 256#else
222#define snd_azf3328_dbgplay(format, args...) 257#define snd_azf3328_dbgcodec(format, args...)
223#endif 258#endif
224 259
225#if DEBUG_MISC 260#if DEBUG_MISC
@@ -234,6 +269,12 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
234#define snd_azf3328_dbggame(format, args...) 269#define snd_azf3328_dbggame(format, args...)
235#endif 270#endif
236 271
272#if DEBUG_PM
273#define snd_azf3328_dbgpm(format, args...) printk(KERN_DEBUG format, ##args)
274#else
275#define snd_azf3328_dbgpm(format, args...)
276#endif
277
237static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 278static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
238module_param_array(index, int, NULL, 0444); 279module_param_array(index, int, NULL, 0444);
239MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard."); 280MODULE_PARM_DESC(index, "Index value for AZF3328 soundcard.");
@@ -250,22 +291,23 @@ static int seqtimer_scaling = 128;
250module_param(seqtimer_scaling, int, 0444); 291module_param(seqtimer_scaling, int, 0444);
251MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 292MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
252 293
253struct snd_azf3328_audio_stream { 294struct snd_azf3328_codec_data {
295 unsigned long io_base;
254 struct snd_pcm_substream *substream; 296 struct snd_pcm_substream *substream;
255 int enabled; 297 bool running;
256 int running; 298 const char *name;
257 unsigned long portbase;
258}; 299};
259 300
260enum snd_azf3328_stream_index { 301enum snd_azf3328_codec_type {
261 AZF_PLAYBACK = 0, 302 AZF_CODEC_PLAYBACK = 0,
262 AZF_CAPTURE = 1, 303 AZF_CODEC_CAPTURE = 1,
304 AZF_CODEC_I2S_OUT = 2,
263}; 305};
264 306
265struct snd_azf3328 { 307struct snd_azf3328 {
266 /* often-used fields towards beginning, then grouped */ 308 /* often-used fields towards beginning, then grouped */
267 309
268 unsigned long codec_io; /* usually 0xb000, size 128 */ 310 unsigned long ctrl_io; /* usually 0xb000, size 128 */
269 unsigned long game_io; /* usually 0xb400, size 8 */ 311 unsigned long game_io; /* usually 0xb400, size 8 */
270 unsigned long mpu_io; /* usually 0xb800, size 4 */ 312 unsigned long mpu_io; /* usually 0xb800, size 4 */
271 unsigned long opl3_io; /* usually 0xbc00, size 8 */ 313 unsigned long opl3_io; /* usually 0xbc00, size 8 */
@@ -275,15 +317,17 @@ struct snd_azf3328 {
275 317
276 struct snd_timer *timer; 318 struct snd_timer *timer;
277 319
278 struct snd_pcm *pcm; 320 struct snd_pcm *pcm[3];
279 struct snd_azf3328_audio_stream audio_stream[2]; 321
322 /* playback, recording and I2S out codecs */
323 struct snd_azf3328_codec_data codecs[3];
280 324
281 struct snd_card *card; 325 struct snd_card *card;
282 struct snd_rawmidi *rmidi; 326 struct snd_rawmidi *rmidi;
283 327
284#ifdef SUPPORT_GAMEPORT 328#ifdef SUPPORT_GAMEPORT
285 struct gameport *gameport; 329 struct gameport *gameport;
286 int axes[4]; 330 u16 axes[4];
287#endif 331#endif
288 332
289 struct pci_dev *pci; 333 struct pci_dev *pci;
@@ -293,16 +337,16 @@ struct snd_azf3328 {
293 * If we need to add more registers here, then we might try to fold this 337 * If we need to add more registers here, then we might try to fold this
294 * into some transparent combined shadow register handling with 338 * into some transparent combined shadow register handling with
295 * CONFIG_PM register storage below, but that's slightly difficult. */ 339 * CONFIG_PM register storage below, but that's slightly difficult. */
296 u16 shadow_reg_codec_6AH; 340 u16 shadow_reg_ctrl_6AH;
297 341
298#ifdef CONFIG_PM 342#ifdef CONFIG_PM
299 /* register value containers for power management 343 /* register value containers for power management
300 * Note: not always full I/O range preserved (just like Win driver!) */ 344 * Note: not always full I/O range preserved (similar to Win driver!) */
301 u16 saved_regs_codec[AZF_IO_SIZE_CODEC_PM / 2]; 345 u32 saved_regs_ctrl[AZF_ALIGN(AZF_IO_SIZE_CTRL_PM) / 4];
302 u16 saved_regs_game [AZF_IO_SIZE_GAME_PM / 2]; 346 u32 saved_regs_game[AZF_ALIGN(AZF_IO_SIZE_GAME_PM) / 4];
303 u16 saved_regs_mpu [AZF_IO_SIZE_MPU_PM / 2]; 347 u32 saved_regs_mpu[AZF_ALIGN(AZF_IO_SIZE_MPU_PM) / 4];
304 u16 saved_regs_opl3 [AZF_IO_SIZE_OPL3_PM / 2]; 348 u32 saved_regs_opl3[AZF_ALIGN(AZF_IO_SIZE_OPL3_PM) / 4];
305 u16 saved_regs_mixer[AZF_IO_SIZE_MIXER_PM / 2]; 349 u32 saved_regs_mixer[AZF_ALIGN(AZF_IO_SIZE_MIXER_PM) / 4];
306#endif 350#endif
307}; 351};
308 352
@@ -316,7 +360,7 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
316 360
317 361
318static int 362static int
319snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set) 363snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
320{ 364{
321 u8 prev = inb(reg), new; 365 u8 prev = inb(reg), new;
322 366
@@ -331,39 +375,72 @@ snd_azf3328_io_reg_setb(unsigned reg, u8 mask, int do_set)
331} 375}
332 376
333static inline void 377static inline void
334snd_azf3328_codec_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value) 378snd_azf3328_codec_outb(const struct snd_azf3328_codec_data *codec,
379 unsigned reg,
380 u8 value
381)
335{ 382{
336 outb(value, chip->codec_io + reg); 383 outb(value, codec->io_base + reg);
337} 384}
338 385
339static inline u8 386static inline u8
340snd_azf3328_codec_inb(const struct snd_azf3328 *chip, unsigned reg) 387snd_azf3328_codec_inb(const struct snd_azf3328_codec_data *codec, unsigned reg)
341{ 388{
342 return inb(chip->codec_io + reg); 389 return inb(codec->io_base + reg);
343} 390}
344 391
345static inline void 392static inline void
346snd_azf3328_codec_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value) 393snd_azf3328_codec_outw(const struct snd_azf3328_codec_data *codec,
394 unsigned reg,
395 u16 value
396)
347{ 397{
348 outw(value, chip->codec_io + reg); 398 outw(value, codec->io_base + reg);
349} 399}
350 400
351static inline u16 401static inline u16
352snd_azf3328_codec_inw(const struct snd_azf3328 *chip, unsigned reg) 402snd_azf3328_codec_inw(const struct snd_azf3328_codec_data *codec, unsigned reg)
353{ 403{
354 return inw(chip->codec_io + reg); 404 return inw(codec->io_base + reg);
355} 405}
356 406
357static inline void 407static inline void
358snd_azf3328_codec_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value) 408snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
409 unsigned reg,
410 u32 value
411)
359{ 412{
360 outl(value, chip->codec_io + reg); 413 outl(value, codec->io_base + reg);
361} 414}
362 415
363static inline u32 416static inline u32
364snd_azf3328_codec_inl(const struct snd_azf3328 *chip, unsigned reg) 417snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
418{
419 return inl(codec->io_base + reg);
420}
421
422static inline void
423snd_azf3328_ctrl_outb(const struct snd_azf3328 *chip, unsigned reg, u8 value)
424{
425 outb(value, chip->ctrl_io + reg);
426}
427
428static inline u8
429snd_azf3328_ctrl_inb(const struct snd_azf3328 *chip, unsigned reg)
430{
431 return inb(chip->ctrl_io + reg);
432}
433
434static inline void
435snd_azf3328_ctrl_outw(const struct snd_azf3328 *chip, unsigned reg, u16 value)
436{
437 outw(value, chip->ctrl_io + reg);
438}
439
440static inline void
441snd_azf3328_ctrl_outl(const struct snd_azf3328 *chip, unsigned reg, u32 value)
365{ 442{
366 return inl(chip->codec_io + reg); 443 outl(value, chip->ctrl_io + reg);
367} 444}
368 445
369static inline void 446static inline void
@@ -404,13 +481,13 @@ snd_azf3328_mixer_inw(const struct snd_azf3328 *chip, unsigned reg)
404 481
405#define AZF_MUTE_BIT 0x80 482#define AZF_MUTE_BIT 0x80
406 483
407static int 484static bool
408snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip, 485snd_azf3328_mixer_set_mute(const struct snd_azf3328 *chip,
409 unsigned reg, int do_mute 486 unsigned reg, bool do_mute
410) 487)
411{ 488{
412 unsigned long portbase = chip->mixer_io + reg + 1; 489 unsigned long portbase = chip->mixer_io + reg + 1;
413 int updated; 490 bool updated;
414 491
415 /* the mute bit is on the *second* (i.e. right) register of a 492 /* the mute bit is on the *second* (i.e. right) register of a
416 * left/right channel setting */ 493 * left/right channel setting */
@@ -569,7 +646,7 @@ snd_azf3328_get_mixer(struct snd_kcontrol *kcontrol,
569{ 646{
570 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 647 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
571 struct azf3328_mixer_reg reg; 648 struct azf3328_mixer_reg reg;
572 unsigned int oreg, val; 649 u16 oreg, val;
573 650
574 snd_azf3328_dbgcallenter(); 651 snd_azf3328_dbgcallenter();
575 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 652 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -600,7 +677,7 @@ snd_azf3328_put_mixer(struct snd_kcontrol *kcontrol,
600{ 677{
601 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 678 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
602 struct azf3328_mixer_reg reg; 679 struct azf3328_mixer_reg reg;
603 unsigned int oreg, nreg, val; 680 u16 oreg, nreg, val;
604 681
605 snd_azf3328_dbgcallenter(); 682 snd_azf3328_dbgcallenter();
606 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 683 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
@@ -709,7 +786,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol,
709{ 786{
710 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol); 787 struct snd_azf3328 *chip = snd_kcontrol_chip(kcontrol);
711 struct azf3328_mixer_reg reg; 788 struct azf3328_mixer_reg reg;
712 unsigned int oreg, nreg, val; 789 u16 oreg, nreg, val;
713 790
714 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value); 791 snd_azf3328_mixer_reg_decode(&reg, kcontrol->private_value);
715 oreg = snd_azf3328_mixer_inw(chip, reg.reg); 792 oreg = snd_azf3328_mixer_inw(chip, reg.reg);
@@ -867,14 +944,15 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
867 944
868static void 945static void
869snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, 946snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
870 unsigned reg, 947 enum snd_azf3328_codec_type codec_type,
871 enum azf_freq_t bitrate, 948 enum azf_freq_t bitrate,
872 unsigned int format_width, 949 unsigned int format_width,
873 unsigned int channels 950 unsigned int channels
874) 951)
875{ 952{
876 u16 val = 0xff00;
877 unsigned long flags; 953 unsigned long flags;
954 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
955 u16 val = 0xff00;
878 956
879 snd_azf3328_dbgcallenter(); 957 snd_azf3328_dbgcallenter();
880 switch (bitrate) { 958 switch (bitrate) {
@@ -917,7 +995,7 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
917 spin_lock_irqsave(&chip->reg_lock, flags); 995 spin_lock_irqsave(&chip->reg_lock, flags);
918 996
919 /* set bitrate/format */ 997 /* set bitrate/format */
920 snd_azf3328_codec_outw(chip, reg, val); 998 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
921 999
922 /* changing the bitrate/format settings switches off the 1000 /* changing the bitrate/format settings switches off the
923 * audio output with an annoying click in case of 8/16bit format change 1001 * audio output with an annoying click in case of 8/16bit format change
@@ -926,11 +1004,11 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
926 * (FIXME: yes, it works, but what exactly am I doing here?? :) 1004 * (FIXME: yes, it works, but what exactly am I doing here?? :)
927 * FIXME: does this have some side effects for full-duplex 1005 * FIXME: does this have some side effects for full-duplex
928 * or other dramatic side effects? */ 1006 * or other dramatic side effects? */
929 if (reg == IDX_IO_PLAY_SOUNDFORMAT) /* only do it for playback */ 1007 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */
930 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1008 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
931 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | 1009 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
932 DMA_PLAY_SOMETHING1 | 1010 DMA_RUN_SOMETHING1 |
933 DMA_PLAY_SOMETHING2 | 1011 DMA_RUN_SOMETHING2 |
934 SOMETHING_ALMOST_ALWAYS_SET | 1012 SOMETHING_ALMOST_ALWAYS_SET |
935 DMA_EPILOGUE_SOMETHING | 1013 DMA_EPILOGUE_SOMETHING |
936 DMA_SOMETHING_ELSE 1014 DMA_SOMETHING_ELSE
@@ -942,112 +1020,134 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
942 1020
943static inline void 1021static inline void
944snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, 1022snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip,
945 unsigned reg 1023 enum snd_azf3328_codec_type codec_type
946) 1024)
947{ 1025{
948 /* choose lowest frequency for low power consumption. 1026 /* choose lowest frequency for low power consumption.
949 * While this will cause louder noise due to rather coarse frequency, 1027 * While this will cause louder noise due to rather coarse frequency,
950 * it should never matter since output should always 1028 * it should never matter since output should always
951 * get disabled properly when idle anyway. */ 1029 * get disabled properly when idle anyway. */
952 snd_azf3328_codec_setfmt(chip, reg, AZF_FREQ_4000, 8, 1); 1030 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1);
953} 1031}
954 1032
955static void 1033static void
956snd_azf3328_codec_reg_6AH_update(struct snd_azf3328 *chip, 1034snd_azf3328_ctrl_reg_6AH_update(struct snd_azf3328 *chip,
957 unsigned bitmask, 1035 unsigned bitmask,
958 int enable 1036 bool enable
959) 1037)
960{ 1038{
961 if (enable) 1039 bool do_mask = !enable;
962 chip->shadow_reg_codec_6AH &= ~bitmask; 1040 if (do_mask)
1041 chip->shadow_reg_ctrl_6AH |= bitmask;
963 else 1042 else
964 chip->shadow_reg_codec_6AH |= bitmask; 1043 chip->shadow_reg_ctrl_6AH &= ~bitmask;
965 snd_azf3328_dbgplay("6AH_update mask 0x%04x enable %d: val 0x%04x\n", 1044 snd_azf3328_dbgcodec("6AH_update mask 0x%04x do_mask %d: val 0x%04x\n",
966 bitmask, enable, chip->shadow_reg_codec_6AH); 1045 bitmask, do_mask, chip->shadow_reg_ctrl_6AH);
967 snd_azf3328_codec_outw(chip, IDX_IO_6AH, chip->shadow_reg_codec_6AH); 1046 snd_azf3328_ctrl_outw(chip, IDX_IO_6AH, chip->shadow_reg_ctrl_6AH);
968} 1047}
969 1048
970static inline void 1049static inline void
971snd_azf3328_codec_enable(struct snd_azf3328 *chip, int enable) 1050snd_azf3328_ctrl_enable_codecs(struct snd_azf3328 *chip, bool enable)
972{ 1051{
973 snd_azf3328_dbgplay("codec_enable %d\n", enable); 1052 snd_azf3328_dbgcodec("codec_enable %d\n", enable);
974 /* no idea what exactly is being done here, but I strongly assume it's 1053 /* no idea what exactly is being done here, but I strongly assume it's
975 * PM related */ 1054 * PM related */
976 snd_azf3328_codec_reg_6AH_update( 1055 snd_azf3328_ctrl_reg_6AH_update(
977 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable 1056 chip, IO_6A_PAUSE_PLAYBACK_BIT8, enable
978 ); 1057 );
979} 1058}
980 1059
981static void 1060static void
982snd_azf3328_codec_activity(struct snd_azf3328 *chip, 1061snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
983 enum snd_azf3328_stream_index stream_type, 1062 enum snd_azf3328_codec_type codec_type,
984 int enable 1063 bool enable
985) 1064)
986{ 1065{
987 int need_change = (chip->audio_stream[stream_type].running != enable); 1066 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1067 bool need_change = (codec->running != enable);
988 1068
989 snd_azf3328_dbgplay( 1069 snd_azf3328_dbgcodec(
990 "codec_activity: type %d, enable %d, need_change %d\n", 1070 "codec_activity: %s codec, enable %d, need_change %d\n",
991 stream_type, enable, need_change 1071 codec->name, enable, need_change
992 ); 1072 );
993 if (need_change) { 1073 if (need_change) {
994 enum snd_azf3328_stream_index other = 1074 static const struct {
995 (stream_type == AZF_PLAYBACK) ? 1075 enum snd_azf3328_codec_type other1;
996 AZF_CAPTURE : AZF_PLAYBACK; 1076 enum snd_azf3328_codec_type other2;
997 /* small check to prevent shutting down the other party 1077 } peer_codecs[3] =
998 * in case it's active */ 1078 { { AZF_CODEC_CAPTURE, AZF_CODEC_I2S_OUT },
999 if ((enable) || !(chip->audio_stream[other].running)) 1079 { AZF_CODEC_PLAYBACK, AZF_CODEC_I2S_OUT },
1000 snd_azf3328_codec_enable(chip, enable); 1080 { AZF_CODEC_PLAYBACK, AZF_CODEC_CAPTURE } };
1081 bool call_function;
1082
1083 if (enable)
1084 /* if enable codec, call enable_codecs func
1085 to enable codec supply... */
1086 call_function = 1;
1087 else {
1088 /* ...otherwise call enable_codecs func
1089 (which globally shuts down operation of codecs)
1090 only in case the other codecs are currently
1091 not active either! */
1092 call_function =
1093 ((!chip->codecs[peer_codecs[codec_type].other1]
1094 .running)
1095 && (!chip->codecs[peer_codecs[codec_type].other2]
1096 .running));
1097 }
1098 if (call_function)
1099 snd_azf3328_ctrl_enable_codecs(chip, enable);
1001 1100
1002 /* ...and adjust clock, too 1101 /* ...and adjust clock, too
1003 * (reduce noise and power consumption) */ 1102 * (reduce noise and power consumption) */
1004 if (!enable) 1103 if (!enable)
1005 snd_azf3328_codec_setfmt_lowpower( 1104 snd_azf3328_codec_setfmt_lowpower(
1006 chip, 1105 chip,
1007 chip->audio_stream[stream_type].portbase 1106 codec_type
1008 + IDX_IO_PLAY_SOUNDFORMAT
1009 ); 1107 );
1108 codec->running = enable;
1010 } 1109 }
1011 chip->audio_stream[stream_type].running = enable;
1012} 1110}
1013 1111
1014static void 1112static void
1015snd_azf3328_setdmaa(struct snd_azf3328 *chip, 1113snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip,
1016 long unsigned int addr, 1114 enum snd_azf3328_codec_type codec_type,
1017 unsigned int count, 1115 unsigned long addr,
1018 unsigned int size, 1116 unsigned int count,
1019 enum snd_azf3328_stream_index stream_type 1117 unsigned int size
1020) 1118)
1021{ 1119{
1120 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1022 snd_azf3328_dbgcallenter(); 1121 snd_azf3328_dbgcallenter();
1023 if (!chip->audio_stream[stream_type].running) { 1122 if (!codec->running) {
1024 /* AZF3328 uses a two buffer pointer DMA playback approach */ 1123 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1025 1124
1026 unsigned long flags, portbase, addr_area2; 1125 unsigned long flags, addr_area2;
1027 1126
1028 /* width 32bit (prevent overflow): */ 1127 /* width 32bit (prevent overflow): */
1029 unsigned long count_areas, count_tmp; 1128 u32 count_areas, lengths;
1030 1129
1031 portbase = chip->audio_stream[stream_type].portbase;
1032 count_areas = size/2; 1130 count_areas = size/2;
1033 addr_area2 = addr+count_areas; 1131 addr_area2 = addr+count_areas;
1034 count_areas--; /* max. index */ 1132 count_areas--; /* max. index */
1035 snd_azf3328_dbgplay("set DMA: buf1 %08lx[%lu], buf2 %08lx[%lu]\n", addr, count_areas, addr_area2, count_areas); 1133 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n",
1134 addr, count_areas, addr_area2, count_areas);
1036 1135
1037 /* build combined I/O buffer length word */ 1136 /* build combined I/O buffer length word */
1038 count_tmp = count_areas; 1137 lengths = (count_areas << 16) | (count_areas);
1039 count_areas |= (count_tmp << 16);
1040 spin_lock_irqsave(&chip->reg_lock, flags); 1138 spin_lock_irqsave(&chip->reg_lock, flags);
1041 outl(addr, portbase + IDX_IO_PLAY_DMA_START_1); 1139 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr);
1042 outl(addr_area2, portbase + IDX_IO_PLAY_DMA_START_2); 1140 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2,
1043 outl(count_areas, portbase + IDX_IO_PLAY_DMA_LEN_1); 1141 addr_area2);
1142 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS,
1143 lengths);
1044 spin_unlock_irqrestore(&chip->reg_lock, flags); 1144 spin_unlock_irqrestore(&chip->reg_lock, flags);
1045 } 1145 }
1046 snd_azf3328_dbgcallleave(); 1146 snd_azf3328_dbgcallleave();
1047} 1147}
1048 1148
1049static int 1149static int
1050snd_azf3328_playback_prepare(struct snd_pcm_substream *substream) 1150snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
1051{ 1151{
1052#if 0 1152#if 0
1053 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1153 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
@@ -1058,157 +1158,161 @@ snd_azf3328_playback_prepare(struct snd_pcm_substream *substream)
1058 1158
1059 snd_azf3328_dbgcallenter(); 1159 snd_azf3328_dbgcallenter();
1060#if 0 1160#if 0
1061 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1161 snd_azf3328_codec_setfmt(chip, AZF_CODEC_...,
1062 runtime->rate, 1162 runtime->rate,
1063 snd_pcm_format_width(runtime->format), 1163 snd_pcm_format_width(runtime->format),
1064 runtime->channels); 1164 runtime->channels);
1065 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_PLAYBACK); 1165 snd_azf3328_codec_setdmaa(chip, AZF_CODEC_...,
1166 runtime->dma_addr, count, size);
1066#endif 1167#endif
1067 snd_azf3328_dbgcallleave(); 1168 snd_azf3328_dbgcallleave();
1068 return 0; 1169 return 0;
1069} 1170}
1070 1171
1071static int 1172static int
1072snd_azf3328_capture_prepare(struct snd_pcm_substream *substream) 1173snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1073{ 1174 struct snd_pcm_substream *substream, int cmd)
1074#if 0
1075 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1076 struct snd_pcm_runtime *runtime = substream->runtime;
1077 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1078 unsigned int count = snd_pcm_lib_period_bytes(substream);
1079#endif
1080
1081 snd_azf3328_dbgcallenter();
1082#if 0
1083 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1084 runtime->rate,
1085 snd_pcm_format_width(runtime->format),
1086 runtime->channels);
1087 snd_azf3328_setdmaa(chip, runtime->dma_addr, count, size, AZF_CAPTURE);
1088#endif
1089 snd_azf3328_dbgcallleave();
1090 return 0;
1091}
1092
1093static int
1094snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1095{ 1175{
1096 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1176 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1177 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1097 struct snd_pcm_runtime *runtime = substream->runtime; 1178 struct snd_pcm_runtime *runtime = substream->runtime;
1098 int result = 0; 1179 int result = 0;
1099 unsigned int status1; 1180 u16 flags1;
1100 int previously_muted; 1181 bool previously_muted = 0;
1182 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type);
1101 1183
1102 snd_azf3328_dbgcalls("snd_azf3328_playback_trigger cmd %d\n", cmd); 1184 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd);
1103 1185
1104 switch (cmd) { 1186 switch (cmd) {
1105 case SNDRV_PCM_TRIGGER_START: 1187 case SNDRV_PCM_TRIGGER_START:
1106 snd_azf3328_dbgplay("START PLAYBACK\n"); 1188 snd_azf3328_dbgcodec("START %s\n", codec->name);
1107 1189
1108 /* mute WaveOut (avoid clicking during setup) */ 1190 if (is_playback_codec) {
1109 previously_muted = 1191 /* mute WaveOut (avoid clicking during setup) */
1110 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1192 previously_muted =
1193 snd_azf3328_mixer_set_mute(
1194 chip, IDX_MIXER_WAVEOUT, 1
1195 );
1196 }
1111 1197
1112 snd_azf3328_codec_setfmt(chip, IDX_IO_PLAY_SOUNDFORMAT, 1198 snd_azf3328_codec_setfmt(chip, codec_type,
1113 runtime->rate, 1199 runtime->rate,
1114 snd_pcm_format_width(runtime->format), 1200 snd_pcm_format_width(runtime->format),
1115 runtime->channels); 1201 runtime->channels);
1116 1202
1117 spin_lock(&chip->reg_lock); 1203 spin_lock(&chip->reg_lock);
1118 /* first, remember current value: */ 1204 /* first, remember current value: */
1119 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1205 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1120 1206
1121 /* stop playback */ 1207 /* stop transfer */
1122 status1 &= ~DMA_RESUME; 1208 flags1 &= ~DMA_RESUME;
1123 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1209 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1124 1210
1125 /* FIXME: clear interrupts or what??? */ 1211 /* FIXME: clear interrupts or what??? */
1126 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_IRQTYPE, 0xffff); 1212 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1127 spin_unlock(&chip->reg_lock); 1213 spin_unlock(&chip->reg_lock);
1128 1214
1129 snd_azf3328_setdmaa(chip, runtime->dma_addr, 1215 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr,
1130 snd_pcm_lib_period_bytes(substream), 1216 snd_pcm_lib_period_bytes(substream),
1131 snd_pcm_lib_buffer_bytes(substream), 1217 snd_pcm_lib_buffer_bytes(substream)
1132 AZF_PLAYBACK); 1218 );
1133 1219
1134 spin_lock(&chip->reg_lock); 1220 spin_lock(&chip->reg_lock);
1135#ifdef WIN9X 1221#ifdef WIN9X
1136 /* FIXME: enable playback/recording??? */ 1222 /* FIXME: enable playback/recording??? */
1137 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2; 1223 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
1138 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1224 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1139 1225
1140 /* start playback again */ 1226 /* start transfer again */
1141 /* FIXME: what is this value (0x0010)??? */ 1227 /* FIXME: what is this value (0x0010)??? */
1142 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING; 1228 flags1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1143 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1229 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1144#else /* NT4 */ 1230#else /* NT4 */
1145 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1231 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1146 0x0000); 1232 0x0000);
1147 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1233 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1148 DMA_PLAY_SOMETHING1); 1234 DMA_RUN_SOMETHING1);
1149 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1235 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1150 DMA_PLAY_SOMETHING1 | 1236 DMA_RUN_SOMETHING1 |
1151 DMA_PLAY_SOMETHING2); 1237 DMA_RUN_SOMETHING2);
1152 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1238 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1153 DMA_RESUME | 1239 DMA_RESUME |
1154 SOMETHING_ALMOST_ALWAYS_SET | 1240 SOMETHING_ALMOST_ALWAYS_SET |
1155 DMA_EPILOGUE_SOMETHING | 1241 DMA_EPILOGUE_SOMETHING |
1156 DMA_SOMETHING_ELSE); 1242 DMA_SOMETHING_ELSE);
1157#endif 1243#endif
1158 spin_unlock(&chip->reg_lock); 1244 spin_unlock(&chip->reg_lock);
1159 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 1); 1245 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1);
1160 1246
1161 /* now unmute WaveOut */ 1247 if (is_playback_codec) {
1162 if (!previously_muted) 1248 /* now unmute WaveOut */
1163 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1249 if (!previously_muted)
1250 snd_azf3328_mixer_set_mute(
1251 chip, IDX_MIXER_WAVEOUT, 0
1252 );
1253 }
1164 1254
1165 snd_azf3328_dbgplay("STARTED PLAYBACK\n"); 1255 snd_azf3328_dbgcodec("STARTED %s\n", codec->name);
1166 break; 1256 break;
1167 case SNDRV_PCM_TRIGGER_RESUME: 1257 case SNDRV_PCM_TRIGGER_RESUME:
1168 snd_azf3328_dbgplay("RESUME PLAYBACK\n"); 1258 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1169 /* resume playback if we were active */ 1259 /* resume codec if we were active */
1170 spin_lock(&chip->reg_lock); 1260 spin_lock(&chip->reg_lock);
1171 if (chip->audio_stream[AZF_PLAYBACK].running) 1261 if (codec->running)
1172 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1262 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1173 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) | DMA_RESUME); 1263 snd_azf3328_codec_inw(
1264 codec, IDX_IO_CODEC_DMA_FLAGS
1265 ) | DMA_RESUME
1266 );
1174 spin_unlock(&chip->reg_lock); 1267 spin_unlock(&chip->reg_lock);
1175 break; 1268 break;
1176 case SNDRV_PCM_TRIGGER_STOP: 1269 case SNDRV_PCM_TRIGGER_STOP:
1177 snd_azf3328_dbgplay("STOP PLAYBACK\n"); 1270 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1178 1271
1179 /* mute WaveOut (avoid clicking during setup) */ 1272 if (is_playback_codec) {
1180 previously_muted = 1273 /* mute WaveOut (avoid clicking during setup) */
1181 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 1274 previously_muted =
1275 snd_azf3328_mixer_set_mute(
1276 chip, IDX_MIXER_WAVEOUT, 1
1277 );
1278 }
1182 1279
1183 spin_lock(&chip->reg_lock); 1280 spin_lock(&chip->reg_lock);
1184 /* first, remember current value: */ 1281 /* first, remember current value: */
1185 status1 = snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS); 1282 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1186 1283
1187 /* stop playback */ 1284 /* stop transfer */
1188 status1 &= ~DMA_RESUME; 1285 flags1 &= ~DMA_RESUME;
1189 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1286 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1190 1287
1191 /* hmm, is this really required? we're resetting the same bit 1288 /* hmm, is this really required? we're resetting the same bit
1192 * immediately thereafter... */ 1289 * immediately thereafter... */
1193 status1 |= DMA_PLAY_SOMETHING1; 1290 flags1 |= DMA_RUN_SOMETHING1;
1194 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1291 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1195 1292
1196 status1 &= ~DMA_PLAY_SOMETHING1; 1293 flags1 &= ~DMA_RUN_SOMETHING1;
1197 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, status1); 1294 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1198 spin_unlock(&chip->reg_lock); 1295 spin_unlock(&chip->reg_lock);
1199 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0); 1296 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
1200 1297
1201 /* now unmute WaveOut */ 1298 if (is_playback_codec) {
1202 if (!previously_muted) 1299 /* now unmute WaveOut */
1203 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 0); 1300 if (!previously_muted)
1301 snd_azf3328_mixer_set_mute(
1302 chip, IDX_MIXER_WAVEOUT, 0
1303 );
1304 }
1204 1305
1205 snd_azf3328_dbgplay("STOPPED PLAYBACK\n"); 1306 snd_azf3328_dbgcodec("STOPPED %s\n", codec->name);
1206 break; 1307 break;
1207 case SNDRV_PCM_TRIGGER_SUSPEND: 1308 case SNDRV_PCM_TRIGGER_SUSPEND:
1208 snd_azf3328_dbgplay("SUSPEND PLAYBACK\n"); 1309 snd_azf3328_dbgcodec("SUSPEND %s\n", codec->name);
1209 /* make sure playback is stopped */ 1310 /* make sure codec is stopped */
1210 snd_azf3328_codec_outw(chip, IDX_IO_PLAY_FLAGS, 1311 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1211 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS) & ~DMA_RESUME); 1312 snd_azf3328_codec_inw(
1313 codec, IDX_IO_CODEC_DMA_FLAGS
1314 ) & ~DMA_RESUME
1315 );
1212 break; 1316 break;
1213 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1317 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1214 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n"); 1318 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
@@ -1217,7 +1321,7 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1217 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n"); 1321 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1218 break; 1322 break;
1219 default: 1323 default:
1220 printk(KERN_ERR "FIXME: unknown trigger mode!\n"); 1324 snd_printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1221 return -EINVAL; 1325 return -EINVAL;
1222 } 1326 }
1223 1327
@@ -1225,172 +1329,74 @@ snd_azf3328_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1225 return result; 1329 return result;
1226} 1330}
1227 1331
1228/* this is just analogous to playback; I'm not quite sure whether recording
1229 * should actually be triggered like that */
1230static int 1332static int
1231snd_azf3328_capture_trigger(struct snd_pcm_substream *substream, int cmd) 1333snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1232{ 1334{
1233 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1335 return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
1234 struct snd_pcm_runtime *runtime = substream->runtime; 1336}
1235 int result = 0;
1236 unsigned int status1;
1237
1238 snd_azf3328_dbgcalls("snd_azf3328_capture_trigger cmd %d\n", cmd);
1239
1240 switch (cmd) {
1241 case SNDRV_PCM_TRIGGER_START:
1242
1243 snd_azf3328_dbgplay("START CAPTURE\n");
1244
1245 snd_azf3328_codec_setfmt(chip, IDX_IO_REC_SOUNDFORMAT,
1246 runtime->rate,
1247 snd_pcm_format_width(runtime->format),
1248 runtime->channels);
1249
1250 spin_lock(&chip->reg_lock);
1251 /* first, remember current value: */
1252 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1253
1254 /* stop recording */
1255 status1 &= ~DMA_RESUME;
1256 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1257
1258 /* FIXME: clear interrupts or what??? */
1259 snd_azf3328_codec_outw(chip, IDX_IO_REC_IRQTYPE, 0xffff);
1260 spin_unlock(&chip->reg_lock);
1261
1262 snd_azf3328_setdmaa(chip, runtime->dma_addr,
1263 snd_pcm_lib_period_bytes(substream),
1264 snd_pcm_lib_buffer_bytes(substream),
1265 AZF_CAPTURE);
1266
1267 spin_lock(&chip->reg_lock);
1268#ifdef WIN9X
1269 /* FIXME: enable playback/recording??? */
1270 status1 |= DMA_PLAY_SOMETHING1 | DMA_PLAY_SOMETHING2;
1271 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1272
1273 /* start capture again */
1274 /* FIXME: what is this value (0x0010)??? */
1275 status1 |= DMA_RESUME | DMA_EPILOGUE_SOMETHING;
1276 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1277#else
1278 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1279 0x0000);
1280 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1281 DMA_PLAY_SOMETHING1);
1282 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1283 DMA_PLAY_SOMETHING1 |
1284 DMA_PLAY_SOMETHING2);
1285 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1286 DMA_RESUME |
1287 SOMETHING_ALMOST_ALWAYS_SET |
1288 DMA_EPILOGUE_SOMETHING |
1289 DMA_SOMETHING_ELSE);
1290#endif
1291 spin_unlock(&chip->reg_lock);
1292 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 1);
1293
1294 snd_azf3328_dbgplay("STARTED CAPTURE\n");
1295 break;
1296 case SNDRV_PCM_TRIGGER_RESUME:
1297 snd_azf3328_dbgplay("RESUME CAPTURE\n");
1298 /* resume recording if we were active */
1299 spin_lock(&chip->reg_lock);
1300 if (chip->audio_stream[AZF_CAPTURE].running)
1301 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1302 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) | DMA_RESUME);
1303 spin_unlock(&chip->reg_lock);
1304 break;
1305 case SNDRV_PCM_TRIGGER_STOP:
1306 snd_azf3328_dbgplay("STOP CAPTURE\n");
1307
1308 spin_lock(&chip->reg_lock);
1309 /* first, remember current value: */
1310 status1 = snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS);
1311
1312 /* stop recording */
1313 status1 &= ~DMA_RESUME;
1314 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1315
1316 status1 |= DMA_PLAY_SOMETHING1;
1317 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1318
1319 status1 &= ~DMA_PLAY_SOMETHING1;
1320 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS, status1);
1321 spin_unlock(&chip->reg_lock);
1322 snd_azf3328_codec_activity(chip, AZF_CAPTURE, 0);
1323 1337
1324 snd_azf3328_dbgplay("STOPPED CAPTURE\n"); 1338static int
1325 break; 1339snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1326 case SNDRV_PCM_TRIGGER_SUSPEND: 1340{
1327 snd_azf3328_dbgplay("SUSPEND CAPTURE\n"); 1341 return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
1328 /* make sure recording is stopped */ 1342}
1329 snd_azf3328_codec_outw(chip, IDX_IO_REC_FLAGS,
1330 snd_azf3328_codec_inw(chip, IDX_IO_REC_FLAGS) & ~DMA_RESUME);
1331 break;
1332 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1333 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_PUSH NIY!\n");
1334 break;
1335 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1336 snd_printk(KERN_ERR "FIXME: SNDRV_PCM_TRIGGER_PAUSE_RELEASE NIY!\n");
1337 break;
1338 default:
1339 printk(KERN_ERR "FIXME: unknown trigger mode!\n");
1340 return -EINVAL;
1341 }
1342 1343
1343 snd_azf3328_dbgcallleave(); 1344static int
1344 return result; 1345snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
1346{
1347 return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
1345} 1348}
1346 1349
1347static snd_pcm_uframes_t 1350static snd_pcm_uframes_t
1348snd_azf3328_playback_pointer(struct snd_pcm_substream *substream) 1351snd_azf3328_codec_pointer(struct snd_pcm_substream *substream,
1352 enum snd_azf3328_codec_type codec_type
1353)
1349{ 1354{
1350 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1355 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1356 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1351 unsigned long bufptr, result; 1357 unsigned long bufptr, result;
1352 snd_pcm_uframes_t frmres; 1358 snd_pcm_uframes_t frmres;
1353 1359
1354#ifdef QUERY_HARDWARE 1360#ifdef QUERY_HARDWARE
1355 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_START_1); 1361 bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1356#else 1362#else
1357 bufptr = substream->runtime->dma_addr; 1363 bufptr = substream->runtime->dma_addr;
1358#endif 1364#endif
1359 result = snd_azf3328_codec_inl(chip, IDX_IO_PLAY_DMA_CURRPOS); 1365 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1360 1366
1361 /* calculate offset */ 1367 /* calculate offset */
1362 result -= bufptr; 1368 result -= bufptr;
1363 frmres = bytes_to_frames( substream->runtime, result); 1369 frmres = bytes_to_frames( substream->runtime, result);
1364 snd_azf3328_dbgplay("PLAY @ 0x%8lx, frames %8ld\n", result, frmres); 1370 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n",
1371 codec->name, result, frmres);
1365 return frmres; 1372 return frmres;
1366} 1373}
1367 1374
1368static snd_pcm_uframes_t 1375static snd_pcm_uframes_t
1369snd_azf3328_capture_pointer(struct snd_pcm_substream *substream) 1376snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
1370{ 1377{
1371 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1378 return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
1372 unsigned long bufptr, result; 1379}
1373 snd_pcm_uframes_t frmres;
1374 1380
1375#ifdef QUERY_HARDWARE 1381static snd_pcm_uframes_t
1376 bufptr = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_START_1); 1382snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
1377#else 1383{
1378 bufptr = substream->runtime->dma_addr; 1384 return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
1379#endif 1385}
1380 result = snd_azf3328_codec_inl(chip, IDX_IO_REC_DMA_CURRPOS);
1381 1386
1382 /* calculate offset */ 1387static snd_pcm_uframes_t
1383 result -= bufptr; 1388snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
1384 frmres = bytes_to_frames( substream->runtime, result); 1389{
1385 snd_azf3328_dbgplay("REC @ 0x%8lx, frames %8ld\n", result, frmres); 1390 return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
1386 return frmres;
1387} 1391}
1388 1392
1389/******************************************************************/ 1393/******************************************************************/
1390 1394
1391#ifdef SUPPORT_GAMEPORT 1395#ifdef SUPPORT_GAMEPORT
1392static inline void 1396static inline void
1393snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable) 1397snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip,
1398 bool enable
1399)
1394{ 1400{
1395 snd_azf3328_io_reg_setb( 1401 snd_azf3328_io_reg_setb(
1396 chip->game_io+IDX_GAME_HWCONFIG, 1402 chip->game_io+IDX_GAME_HWCONFIG,
@@ -1400,7 +1406,9 @@ snd_azf3328_gameport_irq_enable(struct snd_azf3328 *chip, int enable)
1400} 1406}
1401 1407
1402static inline void 1408static inline void
1403snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable) 1409snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip,
1410 bool enable
1411)
1404{ 1412{
1405 snd_azf3328_io_reg_setb( 1413 snd_azf3328_io_reg_setb(
1406 chip->game_io+IDX_GAME_HWCONFIG, 1414 chip->game_io+IDX_GAME_HWCONFIG,
@@ -1409,10 +1417,27 @@ snd_azf3328_gameport_legacy_address_enable(struct snd_azf3328 *chip, int enable)
1409 ); 1417 );
1410} 1418}
1411 1419
1420static void
1421snd_azf3328_gameport_set_counter_frequency(struct snd_azf3328 *chip,
1422 unsigned int freq_cfg
1423)
1424{
1425 snd_azf3328_io_reg_setb(
1426 chip->game_io+IDX_GAME_HWCONFIG,
1427 0x02,
1428 (freq_cfg & 1) != 0
1429 );
1430 snd_azf3328_io_reg_setb(
1431 chip->game_io+IDX_GAME_HWCONFIG,
1432 0x04,
1433 (freq_cfg & 2) != 0
1434 );
1435}
1436
1412static inline void 1437static inline void
1413snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, int enable) 1438snd_azf3328_gameport_axis_circuit_enable(struct snd_azf3328 *chip, bool enable)
1414{ 1439{
1415 snd_azf3328_codec_reg_6AH_update( 1440 snd_azf3328_ctrl_reg_6AH_update(
1416 chip, IO_6A_SOMETHING2_GAMEPORT, enable 1441 chip, IO_6A_SOMETHING2_GAMEPORT, enable
1417 ); 1442 );
1418} 1443}
@@ -1447,6 +1472,8 @@ snd_azf3328_gameport_open(struct gameport *gameport, int mode)
1447 break; 1472 break;
1448 } 1473 }
1449 1474
1475 snd_azf3328_gameport_set_counter_frequency(chip,
1476 GAME_HWCFG_ADC_COUNTER_FREQ_STD);
1450 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0)); 1477 snd_azf3328_gameport_axis_circuit_enable(chip, (res == 0));
1451 1478
1452 return res; 1479 return res;
@@ -1458,6 +1485,8 @@ snd_azf3328_gameport_close(struct gameport *gameport)
1458 struct snd_azf3328 *chip = gameport_get_port_data(gameport); 1485 struct snd_azf3328 *chip = gameport_get_port_data(gameport);
1459 1486
1460 snd_azf3328_dbggame("gameport_close\n"); 1487 snd_azf3328_dbggame("gameport_close\n");
1488 snd_azf3328_gameport_set_counter_frequency(chip,
1489 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1461 snd_azf3328_gameport_axis_circuit_enable(chip, 0); 1490 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1462} 1491}
1463 1492
@@ -1491,7 +1520,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1491 1520
1492 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG); 1521 val = snd_azf3328_game_inb(chip, IDX_GAME_AXES_CONFIG);
1493 if (val & GAME_AXES_SAMPLING_READY) { 1522 if (val & GAME_AXES_SAMPLING_READY) {
1494 for (i = 0; i < 4; ++i) { 1523 for (i = 0; i < ARRAY_SIZE(chip->axes); ++i) {
1495 /* configure the axis to read */ 1524 /* configure the axis to read */
1496 val = (i << 4) | 0x0f; 1525 val = (i << 4) | 0x0f;
1497 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val); 1526 snd_azf3328_game_outb(chip, IDX_GAME_AXES_CONFIG, val);
@@ -1514,7 +1543,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1514 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff); 1543 snd_azf3328_game_outw(chip, IDX_GAME_AXIS_VALUE, 0xffff);
1515 spin_unlock_irqrestore(&chip->reg_lock, flags); 1544 spin_unlock_irqrestore(&chip->reg_lock, flags);
1516 1545
1517 for (i = 0; i < 4; i++) { 1546 for (i = 0; i < ARRAY_SIZE(chip->axes); i++) {
1518 axes[i] = chip->axes[i]; 1547 axes[i] = chip->axes[i];
1519 if (axes[i] == 0xffff) 1548 if (axes[i] == 0xffff)
1520 axes[i] = -1; 1549 axes[i] = -1;
@@ -1552,6 +1581,8 @@ snd_azf3328_gameport(struct snd_azf3328 *chip, int dev)
1552 /* DISABLE legacy address: we don't need it! */ 1581 /* DISABLE legacy address: we don't need it! */
1553 snd_azf3328_gameport_legacy_address_enable(chip, 0); 1582 snd_azf3328_gameport_legacy_address_enable(chip, 0);
1554 1583
1584 snd_azf3328_gameport_set_counter_frequency(chip,
1585 GAME_HWCFG_ADC_COUNTER_FREQ_1_200);
1555 snd_azf3328_gameport_axis_circuit_enable(chip, 0); 1586 snd_azf3328_gameport_axis_circuit_enable(chip, 0);
1556 1587
1557 gameport_register_port(chip->gameport); 1588 gameport_register_port(chip->gameport);
@@ -1585,40 +1616,77 @@ snd_azf3328_gameport_interrupt(struct snd_azf3328 *chip)
1585static inline void 1616static inline void
1586snd_azf3328_irq_log_unknown_type(u8 which) 1617snd_azf3328_irq_log_unknown_type(u8 which)
1587{ 1618{
1588 snd_azf3328_dbgplay( 1619 snd_azf3328_dbgcodec(
1589 "azt3328: unknown IRQ type (%x) occurred, please report!\n", 1620 "azt3328: unknown IRQ type (%x) occurred, please report!\n",
1590 which 1621 which
1591 ); 1622 );
1592} 1623}
1593 1624
1625static inline void
1626snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status)
1627{
1628 u8 which;
1629 enum snd_azf3328_codec_type codec_type;
1630 const struct snd_azf3328_codec_data *codec;
1631
1632 for (codec_type = AZF_CODEC_PLAYBACK;
1633 codec_type <= AZF_CODEC_I2S_OUT;
1634 ++codec_type) {
1635
1636 /* skip codec if there's no interrupt for it */
1637 if (!(status & (1 << codec_type)))
1638 continue;
1639
1640 codec = &chip->codecs[codec_type];
1641
1642 spin_lock(&chip->reg_lock);
1643 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1644 /* ack all IRQ types immediately */
1645 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1646 spin_unlock(&chip->reg_lock);
1647
1648 if ((chip->pcm[codec_type]) && (codec->substream)) {
1649 snd_pcm_period_elapsed(codec->substream);
1650 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1651 codec->name,
1652 which,
1653 snd_azf3328_codec_inl(
1654 codec, IDX_IO_CODEC_DMA_CURRPOS
1655 )
1656 );
1657 } else
1658 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1659 if (which & IRQ_SOMETHING)
1660 snd_azf3328_irq_log_unknown_type(which);
1661 }
1662}
1663
1594static irqreturn_t 1664static irqreturn_t
1595snd_azf3328_interrupt(int irq, void *dev_id) 1665snd_azf3328_interrupt(int irq, void *dev_id)
1596{ 1666{
1597 struct snd_azf3328 *chip = dev_id; 1667 struct snd_azf3328 *chip = dev_id;
1598 u8 status, which; 1668 u8 status;
1599#if DEBUG_PLAY_REC 1669#if DEBUG_CODEC
1600 static unsigned long irq_count; 1670 static unsigned long irq_count;
1601#endif 1671#endif
1602 1672
1603 status = snd_azf3328_codec_inb(chip, IDX_IO_IRQSTATUS); 1673 status = snd_azf3328_ctrl_inb(chip, IDX_IO_IRQSTATUS);
1604 1674
1605 /* fast path out, to ease interrupt sharing */ 1675 /* fast path out, to ease interrupt sharing */
1606 if (!(status & 1676 if (!(status &
1607 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER) 1677 (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT
1678 |IRQ_GAMEPORT|IRQ_MPU401|IRQ_TIMER)
1608 )) 1679 ))
1609 return IRQ_NONE; /* must be interrupt for another device */ 1680 return IRQ_NONE; /* must be interrupt for another device */
1610 1681
1611 snd_azf3328_dbgplay( 1682 snd_azf3328_dbgcodec(
1612 "irq_count %ld! IDX_IO_PLAY_FLAGS %04x, " 1683 "irq_count %ld! IDX_IO_IRQSTATUS %04x\n",
1613 "IDX_IO_PLAY_IRQTYPE %04x, IDX_IO_IRQSTATUS %04x\n",
1614 irq_count++ /* debug-only */, 1684 irq_count++ /* debug-only */,
1615 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_FLAGS),
1616 snd_azf3328_codec_inw(chip, IDX_IO_PLAY_IRQTYPE),
1617 status 1685 status
1618 ); 1686 );
1619 1687
1620 if (status & IRQ_TIMER) { 1688 if (status & IRQ_TIMER) {
1621 /* snd_azf3328_dbgplay("timer %ld\n", 1689 /* snd_azf3328_dbgcodec("timer %ld\n",
1622 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE) 1690 snd_azf3328_codec_inl(chip, IDX_IO_TIMER_VALUE)
1623 & TIMER_VALUE_MASK 1691 & TIMER_VALUE_MASK
1624 ); */ 1692 ); */
@@ -1626,71 +1694,36 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1626 snd_timer_interrupt(chip->timer, chip->timer->sticks); 1694 snd_timer_interrupt(chip->timer, chip->timer->sticks);
1627 /* ACK timer */ 1695 /* ACK timer */
1628 spin_lock(&chip->reg_lock); 1696 spin_lock(&chip->reg_lock);
1629 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07); 1697 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x07);
1630 spin_unlock(&chip->reg_lock); 1698 spin_unlock(&chip->reg_lock);
1631 snd_azf3328_dbgplay("azt3328: timer IRQ\n"); 1699 snd_azf3328_dbgcodec("azt3328: timer IRQ\n");
1632 } 1700 }
1633 if (status & IRQ_PLAYBACK) {
1634 spin_lock(&chip->reg_lock);
1635 which = snd_azf3328_codec_inb(chip, IDX_IO_PLAY_IRQTYPE);
1636 /* ack all IRQ types immediately */
1637 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_IRQTYPE, which);
1638 spin_unlock(&chip->reg_lock);
1639 1701
1640 if (chip->pcm && chip->audio_stream[AZF_PLAYBACK].substream) { 1702 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1641 snd_pcm_period_elapsed( 1703 snd_azf3328_codec_interrupt(chip, status);
1642 chip->audio_stream[AZF_PLAYBACK].substream
1643 );
1644 snd_azf3328_dbgplay("PLAY period done (#%x), @ %x\n",
1645 which,
1646 snd_azf3328_codec_inl(
1647 chip, IDX_IO_PLAY_DMA_CURRPOS
1648 )
1649 );
1650 } else
1651 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1652 if (which & IRQ_PLAY_SOMETHING)
1653 snd_azf3328_irq_log_unknown_type(which);
1654 }
1655 if (status & IRQ_RECORDING) {
1656 spin_lock(&chip->reg_lock);
1657 which = snd_azf3328_codec_inb(chip, IDX_IO_REC_IRQTYPE);
1658 /* ack all IRQ types immediately */
1659 snd_azf3328_codec_outb(chip, IDX_IO_REC_IRQTYPE, which);
1660 spin_unlock(&chip->reg_lock);
1661 1704
1662 if (chip->pcm && chip->audio_stream[AZF_CAPTURE].substream) {
1663 snd_pcm_period_elapsed(
1664 chip->audio_stream[AZF_CAPTURE].substream
1665 );
1666 snd_azf3328_dbgplay("REC period done (#%x), @ %x\n",
1667 which,
1668 snd_azf3328_codec_inl(
1669 chip, IDX_IO_REC_DMA_CURRPOS
1670 )
1671 );
1672 } else
1673 printk(KERN_WARNING "azt3328: irq handler problem!\n");
1674 if (which & IRQ_REC_SOMETHING)
1675 snd_azf3328_irq_log_unknown_type(which);
1676 }
1677 if (status & IRQ_GAMEPORT) 1705 if (status & IRQ_GAMEPORT)
1678 snd_azf3328_gameport_interrupt(chip); 1706 snd_azf3328_gameport_interrupt(chip);
1707
1679 /* MPU401 has less critical IRQ requirements 1708 /* MPU401 has less critical IRQ requirements
1680 * than timer and playback/recording, right? */ 1709 * than timer and playback/recording, right? */
1681 if (status & IRQ_MPU401) { 1710 if (status & IRQ_MPU401) {
1682 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); 1711 snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data);
1683 1712
1684 /* hmm, do we have to ack the IRQ here somehow? 1713 /* hmm, do we have to ack the IRQ here somehow?
1685 * If so, then I don't know how... */ 1714 * If so, then I don't know how yet... */
1686 snd_azf3328_dbgplay("azt3328: MPU401 IRQ\n"); 1715 snd_azf3328_dbgcodec("azt3328: MPU401 IRQ\n");
1687 } 1716 }
1688 return IRQ_HANDLED; 1717 return IRQ_HANDLED;
1689} 1718}
1690 1719
1691/*****************************************************************/ 1720/*****************************************************************/
1692 1721
1693static const struct snd_pcm_hardware snd_azf3328_playback = 1722/* as long as we think we have identical snd_pcm_hardware parameters
1723 for playback, capture and i2s out, we can use the same physical struct
1724 since the struct is simply being copied into a member.
1725*/
1726static const struct snd_pcm_hardware snd_azf3328_hardware =
1694{ 1727{
1695 /* FIXME!! Correct? */ 1728 /* FIXME!! Correct? */
1696 .info = SNDRV_PCM_INFO_MMAP | 1729 .info = SNDRV_PCM_INFO_MMAP |
@@ -1718,31 +1751,6 @@ static const struct snd_pcm_hardware snd_azf3328_playback =
1718 .fifo_size = 0, 1751 .fifo_size = 0,
1719}; 1752};
1720 1753
1721static const struct snd_pcm_hardware snd_azf3328_capture =
1722{
1723 /* FIXME */
1724 .info = SNDRV_PCM_INFO_MMAP |
1725 SNDRV_PCM_INFO_INTERLEAVED |
1726 SNDRV_PCM_INFO_MMAP_VALID,
1727 .formats = SNDRV_PCM_FMTBIT_S8 |
1728 SNDRV_PCM_FMTBIT_U8 |
1729 SNDRV_PCM_FMTBIT_S16_LE |
1730 SNDRV_PCM_FMTBIT_U16_LE,
1731 .rates = SNDRV_PCM_RATE_5512 |
1732 SNDRV_PCM_RATE_8000_48000 |
1733 SNDRV_PCM_RATE_KNOT,
1734 .rate_min = AZF_FREQ_4000,
1735 .rate_max = AZF_FREQ_66200,
1736 .channels_min = 1,
1737 .channels_max = 2,
1738 .buffer_bytes_max = 65536,
1739 .period_bytes_min = 64,
1740 .period_bytes_max = 65536,
1741 .periods_min = 1,
1742 .periods_max = 1024,
1743 .fifo_size = 0,
1744};
1745
1746 1754
1747static unsigned int snd_azf3328_fixed_rates[] = { 1755static unsigned int snd_azf3328_fixed_rates[] = {
1748 AZF_FREQ_4000, 1756 AZF_FREQ_4000,
@@ -1770,14 +1778,19 @@ static struct snd_pcm_hw_constraint_list snd_azf3328_hw_constraints_rates = {
1770/*****************************************************************/ 1778/*****************************************************************/
1771 1779
1772static int 1780static int
1773snd_azf3328_playback_open(struct snd_pcm_substream *substream) 1781snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1782 enum snd_azf3328_codec_type codec_type
1783)
1774{ 1784{
1775 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1785 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1776 struct snd_pcm_runtime *runtime = substream->runtime; 1786 struct snd_pcm_runtime *runtime = substream->runtime;
1777 1787
1778 snd_azf3328_dbgcallenter(); 1788 snd_azf3328_dbgcallenter();
1779 chip->audio_stream[AZF_PLAYBACK].substream = substream; 1789 chip->codecs[codec_type].substream = substream;
1780 runtime->hw = snd_azf3328_playback; 1790
1791 /* same parameters for all our codecs - at least we think so... */
1792 runtime->hw = snd_azf3328_hardware;
1793
1781 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1794 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1782 &snd_azf3328_hw_constraints_rates); 1795 &snd_azf3328_hw_constraints_rates);
1783 snd_azf3328_dbgcallleave(); 1796 snd_azf3328_dbgcallleave();
@@ -1785,40 +1798,52 @@ snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1785} 1798}
1786 1799
1787static int 1800static int
1801snd_azf3328_playback_open(struct snd_pcm_substream *substream)
1802{
1803 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1804}
1805
1806static int
1788snd_azf3328_capture_open(struct snd_pcm_substream *substream) 1807snd_azf3328_capture_open(struct snd_pcm_substream *substream)
1789{ 1808{
1790 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1809 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1791 struct snd_pcm_runtime *runtime = substream->runtime; 1810}
1792 1811
1793 snd_azf3328_dbgcallenter(); 1812static int
1794 chip->audio_stream[AZF_CAPTURE].substream = substream; 1813snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream)
1795 runtime->hw = snd_azf3328_capture; 1814{
1796 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1815 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1797 &snd_azf3328_hw_constraints_rates);
1798 snd_azf3328_dbgcallleave();
1799 return 0;
1800} 1816}
1801 1817
1802static int 1818static int
1803snd_azf3328_playback_close(struct snd_pcm_substream *substream) 1819snd_azf3328_pcm_close(struct snd_pcm_substream *substream,
1820 enum snd_azf3328_codec_type codec_type
1821)
1804{ 1822{
1805 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1823 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1806 1824
1807 snd_azf3328_dbgcallenter(); 1825 snd_azf3328_dbgcallenter();
1808 chip->audio_stream[AZF_PLAYBACK].substream = NULL; 1826 chip->codecs[codec_type].substream = NULL;
1809 snd_azf3328_dbgcallleave(); 1827 snd_azf3328_dbgcallleave();
1810 return 0; 1828 return 0;
1811} 1829}
1812 1830
1813static int 1831static int
1832snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1833{
1834 return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
1835}
1836
1837static int
1814snd_azf3328_capture_close(struct snd_pcm_substream *substream) 1838snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1815{ 1839{
1816 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1840 return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
1841}
1817 1842
1818 snd_azf3328_dbgcallenter(); 1843static int
1819 chip->audio_stream[AZF_CAPTURE].substream = NULL; 1844snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
1820 snd_azf3328_dbgcallleave(); 1845{
1821 return 0; 1846 return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
1822} 1847}
1823 1848
1824/******************************************************************/ 1849/******************************************************************/
@@ -1829,9 +1854,9 @@ static struct snd_pcm_ops snd_azf3328_playback_ops = {
1829 .ioctl = snd_pcm_lib_ioctl, 1854 .ioctl = snd_pcm_lib_ioctl,
1830 .hw_params = snd_azf3328_hw_params, 1855 .hw_params = snd_azf3328_hw_params,
1831 .hw_free = snd_azf3328_hw_free, 1856 .hw_free = snd_azf3328_hw_free,
1832 .prepare = snd_azf3328_playback_prepare, 1857 .prepare = snd_azf3328_codec_prepare,
1833 .trigger = snd_azf3328_playback_trigger, 1858 .trigger = snd_azf3328_codec_playback_trigger,
1834 .pointer = snd_azf3328_playback_pointer 1859 .pointer = snd_azf3328_codec_playback_pointer
1835}; 1860};
1836 1861
1837static struct snd_pcm_ops snd_azf3328_capture_ops = { 1862static struct snd_pcm_ops snd_azf3328_capture_ops = {
@@ -1840,30 +1865,67 @@ static struct snd_pcm_ops snd_azf3328_capture_ops = {
1840 .ioctl = snd_pcm_lib_ioctl, 1865 .ioctl = snd_pcm_lib_ioctl,
1841 .hw_params = snd_azf3328_hw_params, 1866 .hw_params = snd_azf3328_hw_params,
1842 .hw_free = snd_azf3328_hw_free, 1867 .hw_free = snd_azf3328_hw_free,
1843 .prepare = snd_azf3328_capture_prepare, 1868 .prepare = snd_azf3328_codec_prepare,
1844 .trigger = snd_azf3328_capture_trigger, 1869 .trigger = snd_azf3328_codec_capture_trigger,
1845 .pointer = snd_azf3328_capture_pointer 1870 .pointer = snd_azf3328_codec_capture_pointer
1871};
1872
1873static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1874 .open = snd_azf3328_i2s_out_open,
1875 .close = snd_azf3328_i2s_out_close,
1876 .ioctl = snd_pcm_lib_ioctl,
1877 .hw_params = snd_azf3328_hw_params,
1878 .hw_free = snd_azf3328_hw_free,
1879 .prepare = snd_azf3328_codec_prepare,
1880 .trigger = snd_azf3328_codec_i2s_out_trigger,
1881 .pointer = snd_azf3328_codec_i2s_out_pointer
1846}; 1882};
1847 1883
1848static int __devinit 1884static int __devinit
1849snd_azf3328_pcm(struct snd_azf3328 *chip, int device) 1885snd_azf3328_pcm(struct snd_azf3328 *chip)
1850{ 1886{
1887enum { AZF_PCMDEV_STD, AZF_PCMDEV_I2S_OUT, NUM_AZF_PCMDEVS }; /* pcm devices */
1888
1851 struct snd_pcm *pcm; 1889 struct snd_pcm *pcm;
1852 int err; 1890 int err;
1853 1891
1854 snd_azf3328_dbgcallenter(); 1892 snd_azf3328_dbgcallenter();
1855 if ((err = snd_pcm_new(chip->card, "AZF3328 DSP", device, 1, 1, &pcm)) < 0) 1893
1894 err = snd_pcm_new(chip->card, "AZF3328 DSP", AZF_PCMDEV_STD,
1895 1, 1, &pcm);
1896 if (err < 0)
1856 return err; 1897 return err;
1857 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_azf3328_playback_ops); 1898 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1858 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_azf3328_capture_ops); 1899 &snd_azf3328_playback_ops);
1900 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE,
1901 &snd_azf3328_capture_ops);
1859 1902
1860 pcm->private_data = chip; 1903 pcm->private_data = chip;
1861 pcm->info_flags = 0; 1904 pcm->info_flags = 0;
1862 strcpy(pcm->name, chip->card->shortname); 1905 strcpy(pcm->name, chip->card->shortname);
1863 chip->pcm = pcm; 1906 /* same pcm object for playback/capture (see snd_pcm_new() above) */
1907 chip->pcm[AZF_CODEC_PLAYBACK] = pcm;
1908 chip->pcm[AZF_CODEC_CAPTURE] = pcm;
1864 1909
1865 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1910 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1866 snd_dma_pci_data(chip->pci), 64*1024, 64*1024); 1911 snd_dma_pci_data(chip->pci),
1912 64*1024, 64*1024);
1913
1914 err = snd_pcm_new(chip->card, "AZF3328 I2S OUT", AZF_PCMDEV_I2S_OUT,
1915 1, 0, &pcm);
1916 if (err < 0)
1917 return err;
1918 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK,
1919 &snd_azf3328_i2s_out_ops);
1920
1921 pcm->private_data = chip;
1922 pcm->info_flags = 0;
1923 strcpy(pcm->name, chip->card->shortname);
1924 chip->pcm[AZF_CODEC_I2S_OUT] = pcm;
1925
1926 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1927 snd_dma_pci_data(chip->pci),
1928 64*1024, 64*1024);
1867 1929
1868 snd_azf3328_dbgcallleave(); 1930 snd_azf3328_dbgcallleave();
1869 return 0; 1931 return 0;
@@ -1902,7 +1964,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1902 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 1964 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay);
1903 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; 1965 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1904 spin_lock_irqsave(&chip->reg_lock, flags); 1966 spin_lock_irqsave(&chip->reg_lock, flags);
1905 snd_azf3328_codec_outl(chip, IDX_IO_TIMER_VALUE, delay); 1967 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
1906 spin_unlock_irqrestore(&chip->reg_lock, flags); 1968 spin_unlock_irqrestore(&chip->reg_lock, flags);
1907 snd_azf3328_dbgcallleave(); 1969 snd_azf3328_dbgcallleave();
1908 return 0; 1970 return 0;
@@ -1919,7 +1981,7 @@ snd_azf3328_timer_stop(struct snd_timer *timer)
1919 spin_lock_irqsave(&chip->reg_lock, flags); 1981 spin_lock_irqsave(&chip->reg_lock, flags);
1920 /* disable timer countdown and interrupt */ 1982 /* disable timer countdown and interrupt */
1921 /* FIXME: should we write TIMER_IRQ_ACK here? */ 1983 /* FIXME: should we write TIMER_IRQ_ACK here? */
1922 snd_azf3328_codec_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); 1984 snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0);
1923 spin_unlock_irqrestore(&chip->reg_lock, flags); 1985 spin_unlock_irqrestore(&chip->reg_lock, flags);
1924 snd_azf3328_dbgcallleave(); 1986 snd_azf3328_dbgcallleave();
1925 return 0; 1987 return 0;
@@ -2035,7 +2097,7 @@ snd_azf3328_test_bit(unsigned unsigned reg, int bit)
2035 2097
2036 outb(val, reg); 2098 outb(val, reg);
2037 2099
2038 printk(KERN_ERR "reg %04x bit %d: %02x %02x %02x\n", 2100 printk(KERN_DEBUG "reg %04x bit %d: %02x %02x %02x\n",
2039 reg, bit, val, valoff, valon 2101 reg, bit, val, valoff, valon
2040 ); 2102 );
2041} 2103}
@@ -2048,9 +2110,9 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2048 u16 tmp; 2110 u16 tmp;
2049 2111
2050 snd_azf3328_dbgmisc( 2112 snd_azf3328_dbgmisc(
2051 "codec_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, " 2113 "ctrl_io 0x%lx, game_io 0x%lx, mpu_io 0x%lx, "
2052 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n", 2114 "opl3_io 0x%lx, mixer_io 0x%lx, irq %d\n",
2053 chip->codec_io, chip->game_io, chip->mpu_io, 2115 chip->ctrl_io, chip->game_io, chip->mpu_io,
2054 chip->opl3_io, chip->mixer_io, chip->irq 2116 chip->opl3_io, chip->mixer_io, chip->irq
2055 ); 2117 );
2056 2118
@@ -2083,9 +2145,9 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip)
2083 inb(0x38c + tmp) 2145 inb(0x38c + tmp)
2084 ); 2146 );
2085 2147
2086 for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) 2148 for (tmp = 0; tmp < AZF_IO_SIZE_CTRL; tmp += 2)
2087 snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", 2149 snd_azf3328_dbgmisc("ctrl 0x%02x: 0x%04x\n",
2088 tmp, snd_azf3328_codec_inw(chip, tmp) 2150 tmp, snd_azf3328_ctrl_inw(chip, tmp)
2089 ); 2151 );
2090 2152
2091 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) 2153 for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2)
@@ -2106,7 +2168,8 @@ snd_azf3328_create(struct snd_card *card,
2106 static struct snd_device_ops ops = { 2168 static struct snd_device_ops ops = {
2107 .dev_free = snd_azf3328_dev_free, 2169 .dev_free = snd_azf3328_dev_free,
2108 }; 2170 };
2109 u16 tmp; 2171 u8 dma_init;
2172 enum snd_azf3328_codec_type codec_type;
2110 2173
2111 *rchip = NULL; 2174 *rchip = NULL;
2112 2175
@@ -2138,14 +2201,21 @@ snd_azf3328_create(struct snd_card *card,
2138 if (err < 0) 2201 if (err < 0)
2139 goto out_err; 2202 goto out_err;
2140 2203
2141 chip->codec_io = pci_resource_start(pci, 0); 2204 chip->ctrl_io = pci_resource_start(pci, 0);
2142 chip->game_io = pci_resource_start(pci, 1); 2205 chip->game_io = pci_resource_start(pci, 1);
2143 chip->mpu_io = pci_resource_start(pci, 2); 2206 chip->mpu_io = pci_resource_start(pci, 2);
2144 chip->opl3_io = pci_resource_start(pci, 3); 2207 chip->opl3_io = pci_resource_start(pci, 3);
2145 chip->mixer_io = pci_resource_start(pci, 4); 2208 chip->mixer_io = pci_resource_start(pci, 4);
2146 2209
2147 chip->audio_stream[AZF_PLAYBACK].portbase = chip->codec_io + 0x00; 2210 chip->codecs[AZF_CODEC_PLAYBACK].io_base =
2148 chip->audio_stream[AZF_CAPTURE].portbase = chip->codec_io + 0x20; 2211 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2212 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK";
2213 chip->codecs[AZF_CODEC_CAPTURE].io_base =
2214 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2215 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE";
2216 chip->codecs[AZF_CODEC_I2S_OUT].io_base =
2217 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2218 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT";
2149 2219
2150 if (request_irq(pci->irq, snd_azf3328_interrupt, 2220 if (request_irq(pci->irq, snd_azf3328_interrupt,
2151 IRQF_SHARED, card->shortname, chip)) { 2221 IRQF_SHARED, card->shortname, chip)) {
@@ -2168,20 +2238,25 @@ snd_azf3328_create(struct snd_card *card,
2168 if (err < 0) 2238 if (err < 0)
2169 goto out_err; 2239 goto out_err;
2170 2240
2171 /* shutdown codecs to save power */ 2241 /* standard codec init stuff */
2172 /* have snd_azf3328_codec_activity() act properly */ 2242 /* default DMA init value */
2173 chip->audio_stream[AZF_PLAYBACK].running = 1; 2243 dma_init = DMA_RUN_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE;
2174 snd_azf3328_codec_activity(chip, AZF_PLAYBACK, 0);
2175 2244
2176 /* standard chip init stuff */ 2245 for (codec_type = AZF_CODEC_PLAYBACK;
2177 /* default IRQ init value */ 2246 codec_type <= AZF_CODEC_I2S_OUT; ++codec_type) {
2178 tmp = DMA_PLAY_SOMETHING2|DMA_EPILOGUE_SOMETHING|DMA_SOMETHING_ELSE; 2247 struct snd_azf3328_codec_data *codec =
2248 &chip->codecs[codec_type];
2179 2249
2180 spin_lock_irq(&chip->reg_lock); 2250 /* shutdown codecs to save power */
2181 snd_azf3328_codec_outb(chip, IDX_IO_PLAY_FLAGS, tmp); 2251 /* have ...ctrl_codec_activity() act properly */
2182 snd_azf3328_codec_outb(chip, IDX_IO_REC_FLAGS, tmp); 2252 codec->running = 1;
2183 snd_azf3328_codec_outb(chip, IDX_IO_SOMETHING_FLAGS, tmp); 2253 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2184 spin_unlock_irq(&chip->reg_lock); 2254
2255 spin_lock_irq(&chip->reg_lock);
2256 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2257 dma_init);
2258 spin_unlock_irq(&chip->reg_lock);
2259 }
2185 2260
2186 snd_card_set_dev(card, &pci->dev); 2261 snd_card_set_dev(card, &pci->dev);
2187 2262
@@ -2229,8 +2304,11 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2229 2304
2230 card->private_data = chip; 2305 card->private_data = chip;
2231 2306
2307 /* chose to use MPU401_HW_AZT2320 ID instead of MPU401_HW_MPU401,
2308 since our hardware ought to be similar, thus use same ID. */
2232 err = snd_mpu401_uart_new( 2309 err = snd_mpu401_uart_new(
2233 card, 0, MPU401_HW_MPU401, chip->mpu_io, MPU401_INFO_INTEGRATED, 2310 card, 0,
2311 MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED,
2234 pci->irq, 0, &chip->rmidi 2312 pci->irq, 0, &chip->rmidi
2235 ); 2313 );
2236 if (err < 0) { 2314 if (err < 0) {
@@ -2244,7 +2322,7 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2244 if (err < 0) 2322 if (err < 0)
2245 goto out_err; 2323 goto out_err;
2246 2324
2247 err = snd_azf3328_pcm(chip, 0); 2325 err = snd_azf3328_pcm(chip);
2248 if (err < 0) 2326 if (err < 0)
2249 goto out_err; 2327 goto out_err;
2250 2328
@@ -2266,14 +2344,14 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2266 opl3->private_data = chip; 2344 opl3->private_data = chip;
2267 2345
2268 sprintf(card->longname, "%s at 0x%lx, irq %i", 2346 sprintf(card->longname, "%s at 0x%lx, irq %i",
2269 card->shortname, chip->codec_io, chip->irq); 2347 card->shortname, chip->ctrl_io, chip->irq);
2270 2348
2271 err = snd_card_register(card); 2349 err = snd_card_register(card);
2272 if (err < 0) 2350 if (err < 0)
2273 goto out_err; 2351 goto out_err;
2274 2352
2275#ifdef MODULE 2353#ifdef MODULE
2276 printk( 2354 printk(KERN_INFO
2277"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n" 2355"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n"
2278"azt3328: Hardware was completely undocumented, unfortunately.\n" 2356"azt3328: Hardware was completely undocumented, unfortunately.\n"
2279"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" 2357"azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n"
@@ -2308,36 +2386,52 @@ snd_azf3328_remove(struct pci_dev *pci)
2308} 2386}
2309 2387
2310#ifdef CONFIG_PM 2388#ifdef CONFIG_PM
2389static inline void
2390snd_azf3328_suspend_regs(unsigned long io_addr, unsigned count, u32 *saved_regs)
2391{
2392 unsigned reg;
2393
2394 for (reg = 0; reg < count; ++reg) {
2395 *saved_regs = inl(io_addr);
2396 snd_azf3328_dbgpm("suspend: io 0x%04lx: 0x%08x\n",
2397 io_addr, *saved_regs);
2398 ++saved_regs;
2399 io_addr += sizeof(*saved_regs);
2400 }
2401}
2402
2311static int 2403static int
2312snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2404snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2313{ 2405{
2314 struct snd_card *card = pci_get_drvdata(pci); 2406 struct snd_card *card = pci_get_drvdata(pci);
2315 struct snd_azf3328 *chip = card->private_data; 2407 struct snd_azf3328 *chip = card->private_data;
2316 unsigned reg; 2408 u16 *saved_regs_ctrl_u16;
2317 2409
2318 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2410 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2319 2411
2320 snd_pcm_suspend_all(chip->pcm); 2412 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2413 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2321 2414
2322 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg) 2415 snd_azf3328_suspend_regs(chip->mixer_io,
2323 chip->saved_regs_mixer[reg] = inw(chip->mixer_io + reg * 2); 2416 ARRAY_SIZE(chip->saved_regs_mixer), chip->saved_regs_mixer);
2324 2417
2325 /* make sure to disable master volume etc. to prevent looping sound */ 2418 /* make sure to disable master volume etc. to prevent looping sound */
2326 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1); 2419 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_PLAY_MASTER, 1);
2327 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1); 2420 snd_azf3328_mixer_set_mute(chip, IDX_MIXER_WAVEOUT, 1);
2328 2421
2329 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg) 2422 snd_azf3328_suspend_regs(chip->ctrl_io,
2330 chip->saved_regs_codec[reg] = inw(chip->codec_io + reg * 2); 2423 ARRAY_SIZE(chip->saved_regs_ctrl), chip->saved_regs_ctrl);
2331 2424
2332 /* manually store the one currently relevant write-only reg, too */ 2425 /* manually store the one currently relevant write-only reg, too */
2333 chip->saved_regs_codec[IDX_IO_6AH / 2] = chip->shadow_reg_codec_6AH; 2426 saved_regs_ctrl_u16 = (u16 *)chip->saved_regs_ctrl;
2427 saved_regs_ctrl_u16[IDX_IO_6AH / 2] = chip->shadow_reg_ctrl_6AH;
2334 2428
2335 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg) 2429 snd_azf3328_suspend_regs(chip->game_io,
2336 chip->saved_regs_game[reg] = inw(chip->game_io + reg * 2); 2430 ARRAY_SIZE(chip->saved_regs_game), chip->saved_regs_game);
2337 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg) 2431 snd_azf3328_suspend_regs(chip->mpu_io,
2338 chip->saved_regs_mpu[reg] = inw(chip->mpu_io + reg * 2); 2432 ARRAY_SIZE(chip->saved_regs_mpu), chip->saved_regs_mpu);
2339 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg) 2433 snd_azf3328_suspend_regs(chip->opl3_io,
2340 chip->saved_regs_opl3[reg] = inw(chip->opl3_io + reg * 2); 2434 ARRAY_SIZE(chip->saved_regs_opl3), chip->saved_regs_opl3);
2341 2435
2342 pci_disable_device(pci); 2436 pci_disable_device(pci);
2343 pci_save_state(pci); 2437 pci_save_state(pci);
@@ -2345,12 +2439,28 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2345 return 0; 2439 return 0;
2346} 2440}
2347 2441
2442static inline void
2443snd_azf3328_resume_regs(const u32 *saved_regs,
2444 unsigned long io_addr,
2445 unsigned count
2446)
2447{
2448 unsigned reg;
2449
2450 for (reg = 0; reg < count; ++reg) {
2451 outl(*saved_regs, io_addr);
2452 snd_azf3328_dbgpm("resume: io 0x%04lx: 0x%08x --> 0x%08x\n",
2453 io_addr, *saved_regs, inl(io_addr));
2454 ++saved_regs;
2455 io_addr += sizeof(*saved_regs);
2456 }
2457}
2458
2348static int 2459static int
2349snd_azf3328_resume(struct pci_dev *pci) 2460snd_azf3328_resume(struct pci_dev *pci)
2350{ 2461{
2351 struct snd_card *card = pci_get_drvdata(pci); 2462 struct snd_card *card = pci_get_drvdata(pci);
2352 struct snd_azf3328 *chip = card->private_data; 2463 const struct snd_azf3328 *chip = card->private_data;
2353 unsigned reg;
2354 2464
2355 pci_set_power_state(pci, PCI_D0); 2465 pci_set_power_state(pci, PCI_D0);
2356 pci_restore_state(pci); 2466 pci_restore_state(pci);
@@ -2362,16 +2472,24 @@ snd_azf3328_resume(struct pci_dev *pci)
2362 } 2472 }
2363 pci_set_master(pci); 2473 pci_set_master(pci);
2364 2474
2365 for (reg = 0; reg < AZF_IO_SIZE_GAME_PM / 2; ++reg) 2475 snd_azf3328_resume_regs(chip->saved_regs_game, chip->game_io,
2366 outw(chip->saved_regs_game[reg], chip->game_io + reg * 2); 2476 ARRAY_SIZE(chip->saved_regs_game));
2367 for (reg = 0; reg < AZF_IO_SIZE_MPU_PM / 2; ++reg) 2477 snd_azf3328_resume_regs(chip->saved_regs_mpu, chip->mpu_io,
2368 outw(chip->saved_regs_mpu[reg], chip->mpu_io + reg * 2); 2478 ARRAY_SIZE(chip->saved_regs_mpu));
2369 for (reg = 0; reg < AZF_IO_SIZE_OPL3_PM / 2; ++reg) 2479 snd_azf3328_resume_regs(chip->saved_regs_opl3, chip->opl3_io,
2370 outw(chip->saved_regs_opl3[reg], chip->opl3_io + reg * 2); 2480 ARRAY_SIZE(chip->saved_regs_opl3));
2371 for (reg = 0; reg < AZF_IO_SIZE_MIXER_PM / 2; ++reg) 2481
2372 outw(chip->saved_regs_mixer[reg], chip->mixer_io + reg * 2); 2482 snd_azf3328_resume_regs(chip->saved_regs_mixer, chip->mixer_io,
2373 for (reg = 0; reg < AZF_IO_SIZE_CODEC_PM / 2; ++reg) 2483 ARRAY_SIZE(chip->saved_regs_mixer));
2374 outw(chip->saved_regs_codec[reg], chip->codec_io + reg * 2); 2484
2485 /* unfortunately with 32bit transfers, IDX_MIXER_PLAY_MASTER (0x02)
2486 and IDX_MIXER_RESET (offset 0x00) get touched at the same time,
2487 resulting in a mixer reset condition persisting until _after_
2488 master vol was restored. Thus master vol needs an extra restore. */
2489 outw(((u16 *)chip->saved_regs_mixer)[1], chip->mixer_io + 2);
2490
2491 snd_azf3328_resume_regs(chip->saved_regs_ctrl, chip->ctrl_io,
2492 ARRAY_SIZE(chip->saved_regs_ctrl));
2375 2493
2376 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2494 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2377 return 0; 2495 return 0;
diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h
index 974e05122f00..6f46b97650cc 100644
--- a/sound/pci/azt3328.h
+++ b/sound/pci/azt3328.h
@@ -6,50 +6,59 @@
6 6
7/*** main I/O area port indices ***/ 7/*** main I/O area port indices ***/
8/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */ 8/* (only 0x70 of 0x80 bytes saved/restored by Windows driver) */
9#define AZF_IO_SIZE_CODEC 0x80 9#define AZF_IO_SIZE_CTRL 0x80
10#define AZF_IO_SIZE_CODEC_PM 0x70 10#define AZF_IO_SIZE_CTRL_PM 0x70
11 11
12/* the driver initialisation suggests a layout of 4 main areas: 12/* the driver initialisation suggests a layout of 4 areas
13 * from 0x00 (playback), from 0x20 (recording) and from 0x40 (maybe MPU401??). 13 * within the main card control I/O:
14 * from 0x00 (playback codec), from 0x20 (recording codec)
15 * and from 0x40 (most certainly I2S out codec).
14 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management, 16 * And another area from 0x60 to 0x6f (DirectX timer, IRQ management,
15 * power management etc.???). */ 17 * power management etc.???). */
16 18
17/** playback area **/ 19#define AZF_IO_OFFS_CODEC_PLAYBACK 0x00
18#define IDX_IO_PLAY_FLAGS 0x00 /* PU:0x0000 */ 20#define AZF_IO_OFFS_CODEC_CAPTURE 0x20
21#define AZF_IO_OFFS_CODEC_I2S_OUT 0x40
22
23#define IDX_IO_CODEC_DMA_FLAGS 0x00 /* PU:0x0000 */
19 /* able to reactivate output after output muting due to 8/16bit 24 /* able to reactivate output after output muting due to 8/16bit
20 * output change, just like 0x0002. 25 * output change, just like 0x0002.
21 * 0x0001 is the only bit that's able to start the DMA counter */ 26 * 0x0001 is the only bit that's able to start the DMA counter */
22 #define DMA_RESUME 0x0001 /* paused if cleared ? */ 27 #define DMA_RESUME 0x0001 /* paused if cleared? */
23 /* 0x0002 *temporarily* set during DMA stopping. hmm 28 /* 0x0002 *temporarily* set during DMA stopping. hmm
24 * both 0x0002 and 0x0004 set in playback setup. */ 29 * both 0x0002 and 0x0004 set in playback setup. */
25 /* able to reactivate output after output muting due to 8/16bit 30 /* able to reactivate output after output muting due to 8/16bit
26 * output change, just like 0x0001. */ 31 * output change, just like 0x0001. */
27 #define DMA_PLAY_SOMETHING1 0x0002 /* \ alternated (toggled) */ 32 #define DMA_RUN_SOMETHING1 0x0002 /* \ alternated (toggled) */
28 /* 0x0004: NOT able to reactivate output */ 33 /* 0x0004: NOT able to reactivate output */
29 #define DMA_PLAY_SOMETHING2 0x0004 /* / bits */ 34 #define DMA_RUN_SOMETHING2 0x0004 /* / bits */
30 #define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */ 35 #define SOMETHING_ALMOST_ALWAYS_SET 0x0008 /* ???; can be modified */
31 #define DMA_EPILOGUE_SOMETHING 0x0010 36 #define DMA_EPILOGUE_SOMETHING 0x0010
32 #define DMA_SOMETHING_ELSE 0x0020 /* ??? */ 37 #define DMA_SOMETHING_ELSE 0x0020 /* ??? */
33 #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused ? not modifiable */ 38 #define SOMETHING_UNMODIFIABLE 0xffc0 /* unused? not modifiable */
34#define IDX_IO_PLAY_IRQTYPE 0x02 /* PU:0x0001 */ 39#define IDX_IO_CODEC_IRQTYPE 0x02 /* PU:0x0001 */
35 /* write back to flags in case flags are set, in order to ACK IRQ in handler 40 /* write back to flags in case flags are set, in order to ACK IRQ in handler
36 * (bit 1 of port 0x64 indicates interrupt for one of these three types) 41 * (bit 1 of port 0x64 indicates interrupt for one of these three types)
37 * sometimes in this case it just writes 0xffff to globally ACK all IRQs 42 * sometimes in this case it just writes 0xffff to globally ACK all IRQs
38 * settings written are not reflected when reading back, though. 43 * settings written are not reflected when reading back, though.
39 * seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows ? */ 44 * seems to be IRQ, too (frequently used: port |= 0x07 !), but who knows? */
40 #define IRQ_PLAY_SOMETHING 0x0001 /* something & ACK */ 45 #define IRQ_SOMETHING 0x0001 /* something & ACK */
41 #define IRQ_FINISHED_PLAYBUF_1 0x0002 /* 1st dmabuf finished & ACK */ 46 #define IRQ_FINISHED_DMABUF_1 0x0002 /* 1st dmabuf finished & ACK */
42 #define IRQ_FINISHED_PLAYBUF_2 0x0004 /* 2nd dmabuf finished & ACK */ 47 #define IRQ_FINISHED_DMABUF_2 0x0004 /* 2nd dmabuf finished & ACK */
43 #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */ 48 #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
44 #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */ 49 #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
45 #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused ? not modifiable */ 50 #define IRQMASK_UNMODIFIABLE 0xffe0 /* unused? not modifiable */
46#define IDX_IO_PLAY_DMA_START_1 0x04 /* start address of 1st DMA play area, PU:0x00000000 */ 51 /* start address of 1st DMA transfer area, PU:0x00000000 */
47#define IDX_IO_PLAY_DMA_START_2 0x08 /* start address of 2nd DMA play area, PU:0x00000000 */ 52#define IDX_IO_CODEC_DMA_START_1 0x04
48#define IDX_IO_PLAY_DMA_LEN_1 0x0c /* length of 1st DMA play area, PU:0x0000 */ 53 /* start address of 2nd DMA transfer area, PU:0x00000000 */
49#define IDX_IO_PLAY_DMA_LEN_2 0x0e /* length of 2nd DMA play area, PU:0x0000 */ 54#define IDX_IO_CODEC_DMA_START_2 0x08
50#define IDX_IO_PLAY_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */ 55 /* both lengths of DMA transfer areas, PU:0x00000000
51#define IDX_IO_PLAY_DMA_CURROFS 0x14 /* offset within current DMA play area, PU:0x0000 */ 56 length1: offset 0x0c, length2: offset 0x0e */
52#define IDX_IO_PLAY_SOUNDFORMAT 0x16 /* PU:0x0010 */ 57#define IDX_IO_CODEC_DMA_LENGTHS 0x0c
58#define IDX_IO_CODEC_DMA_CURRPOS 0x10 /* current DMA position, PU:0x00000000 */
59 /* offset within current DMA transfer area, PU:0x0000 */
60#define IDX_IO_CODEC_DMA_CURROFS 0x14
61#define IDX_IO_CODEC_SOUNDFORMAT 0x16 /* PU:0x0010 */
53 /* all unspecified bits can't be modified */ 62 /* all unspecified bits can't be modified */
54 #define SOUNDFORMAT_FREQUENCY_MASK 0x000f 63 #define SOUNDFORMAT_FREQUENCY_MASK 0x000f
55 #define SOUNDFORMAT_XTAL1 0x00 64 #define SOUNDFORMAT_XTAL1 0x00
@@ -76,6 +85,7 @@
76 #define SOUNDFORMAT_FLAG_16BIT 0x0010 85 #define SOUNDFORMAT_FLAG_16BIT 0x0010
77 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020 86 #define SOUNDFORMAT_FLAG_2CHANNELS 0x0020
78 87
88
79/* define frequency helpers, for maximum value safety */ 89/* define frequency helpers, for maximum value safety */
80enum azf_freq_t { 90enum azf_freq_t {
81#define AZF_FREQ(rate) AZF_FREQ_##rate = rate 91#define AZF_FREQ(rate) AZF_FREQ_##rate = rate
@@ -96,29 +106,6 @@ enum azf_freq_t {
96#undef AZF_FREQ 106#undef AZF_FREQ
97}; 107};
98 108
99/** recording area (see also: playback bit flag definitions) **/
100#define IDX_IO_REC_FLAGS 0x20 /* ??, PU:0x0000 */
101#define IDX_IO_REC_IRQTYPE 0x22 /* ??, PU:0x0000 */
102 #define IRQ_REC_SOMETHING 0x0001 /* something & ACK */
103 #define IRQ_FINISHED_RECBUF_1 0x0002 /* 1st dmabuf finished & ACK */
104 #define IRQ_FINISHED_RECBUF_2 0x0004 /* 2nd dmabuf finished & ACK */
105 /* hmm, maybe these are just the corresponding *recording* flags ?
106 * but OTOH they are most likely at port 0x22 instead */
107 #define IRQMASK_SOME_STATUS_1 0x0008 /* \ related bits */
108 #define IRQMASK_SOME_STATUS_2 0x0010 /* / (checked together in loop) */
109#define IDX_IO_REC_DMA_START_1 0x24 /* PU:0x00000000 */
110#define IDX_IO_REC_DMA_START_2 0x28 /* PU:0x00000000 */
111#define IDX_IO_REC_DMA_LEN_1 0x2c /* PU:0x0000 */
112#define IDX_IO_REC_DMA_LEN_2 0x2e /* PU:0x0000 */
113#define IDX_IO_REC_DMA_CURRPOS 0x30 /* PU:0x00000000 */
114#define IDX_IO_REC_DMA_CURROFS 0x34 /* PU:0x00000000 */
115#define IDX_IO_REC_SOUNDFORMAT 0x36 /* PU:0x0000 */
116
117/** hmm, what is this I/O area for? MPU401?? or external DAC via I2S?? (after playback, recording, ???, timer) **/
118#define IDX_IO_SOMETHING_FLAGS 0x40 /* gets set to 0x34 just like port 0x0 and 0x20 on card init, PU:0x0000 */
119/* general */
120#define IDX_IO_42H 0x42 /* PU:0x0001 */
121
122/** DirectX timer, main interrupt area (FIXME: and something else?) **/ 109/** DirectX timer, main interrupt area (FIXME: and something else?) **/
123#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */ 110#define IDX_IO_TIMER_VALUE 0x60 /* found this timer area by pure luck :-) */
124 /* timer countdown value; triggers IRQ when timer is finished */ 111 /* timer countdown value; triggers IRQ when timer is finished */
@@ -133,17 +120,19 @@ enum azf_freq_t {
133#define IDX_IO_IRQSTATUS 0x64 120#define IDX_IO_IRQSTATUS 0x64
134 /* some IRQ bit in here might also be used to signal a power-management timer 121 /* some IRQ bit in here might also be used to signal a power-management timer
135 * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing). 122 * timeout, to request shutdown of the chip (e.g. AD1815JS has such a thing).
136 * Some OPL3 hardware (e.g. in LM4560) has some special timer hardware which 123 * OPL3 hardware contains several timers which confusingly in most cases
137 * can trigger an OPL3 timer IRQ, so maybe there's such a thing as well... */ 124 * are NOT routed to an IRQ, but some designs (e.g. LM4560) DO support that,
125 * so I wouldn't be surprised at all to discover that AZF3328
126 * supports that thing as well... */
138 127
139 #define IRQ_PLAYBACK 0x0001 128 #define IRQ_PLAYBACK 0x0001
140 #define IRQ_RECORDING 0x0002 129 #define IRQ_RECORDING 0x0002
141 #define IRQ_UNKNOWN1 0x0004 /* most probably I2S port */ 130 #define IRQ_I2S_OUT 0x0004 /* this IS I2S, right!? (untested) */
142 #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */ 131 #define IRQ_GAMEPORT 0x0008 /* Interrupt of Digital(ly) Enhanced Game Port */
143 #define IRQ_MPU401 0x0010 132 #define IRQ_MPU401 0x0010
144 #define IRQ_TIMER 0x0020 /* DirectX timer */ 133 #define IRQ_TIMER 0x0020 /* DirectX timer */
145 #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly I2S port? */ 134 #define IRQ_UNKNOWN2 0x0040 /* probably unused, or possibly OPL3 timer? */
146 #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly I2S port? */ 135 #define IRQ_UNKNOWN3 0x0080 /* probably unused, or possibly OPL3 timer? */
147#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ 136#define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */
148 /* this is set to e.g. 0x3ff or 0x300, and writable; 137 /* this is set to e.g. 0x3ff or 0x300, and writable;
149 * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */ 138 * maybe some buffer limit, but I couldn't find out more, PU:0x00ff: */
@@ -206,7 +195,7 @@ enum azf_freq_t {
206/*** Gameport area port indices ***/ 195/*** Gameport area port indices ***/
207/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */ 196/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
208#define AZF_IO_SIZE_GAME 0x08 197#define AZF_IO_SIZE_GAME 0x08
209#define AZF_IO_SIZE_GAME_PM 0x06 198#define AZF_IO_SIZE_GAME_PM 0x06
210 199
211enum { 200enum {
212 AZF_GAME_LEGACY_IO_PORT = 0x200 201 AZF_GAME_LEGACY_IO_PORT = 0x200
@@ -272,6 +261,12 @@ enum {
272 * 11 --> 1/200: */ 261 * 11 --> 1/200: */
273 #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06 262 #define GAME_HWCFG_ADC_COUNTER_FREQ_MASK 0x06
274 263
264 /* FIXME: these values might be reversed... */
265 #define GAME_HWCFG_ADC_COUNTER_FREQ_STD 0
266 #define GAME_HWCFG_ADC_COUNTER_FREQ_1_2 1
267 #define GAME_HWCFG_ADC_COUNTER_FREQ_1_20 2
268 #define GAME_HWCFG_ADC_COUNTER_FREQ_1_200 3
269
275 /* enable gameport legacy I/O address (0x200) 270 /* enable gameport legacy I/O address (0x200)
276 * I was unable to locate any configurability for a different address: */ 271 * I was unable to locate any configurability for a different address: */
277 #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08 272 #define GAME_HWCFG_LEGACY_ADDRESS_ENABLE 0x08
@@ -281,6 +276,7 @@ enum {
281#define AZF_IO_SIZE_MPU_PM 0x04 276#define AZF_IO_SIZE_MPU_PM 0x04
282 277
283/*** OPL3 synth ***/ 278/*** OPL3 synth ***/
279/* (only 0x06 of 0x08 bytes saved/restored by Windows driver) */
284#define AZF_IO_SIZE_OPL3 0x08 280#define AZF_IO_SIZE_OPL3 0x08
285#define AZF_IO_SIZE_OPL3_PM 0x06 281#define AZF_IO_SIZE_OPL3_PM 0x06
286/* hmm, given that a standard OPL3 has 4 registers only, 282/* hmm, given that a standard OPL3 has 4 registers only,
@@ -340,4 +336,7 @@ enum {
340#define SET_CHAN_LEFT 1 336#define SET_CHAN_LEFT 1
341#define SET_CHAN_RIGHT 2 337#define SET_CHAN_RIGHT 2
342 338
339/* helper macro to align I/O port ranges to 32bit I/O width */
340#define AZF_ALIGN(x) (((x) + 3) & (~3))
341
343#endif /* __SOUND_AZT3328_H */ 342#endif /* __SOUND_AZT3328_H */
diff --git a/sound/pci/cs46xx/cs46xx_lib.h b/sound/pci/cs46xx/cs46xx_lib.h
index 4eb55aa33612..b5189495d58a 100644
--- a/sound/pci/cs46xx/cs46xx_lib.h
+++ b/sound/pci/cs46xx/cs46xx_lib.h
@@ -35,7 +35,7 @@
35 35
36 36
37#ifdef CONFIG_SND_CS46XX_NEW_DSP 37#ifdef CONFIG_SND_CS46XX_NEW_DSP
38#define CS46XX_MIN_PERIOD_SIZE 1 38#define CS46XX_MIN_PERIOD_SIZE 64
39#define CS46XX_MAX_PERIOD_SIZE 1024*1024 39#define CS46XX_MAX_PERIOD_SIZE 1024*1024
40#else 40#else
41#define CS46XX_MIN_PERIOD_SIZE 2048 41#define CS46XX_MIN_PERIOD_SIZE 2048
diff --git a/sound/pci/ctxfi/ct20k2reg.h b/sound/pci/ctxfi/ct20k2reg.h
index 2d07986f57cc..e0394e3996e8 100644
--- a/sound/pci/ctxfi/ct20k2reg.h
+++ b/sound/pci/ctxfi/ct20k2reg.h
@@ -11,9 +11,12 @@
11 11
12 12
13/* Timer Registers */ 13/* Timer Registers */
14#define TIMER_TIMR 0x1B7004 14#define WC 0x1b7000
15#define INTERRUPT_GIP 0x1B7010 15#define TIMR 0x1b7004
16#define INTERRUPT_GIE 0x1B7014 16# define TIMR_IE (1<<15)
17# define TIMR_IP (1<<14)
18#define GIP 0x1b7010
19#define GIE 0x1b7014
17 20
18/* I2C Registers */ 21/* I2C Registers */
19#define I2C_IF_ADDRESS 0x1B9000 22#define I2C_IF_ADDRESS 0x1B9000
diff --git a/sound/pci/ctxfi/ctamixer.c b/sound/pci/ctxfi/ctamixer.c
index a7f4a671f7b7..fee35cfc0c7f 100644
--- a/sound/pci/ctxfi/ctamixer.c
+++ b/sound/pci/ctxfi/ctamixer.c
@@ -63,7 +63,7 @@ static int amixer_set_input(struct amixer *amixer, struct rsc *rsc)
63 hw = amixer->rsc.hw; 63 hw = amixer->rsc.hw;
64 hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE); 64 hw->amixer_set_mode(amixer->rsc.ctrl_blk, AMIXER_Y_IMMEDIATE);
65 amixer->input = rsc; 65 amixer->input = rsc;
66 if (NULL == rsc) 66 if (!rsc)
67 hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT); 67 hw->amixer_set_x(amixer->rsc.ctrl_blk, BLANK_SLOT);
68 else 68 else
69 hw->amixer_set_x(amixer->rsc.ctrl_blk, 69 hw->amixer_set_x(amixer->rsc.ctrl_blk,
@@ -99,7 +99,7 @@ static int amixer_set_sum(struct amixer *amixer, struct sum *sum)
99 99
100 hw = amixer->rsc.hw; 100 hw = amixer->rsc.hw;
101 amixer->sum = sum; 101 amixer->sum = sum;
102 if (NULL == sum) { 102 if (!sum) {
103 hw->amixer_set_se(amixer->rsc.ctrl_blk, 0); 103 hw->amixer_set_se(amixer->rsc.ctrl_blk, 0);
104 } else { 104 } else {
105 hw->amixer_set_se(amixer->rsc.ctrl_blk, 1); 105 hw->amixer_set_se(amixer->rsc.ctrl_blk, 1);
@@ -124,20 +124,20 @@ static int amixer_commit_write(struct amixer *amixer)
124 124
125 /* Program master and conjugate resources */ 125 /* Program master and conjugate resources */
126 amixer->rsc.ops->master(&amixer->rsc); 126 amixer->rsc.ops->master(&amixer->rsc);
127 if (NULL != input) 127 if (input)
128 input->ops->master(input); 128 input->ops->master(input);
129 129
130 if (NULL != sum) 130 if (sum)
131 sum->rsc.ops->master(&sum->rsc); 131 sum->rsc.ops->master(&sum->rsc);
132 132
133 for (i = 0; i < amixer->rsc.msr; i++) { 133 for (i = 0; i < amixer->rsc.msr; i++) {
134 hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk); 134 hw->amixer_set_dirty_all(amixer->rsc.ctrl_blk);
135 if (NULL != input) { 135 if (input) {
136 hw->amixer_set_x(amixer->rsc.ctrl_blk, 136 hw->amixer_set_x(amixer->rsc.ctrl_blk,
137 input->ops->output_slot(input)); 137 input->ops->output_slot(input));
138 input->ops->next_conj(input); 138 input->ops->next_conj(input);
139 } 139 }
140 if (NULL != sum) { 140 if (sum) {
141 hw->amixer_set_sadr(amixer->rsc.ctrl_blk, 141 hw->amixer_set_sadr(amixer->rsc.ctrl_blk,
142 sum->rsc.ops->index(&sum->rsc)); 142 sum->rsc.ops->index(&sum->rsc));
143 sum->rsc.ops->next_conj(&sum->rsc); 143 sum->rsc.ops->next_conj(&sum->rsc);
@@ -147,10 +147,10 @@ static int amixer_commit_write(struct amixer *amixer)
147 amixer->rsc.ops->next_conj(&amixer->rsc); 147 amixer->rsc.ops->next_conj(&amixer->rsc);
148 } 148 }
149 amixer->rsc.ops->master(&amixer->rsc); 149 amixer->rsc.ops->master(&amixer->rsc);
150 if (NULL != input) 150 if (input)
151 input->ops->master(input); 151 input->ops->master(input);
152 152
153 if (NULL != sum) 153 if (sum)
154 sum->rsc.ops->master(&sum->rsc); 154 sum->rsc.ops->master(&sum->rsc);
155 155
156 return 0; 156 return 0;
@@ -303,7 +303,7 @@ int amixer_mgr_create(void *hw, struct amixer_mgr **ramixer_mgr)
303 303
304 *ramixer_mgr = NULL; 304 *ramixer_mgr = NULL;
305 amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL); 305 amixer_mgr = kzalloc(sizeof(*amixer_mgr), GFP_KERNEL);
306 if (NULL == amixer_mgr) 306 if (!amixer_mgr)
307 return -ENOMEM; 307 return -ENOMEM;
308 308
309 err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw); 309 err = rsc_mgr_init(&amixer_mgr->mgr, AMIXER, AMIXER_RESOURCE_NUM, hw);
@@ -456,7 +456,7 @@ int sum_mgr_create(void *hw, struct sum_mgr **rsum_mgr)
456 456
457 *rsum_mgr = NULL; 457 *rsum_mgr = NULL;
458 sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL); 458 sum_mgr = kzalloc(sizeof(*sum_mgr), GFP_KERNEL);
459 if (NULL == sum_mgr) 459 if (!sum_mgr)
460 return -ENOMEM; 460 return -ENOMEM;
461 461
462 err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw); 462 err = rsc_mgr_init(&sum_mgr->mgr, SUM, SUM_RESOURCE_NUM, hw);
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index a49c76647307..b1b3a644f738 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -136,7 +136,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
136 struct snd_pcm_runtime *runtime; 136 struct snd_pcm_runtime *runtime;
137 struct ct_vm *vm; 137 struct ct_vm *vm;
138 138
139 if (NULL == apcm->substream) 139 if (!apcm->substream)
140 return 0; 140 return 0;
141 141
142 runtime = apcm->substream->runtime; 142 runtime = apcm->substream->runtime;
@@ -144,7 +144,7 @@ static int ct_map_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
144 144
145 apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes); 145 apcm->vm_block = vm->map(vm, apcm->substream, runtime->dma_bytes);
146 146
147 if (NULL == apcm->vm_block) 147 if (!apcm->vm_block)
148 return -ENOENT; 148 return -ENOENT;
149 149
150 return 0; 150 return 0;
@@ -154,7 +154,7 @@ static void ct_unmap_audio_buffer(struct ct_atc *atc, struct ct_atc_pcm *apcm)
154{ 154{
155 struct ct_vm *vm; 155 struct ct_vm *vm;
156 156
157 if (NULL == apcm->vm_block) 157 if (!apcm->vm_block)
158 return; 158 return;
159 159
160 vm = atc->vm; 160 vm = atc->vm;
@@ -231,16 +231,16 @@ atc_get_pitch(unsigned int input_rate, unsigned int output_rate)
231 231
232static int select_rom(unsigned int pitch) 232static int select_rom(unsigned int pitch)
233{ 233{
234 if ((pitch > 0x00428f5c) && (pitch < 0x01b851ec)) { 234 if (pitch > 0x00428f5c && pitch < 0x01b851ec) {
235 /* 0.26 <= pitch <= 1.72 */ 235 /* 0.26 <= pitch <= 1.72 */
236 return 1; 236 return 1;
237 } else if ((0x01d66666 == pitch) || (0x01d66667 == pitch)) { 237 } else if (pitch == 0x01d66666 || pitch == 0x01d66667) {
238 /* pitch == 1.8375 */ 238 /* pitch == 1.8375 */
239 return 2; 239 return 2;
240 } else if (0x02000000 == pitch) { 240 } else if (pitch == 0x02000000) {
241 /* pitch == 2 */ 241 /* pitch == 2 */
242 return 3; 242 return 3;
243 } else if ((pitch >= 0x0) && (pitch <= 0x08000000)) { 243 } else if (pitch >= 0x0 && pitch <= 0x08000000) {
244 /* 0 <= pitch <= 8 */ 244 /* 0 <= pitch <= 8 */
245 return 0; 245 return 0;
246 } else { 246 } else {
@@ -283,7 +283,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
283 /* Get AMIXER resource */ 283 /* Get AMIXER resource */
284 n_amixer = (n_amixer < 2) ? 2 : n_amixer; 284 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
285 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); 285 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
286 if (NULL == apcm->amixers) { 286 if (!apcm->amixers) {
287 err = -ENOMEM; 287 err = -ENOMEM;
288 goto error1; 288 goto error1;
289 } 289 }
@@ -311,7 +311,7 @@ static int atc_pcm_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
311 INIT_VOL, atc->pcm[i+device*2]); 311 INIT_VOL, atc->pcm[i+device*2]);
312 mutex_unlock(&atc->atc_mutex); 312 mutex_unlock(&atc->atc_mutex);
313 src = src->ops->next_interleave(src); 313 src = src->ops->next_interleave(src);
314 if (NULL == src) 314 if (!src)
315 src = apcm->src; 315 src = apcm->src;
316 } 316 }
317 317
@@ -334,7 +334,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
334 struct srcimp *srcimp; 334 struct srcimp *srcimp;
335 int i; 335 int i;
336 336
337 if (NULL != apcm->srcimps) { 337 if (apcm->srcimps) {
338 for (i = 0; i < apcm->n_srcimp; i++) { 338 for (i = 0; i < apcm->n_srcimp; i++) {
339 srcimp = apcm->srcimps[i]; 339 srcimp = apcm->srcimps[i];
340 srcimp->ops->unmap(srcimp); 340 srcimp->ops->unmap(srcimp);
@@ -345,7 +345,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
345 apcm->srcimps = NULL; 345 apcm->srcimps = NULL;
346 } 346 }
347 347
348 if (NULL != apcm->srccs) { 348 if (apcm->srccs) {
349 for (i = 0; i < apcm->n_srcc; i++) { 349 for (i = 0; i < apcm->n_srcc; i++) {
350 src_mgr->put_src(src_mgr, apcm->srccs[i]); 350 src_mgr->put_src(src_mgr, apcm->srccs[i]);
351 apcm->srccs[i] = NULL; 351 apcm->srccs[i] = NULL;
@@ -354,7 +354,7 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
354 apcm->srccs = NULL; 354 apcm->srccs = NULL;
355 } 355 }
356 356
357 if (NULL != apcm->amixers) { 357 if (apcm->amixers) {
358 for (i = 0; i < apcm->n_amixer; i++) { 358 for (i = 0; i < apcm->n_amixer; i++) {
359 amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]); 359 amixer_mgr->put_amixer(amixer_mgr, apcm->amixers[i]);
360 apcm->amixers[i] = NULL; 360 apcm->amixers[i] = NULL;
@@ -363,17 +363,17 @@ atc_pcm_release_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
363 apcm->amixers = NULL; 363 apcm->amixers = NULL;
364 } 364 }
365 365
366 if (NULL != apcm->mono) { 366 if (apcm->mono) {
367 sum_mgr->put_sum(sum_mgr, apcm->mono); 367 sum_mgr->put_sum(sum_mgr, apcm->mono);
368 apcm->mono = NULL; 368 apcm->mono = NULL;
369 } 369 }
370 370
371 if (NULL != apcm->src) { 371 if (apcm->src) {
372 src_mgr->put_src(src_mgr, apcm->src); 372 src_mgr->put_src(src_mgr, apcm->src);
373 apcm->src = NULL; 373 apcm->src = NULL;
374 } 374 }
375 375
376 if (NULL != apcm->vm_block) { 376 if (apcm->vm_block) {
377 /* Undo device virtual mem map */ 377 /* Undo device virtual mem map */
378 ct_unmap_audio_buffer(atc, apcm); 378 ct_unmap_audio_buffer(atc, apcm);
379 apcm->vm_block = NULL; 379 apcm->vm_block = NULL;
@@ -419,7 +419,7 @@ static int atc_pcm_stop(struct ct_atc *atc, struct ct_atc_pcm *apcm)
419 src->ops->set_state(src, SRC_STATE_OFF); 419 src->ops->set_state(src, SRC_STATE_OFF);
420 src->ops->commit_write(src); 420 src->ops->commit_write(src);
421 421
422 if (NULL != apcm->srccs) { 422 if (apcm->srccs) {
423 for (i = 0; i < apcm->n_srcc; i++) { 423 for (i = 0; i < apcm->n_srcc; i++) {
424 src = apcm->srccs[i]; 424 src = apcm->srccs[i];
425 src->ops->set_bm(src, 0); 425 src->ops->set_bm(src, 0);
@@ -544,18 +544,18 @@ atc_pcm_capture_get_resources(struct ct_atc *atc, struct ct_atc_pcm *apcm)
544 544
545 if (n_srcc) { 545 if (n_srcc) {
546 apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL); 546 apcm->srccs = kzalloc(sizeof(void *)*n_srcc, GFP_KERNEL);
547 if (NULL == apcm->srccs) 547 if (!apcm->srccs)
548 return -ENOMEM; 548 return -ENOMEM;
549 } 549 }
550 if (n_amixer) { 550 if (n_amixer) {
551 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); 551 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
552 if (NULL == apcm->amixers) { 552 if (!apcm->amixers) {
553 err = -ENOMEM; 553 err = -ENOMEM;
554 goto error1; 554 goto error1;
555 } 555 }
556 } 556 }
557 apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL); 557 apcm->srcimps = kzalloc(sizeof(void *)*n_srcimp, GFP_KERNEL);
558 if (NULL == apcm->srcimps) { 558 if (!apcm->srcimps) {
559 err = -ENOMEM; 559 err = -ENOMEM;
560 goto error1; 560 goto error1;
561 } 561 }
@@ -818,7 +818,7 @@ static int spdif_passthru_playback_get_resources(struct ct_atc *atc,
818 /* Get AMIXER resource */ 818 /* Get AMIXER resource */
819 n_amixer = (n_amixer < 2) ? 2 : n_amixer; 819 n_amixer = (n_amixer < 2) ? 2 : n_amixer;
820 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL); 820 apcm->amixers = kzalloc(sizeof(void *)*n_amixer, GFP_KERNEL);
821 if (NULL == apcm->amixers) { 821 if (!apcm->amixers) {
822 err = -ENOMEM; 822 err = -ENOMEM;
823 goto error1; 823 goto error1;
824 } 824 }
@@ -919,7 +919,7 @@ spdif_passthru_playback_prepare(struct ct_atc *atc, struct ct_atc_pcm *apcm)
919 amixer = apcm->amixers[i]; 919 amixer = apcm->amixers[i];
920 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL); 920 amixer->ops->setup(amixer, &src->rsc, INIT_VOL, NULL);
921 src = src->ops->next_interleave(src); 921 src = src->ops->next_interleave(src);
922 if (NULL == src) 922 if (!src)
923 src = apcm->src; 923 src = apcm->src;
924 } 924 }
925 /* Connect to SPDIFOO */ 925 /* Connect to SPDIFOO */
@@ -1121,7 +1121,7 @@ static int atc_release_resources(struct ct_atc *atc)
1121 struct ct_mixer *mixer = NULL; 1121 struct ct_mixer *mixer = NULL;
1122 1122
1123 /* disconnect internal mixer objects */ 1123 /* disconnect internal mixer objects */
1124 if (NULL != atc->mixer) { 1124 if (atc->mixer) {
1125 mixer = atc->mixer; 1125 mixer = atc->mixer;
1126 mixer->set_input_left(mixer, MIX_LINE_IN, NULL); 1126 mixer->set_input_left(mixer, MIX_LINE_IN, NULL);
1127 mixer->set_input_right(mixer, MIX_LINE_IN, NULL); 1127 mixer->set_input_right(mixer, MIX_LINE_IN, NULL);
@@ -1131,7 +1131,7 @@ static int atc_release_resources(struct ct_atc *atc)
1131 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL); 1131 mixer->set_input_right(mixer, MIX_SPDIF_IN, NULL);
1132 } 1132 }
1133 1133
1134 if (NULL != atc->daios) { 1134 if (atc->daios) {
1135 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; 1135 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
1136 for (i = 0; i < atc->n_daio; i++) { 1136 for (i = 0; i < atc->n_daio; i++) {
1137 daio = atc->daios[i]; 1137 daio = atc->daios[i];
@@ -1149,7 +1149,7 @@ static int atc_release_resources(struct ct_atc *atc)
1149 atc->daios = NULL; 1149 atc->daios = NULL;
1150 } 1150 }
1151 1151
1152 if (NULL != atc->pcm) { 1152 if (atc->pcm) {
1153 sum_mgr = atc->rsc_mgrs[SUM]; 1153 sum_mgr = atc->rsc_mgrs[SUM];
1154 for (i = 0; i < atc->n_pcm; i++) 1154 for (i = 0; i < atc->n_pcm; i++)
1155 sum_mgr->put_sum(sum_mgr, atc->pcm[i]); 1155 sum_mgr->put_sum(sum_mgr, atc->pcm[i]);
@@ -1158,7 +1158,7 @@ static int atc_release_resources(struct ct_atc *atc)
1158 atc->pcm = NULL; 1158 atc->pcm = NULL;
1159 } 1159 }
1160 1160
1161 if (NULL != atc->srcs) { 1161 if (atc->srcs) {
1162 src_mgr = atc->rsc_mgrs[SRC]; 1162 src_mgr = atc->rsc_mgrs[SRC];
1163 for (i = 0; i < atc->n_src; i++) 1163 for (i = 0; i < atc->n_src; i++)
1164 src_mgr->put_src(src_mgr, atc->srcs[i]); 1164 src_mgr->put_src(src_mgr, atc->srcs[i]);
@@ -1167,7 +1167,7 @@ static int atc_release_resources(struct ct_atc *atc)
1167 atc->srcs = NULL; 1167 atc->srcs = NULL;
1168 } 1168 }
1169 1169
1170 if (NULL != atc->srcimps) { 1170 if (atc->srcimps) {
1171 srcimp_mgr = atc->rsc_mgrs[SRCIMP]; 1171 srcimp_mgr = atc->rsc_mgrs[SRCIMP];
1172 for (i = 0; i < atc->n_srcimp; i++) { 1172 for (i = 0; i < atc->n_srcimp; i++) {
1173 srcimp = atc->srcimps[i]; 1173 srcimp = atc->srcimps[i];
@@ -1185,7 +1185,7 @@ static int ct_atc_destroy(struct ct_atc *atc)
1185{ 1185{
1186 int i = 0; 1186 int i = 0;
1187 1187
1188 if (NULL == atc) 1188 if (!atc)
1189 return 0; 1189 return 0;
1190 1190
1191 if (atc->timer) { 1191 if (atc->timer) {
@@ -1196,21 +1196,20 @@ static int ct_atc_destroy(struct ct_atc *atc)
1196 atc_release_resources(atc); 1196 atc_release_resources(atc);
1197 1197
1198 /* Destroy internal mixer objects */ 1198 /* Destroy internal mixer objects */
1199 if (NULL != atc->mixer) 1199 if (atc->mixer)
1200 ct_mixer_destroy(atc->mixer); 1200 ct_mixer_destroy(atc->mixer);
1201 1201
1202 for (i = 0; i < NUM_RSCTYP; i++) { 1202 for (i = 0; i < NUM_RSCTYP; i++) {
1203 if ((NULL != rsc_mgr_funcs[i].destroy) && 1203 if (rsc_mgr_funcs[i].destroy && atc->rsc_mgrs[i])
1204 (NULL != atc->rsc_mgrs[i]))
1205 rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]); 1204 rsc_mgr_funcs[i].destroy(atc->rsc_mgrs[i]);
1206 1205
1207 } 1206 }
1208 1207
1209 if (NULL != atc->hw) 1208 if (atc->hw)
1210 destroy_hw_obj((struct hw *)atc->hw); 1209 destroy_hw_obj((struct hw *)atc->hw);
1211 1210
1212 /* Destroy device virtual memory manager object */ 1211 /* Destroy device virtual memory manager object */
1213 if (NULL != atc->vm) { 1212 if (atc->vm) {
1214 ct_vm_destroy(atc->vm); 1213 ct_vm_destroy(atc->vm);
1215 atc->vm = NULL; 1214 atc->vm = NULL;
1216 } 1215 }
@@ -1275,7 +1274,7 @@ int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc)
1275 alsa_dev_funcs[MIXER].public_name = atc->chip_name; 1274 alsa_dev_funcs[MIXER].public_name = atc->chip_name;
1276 1275
1277 for (i = 0; i < NUM_CTALSADEVS; i++) { 1276 for (i = 0; i < NUM_CTALSADEVS; i++) {
1278 if (NULL == alsa_dev_funcs[i].create) 1277 if (!alsa_dev_funcs[i].create)
1279 continue; 1278 continue;
1280 1279
1281 err = alsa_dev_funcs[i].create(atc, i, 1280 err = alsa_dev_funcs[i].create(atc, i,
@@ -1312,7 +1311,7 @@ static int __devinit atc_create_hw_devs(struct ct_atc *atc)
1312 return err; 1311 return err;
1313 1312
1314 for (i = 0; i < NUM_RSCTYP; i++) { 1313 for (i = 0; i < NUM_RSCTYP; i++) {
1315 if (NULL == rsc_mgr_funcs[i].create) 1314 if (!rsc_mgr_funcs[i].create)
1316 continue; 1315 continue;
1317 1316
1318 err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]); 1317 err = rsc_mgr_funcs[i].create(atc->hw, &atc->rsc_mgrs[i]);
@@ -1339,19 +1338,19 @@ static int atc_get_resources(struct ct_atc *atc)
1339 int err, i; 1338 int err, i;
1340 1339
1341 atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL); 1340 atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
1342 if (NULL == atc->daios) 1341 if (!atc->daios)
1343 return -ENOMEM; 1342 return -ENOMEM;
1344 1343
1345 atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1344 atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1346 if (NULL == atc->srcs) 1345 if (!atc->srcs)
1347 return -ENOMEM; 1346 return -ENOMEM;
1348 1347
1349 atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL); 1348 atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
1350 if (NULL == atc->srcimps) 1349 if (!atc->srcimps)
1351 return -ENOMEM; 1350 return -ENOMEM;
1352 1351
1353 atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL); 1352 atc->pcm = kzalloc(sizeof(void *)*(2*4), GFP_KERNEL);
1354 if (NULL == atc->pcm) 1353 if (!atc->pcm)
1355 return -ENOMEM; 1354 return -ENOMEM;
1356 1355
1357 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO]; 1356 daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
@@ -1648,7 +1647,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
1648 *ratc = NULL; 1647 *ratc = NULL;
1649 1648
1650 atc = kzalloc(sizeof(*atc), GFP_KERNEL); 1649 atc = kzalloc(sizeof(*atc), GFP_KERNEL);
1651 if (NULL == atc) 1650 if (!atc)
1652 return -ENOMEM; 1651 return -ENOMEM;
1653 1652
1654 /* Set operations */ 1653 /* Set operations */
diff --git a/sound/pci/ctxfi/ctdaio.c b/sound/pci/ctxfi/ctdaio.c
index deb6cfa73600..af56eb949bde 100644
--- a/sound/pci/ctxfi/ctdaio.c
+++ b/sound/pci/ctxfi/ctdaio.c
@@ -173,7 +173,7 @@ static int dao_set_left_input(struct dao *dao, struct rsc *input)
173 int i; 173 int i;
174 174
175 entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL); 175 entry = kzalloc((sizeof(*entry) * daio->rscl.msr), GFP_KERNEL);
176 if (NULL == entry) 176 if (!entry)
177 return -ENOMEM; 177 return -ENOMEM;
178 178
179 /* Program master and conjugate resources */ 179 /* Program master and conjugate resources */
@@ -201,7 +201,7 @@ static int dao_set_right_input(struct dao *dao, struct rsc *input)
201 int i; 201 int i;
202 202
203 entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL); 203 entry = kzalloc((sizeof(*entry) * daio->rscr.msr), GFP_KERNEL);
204 if (NULL == entry) 204 if (!entry)
205 return -ENOMEM; 205 return -ENOMEM;
206 206
207 /* Program master and conjugate resources */ 207 /* Program master and conjugate resources */
@@ -228,7 +228,7 @@ static int dao_clear_left_input(struct dao *dao)
228 struct daio *daio = &dao->daio; 228 struct daio *daio = &dao->daio;
229 int i; 229 int i;
230 230
231 if (NULL == dao->imappers[0]) 231 if (!dao->imappers[0])
232 return 0; 232 return 0;
233 233
234 entry = dao->imappers[0]; 234 entry = dao->imappers[0];
@@ -252,7 +252,7 @@ static int dao_clear_right_input(struct dao *dao)
252 struct daio *daio = &dao->daio; 252 struct daio *daio = &dao->daio;
253 int i; 253 int i;
254 254
255 if (NULL == dao->imappers[daio->rscl.msr]) 255 if (!dao->imappers[daio->rscl.msr])
256 return 0; 256 return 0;
257 257
258 entry = dao->imappers[daio->rscl.msr]; 258 entry = dao->imappers[daio->rscl.msr];
@@ -408,7 +408,7 @@ static int dao_rsc_init(struct dao *dao,
408 return err; 408 return err;
409 409
410 dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL); 410 dao->imappers = kzalloc(sizeof(void *)*desc->msr*2, GFP_KERNEL);
411 if (NULL == dao->imappers) { 411 if (!dao->imappers) {
412 err = -ENOMEM; 412 err = -ENOMEM;
413 goto error1; 413 goto error1;
414 } 414 }
@@ -442,11 +442,11 @@ error1:
442 442
443static int dao_rsc_uninit(struct dao *dao) 443static int dao_rsc_uninit(struct dao *dao)
444{ 444{
445 if (NULL != dao->imappers) { 445 if (dao->imappers) {
446 if (NULL != dao->imappers[0]) 446 if (dao->imappers[0])
447 dao_clear_left_input(dao); 447 dao_clear_left_input(dao);
448 448
449 if (NULL != dao->imappers[dao->daio.rscl.msr]) 449 if (dao->imappers[dao->daio.rscl.msr])
450 dao_clear_right_input(dao); 450 dao_clear_right_input(dao);
451 451
452 kfree(dao->imappers); 452 kfree(dao->imappers);
@@ -555,7 +555,7 @@ static int get_daio_rsc(struct daio_mgr *mgr,
555 /* Allocate mem for daio resource */ 555 /* Allocate mem for daio resource */
556 if (desc->type <= DAIO_OUT_MAX) { 556 if (desc->type <= DAIO_OUT_MAX) {
557 dao = kzalloc(sizeof(*dao), GFP_KERNEL); 557 dao = kzalloc(sizeof(*dao), GFP_KERNEL);
558 if (NULL == dao) { 558 if (!dao) {
559 err = -ENOMEM; 559 err = -ENOMEM;
560 goto error; 560 goto error;
561 } 561 }
@@ -566,7 +566,7 @@ static int get_daio_rsc(struct daio_mgr *mgr,
566 *rdaio = &dao->daio; 566 *rdaio = &dao->daio;
567 } else { 567 } else {
568 dai = kzalloc(sizeof(*dai), GFP_KERNEL); 568 dai = kzalloc(sizeof(*dai), GFP_KERNEL);
569 if (NULL == dai) { 569 if (!dai) {
570 err = -ENOMEM; 570 err = -ENOMEM;
571 goto error; 571 goto error;
572 } 572 }
@@ -583,9 +583,9 @@ static int get_daio_rsc(struct daio_mgr *mgr,
583 return 0; 583 return 0;
584 584
585error: 585error:
586 if (NULL != dao) 586 if (dao)
587 kfree(dao); 587 kfree(dao);
588 else if (NULL != dai) 588 else if (dai)
589 kfree(dai); 589 kfree(dai);
590 590
591 spin_lock_irqsave(&mgr->mgr_lock, flags); 591 spin_lock_irqsave(&mgr->mgr_lock, flags);
@@ -663,7 +663,7 @@ static int daio_imap_add(struct daio_mgr *mgr, struct imapper *entry)
663 int err; 663 int err;
664 664
665 spin_lock_irqsave(&mgr->imap_lock, flags); 665 spin_lock_irqsave(&mgr->imap_lock, flags);
666 if ((0 == entry->addr) && (mgr->init_imap_added)) { 666 if (!entry->addr && mgr->init_imap_added) {
667 input_mapper_delete(&mgr->imappers, mgr->init_imap, 667 input_mapper_delete(&mgr->imappers, mgr->init_imap,
668 daio_map_op, mgr); 668 daio_map_op, mgr);
669 mgr->init_imap_added = 0; 669 mgr->init_imap_added = 0;
@@ -707,7 +707,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
707 707
708 *rdaio_mgr = NULL; 708 *rdaio_mgr = NULL;
709 daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL); 709 daio_mgr = kzalloc(sizeof(*daio_mgr), GFP_KERNEL);
710 if (NULL == daio_mgr) 710 if (!daio_mgr)
711 return -ENOMEM; 711 return -ENOMEM;
712 712
713 err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw); 713 err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
@@ -718,7 +718,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
718 spin_lock_init(&daio_mgr->imap_lock); 718 spin_lock_init(&daio_mgr->imap_lock);
719 INIT_LIST_HEAD(&daio_mgr->imappers); 719 INIT_LIST_HEAD(&daio_mgr->imappers);
720 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 720 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
721 if (NULL == entry) { 721 if (!entry) {
722 err = -ENOMEM; 722 err = -ENOMEM;
723 goto error2; 723 goto error2;
724 } 724 }
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index ad3e1d144464..0cf400f879f9 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -168,7 +168,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
168 168
169 *rblk = NULL; 169 *rblk = NULL;
170 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 170 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
171 if (NULL == blk) 171 if (!blk)
172 return -ENOMEM; 172 return -ENOMEM;
173 173
174 *rblk = blk; 174 *rblk = blk;
@@ -494,7 +494,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
494 494
495 *rblk = NULL; 495 *rblk = NULL;
496 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 496 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
497 if (NULL == blk) 497 if (!blk)
498 return -ENOMEM; 498 return -ENOMEM;
499 499
500 *rblk = blk; 500 *rblk = blk;
@@ -515,7 +515,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
515 515
516 *rblk = NULL; 516 *rblk = NULL;
517 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 517 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
518 if (NULL == blk) 518 if (!blk)
519 return -ENOMEM; 519 return -ENOMEM;
520 520
521 *rblk = blk; 521 *rblk = blk;
@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
702 702
703 *rblk = NULL; 703 *rblk = NULL;
704 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 704 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
705 if (NULL == blk) 705 if (!blk)
706 return -ENOMEM; 706 return -ENOMEM;
707 707
708 *rblk = blk; 708 *rblk = blk;
@@ -723,7 +723,7 @@ static int amixer_mgr_get_ctrl_blk(void **rblk)
723 723
724 *rblk = NULL; 724 *rblk = NULL;
725 /*blk = kzalloc(sizeof(*blk), GFP_KERNEL); 725 /*blk = kzalloc(sizeof(*blk), GFP_KERNEL);
726 if (NULL == blk) 726 if (!blk)
727 return -ENOMEM; 727 return -ENOMEM;
728 728
729 *rblk = blk;*/ 729 *rblk = blk;*/
@@ -909,7 +909,7 @@ static int dai_get_ctrl_blk(void **rblk)
909 909
910 *rblk = NULL; 910 *rblk = NULL;
911 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 911 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
912 if (NULL == blk) 912 if (!blk)
913 return -ENOMEM; 913 return -ENOMEM;
914 914
915 *rblk = blk; 915 *rblk = blk;
@@ -958,7 +958,7 @@ static int dao_get_ctrl_blk(void **rblk)
958 958
959 *rblk = NULL; 959 *rblk = NULL;
960 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 960 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
961 if (NULL == blk) 961 if (!blk)
962 return -ENOMEM; 962 return -ENOMEM;
963 963
964 *rblk = blk; 964 *rblk = blk;
@@ -1152,7 +1152,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
1152 1152
1153 *rblk = NULL; 1153 *rblk = NULL;
1154 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 1154 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
1155 if (NULL == blk) 1155 if (!blk)
1156 return -ENOMEM; 1156 return -ENOMEM;
1157 1157
1158 blk->i2sctl = hw_read_20kx(hw, I2SCTL); 1158 blk->i2sctl = hw_read_20kx(hw, I2SCTL);
@@ -1808,7 +1808,7 @@ static int uaa_to_xfi(struct pci_dev *pci)
1808 /* By default, Hendrix card UAA Bar0 should be using memory... */ 1808 /* By default, Hendrix card UAA Bar0 should be using memory... */
1809 io_base = pci_resource_start(pci, 0); 1809 io_base = pci_resource_start(pci, 0);
1810 mem_base = ioremap(io_base, pci_resource_len(pci, 0)); 1810 mem_base = ioremap(io_base, pci_resource_len(pci, 0));
1811 if (NULL == mem_base) 1811 if (!mem_base)
1812 return -ENOENT; 1812 return -ENOENT;
1813 1813
1814 /* Read current mode from Mode Change Register */ 1814 /* Read current mode from Mode Change Register */
@@ -1977,7 +1977,7 @@ static int hw_card_shutdown(struct hw *hw)
1977 1977
1978 hw->irq = -1; 1978 hw->irq = -1;
1979 1979
1980 if (NULL != ((void *)hw->mem_base)) 1980 if (hw->mem_base)
1981 iounmap((void *)hw->mem_base); 1981 iounmap((void *)hw->mem_base);
1982 1982
1983 hw->mem_base = (unsigned long)NULL; 1983 hw->mem_base = (unsigned long)NULL;
@@ -2274,7 +2274,7 @@ int __devinit create_20k1_hw_obj(struct hw **rhw)
2274 2274
2275 *rhw = NULL; 2275 *rhw = NULL;
2276 hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL); 2276 hw20k1 = kzalloc(sizeof(*hw20k1), GFP_KERNEL);
2277 if (NULL == hw20k1) 2277 if (!hw20k1)
2278 return -ENOMEM; 2278 return -ENOMEM;
2279 2279
2280 spin_lock_init(&hw20k1->reg_20k1_lock); 2280 spin_lock_init(&hw20k1->reg_20k1_lock);
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index dec46d04b041..b6b11bfe7574 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -166,7 +166,7 @@ static int src_get_rsc_ctrl_blk(void **rblk)
166 166
167 *rblk = NULL; 167 *rblk = NULL;
168 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 168 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
169 if (NULL == blk) 169 if (!blk)
170 return -ENOMEM; 170 return -ENOMEM;
171 171
172 *rblk = blk; 172 *rblk = blk;
@@ -492,7 +492,7 @@ static int src_mgr_get_ctrl_blk(void **rblk)
492 492
493 *rblk = NULL; 493 *rblk = NULL;
494 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 494 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
495 if (NULL == blk) 495 if (!blk)
496 return -ENOMEM; 496 return -ENOMEM;
497 497
498 *rblk = blk; 498 *rblk = blk;
@@ -513,7 +513,7 @@ static int srcimp_mgr_get_ctrl_blk(void **rblk)
513 513
514 *rblk = NULL; 514 *rblk = NULL;
515 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 515 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
516 if (NULL == blk) 516 if (!blk)
517 return -ENOMEM; 517 return -ENOMEM;
518 518
519 *rblk = blk; 519 *rblk = blk;
@@ -702,7 +702,7 @@ static int amixer_rsc_get_ctrl_blk(void **rblk)
702 702
703 *rblk = NULL; 703 *rblk = NULL;
704 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 704 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
705 if (NULL == blk) 705 if (!blk)
706 return -ENOMEM; 706 return -ENOMEM;
707 707
708 *rblk = blk; 708 *rblk = blk;
@@ -891,7 +891,7 @@ static int dai_get_ctrl_blk(void **rblk)
891 891
892 *rblk = NULL; 892 *rblk = NULL;
893 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 893 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
894 if (NULL == blk) 894 if (!blk)
895 return -ENOMEM; 895 return -ENOMEM;
896 896
897 *rblk = blk; 897 *rblk = blk;
@@ -941,7 +941,7 @@ static int dao_get_ctrl_blk(void **rblk)
941 941
942 *rblk = NULL; 942 *rblk = NULL;
943 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 943 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
944 if (NULL == blk) 944 if (!blk)
945 return -ENOMEM; 945 return -ENOMEM;
946 946
947 *rblk = blk; 947 *rblk = blk;
@@ -1092,7 +1092,7 @@ static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
1092 1092
1093 *rblk = NULL; 1093 *rblk = NULL;
1094 blk = kzalloc(sizeof(*blk), GFP_KERNEL); 1094 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
1095 if (NULL == blk) 1095 if (!blk)
1096 return -ENOMEM; 1096 return -ENOMEM;
1097 1097
1098 for (i = 0; i < 8; i++) { 1098 for (i = 0; i < 8; i++) {
@@ -1112,6 +1112,26 @@ static int daio_mgr_put_ctrl_blk(void *blk)
1112 return 0; 1112 return 0;
1113} 1113}
1114 1114
1115/* Timer interrupt */
1116static int set_timer_irq(struct hw *hw, int enable)
1117{
1118 hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
1119 return 0;
1120}
1121
1122static int set_timer_tick(struct hw *hw, unsigned int ticks)
1123{
1124 if (ticks)
1125 ticks |= TIMR_IE | TIMR_IP;
1126 hw_write_20kx(hw, TIMR, ticks);
1127 return 0;
1128}
1129
1130static unsigned int get_wc(struct hw *hw)
1131{
1132 return hw_read_20kx(hw, WC);
1133}
1134
1115/* Card hardware initialization block */ 1135/* Card hardware initialization block */
1116struct dac_conf { 1136struct dac_conf {
1117 unsigned int msr; /* master sample rate in rsrs */ 1137 unsigned int msr; /* master sample rate in rsrs */
@@ -1841,6 +1861,22 @@ static int hw_have_digit_io_switch(struct hw *hw)
1841 return 0; 1861 return 0;
1842} 1862}
1843 1863
1864static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
1865{
1866 struct hw *hw = dev_id;
1867 unsigned int status;
1868
1869 status = hw_read_20kx(hw, GIP);
1870 if (!status)
1871 return IRQ_NONE;
1872
1873 if (hw->irq_callback)
1874 hw->irq_callback(hw->irq_callback_data, status);
1875
1876 hw_write_20kx(hw, GIP, status);
1877 return IRQ_HANDLED;
1878}
1879
1844static int hw_card_start(struct hw *hw) 1880static int hw_card_start(struct hw *hw)
1845{ 1881{
1846 int err = 0; 1882 int err = 0;
@@ -1868,7 +1904,7 @@ static int hw_card_start(struct hw *hw)
1868 hw->io_base = pci_resource_start(hw->pci, 2); 1904 hw->io_base = pci_resource_start(hw->pci, 2);
1869 hw->mem_base = (unsigned long)ioremap(hw->io_base, 1905 hw->mem_base = (unsigned long)ioremap(hw->io_base,
1870 pci_resource_len(hw->pci, 2)); 1906 pci_resource_len(hw->pci, 2));
1871 if (NULL == (void *)hw->mem_base) { 1907 if (!hw->mem_base) {
1872 err = -ENOENT; 1908 err = -ENOENT;
1873 goto error2; 1909 goto error2;
1874 } 1910 }
@@ -1879,12 +1915,15 @@ static int hw_card_start(struct hw *hw)
1879 set_field(&gctl, GCTL_UAA, 0); 1915 set_field(&gctl, GCTL_UAA, 0);
1880 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); 1916 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1881 1917
1882 /*if ((err = request_irq(pci->irq, ct_atc_interrupt, IRQF_SHARED, 1918 if (hw->irq < 0) {
1883 atc->chip_details->nm_card, hw))) { 1919 err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
1884 goto error3; 1920 "ctxfi", hw);
1921 if (err < 0) {
1922 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1923 goto error2;
1924 }
1925 hw->irq = pci->irq;
1885 } 1926 }
1886 hw->irq = pci->irq;
1887 */
1888 1927
1889 pci_set_master(pci); 1928 pci_set_master(pci);
1890 1929
@@ -1923,7 +1962,7 @@ static int hw_card_shutdown(struct hw *hw)
1923 1962
1924 hw->irq = -1; 1963 hw->irq = -1;
1925 1964
1926 if (NULL != ((void *)hw->mem_base)) 1965 if (hw->mem_base)
1927 iounmap((void *)hw->mem_base); 1966 iounmap((void *)hw->mem_base);
1928 1967
1929 hw->mem_base = (unsigned long)NULL; 1968 hw->mem_base = (unsigned long)NULL;
@@ -1972,7 +2011,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
1972 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl); 2011 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1973 2012
1974 /* Reset all global pending interrupts */ 2013 /* Reset all global pending interrupts */
1975 hw_write_20kx(hw, INTERRUPT_GIE, 0); 2014 hw_write_20kx(hw, GIE, 0);
1976 /* Reset all SRC pending interrupts */ 2015 /* Reset all SRC pending interrupts */
1977 hw_write_20kx(hw, SRC_IP, 0); 2016 hw_write_20kx(hw, SRC_IP, 0);
1978 2017
@@ -2149,6 +2188,10 @@ static struct hw ct20k2_preset __devinitdata = {
2149 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt, 2188 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
2150 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr, 2189 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
2151 .daio_mgr_commit_write = daio_mgr_commit_write, 2190 .daio_mgr_commit_write = daio_mgr_commit_write,
2191
2192 .set_timer_irq = set_timer_irq,
2193 .set_timer_tick = set_timer_tick,
2194 .get_wc = get_wc,
2152}; 2195};
2153 2196
2154int __devinit create_20k2_hw_obj(struct hw **rhw) 2197int __devinit create_20k2_hw_obj(struct hw **rhw)
diff --git a/sound/pci/ctxfi/ctmixer.c b/sound/pci/ctxfi/ctmixer.c
index f26d7cd9db9f..15c1e7271ea8 100644
--- a/sound/pci/ctxfi/ctmixer.c
+++ b/sound/pci/ctxfi/ctmixer.c
@@ -654,7 +654,7 @@ ct_mixer_kcontrol_new(struct ct_mixer *mixer, struct snd_kcontrol_new *new)
654 int err; 654 int err;
655 655
656 kctl = snd_ctl_new1(new, mixer->atc); 656 kctl = snd_ctl_new1(new, mixer->atc);
657 if (NULL == kctl) 657 if (!kctl)
658 return -ENOMEM; 658 return -ENOMEM;
659 659
660 if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface) 660 if (SNDRV_CTL_ELEM_IFACE_PCM == kctl->id.iface)
@@ -837,17 +837,17 @@ static int ct_mixer_get_mem(struct ct_mixer **rmixer)
837 *rmixer = NULL; 837 *rmixer = NULL;
838 /* Allocate mem for mixer obj */ 838 /* Allocate mem for mixer obj */
839 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL); 839 mixer = kzalloc(sizeof(*mixer), GFP_KERNEL);
840 if (NULL == mixer) 840 if (!mixer)
841 return -ENOMEM; 841 return -ENOMEM;
842 842
843 mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM), 843 mixer->amixers = kzalloc(sizeof(void *)*(NUM_CT_AMIXERS*CHN_NUM),
844 GFP_KERNEL); 844 GFP_KERNEL);
845 if (NULL == mixer->amixers) { 845 if (!mixer->amixers) {
846 err = -ENOMEM; 846 err = -ENOMEM;
847 goto error1; 847 goto error1;
848 } 848 }
849 mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL); 849 mixer->sums = kzalloc(sizeof(void *)*(NUM_CT_SUMS*CHN_NUM), GFP_KERNEL);
850 if (NULL == mixer->sums) { 850 if (!mixer->sums) {
851 err = -ENOMEM; 851 err = -ENOMEM;
852 goto error2; 852 goto error2;
853 } 853 }
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c
index 60ea23180acb..d0dc227fbdd3 100644
--- a/sound/pci/ctxfi/ctpcm.c
+++ b/sound/pci/ctxfi/ctpcm.c
@@ -97,7 +97,7 @@ static void ct_atc_pcm_interrupt(struct ct_atc_pcm *atc_pcm)
97{ 97{
98 struct ct_atc_pcm *apcm = atc_pcm; 98 struct ct_atc_pcm *apcm = atc_pcm;
99 99
100 if (NULL == apcm->substream) 100 if (!apcm->substream)
101 return; 101 return;
102 102
103 snd_pcm_period_elapsed(apcm->substream); 103 snd_pcm_period_elapsed(apcm->substream);
@@ -123,7 +123,7 @@ static int ct_pcm_playback_open(struct snd_pcm_substream *substream)
123 int err; 123 int err;
124 124
125 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 125 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
126 if (NULL == apcm) 126 if (!apcm)
127 return -ENOMEM; 127 return -ENOMEM;
128 128
129 apcm->substream = substream; 129 apcm->substream = substream;
@@ -271,7 +271,7 @@ static int ct_pcm_capture_open(struct snd_pcm_substream *substream)
271 int err; 271 int err;
272 272
273 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL); 273 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
274 if (NULL == apcm) 274 if (!apcm)
275 return -ENOMEM; 275 return -ENOMEM;
276 276
277 apcm->started = 0; 277 apcm->started = 0;
diff --git a/sound/pci/ctxfi/ctresource.c b/sound/pci/ctxfi/ctresource.c
index 889c495bb7d1..7dfaf67344d4 100644
--- a/sound/pci/ctxfi/ctresource.c
+++ b/sound/pci/ctxfi/ctresource.c
@@ -144,7 +144,7 @@ int rsc_init(struct rsc *rsc, u32 idx, enum RSCTYP type, u32 msr, void *hw)
144 rsc->msr = msr; 144 rsc->msr = msr;
145 rsc->hw = hw; 145 rsc->hw = hw;
146 rsc->ops = &rsc_generic_ops; 146 rsc->ops = &rsc_generic_ops;
147 if (NULL == hw) { 147 if (!hw) {
148 rsc->ctrl_blk = NULL; 148 rsc->ctrl_blk = NULL;
149 return 0; 149 return 0;
150 } 150 }
@@ -216,7 +216,7 @@ int rsc_mgr_init(struct rsc_mgr *mgr, enum RSCTYP type,
216 mgr->type = NUM_RSCTYP; 216 mgr->type = NUM_RSCTYP;
217 217
218 mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL); 218 mgr->rscs = kzalloc(((amount + 8 - 1) / 8), GFP_KERNEL);
219 if (NULL == mgr->rscs) 219 if (!mgr->rscs)
220 return -ENOMEM; 220 return -ENOMEM;
221 221
222 switch (type) { 222 switch (type) {
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c
index df43a5cd3938..c749fa720889 100644
--- a/sound/pci/ctxfi/ctsrc.c
+++ b/sound/pci/ctxfi/ctsrc.c
@@ -441,7 +441,7 @@ get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
441 else 441 else
442 src = kzalloc(sizeof(*src), GFP_KERNEL); 442 src = kzalloc(sizeof(*src), GFP_KERNEL);
443 443
444 if (NULL == src) { 444 if (!src) {
445 err = -ENOMEM; 445 err = -ENOMEM;
446 goto error1; 446 goto error1;
447 } 447 }
@@ -550,7 +550,7 @@ int src_mgr_create(void *hw, struct src_mgr **rsrc_mgr)
550 550
551 *rsrc_mgr = NULL; 551 *rsrc_mgr = NULL;
552 src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL); 552 src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
553 if (NULL == src_mgr) 553 if (!src_mgr)
554 return -ENOMEM; 554 return -ENOMEM;
555 555
556 err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw); 556 err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
@@ -679,7 +679,7 @@ static int srcimp_rsc_init(struct srcimp *srcimp,
679 /* Reserve memory for imapper nodes */ 679 /* Reserve memory for imapper nodes */
680 srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr, 680 srcimp->imappers = kzalloc(sizeof(struct imapper)*desc->msr,
681 GFP_KERNEL); 681 GFP_KERNEL);
682 if (NULL == srcimp->imappers) { 682 if (!srcimp->imappers) {
683 err = -ENOMEM; 683 err = -ENOMEM;
684 goto error1; 684 goto error1;
685 } 685 }
@@ -833,7 +833,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
833 833
834 *rsrcimp_mgr = NULL; 834 *rsrcimp_mgr = NULL;
835 srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL); 835 srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
836 if (NULL == srcimp_mgr) 836 if (!srcimp_mgr)
837 return -ENOMEM; 837 return -ENOMEM;
838 838
839 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw); 839 err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
@@ -844,7 +844,7 @@ int srcimp_mgr_create(void *hw, struct srcimp_mgr **rsrcimp_mgr)
844 spin_lock_init(&srcimp_mgr->imap_lock); 844 spin_lock_init(&srcimp_mgr->imap_lock);
845 INIT_LIST_HEAD(&srcimp_mgr->imappers); 845 INIT_LIST_HEAD(&srcimp_mgr->imappers);
846 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 846 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
847 if (NULL == entry) { 847 if (!entry) {
848 err = -ENOMEM; 848 err = -ENOMEM;
849 goto error2; 849 goto error2;
850 } 850 }
diff --git a/sound/pci/ctxfi/ctvmem.c b/sound/pci/ctxfi/ctvmem.c
index 67665a7e43c6..6b78752e9503 100644
--- a/sound/pci/ctxfi/ctvmem.c
+++ b/sound/pci/ctxfi/ctvmem.c
@@ -60,7 +60,7 @@ get_vm_block(struct ct_vm *vm, unsigned int size)
60 } 60 }
61 61
62 block = kzalloc(sizeof(*block), GFP_KERNEL); 62 block = kzalloc(sizeof(*block), GFP_KERNEL);
63 if (NULL == block) 63 if (!block)
64 goto out; 64 goto out;
65 65
66 block->addr = entry->addr; 66 block->addr = entry->addr;
@@ -181,7 +181,7 @@ int ct_vm_create(struct ct_vm **rvm)
181 *rvm = NULL; 181 *rvm = NULL;
182 182
183 vm = kzalloc(sizeof(*vm), GFP_KERNEL); 183 vm = kzalloc(sizeof(*vm), GFP_KERNEL);
184 if (NULL == vm) 184 if (!vm)
185 return -ENOMEM; 185 return -ENOMEM;
186 186
187 mutex_init(&vm->lock); 187 mutex_init(&vm->lock);
@@ -189,7 +189,7 @@ int ct_vm_create(struct ct_vm **rvm)
189 /* Allocate page table pages */ 189 /* Allocate page table pages */
190 for (i = 0; i < CT_PTP_NUM; i++) { 190 for (i = 0; i < CT_PTP_NUM; i++) {
191 vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL); 191 vm->ptp[i] = kmalloc(PAGE_SIZE, GFP_KERNEL);
192 if (NULL == vm->ptp[i]) 192 if (!vm->ptp[i])
193 break; 193 break;
194 } 194 }
195 if (!i) { 195 if (!i) {
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 04438f1d682d..55545e0818b5 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -46,6 +46,20 @@ config SND_HDA_INPUT_JACK
46 Say Y here to enable the jack plugging notification via 46 Say Y here to enable the jack plugging notification via
47 input layer. 47 input layer.
48 48
49config SND_HDA_PATCH_LOADER
50 bool "Support initialization patch loading for HD-audio"
51 depends on EXPERIMENTAL
52 select FW_LOADER
53 select SND_HDA_HWDEP
54 select SND_HDA_RECONFIG
55 help
56 Say Y here to allow the HD-audio driver to load a pseudo
57 firmware file ("patch") for overriding the BIOS setup at
58 start up. The "patch" file can be specified via patch module
59 option, such as patch=hda-init.
60
61 This option turns on hwdep and reconfig features automatically.
62
49config SND_HDA_CODEC_REALTEK 63config SND_HDA_CODEC_REALTEK
50 bool "Build Realtek HD-audio codec support" 64 bool "Build Realtek HD-audio codec support"
51 default y 65 default y
@@ -134,6 +148,19 @@ config SND_HDA_ELD
134 def_bool y 148 def_bool y
135 depends on SND_HDA_CODEC_INTELHDMI 149 depends on SND_HDA_CODEC_INTELHDMI
136 150
151config SND_HDA_CODEC_CIRRUS
152 bool "Build Cirrus Logic codec support"
153 depends on SND_HDA_INTEL
154 default y
155 help
156 Say Y here to include Cirrus Logic codec support in
157 snd-hda-intel driver, such as CS4206.
158
159 When the HD-audio driver is built as a module, the codec
160 support code is also built as another module,
161 snd-hda-codec-cirrus.
162 This module is automatically loaded at probing.
163
137config SND_HDA_CODEC_CONEXANT 164config SND_HDA_CODEC_CONEXANT
138 bool "Build Conexant HD-audio codec support" 165 bool "Build Conexant HD-audio codec support"
139 default y 166 default y
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index e3081d4586cc..315a1c4f8998 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -13,6 +13,7 @@ snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o 13snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o 14snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o 15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-cirrus-objs := patch_cirrus.o
16snd-hda-codec-ca0110-objs := patch_ca0110.o 17snd-hda-codec-ca0110-objs := patch_ca0110.o
17snd-hda-codec-conexant-objs := patch_conexant.o 18snd-hda-codec-conexant-objs := patch_conexant.o
18snd-hda-codec-via-objs := patch_via.o 19snd-hda-codec-via-objs := patch_via.o
@@ -41,6 +42,9 @@ endif
41ifdef CONFIG_SND_HDA_CODEC_ATIHDMI 42ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
42obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o 43obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
43endif 44endif
45ifdef CONFIG_SND_HDA_CODEC_CIRRUS
46obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cirrus.o
47endif
44ifdef CONFIG_SND_HDA_CODEC_CA0110 48ifdef CONFIG_SND_HDA_CODEC_CA0110
45obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o 49obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-ca0110.o
46endif 50endif
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index b0275a050870..3f51a981e604 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -24,6 +24,7 @@
24#include <linux/workqueue.h> 24#include <linux/workqueue.h>
25#include <sound/core.h> 25#include <sound/core.h>
26#include "hda_beep.h" 26#include "hda_beep.h"
27#include "hda_local.h"
27 28
28enum { 29enum {
29 DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */ 30 DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */
@@ -118,6 +119,9 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
118 struct hda_beep *beep; 119 struct hda_beep *beep;
119 int err; 120 int err;
120 121
122 if (!snd_hda_get_bool_hint(codec, "beep"))
123 return 0; /* disabled explicitly */
124
121 beep = kzalloc(sizeof(*beep), GFP_KERNEL); 125 beep = kzalloc(sizeof(*beep), GFP_KERNEL);
122 if (beep == NULL) 126 if (beep == NULL)
123 return -ENOMEM; 127 return -ENOMEM;
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c7df01b72cac..af989f660cca 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -44,6 +44,7 @@ struct hda_vendor_id {
44/* codec vendor labels */ 44/* codec vendor labels */
45static struct hda_vendor_id hda_vendor_ids[] = { 45static struct hda_vendor_id hda_vendor_ids[] = {
46 { 0x1002, "ATI" }, 46 { 0x1002, "ATI" },
47 { 0x1013, "Cirrus Logic" },
47 { 0x1057, "Motorola" }, 48 { 0x1057, "Motorola" },
48 { 0x1095, "Silicon Image" }, 49 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" }, 50 { 0x10de, "Nvidia" },
@@ -150,7 +151,14 @@ make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
150{ 151{
151 u32 val; 152 u32 val;
152 153
153 val = (u32)(codec->addr & 0x0f) << 28; 154 if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
155 (verb & ~0xfff) || (parm & ~0xffff)) {
156 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
157 codec->addr, direct, nid, verb, parm);
158 return ~0;
159 }
160
161 val = (u32)codec->addr << 28;
154 val |= (u32)direct << 27; 162 val |= (u32)direct << 27;
155 val |= (u32)nid << 20; 163 val |= (u32)nid << 20;
156 val |= verb << 8; 164 val |= verb << 8;
@@ -167,6 +175,9 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
167 struct hda_bus *bus = codec->bus; 175 struct hda_bus *bus = codec->bus;
168 int err; 176 int err;
169 177
178 if (cmd == ~0)
179 return -1;
180
170 if (res) 181 if (res)
171 *res = -1; 182 *res = -1;
172 again: 183 again:
@@ -291,11 +302,20 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
291 unsigned int parm; 302 unsigned int parm;
292 int i, conn_len, conns; 303 int i, conn_len, conns;
293 unsigned int shift, num_elems, mask; 304 unsigned int shift, num_elems, mask;
305 unsigned int wcaps;
294 hda_nid_t prev_nid; 306 hda_nid_t prev_nid;
295 307
296 if (snd_BUG_ON(!conn_list || max_conns <= 0)) 308 if (snd_BUG_ON(!conn_list || max_conns <= 0))
297 return -EINVAL; 309 return -EINVAL;
298 310
311 wcaps = get_wcaps(codec, nid);
312 if (!(wcaps & AC_WCAP_CONN_LIST) &&
313 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) {
314 snd_printk(KERN_WARNING "hda_codec: "
315 "connection list not available for 0x%x\n", nid);
316 return -EINVAL;
317 }
318
299 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 319 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
300 if (parm & AC_CLIST_LONG) { 320 if (parm & AC_CLIST_LONG) {
301 /* long form */ 321 /* long form */
@@ -316,6 +336,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
316 /* single connection */ 336 /* single connection */
317 parm = snd_hda_codec_read(codec, nid, 0, 337 parm = snd_hda_codec_read(codec, nid, 0,
318 AC_VERB_GET_CONNECT_LIST, 0); 338 AC_VERB_GET_CONNECT_LIST, 0);
339 if (parm == -1 && codec->bus->rirb_error)
340 return -EIO;
319 conn_list[0] = parm & mask; 341 conn_list[0] = parm & mask;
320 return 1; 342 return 1;
321 } 343 }
@@ -327,9 +349,12 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
327 int range_val; 349 int range_val;
328 hda_nid_t val, n; 350 hda_nid_t val, n;
329 351
330 if (i % num_elems == 0) 352 if (i % num_elems == 0) {
331 parm = snd_hda_codec_read(codec, nid, 0, 353 parm = snd_hda_codec_read(codec, nid, 0,
332 AC_VERB_GET_CONNECT_LIST, i); 354 AC_VERB_GET_CONNECT_LIST, i);
355 if (parm == -1 && codec->bus->rirb_error)
356 return -EIO;
357 }
333 range_val = !!(parm & (1 << (shift-1))); /* ranges */ 358 range_val = !!(parm & (1 << (shift-1))); /* ranges */
334 val = parm & mask; 359 val = parm & mask;
335 if (val == 0) { 360 if (val == 0) {
@@ -727,8 +752,7 @@ static int read_pin_defaults(struct hda_codec *codec)
727 for (i = 0; i < codec->num_nodes; i++, nid++) { 752 for (i = 0; i < codec->num_nodes; i++, nid++) {
728 struct hda_pincfg *pin; 753 struct hda_pincfg *pin;
729 unsigned int wcaps = get_wcaps(codec, nid); 754 unsigned int wcaps = get_wcaps(codec, nid);
730 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 755 unsigned int wid_type = get_wcaps_type(wcaps);
731 AC_WCAP_TYPE_SHIFT;
732 if (wid_type != AC_WID_PIN) 756 if (wid_type != AC_WID_PIN)
733 continue; 757 continue;
734 pin = snd_array_new(&codec->init_pins); 758 pin = snd_array_new(&codec->init_pins);
@@ -891,7 +915,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
891 * Returns 0 if successful, or a negative error code. 915 * Returns 0 if successful, or a negative error code.
892 */ 916 */
893int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 917int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
894 int do_init, struct hda_codec **codecp) 918 struct hda_codec **codecp)
895{ 919{
896 struct hda_codec *codec; 920 struct hda_codec *codec;
897 char component[31]; 921 char component[31];
@@ -984,11 +1008,6 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
984 codec->afg ? codec->afg : codec->mfg, 1008 codec->afg ? codec->afg : codec->mfg,
985 AC_PWRST_D0); 1009 AC_PWRST_D0);
986 1010
987 if (do_init) {
988 err = snd_hda_codec_configure(codec);
989 if (err < 0)
990 goto error;
991 }
992 snd_hda_codec_proc_new(codec); 1011 snd_hda_codec_proc_new(codec);
993 1012
994 snd_hda_create_hwdep(codec); 1013 snd_hda_create_hwdep(codec);
@@ -1042,6 +1061,7 @@ int snd_hda_codec_configure(struct hda_codec *codec)
1042 err = init_unsol_queue(codec->bus); 1061 err = init_unsol_queue(codec->bus);
1043 return err; 1062 return err;
1044} 1063}
1064EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
1045 1065
1046/** 1066/**
1047 * snd_hda_codec_setup_stream - set up the codec for streaming 1067 * snd_hda_codec_setup_stream - set up the codec for streaming
@@ -2356,16 +2376,20 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2356 hda_nid_t nid; 2376 hda_nid_t nid;
2357 int i; 2377 int i;
2358 2378
2359 snd_hda_codec_write(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2379 /* this delay seems necessary to avoid click noise at power-down */
2380 if (power_state == AC_PWRST_D3)
2381 msleep(100);
2382 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2360 power_state); 2383 power_state);
2361 msleep(10); /* partial workaround for "azx_get_response timeout" */ 2384 /* partial workaround for "azx_get_response timeout" */
2385 if (power_state == AC_PWRST_D0)
2386 msleep(10);
2362 2387
2363 nid = codec->start_nid; 2388 nid = codec->start_nid;
2364 for (i = 0; i < codec->num_nodes; i++, nid++) { 2389 for (i = 0; i < codec->num_nodes; i++, nid++) {
2365 unsigned int wcaps = get_wcaps(codec, nid); 2390 unsigned int wcaps = get_wcaps(codec, nid);
2366 if (wcaps & AC_WCAP_POWER) { 2391 if (wcaps & AC_WCAP_POWER) {
2367 unsigned int wid_type = (wcaps & AC_WCAP_TYPE) >> 2392 unsigned int wid_type = get_wcaps_type(wcaps);
2368 AC_WCAP_TYPE_SHIFT;
2369 if (power_state == AC_PWRST_D3 && 2393 if (power_state == AC_PWRST_D3 &&
2370 wid_type == AC_WID_PIN) { 2394 wid_type == AC_WID_PIN) {
2371 unsigned int pincap; 2395 unsigned int pincap;
@@ -2573,7 +2597,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2573 case 20: 2597 case 20:
2574 case 24: 2598 case 24:
2575 case 32: 2599 case 32:
2576 if (maxbps >= 32) 2600 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
2577 val |= 0x40; 2601 val |= 0x40;
2578 else if (maxbps >= 24) 2602 else if (maxbps >= 24)
2579 val |= 0x30; 2603 val |= 0x30;
@@ -2700,11 +2724,12 @@ static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2700 bps = 20; 2724 bps = 20;
2701 } 2725 }
2702 } 2726 }
2703 else if (streams == AC_SUPFMT_FLOAT32) { 2727 if (streams & AC_SUPFMT_FLOAT32) {
2704 /* should be exclusive */
2705 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; 2728 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
2706 bps = 32; 2729 if (!bps)
2707 } else if (streams == AC_SUPFMT_AC3) { 2730 bps = 32;
2731 }
2732 if (streams == AC_SUPFMT_AC3) {
2708 /* should be exclusive */ 2733 /* should be exclusive */
2709 /* temporary hack: we have still no proper support 2734 /* temporary hack: we have still no proper support
2710 * for the direct AC3 stream... 2735 * for the direct AC3 stream...
@@ -3102,7 +3127,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3102 tbl = q; 3127 tbl = q;
3103 3128
3104 if (tbl->value >= 0 && tbl->value < num_configs) { 3129 if (tbl->value >= 0 && tbl->value < num_configs) {
3105#ifdef CONFIG_SND_DEBUG_DETECT 3130#ifdef CONFIG_SND_DEBUG_VERBOSE
3106 char tmp[10]; 3131 char tmp[10];
3107 const char *model = NULL; 3132 const char *model = NULL;
3108 if (models) 3133 if (models)
@@ -3655,8 +3680,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3655 end_nid = codec->start_nid + codec->num_nodes; 3680 end_nid = codec->start_nid + codec->num_nodes;
3656 for (nid = codec->start_nid; nid < end_nid; nid++) { 3681 for (nid = codec->start_nid; nid < end_nid; nid++) {
3657 unsigned int wid_caps = get_wcaps(codec, nid); 3682 unsigned int wid_caps = get_wcaps(codec, nid);
3658 unsigned int wid_type = 3683 unsigned int wid_type = get_wcaps_type(wid_caps);
3659 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
3660 unsigned int def_conf; 3684 unsigned int def_conf;
3661 short assoc, loc; 3685 short assoc, loc;
3662 3686
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 1b75f28ed092..99552fb5f756 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -830,7 +830,8 @@ enum {
830int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 830int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
831 struct hda_bus **busp); 831 struct hda_bus **busp);
832int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 832int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
833 int do_init, struct hda_codec **codecp); 833 struct hda_codec **codecp);
834int snd_hda_codec_configure(struct hda_codec *codec);
834 835
835/* 836/*
836 * low level functions 837 * low level functions
@@ -938,6 +939,13 @@ static inline void snd_hda_power_down(struct hda_codec *codec) {}
938#define snd_hda_codec_needs_resume(codec) 1 939#define snd_hda_codec_needs_resume(codec) 1
939#endif 940#endif
940 941
942#ifdef CONFIG_SND_HDA_PATCH_LOADER
943/*
944 * patch firmware
945 */
946int snd_hda_load_patch(struct hda_bus *bus, const char *patch);
947#endif
948
941/* 949/*
942 * Codec modularization 950 * Codec modularization
943 */ 951 */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 1d5797a96682..b36f6c5a92df 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -121,11 +121,17 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
121 if (node == NULL) 121 if (node == NULL)
122 return -ENOMEM; 122 return -ENOMEM;
123 node->nid = nid; 123 node->nid = nid;
124 nconns = snd_hda_get_connections(codec, nid, conn_list, 124 node->wid_caps = get_wcaps(codec, nid);
125 HDA_MAX_CONNECTIONS); 125 node->type = get_wcaps_type(node->wid_caps);
126 if (nconns < 0) { 126 if (node->wid_caps & AC_WCAP_CONN_LIST) {
127 kfree(node); 127 nconns = snd_hda_get_connections(codec, nid, conn_list,
128 return nconns; 128 HDA_MAX_CONNECTIONS);
129 if (nconns < 0) {
130 kfree(node);
131 return nconns;
132 }
133 } else {
134 nconns = 0;
129 } 135 }
130 if (nconns <= ARRAY_SIZE(node->slist)) 136 if (nconns <= ARRAY_SIZE(node->slist))
131 node->conn_list = node->slist; 137 node->conn_list = node->slist;
@@ -140,8 +146,6 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid
140 } 146 }
141 memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); 147 memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t));
142 node->nconns = nconns; 148 node->nconns = nconns;
143 node->wid_caps = get_wcaps(codec, nid);
144 node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
145 149
146 if (node->type == AC_WID_PIN) { 150 if (node->type == AC_WID_PIN) {
147 node->pin_caps = snd_hda_query_pin_caps(codec, node->nid); 151 node->pin_caps = snd_hda_query_pin_caps(codec, node->nid);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6812fbe80fa4..cc24e6721d74 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -24,6 +24,7 @@
24#include <linux/compat.h> 24#include <linux/compat.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/ctype.h> 26#include <linux/ctype.h>
27#include <linux/firmware.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include "hda_codec.h" 29#include "hda_codec.h"
29#include "hda_local.h" 30#include "hda_local.h"
@@ -312,12 +313,8 @@ static ssize_t init_verbs_show(struct device *dev,
312 return len; 313 return len;
313} 314}
314 315
315static ssize_t init_verbs_store(struct device *dev, 316static int parse_init_verbs(struct hda_codec *codec, const char *buf)
316 struct device_attribute *attr,
317 const char *buf, size_t count)
318{ 317{
319 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
320 struct hda_codec *codec = hwdep->private_data;
321 struct hda_verb *v; 318 struct hda_verb *v;
322 int nid, verb, param; 319 int nid, verb, param;
323 320
@@ -331,6 +328,18 @@ static ssize_t init_verbs_store(struct device *dev,
331 v->nid = nid; 328 v->nid = nid;
332 v->verb = verb; 329 v->verb = verb;
333 v->param = param; 330 v->param = param;
331 return 0;
332}
333
334static ssize_t init_verbs_store(struct device *dev,
335 struct device_attribute *attr,
336 const char *buf, size_t count)
337{
338 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
339 struct hda_codec *codec = hwdep->private_data;
340 int err = parse_init_verbs(codec, buf);
341 if (err < 0)
342 return err;
334 return count; 343 return count;
335} 344}
336 345
@@ -376,19 +385,15 @@ static void remove_trail_spaces(char *str)
376 385
377#define MAX_HINTS 1024 386#define MAX_HINTS 1024
378 387
379static ssize_t hints_store(struct device *dev, 388static int parse_hints(struct hda_codec *codec, const char *buf)
380 struct device_attribute *attr,
381 const char *buf, size_t count)
382{ 389{
383 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
384 struct hda_codec *codec = hwdep->private_data;
385 char *key, *val; 390 char *key, *val;
386 struct hda_hint *hint; 391 struct hda_hint *hint;
387 392
388 while (isspace(*buf)) 393 while (isspace(*buf))
389 buf++; 394 buf++;
390 if (!*buf || *buf == '#' || *buf == '\n') 395 if (!*buf || *buf == '#' || *buf == '\n')
391 return count; 396 return 0;
392 if (*buf == '=') 397 if (*buf == '=')
393 return -EINVAL; 398 return -EINVAL;
394 key = kstrndup_noeol(buf, 1024); 399 key = kstrndup_noeol(buf, 1024);
@@ -411,7 +416,7 @@ static ssize_t hints_store(struct device *dev,
411 kfree(hint->key); 416 kfree(hint->key);
412 hint->key = key; 417 hint->key = key;
413 hint->val = val; 418 hint->val = val;
414 return count; 419 return 0;
415 } 420 }
416 /* allocate a new hint entry */ 421 /* allocate a new hint entry */
417 if (codec->hints.used >= MAX_HINTS) 422 if (codec->hints.used >= MAX_HINTS)
@@ -424,6 +429,18 @@ static ssize_t hints_store(struct device *dev,
424 } 429 }
425 hint->key = key; 430 hint->key = key;
426 hint->val = val; 431 hint->val = val;
432 return 0;
433}
434
435static ssize_t hints_store(struct device *dev,
436 struct device_attribute *attr,
437 const char *buf, size_t count)
438{
439 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
440 struct hda_codec *codec = hwdep->private_data;
441 int err = parse_hints(codec, buf);
442 if (err < 0)
443 return err;
427 return count; 444 return count;
428} 445}
429 446
@@ -469,20 +486,24 @@ static ssize_t driver_pin_configs_show(struct device *dev,
469 486
470#define MAX_PIN_CONFIGS 32 487#define MAX_PIN_CONFIGS 32
471 488
472static ssize_t user_pin_configs_store(struct device *dev, 489static int parse_user_pin_configs(struct hda_codec *codec, const char *buf)
473 struct device_attribute *attr,
474 const char *buf, size_t count)
475{ 490{
476 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
477 struct hda_codec *codec = hwdep->private_data;
478 int nid, cfg; 491 int nid, cfg;
479 int err;
480 492
481 if (sscanf(buf, "%i %i", &nid, &cfg) != 2) 493 if (sscanf(buf, "%i %i", &nid, &cfg) != 2)
482 return -EINVAL; 494 return -EINVAL;
483 if (!nid) 495 if (!nid)
484 return -EINVAL; 496 return -EINVAL;
485 err = snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg); 497 return snd_hda_add_pincfg(codec, &codec->user_pins, nid, cfg);
498}
499
500static ssize_t user_pin_configs_store(struct device *dev,
501 struct device_attribute *attr,
502 const char *buf, size_t count)
503{
504 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
505 struct hda_codec *codec = hwdep->private_data;
506 int err = parse_user_pin_configs(codec, buf);
486 if (err < 0) 507 if (err < 0)
487 return err; 508 return err;
488 return count; 509 return count;
@@ -553,3 +574,180 @@ int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
553EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint); 574EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);
554 575
555#endif /* CONFIG_SND_HDA_RECONFIG */ 576#endif /* CONFIG_SND_HDA_RECONFIG */
577
578#ifdef CONFIG_SND_HDA_PATCH_LOADER
579
580/* parser mode */
581enum {
582 LINE_MODE_NONE,
583 LINE_MODE_CODEC,
584 LINE_MODE_MODEL,
585 LINE_MODE_PINCFG,
586 LINE_MODE_VERB,
587 LINE_MODE_HINT,
588 NUM_LINE_MODES,
589};
590
591static inline int strmatch(const char *a, const char *b)
592{
593 return strnicmp(a, b, strlen(b)) == 0;
594}
595
596/* parse the contents after the line "[codec]"
597 * accept only the line with three numbers, and assign the current codec
598 */
599static void parse_codec_mode(char *buf, struct hda_bus *bus,
600 struct hda_codec **codecp)
601{
602 unsigned int vendorid, subid, caddr;
603 struct hda_codec *codec;
604
605 *codecp = NULL;
606 if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) {
607 list_for_each_entry(codec, &bus->codec_list, list) {
608 if (codec->addr == caddr) {
609 *codecp = codec;
610 break;
611 }
612 }
613 }
614}
615
616/* parse the contents after the other command tags, [pincfg], [verb],
617 * [hint] and [model]
618 * just pass to the sysfs helper (only when any codec was specified)
619 */
620static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
621 struct hda_codec **codecp)
622{
623 if (!*codecp)
624 return;
625 parse_user_pin_configs(*codecp, buf);
626}
627
628static void parse_verb_mode(char *buf, struct hda_bus *bus,
629 struct hda_codec **codecp)
630{
631 if (!*codecp)
632 return;
633 parse_init_verbs(*codecp, buf);
634}
635
636static void parse_hint_mode(char *buf, struct hda_bus *bus,
637 struct hda_codec **codecp)
638{
639 if (!*codecp)
640 return;
641 parse_hints(*codecp, buf);
642}
643
644static void parse_model_mode(char *buf, struct hda_bus *bus,
645 struct hda_codec **codecp)
646{
647 if (!*codecp)
648 return;
649 kfree((*codecp)->modelname);
650 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
651}
652
653struct hda_patch_item {
654 const char *tag;
655 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
656};
657
658static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
659 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode },
660 [LINE_MODE_MODEL] = { "[model]", parse_model_mode },
661 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode },
662 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode },
663 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode },
664};
665
666/* check the line starting with '[' -- change the parser mode accodingly */
667static int parse_line_mode(char *buf, struct hda_bus *bus)
668{
669 int i;
670 for (i = 0; i < ARRAY_SIZE(patch_items); i++) {
671 if (!patch_items[i].tag)
672 continue;
673 if (strmatch(buf, patch_items[i].tag))
674 return i;
675 }
676 return LINE_MODE_NONE;
677}
678
679/* copy one line from the buffer in fw, and update the fields in fw
680 * return zero if it reaches to the end of the buffer, or non-zero
681 * if successfully copied a line
682 *
683 * the spaces at the beginning and the end of the line are stripped
684 */
685static int get_line_from_fw(char *buf, int size, struct firmware *fw)
686{
687 int len;
688 const char *p = fw->data;
689 while (isspace(*p) && fw->size) {
690 p++;
691 fw->size--;
692 }
693 if (!fw->size)
694 return 0;
695 if (size < fw->size)
696 size = fw->size;
697
698 for (len = 0; len < fw->size; len++) {
699 if (!*p)
700 break;
701 if (*p == '\n') {
702 p++;
703 len++;
704 break;
705 }
706 if (len < size)
707 *buf++ = *p++;
708 }
709 *buf = 0;
710 fw->size -= len;
711 fw->data = p;
712 remove_trail_spaces(buf);
713 return 1;
714}
715
716/*
717 * load a "patch" firmware file and parse it
718 */
719int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
720{
721 int err;
722 const struct firmware *fw;
723 struct firmware tmp;
724 char buf[128];
725 struct hda_codec *codec;
726 int line_mode;
727 struct device *dev = bus->card->dev;
728
729 if (snd_BUG_ON(!dev))
730 return -ENODEV;
731 err = request_firmware(&fw, patch, dev);
732 if (err < 0) {
733 printk(KERN_ERR "hda-codec: Cannot load the patch '%s'\n",
734 patch);
735 return err;
736 }
737
738 tmp = *fw;
739 line_mode = LINE_MODE_NONE;
740 codec = NULL;
741 while (get_line_from_fw(buf, sizeof(buf) - 1, &tmp)) {
742 if (!*buf || *buf == '#' || *buf == '\n')
743 continue;
744 if (*buf == '[')
745 line_mode = parse_line_mode(buf, bus);
746 else if (patch_items[line_mode].parser)
747 patch_items[line_mode].parser(buf, bus, &codec);
748 }
749 release_firmware(fw);
750 return 0;
751}
752EXPORT_SYMBOL_HDA(snd_hda_load_patch);
753#endif /* CONFIG_SND_HDA_PATCH_LOADER */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 175f07a381ba..20a66f85f0a4 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -61,6 +61,9 @@ static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS]; 61static int probe_only[SNDRV_CARDS];
62static int single_cmd; 62static int single_cmd;
63static int enable_msi; 63static int enable_msi;
64#ifdef CONFIG_SND_HDA_PATCH_LOADER
65static char *patch[SNDRV_CARDS];
66#endif
64 67
65module_param_array(index, int, NULL, 0444); 68module_param_array(index, int, NULL, 0444);
66MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); 69MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
@@ -84,6 +87,10 @@ MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
84 "(for debugging only)."); 87 "(for debugging only).");
85module_param(enable_msi, int, 0444); 88module_param(enable_msi, int, 0444);
86MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 89MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
90#ifdef CONFIG_SND_HDA_PATCH_LOADER
91module_param_array(patch, charp, NULL, 0444);
92MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
93#endif
87 94
88#ifdef CONFIG_SND_HDA_POWER_SAVE 95#ifdef CONFIG_SND_HDA_POWER_SAVE
89static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; 96static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
@@ -1331,8 +1338,7 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1331 [AZX_DRIVER_TERA] = 1, 1338 [AZX_DRIVER_TERA] = 1,
1332}; 1339};
1333 1340
1334static int __devinit azx_codec_create(struct azx *chip, const char *model, 1341static int __devinit azx_codec_create(struct azx *chip, const char *model)
1335 int no_init)
1336{ 1342{
1337 struct hda_bus_template bus_temp; 1343 struct hda_bus_template bus_temp;
1338 int c, codecs, err; 1344 int c, codecs, err;
@@ -1391,7 +1397,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1391 for (c = 0; c < max_slots; c++) { 1397 for (c = 0; c < max_slots; c++) {
1392 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { 1398 if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) {
1393 struct hda_codec *codec; 1399 struct hda_codec *codec;
1394 err = snd_hda_codec_new(chip->bus, c, !no_init, &codec); 1400 err = snd_hda_codec_new(chip->bus, c, &codec);
1395 if (err < 0) 1401 if (err < 0)
1396 continue; 1402 continue;
1397 codecs++; 1403 codecs++;
@@ -1401,7 +1407,16 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1401 snd_printk(KERN_ERR SFX "no codecs initialized\n"); 1407 snd_printk(KERN_ERR SFX "no codecs initialized\n");
1402 return -ENXIO; 1408 return -ENXIO;
1403 } 1409 }
1410 return 0;
1411}
1404 1412
1413/* configure each codec instance */
1414static int __devinit azx_codec_configure(struct azx *chip)
1415{
1416 struct hda_codec *codec;
1417 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1418 snd_hda_codec_configure(codec);
1419 }
1405 return 0; 1420 return 0;
1406} 1421}
1407 1422
@@ -2284,6 +2299,30 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2284 } 2299 }
2285} 2300}
2286 2301
2302/*
2303 * white-list for enable_msi
2304 */
2305static struct snd_pci_quirk msi_white_list[] __devinitdata = {
2306 SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1),
2307 {}
2308};
2309
2310static void __devinit check_msi(struct azx *chip)
2311{
2312 const struct snd_pci_quirk *q;
2313
2314 chip->msi = enable_msi;
2315 if (chip->msi)
2316 return;
2317 q = snd_pci_quirk_lookup(chip->pci, msi_white_list);
2318 if (q) {
2319 printk(KERN_INFO
2320 "hda_intel: msi for device %04x:%04x set to %d\n",
2321 q->subvendor, q->subdevice, q->value);
2322 chip->msi = q->value;
2323 }
2324}
2325
2287 2326
2288/* 2327/*
2289 * constructor 2328 * constructor
@@ -2318,7 +2357,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2318 chip->pci = pci; 2357 chip->pci = pci;
2319 chip->irq = -1; 2358 chip->irq = -1;
2320 chip->driver_type = driver_type; 2359 chip->driver_type = driver_type;
2321 chip->msi = enable_msi; 2360 check_msi(chip);
2322 chip->dev_index = dev; 2361 chip->dev_index = dev;
2323 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); 2362 INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work);
2324 2363
@@ -2526,15 +2565,32 @@ static int __devinit azx_probe(struct pci_dev *pci,
2526 return err; 2565 return err;
2527 } 2566 }
2528 2567
2568 /* set this here since it's referred in snd_hda_load_patch() */
2569 snd_card_set_dev(card, &pci->dev);
2570
2529 err = azx_create(card, pci, dev, pci_id->driver_data, &chip); 2571 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
2530 if (err < 0) 2572 if (err < 0)
2531 goto out_free; 2573 goto out_free;
2532 card->private_data = chip; 2574 card->private_data = chip;
2533 2575
2534 /* create codec instances */ 2576 /* create codec instances */
2535 err = azx_codec_create(chip, model[dev], probe_only[dev]); 2577 err = azx_codec_create(chip, model[dev]);
2536 if (err < 0) 2578 if (err < 0)
2537 goto out_free; 2579 goto out_free;
2580#ifdef CONFIG_SND_HDA_PATCH_LOADER
2581 if (patch[dev]) {
2582 snd_printk(KERN_ERR SFX "Applying patch firmware '%s'\n",
2583 patch[dev]);
2584 err = snd_hda_load_patch(chip->bus, patch[dev]);
2585 if (err < 0)
2586 goto out_free;
2587 }
2588#endif
2589 if (!probe_only[dev]) {
2590 err = azx_codec_configure(chip);
2591 if (err < 0)
2592 goto out_free;
2593 }
2538 2594
2539 /* create PCM streams */ 2595 /* create PCM streams */
2540 err = snd_hda_build_pcms(chip->bus); 2596 err = snd_hda_build_pcms(chip->bus);
@@ -2546,8 +2602,6 @@ static int __devinit azx_probe(struct pci_dev *pci,
2546 if (err < 0) 2602 if (err < 0)
2547 goto out_free; 2603 goto out_free;
2548 2604
2549 snd_card_set_dev(card, &pci->dev);
2550
2551 err = snd_card_register(card); 2605 err = snd_card_register(card);
2552 if (err < 0) 2606 if (err < 0)
2553 goto out_free; 2607 goto out_free;
@@ -2649,11 +2703,15 @@ static struct pci_device_id azx_ids[] = {
2649 /* this entry seems still valid -- i.e. without emu20kx chip */ 2703 /* this entry seems still valid -- i.e. without emu20kx chip */
2650 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC }, 2704 { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_GENERIC },
2651#endif 2705#endif
2652 /* AMD Generic, PCI class code and Vendor ID for HD Audio */ 2706 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2653 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), 2707 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2654 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2708 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2655 .class_mask = 0xffffff, 2709 .class_mask = 0xffffff,
2656 .driver_data = AZX_DRIVER_GENERIC }, 2710 .driver_data = AZX_DRIVER_GENERIC },
2711 { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID),
2712 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2713 .class_mask = 0xffffff,
2714 .driver_data = AZX_DRIVER_GENERIC },
2657 { 0, } 2715 { 0, }
2658}; 2716};
2659MODULE_DEVICE_TABLE(pci, azx_ids); 2717MODULE_DEVICE_TABLE(pci, azx_ids);
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 83349013b4df..5f1dcc59002b 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -99,7 +99,6 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
99int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 99int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
100 unsigned int *tlv, const char **slaves); 100 unsigned int *tlv, const char **slaves);
101int snd_hda_codec_reset(struct hda_codec *codec); 101int snd_hda_codec_reset(struct hda_codec *codec);
102int snd_hda_codec_configure(struct hda_codec *codec);
103 102
104/* amp value bits */ 103/* amp value bits */
105#define HDA_AMP_MUTE 0x80 104#define HDA_AMP_MUTE 0x80
@@ -408,6 +407,19 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
408 return codec->wcaps[nid - codec->start_nid]; 407 return codec->wcaps[nid - codec->start_nid];
409} 408}
410 409
410/* get the widget type from widget capability bits */
411#define get_wcaps_type(wcaps) (((wcaps) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT)
412
413static inline unsigned int get_wcaps_channels(u32 wcaps)
414{
415 unsigned int chans;
416
417 chans = (wcaps & AC_WCAP_CHAN_CNT_EXT) >> 13;
418 chans = ((chans << 1) | 1) + 1;
419
420 return chans;
421}
422
411u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); 423u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
412int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 424int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
413 unsigned int caps); 425 unsigned int caps);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 418c5d1badaa..95f24e4729f8 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -508,17 +508,14 @@ static void print_codec_info(struct snd_info_entry *entry,
508 unsigned int wid_caps = 508 unsigned int wid_caps =
509 snd_hda_param_read(codec, nid, 509 snd_hda_param_read(codec, nid,
510 AC_PAR_AUDIO_WIDGET_CAP); 510 AC_PAR_AUDIO_WIDGET_CAP);
511 unsigned int wid_type = 511 unsigned int wid_type = get_wcaps_type(wid_caps);
512 (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
513 hda_nid_t conn[HDA_MAX_CONNECTIONS]; 512 hda_nid_t conn[HDA_MAX_CONNECTIONS];
514 int conn_len = 0; 513 int conn_len = 0;
515 514
516 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, 515 snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid,
517 get_wid_type_name(wid_type), wid_caps); 516 get_wid_type_name(wid_type), wid_caps);
518 if (wid_caps & AC_WCAP_STEREO) { 517 if (wid_caps & AC_WCAP_STEREO) {
519 unsigned int chans; 518 unsigned int chans = get_wcaps_channels(wid_caps);
520 chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13;
521 chans = ((chans << 1) | 1) + 1;
522 if (chans == 2) 519 if (chans == 2)
523 snd_iprintf(buffer, " Stereo"); 520 snd_iprintf(buffer, " Stereo");
524 else 521 else
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 403588c6e3f6..215e72a87113 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -2982,7 +2982,8 @@ static int patch_ad1988(struct hda_codec *codec)
2982 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, 2982 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2983 ad1988_models, ad1988_cfg_tbl); 2983 ad1988_models, ad1988_cfg_tbl);
2984 if (board_config < 0) { 2984 if (board_config < 0) {
2985 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); 2985 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2986 codec->chip_name);
2986 board_config = AD1988_AUTO; 2987 board_config = AD1988_AUTO;
2987 } 2988 }
2988 2989
@@ -3702,19 +3703,29 @@ static struct hda_amp_list ad1884a_loopbacks[] = {
3702 * Port F: Internal speakers 3703 * Port F: Internal speakers
3703 */ 3704 */
3704 3705
3705static struct hda_input_mux ad1884a_laptop_capture_source = { 3706static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3706 .num_items = 4, 3707 struct snd_ctl_elem_value *ucontrol)
3707 .items = { 3708{
3708 { "Mic", 0x0 }, /* port-B */ 3709 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3709 { "Internal Mic", 0x1 }, /* port-C */ 3710 int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3710 { "Dock Mic", 0x4 }, /* port-E */ 3711 int mute = (!ucontrol->value.integer.value[0] &&
3711 { "Mix", 0x3 }, 3712 !ucontrol->value.integer.value[1]);
3712 }, 3713 /* toggle GPIO1 according to the mute state */
3713}; 3714 snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3715 mute ? 0x02 : 0x0);
3716 return ret;
3717}
3714 3718
3715static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { 3719static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3716 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3720 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3717 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 3721 {
3722 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3723 .name = "Master Playback Switch",
3724 .info = snd_hda_mixer_amp_switch_info,
3725 .get = snd_hda_mixer_amp_switch_get,
3726 .put = ad1884a_mobile_master_sw_put,
3727 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
3728 },
3718 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT), 3729 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3719 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 3730 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
3720 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 3731 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
@@ -3729,36 +3740,9 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3729 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3740 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT),
3730 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3741 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3731 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3742 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3732 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3733 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3734 {
3735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3736 /* The multiple "Capture Source" controls confuse alsamixer
3737 * So call somewhat different..
3738 */
3739 /* .name = "Capture Source", */
3740 .name = "Input Source",
3741 .count = 2,
3742 .info = ad198x_mux_enum_info,
3743 .get = ad198x_mux_enum_get,
3744 .put = ad198x_mux_enum_put,
3745 },
3746 { } /* end */ 3743 { } /* end */
3747}; 3744};
3748 3745
3749static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
3750 struct snd_ctl_elem_value *ucontrol)
3751{
3752 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3753 int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3754 int mute = (!ucontrol->value.integer.value[0] &&
3755 !ucontrol->value.integer.value[1]);
3756 /* toggle GPIO1 according to the mute state */
3757 snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
3758 mute ? 0x02 : 0x0);
3759 return ret;
3760}
3761
3762static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 3746static struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
3763 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 3747 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
3764 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 3748 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
@@ -3828,6 +3812,63 @@ static int ad1884a_hp_init(struct hda_codec *codec)
3828 return 0; 3812 return 0;
3829} 3813}
3830 3814
3815/* mute internal speaker if HP or docking HP is plugged */
3816static void ad1884a_laptop_automute(struct hda_codec *codec)
3817{
3818 unsigned int present;
3819
3820 present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0);
3821 present &= AC_PINSENSE_PRESENCE;
3822 if (!present) {
3823 present = snd_hda_codec_read(codec, 0x12, 0,
3824 AC_VERB_GET_PIN_SENSE, 0);
3825 present &= AC_PINSENSE_PRESENCE;
3826 }
3827 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
3828 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
3829 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
3830 present ? 0x00 : 0x02);
3831}
3832
3833/* switch to external mic if plugged */
3834static void ad1884a_laptop_automic(struct hda_codec *codec)
3835{
3836 unsigned int idx;
3837
3838 if (snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) &
3839 AC_PINSENSE_PRESENCE)
3840 idx = 0;
3841 else if (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0) &
3842 AC_PINSENSE_PRESENCE)
3843 idx = 4;
3844 else
3845 idx = 1;
3846 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
3847}
3848
3849/* unsolicited event for HP jack sensing */
3850static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
3851 unsigned int res)
3852{
3853 switch (res >> 26) {
3854 case AD1884A_HP_EVENT:
3855 ad1884a_laptop_automute(codec);
3856 break;
3857 case AD1884A_MIC_EVENT:
3858 ad1884a_laptop_automic(codec);
3859 break;
3860 }
3861}
3862
3863/* initialize jack-sensing, too */
3864static int ad1884a_laptop_init(struct hda_codec *codec)
3865{
3866 ad198x_init(codec);
3867 ad1884a_laptop_automute(codec);
3868 ad1884a_laptop_automic(codec);
3869 return 0;
3870}
3871
3831/* additional verbs for laptop model */ 3872/* additional verbs for laptop model */
3832static struct hda_verb ad1884a_laptop_verbs[] = { 3873static struct hda_verb ad1884a_laptop_verbs[] = {
3833 /* Port-A (HP) pin - always unmuted */ 3874 /* Port-A (HP) pin - always unmuted */
@@ -3844,11 +3885,19 @@ static struct hda_verb ad1884a_laptop_verbs[] = {
3844 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 3885 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3845 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 3886 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3846 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 3887 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
3888 /* Port-D (docking line-out) pin - default unmuted */
3889 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3847 /* analog mix */ 3890 /* analog mix */
3848 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 3891 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3849 /* unsolicited event for pin-sense */ 3892 /* unsolicited event for pin-sense */
3850 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 3893 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
3894 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
3851 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 3895 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
3896 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
3897 /* allow to touch GPIO1 (for mute control) */
3898 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
3899 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
3900 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
3852 { } /* end */ 3901 { } /* end */
3853}; 3902};
3854 3903
@@ -4008,6 +4057,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4008 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP), 4057 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4009 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP), 4058 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4010 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), 4059 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4060 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4011 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 4061 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4012 {} 4062 {}
4013}; 4063};
@@ -4057,9 +4107,8 @@ static int patch_ad1884a(struct hda_codec *codec)
4057 spec->mixers[0] = ad1884a_laptop_mixers; 4107 spec->mixers[0] = ad1884a_laptop_mixers;
4058 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; 4108 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4059 spec->multiout.dig_out_nid = 0; 4109 spec->multiout.dig_out_nid = 0;
4060 spec->input_mux = &ad1884a_laptop_capture_source; 4110 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4061 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; 4111 codec->patch_ops.init = ad1884a_laptop_init;
4062 codec->patch_ops.init = ad1884a_hp_init;
4063 /* set the upper-limit for mixer amp to 0dB for avoiding the 4112 /* set the upper-limit for mixer amp to 0dB for avoiding the
4064 * possible damage by overloading 4113 * possible damage by overloading
4065 */ 4114 */
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index 233e4778bba9..fb684f00156b 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -141,8 +141,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec)
141 /* FIXME: we must check ELD and change the PCM parameters dynamically 141 /* FIXME: we must check ELD and change the PCM parameters dynamically
142 */ 142 */
143 chans = get_wcaps(codec, CVT_NID); 143 chans = get_wcaps(codec, CVT_NID);
144 chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13; 144 chans = get_wcaps_channels(chans);
145 chans = ((chans << 1) | 1) + 1;
146 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans; 145 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
147 146
148 return 0; 147 return 0;
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c
index 019ca7cb56d7..d08353d3bb7f 100644
--- a/sound/pci/hda/patch_ca0110.c
+++ b/sound/pci/hda/patch_ca0110.c
@@ -459,8 +459,7 @@ static void parse_input(struct hda_codec *codec)
459 nid = codec->start_nid; 459 nid = codec->start_nid;
460 for (i = 0; i < codec->num_nodes; i++, nid++) { 460 for (i = 0; i < codec->num_nodes; i++, nid++) {
461 unsigned int wcaps = get_wcaps(codec, nid); 461 unsigned int wcaps = get_wcaps(codec, nid);
462 unsigned int type = (wcaps & AC_WCAP_TYPE) >> 462 unsigned int type = get_wcaps_type(wcaps);
463 AC_WCAP_TYPE_SHIFT;
464 if (type != AC_WID_AUD_IN) 463 if (type != AC_WID_AUD_IN)
465 continue; 464 continue;
466 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1) 465 if (snd_hda_get_connections(codec, nid, &pin, 1) != 1)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
new file mode 100644
index 000000000000..8ba306856d38
--- /dev/null
+++ b/sound/pci/hda/patch_cirrus.c
@@ -0,0 +1,1194 @@
1/*
2 * HD audio interface patch for Cirrus Logic CS420x chip
3 *
4 * Copyright (c) 2009 Takashi Iwai <tiwai@suse.de>
5 *
6 * This driver is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This driver is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/slab.h>
24#include <linux/pci.h>
25#include <sound/core.h>
26#include "hda_codec.h"
27#include "hda_local.h"
28
29/*
30 */
31
32struct cs_spec {
33 int board_config;
34 struct auto_pin_cfg autocfg;
35 struct hda_multi_out multiout;
36 struct snd_kcontrol *vmaster_sw;
37 struct snd_kcontrol *vmaster_vol;
38
39 hda_nid_t dac_nid[AUTO_CFG_MAX_OUTS];
40 hda_nid_t slave_dig_outs[2];
41
42 unsigned int input_idx[AUTO_PIN_LAST];
43 unsigned int capsrc_idx[AUTO_PIN_LAST];
44 hda_nid_t adc_nid[AUTO_PIN_LAST];
45 unsigned int adc_idx[AUTO_PIN_LAST];
46 unsigned int num_inputs;
47 unsigned int cur_input;
48 unsigned int automic_idx;
49 hda_nid_t cur_adc;
50 unsigned int cur_adc_stream_tag;
51 unsigned int cur_adc_format;
52 hda_nid_t dig_in;
53
54 struct hda_bind_ctls *capture_bind[2];
55
56 unsigned int gpio_mask;
57 unsigned int gpio_dir;
58 unsigned int gpio_data;
59
60 struct hda_pcm pcm_rec[2]; /* PCM information */
61
62 unsigned int hp_detect:1;
63 unsigned int mic_detect:1;
64};
65
66/* available models */
67enum {
68 CS420X_MBP55,
69 CS420X_AUTO,
70 CS420X_MODELS
71};
72
73/* Vendor-specific processing widget */
74#define CS420X_VENDOR_NID 0x11
75#define CS_DIG_OUT1_PIN_NID 0x10
76#define CS_DIG_OUT2_PIN_NID 0x15
77#define CS_DMIC1_PIN_NID 0x12
78#define CS_DMIC2_PIN_NID 0x0e
79
80/* coef indices */
81#define IDX_SPDIF_STAT 0x0000
82#define IDX_SPDIF_CTL 0x0001
83#define IDX_ADC_CFG 0x0002
84/* SZC bitmask, 4 modes below:
85 * 0 = immediate,
86 * 1 = digital immediate, analog zero-cross
87 * 2 = digtail & analog soft-ramp
88 * 3 = digital soft-ramp, analog zero-cross
89 */
90#define CS_COEF_ADC_SZC_MASK (3 << 0)
91#define CS_COEF_ADC_MIC_SZC_MODE (3 << 0) /* SZC setup for mic */
92#define CS_COEF_ADC_LI_SZC_MODE (3 << 0) /* SZC setup for line-in */
93/* PGA mode: 0 = differential, 1 = signle-ended */
94#define CS_COEF_ADC_MIC_PGA_MODE (1 << 5) /* PGA setup for mic */
95#define CS_COEF_ADC_LI_PGA_MODE (1 << 6) /* PGA setup for line-in */
96#define IDX_DAC_CFG 0x0003
97/* SZC bitmask, 4 modes below:
98 * 0 = Immediate
99 * 1 = zero-cross
100 * 2 = soft-ramp
101 * 3 = soft-ramp on zero-cross
102 */
103#define CS_COEF_DAC_HP_SZC_MODE (3 << 0) /* nid 0x02 */
104#define CS_COEF_DAC_LO_SZC_MODE (3 << 2) /* nid 0x03 */
105#define CS_COEF_DAC_SPK_SZC_MODE (3 << 4) /* nid 0x04 */
106
107#define IDX_BEEP_CFG 0x0004
108/* 0x0008 - test reg key */
109/* 0x0009 - 0x0014 -> 12 test regs */
110/* 0x0015 - visibility reg */
111
112
113static inline int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx)
114{
115 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
116 AC_VERB_SET_COEF_INDEX, idx);
117 return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0,
118 AC_VERB_GET_PROC_COEF, 0);
119}
120
121static inline void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx,
122 unsigned int coef)
123{
124 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
125 AC_VERB_SET_COEF_INDEX, idx);
126 snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0,
127 AC_VERB_SET_PROC_COEF, coef);
128}
129
130
131#define HP_EVENT 1
132#define MIC_EVENT 2
133
134/*
135 * PCM callbacks
136 */
137static int cs_playback_pcm_open(struct hda_pcm_stream *hinfo,
138 struct hda_codec *codec,
139 struct snd_pcm_substream *substream)
140{
141 struct cs_spec *spec = codec->spec;
142 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
143 hinfo);
144}
145
146static int cs_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
147 struct hda_codec *codec,
148 unsigned int stream_tag,
149 unsigned int format,
150 struct snd_pcm_substream *substream)
151{
152 struct cs_spec *spec = codec->spec;
153 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
154 stream_tag, format, substream);
155}
156
157static int cs_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
158 struct hda_codec *codec,
159 struct snd_pcm_substream *substream)
160{
161 struct cs_spec *spec = codec->spec;
162 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
163}
164
165/*
166 * Digital out
167 */
168static int cs_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
169 struct hda_codec *codec,
170 struct snd_pcm_substream *substream)
171{
172 struct cs_spec *spec = codec->spec;
173 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
174}
175
176static int cs_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
177 struct hda_codec *codec,
178 struct snd_pcm_substream *substream)
179{
180 struct cs_spec *spec = codec->spec;
181 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
182}
183
184static int cs_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
185 struct hda_codec *codec,
186 unsigned int stream_tag,
187 unsigned int format,
188 struct snd_pcm_substream *substream)
189{
190 struct cs_spec *spec = codec->spec;
191 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
192 format, substream);
193}
194
195static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
196 struct hda_codec *codec,
197 struct snd_pcm_substream *substream)
198{
199 struct cs_spec *spec = codec->spec;
200 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
201}
202
203/*
204 * Analog capture
205 */
206static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
207 struct hda_codec *codec,
208 unsigned int stream_tag,
209 unsigned int format,
210 struct snd_pcm_substream *substream)
211{
212 struct cs_spec *spec = codec->spec;
213 spec->cur_adc = spec->adc_nid[spec->cur_input];
214 spec->cur_adc_stream_tag = stream_tag;
215 spec->cur_adc_format = format;
216 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
217 return 0;
218}
219
220static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
221 struct hda_codec *codec,
222 struct snd_pcm_substream *substream)
223{
224 struct cs_spec *spec = codec->spec;
225 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
226 spec->cur_adc = 0;
227 return 0;
228}
229
230/*
231 */
232static struct hda_pcm_stream cs_pcm_analog_playback = {
233 .substreams = 1,
234 .channels_min = 2,
235 .channels_max = 2,
236 .ops = {
237 .open = cs_playback_pcm_open,
238 .prepare = cs_playback_pcm_prepare,
239 .cleanup = cs_playback_pcm_cleanup
240 },
241};
242
243static struct hda_pcm_stream cs_pcm_analog_capture = {
244 .substreams = 1,
245 .channels_min = 2,
246 .channels_max = 2,
247 .ops = {
248 .prepare = cs_capture_pcm_prepare,
249 .cleanup = cs_capture_pcm_cleanup
250 },
251};
252
253static struct hda_pcm_stream cs_pcm_digital_playback = {
254 .substreams = 1,
255 .channels_min = 2,
256 .channels_max = 2,
257 .ops = {
258 .open = cs_dig_playback_pcm_open,
259 .close = cs_dig_playback_pcm_close,
260 .prepare = cs_dig_playback_pcm_prepare,
261 .cleanup = cs_dig_playback_pcm_cleanup
262 },
263};
264
265static struct hda_pcm_stream cs_pcm_digital_capture = {
266 .substreams = 1,
267 .channels_min = 2,
268 .channels_max = 2,
269};
270
271static int cs_build_pcms(struct hda_codec *codec)
272{
273 struct cs_spec *spec = codec->spec;
274 struct hda_pcm *info = spec->pcm_rec;
275
276 codec->pcm_info = info;
277 codec->num_pcms = 0;
278
279 info->name = "Cirrus Analog";
280 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = cs_pcm_analog_playback;
281 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dac_nid[0];
282 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
283 spec->multiout.max_channels;
284 info->stream[SNDRV_PCM_STREAM_CAPTURE] = cs_pcm_analog_capture;
285 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
286 spec->adc_nid[spec->cur_input];
287 codec->num_pcms++;
288
289 if (!spec->multiout.dig_out_nid && !spec->dig_in)
290 return 0;
291
292 info++;
293 info->name = "Cirrus Digital";
294 info->pcm_type = spec->autocfg.dig_out_type[0];
295 if (!info->pcm_type)
296 info->pcm_type = HDA_PCM_TYPE_SPDIF;
297 if (spec->multiout.dig_out_nid) {
298 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
299 cs_pcm_digital_playback;
300 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
301 spec->multiout.dig_out_nid;
302 }
303 if (spec->dig_in) {
304 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
305 cs_pcm_digital_capture;
306 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in;
307 }
308 codec->num_pcms++;
309
310 return 0;
311}
312
313/*
314 * parse codec topology
315 */
316
317static hda_nid_t get_dac(struct hda_codec *codec, hda_nid_t pin)
318{
319 hda_nid_t dac;
320 if (!pin)
321 return 0;
322 if (snd_hda_get_connections(codec, pin, &dac, 1) != 1)
323 return 0;
324 return dac;
325}
326
327static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
328{
329 struct cs_spec *spec = codec->spec;
330 struct auto_pin_cfg *cfg = &spec->autocfg;
331 hda_nid_t pin = cfg->input_pins[idx];
332 unsigned int val = snd_hda_query_pin_caps(codec, pin);
333 if (!(val & AC_PINCAP_PRES_DETECT))
334 return 0;
335 val = snd_hda_codec_get_pincfg(codec, pin);
336 return (get_defcfg_connect(val) == AC_JACK_PORT_COMPLEX);
337}
338
339static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
340 unsigned int *idxp)
341{
342 int i;
343 hda_nid_t nid;
344
345 nid = codec->start_nid;
346 for (i = 0; i < codec->num_nodes; i++, nid++) {
347 hda_nid_t pins[2];
348 unsigned int type;
349 int j, nums;
350 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE)
351 >> AC_WCAP_TYPE_SHIFT;
352 if (type != AC_WID_AUD_IN)
353 continue;
354 nums = snd_hda_get_connections(codec, nid, pins,
355 ARRAY_SIZE(pins));
356 if (nums <= 0)
357 continue;
358 for (j = 0; j < nums; j++) {
359 if (pins[j] == pin) {
360 *idxp = j;
361 return nid;
362 }
363 }
364 }
365 return 0;
366}
367
368static int is_active_pin(struct hda_codec *codec, hda_nid_t nid)
369{
370 unsigned int val;
371 val = snd_hda_codec_get_pincfg(codec, nid);
372 return (get_defcfg_connect(val) != AC_JACK_PORT_NONE);
373}
374
375static int parse_output(struct hda_codec *codec)
376{
377 struct cs_spec *spec = codec->spec;
378 struct auto_pin_cfg *cfg = &spec->autocfg;
379 int i, extra_nids;
380 hda_nid_t dac;
381
382 for (i = 0; i < cfg->line_outs; i++) {
383 dac = get_dac(codec, cfg->line_out_pins[i]);
384 if (!dac)
385 break;
386 spec->dac_nid[i] = dac;
387 }
388 spec->multiout.num_dacs = i;
389 spec->multiout.dac_nids = spec->dac_nid;
390 spec->multiout.max_channels = i * 2;
391
392 /* add HP and speakers */
393 extra_nids = 0;
394 for (i = 0; i < cfg->hp_outs; i++) {
395 dac = get_dac(codec, cfg->hp_pins[i]);
396 if (!dac)
397 break;
398 if (!i)
399 spec->multiout.hp_nid = dac;
400 else
401 spec->multiout.extra_out_nid[extra_nids++] = dac;
402 }
403 for (i = 0; i < cfg->speaker_outs; i++) {
404 dac = get_dac(codec, cfg->speaker_pins[i]);
405 if (!dac)
406 break;
407 spec->multiout.extra_out_nid[extra_nids++] = dac;
408 }
409
410 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
411 cfg->speaker_outs = cfg->line_outs;
412 memcpy(cfg->speaker_pins, cfg->line_out_pins,
413 sizeof(cfg->speaker_pins));
414 cfg->line_outs = 0;
415 }
416
417 return 0;
418}
419
420static int parse_input(struct hda_codec *codec)
421{
422 struct cs_spec *spec = codec->spec;
423 struct auto_pin_cfg *cfg = &spec->autocfg;
424 int i;
425
426 for (i = 0; i < AUTO_PIN_LAST; i++) {
427 hda_nid_t pin = cfg->input_pins[i];
428 if (!pin)
429 continue;
430 spec->input_idx[spec->num_inputs] = i;
431 spec->capsrc_idx[i] = spec->num_inputs++;
432 spec->cur_input = i;
433 spec->adc_nid[i] = get_adc(codec, pin, &spec->adc_idx[i]);
434 }
435 if (!spec->num_inputs)
436 return 0;
437
438 /* check whether the automatic mic switch is available */
439 if (spec->num_inputs == 2 &&
440 spec->adc_nid[AUTO_PIN_MIC] && spec->adc_nid[AUTO_PIN_FRONT_MIC]) {
441 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_FRONT_MIC])) {
442 if (!is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
443 spec->mic_detect = 1;
444 spec->automic_idx = AUTO_PIN_FRONT_MIC;
445 }
446 } else {
447 if (is_ext_mic(codec, cfg->input_pins[AUTO_PIN_MIC])) {
448 spec->mic_detect = 1;
449 spec->automic_idx = AUTO_PIN_MIC;
450 }
451 }
452 }
453 return 0;
454}
455
456
457static int parse_digital_output(struct hda_codec *codec)
458{
459 struct cs_spec *spec = codec->spec;
460 struct auto_pin_cfg *cfg = &spec->autocfg;
461 hda_nid_t nid;
462
463 if (!cfg->dig_outs)
464 return 0;
465 if (snd_hda_get_connections(codec, cfg->dig_out_pins[0], &nid, 1) < 1)
466 return 0;
467 spec->multiout.dig_out_nid = nid;
468 spec->multiout.share_spdif = 1;
469 if (cfg->dig_outs > 1 &&
470 snd_hda_get_connections(codec, cfg->dig_out_pins[1], &nid, 1) > 0) {
471 spec->slave_dig_outs[0] = nid;
472 codec->slave_dig_outs = spec->slave_dig_outs;
473 }
474 return 0;
475}
476
477static int parse_digital_input(struct hda_codec *codec)
478{
479 struct cs_spec *spec = codec->spec;
480 struct auto_pin_cfg *cfg = &spec->autocfg;
481 int idx;
482
483 if (cfg->dig_in_pin)
484 spec->dig_in = get_adc(codec, cfg->dig_in_pin, &idx);
485 return 0;
486}
487
488/*
489 * create mixer controls
490 */
491
492static const char *dir_sfx[2] = { "Playback", "Capture" };
493
494static int add_mute(struct hda_codec *codec, const char *name, int index,
495 unsigned int pval, int dir, struct snd_kcontrol **kctlp)
496{
497 char tmp[44];
498 struct snd_kcontrol_new knew =
499 HDA_CODEC_MUTE_IDX(tmp, index, 0, 0, HDA_OUTPUT);
500 knew.private_value = pval;
501 snprintf(tmp, sizeof(tmp), "%s %s Switch", name, dir_sfx[dir]);
502 *kctlp = snd_ctl_new1(&knew, codec);
503 return snd_hda_ctl_add(codec, *kctlp);
504}
505
506static int add_volume(struct hda_codec *codec, const char *name,
507 int index, unsigned int pval, int dir,
508 struct snd_kcontrol **kctlp)
509{
510 char tmp[32];
511 struct snd_kcontrol_new knew =
512 HDA_CODEC_VOLUME_IDX(tmp, index, 0, 0, HDA_OUTPUT);
513 knew.private_value = pval;
514 snprintf(tmp, sizeof(tmp), "%s %s Volume", name, dir_sfx[dir]);
515 *kctlp = snd_ctl_new1(&knew, codec);
516 return snd_hda_ctl_add(codec, *kctlp);
517}
518
519static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
520{
521 unsigned int caps;
522
523 /* set the upper-limit for mixer amp to 0dB */
524 caps = query_amp_caps(codec, dac, HDA_OUTPUT);
525 caps &= ~(0x7f << AC_AMPCAP_NUM_STEPS_SHIFT);
526 caps |= ((caps >> AC_AMPCAP_OFFSET_SHIFT) & 0x7f)
527 << AC_AMPCAP_NUM_STEPS_SHIFT;
528 snd_hda_override_amp_caps(codec, dac, HDA_OUTPUT, caps);
529}
530
531static int add_vmaster(struct hda_codec *codec, hda_nid_t dac)
532{
533 struct cs_spec *spec = codec->spec;
534 unsigned int tlv[4];
535 int err;
536
537 spec->vmaster_sw =
538 snd_ctl_make_virtual_master("Master Playback Switch", NULL);
539 err = snd_hda_ctl_add(codec, spec->vmaster_sw);
540 if (err < 0)
541 return err;
542
543 snd_hda_set_vmaster_tlv(codec, dac, HDA_OUTPUT, tlv);
544 spec->vmaster_vol =
545 snd_ctl_make_virtual_master("Master Playback Volume", tlv);
546 err = snd_hda_ctl_add(codec, spec->vmaster_vol);
547 if (err < 0)
548 return err;
549 return 0;
550}
551
552static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
553 int num_ctls, int type)
554{
555 struct cs_spec *spec = codec->spec;
556 const char *name;
557 int err, index;
558 struct snd_kcontrol *kctl;
559 static char *speakers[] = {
560 "Front Speaker", "Surround Speaker", "Bass Speaker"
561 };
562 static char *line_outs[] = {
563 "Front Line-Out", "Surround Line-Out", "Bass Line-Out"
564 };
565
566 fix_volume_caps(codec, dac);
567 if (!spec->vmaster_sw) {
568 err = add_vmaster(codec, dac);
569 if (err < 0)
570 return err;
571 }
572
573 index = 0;
574 switch (type) {
575 case AUTO_PIN_HP_OUT:
576 name = "Headphone";
577 index = idx;
578 break;
579 case AUTO_PIN_SPEAKER_OUT:
580 if (num_ctls > 1)
581 name = speakers[idx];
582 else
583 name = "Speaker";
584 break;
585 default:
586 if (num_ctls > 1)
587 name = line_outs[idx];
588 else
589 name = "Line-Out";
590 break;
591 }
592
593 err = add_mute(codec, name, index,
594 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
595 if (err < 0)
596 return err;
597 err = snd_ctl_add_slave(spec->vmaster_sw, kctl);
598 if (err < 0)
599 return err;
600
601 err = add_volume(codec, name, index,
602 HDA_COMPOSE_AMP_VAL(dac, 3, 0, HDA_OUTPUT), 0, &kctl);
603 if (err < 0)
604 return err;
605 err = snd_ctl_add_slave(spec->vmaster_vol, kctl);
606 if (err < 0)
607 return err;
608
609 return 0;
610}
611
612static int build_output(struct hda_codec *codec)
613{
614 struct cs_spec *spec = codec->spec;
615 struct auto_pin_cfg *cfg = &spec->autocfg;
616 int i, err;
617
618 for (i = 0; i < cfg->line_outs; i++) {
619 err = add_output(codec, get_dac(codec, cfg->line_out_pins[i]),
620 i, cfg->line_outs, cfg->line_out_type);
621 if (err < 0)
622 return err;
623 }
624 for (i = 0; i < cfg->hp_outs; i++) {
625 err = add_output(codec, get_dac(codec, cfg->hp_pins[i]),
626 i, cfg->hp_outs, AUTO_PIN_HP_OUT);
627 if (err < 0)
628 return err;
629 }
630 for (i = 0; i < cfg->speaker_outs; i++) {
631 err = add_output(codec, get_dac(codec, cfg->speaker_pins[i]),
632 i, cfg->speaker_outs, AUTO_PIN_SPEAKER_OUT);
633 if (err < 0)
634 return err;
635 }
636 return 0;
637}
638
639/*
640 */
641
642static struct snd_kcontrol_new cs_capture_ctls[] = {
643 HDA_BIND_SW("Capture Switch", 0),
644 HDA_BIND_VOL("Capture Volume", 0),
645};
646
647static int change_cur_input(struct hda_codec *codec, unsigned int idx,
648 int force)
649{
650 struct cs_spec *spec = codec->spec;
651
652 if (spec->cur_input == idx && !force)
653 return 0;
654 if (spec->cur_adc && spec->cur_adc != spec->adc_nid[idx]) {
655 /* stream is running, let's swap the current ADC */
656 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
657 spec->cur_adc = spec->adc_nid[idx];
658 snd_hda_codec_setup_stream(codec, spec->cur_adc,
659 spec->cur_adc_stream_tag, 0,
660 spec->cur_adc_format);
661 }
662 snd_hda_codec_write(codec, spec->cur_adc, 0,
663 AC_VERB_SET_CONNECT_SEL,
664 spec->adc_idx[idx]);
665 spec->cur_input = idx;
666 return 1;
667}
668
669static int cs_capture_source_info(struct snd_kcontrol *kcontrol,
670 struct snd_ctl_elem_info *uinfo)
671{
672 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
673 struct cs_spec *spec = codec->spec;
674 unsigned int idx;
675
676 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
677 uinfo->count = 1;
678 uinfo->value.enumerated.items = spec->num_inputs;
679 if (uinfo->value.enumerated.item >= spec->num_inputs)
680 uinfo->value.enumerated.item = spec->num_inputs - 1;
681 idx = spec->input_idx[uinfo->value.enumerated.item];
682 strcpy(uinfo->value.enumerated.name, auto_pin_cfg_labels[idx]);
683 return 0;
684}
685
686static int cs_capture_source_get(struct snd_kcontrol *kcontrol,
687 struct snd_ctl_elem_value *ucontrol)
688{
689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
690 struct cs_spec *spec = codec->spec;
691 ucontrol->value.enumerated.item[0] = spec->capsrc_idx[spec->cur_input];
692 return 0;
693}
694
695static int cs_capture_source_put(struct snd_kcontrol *kcontrol,
696 struct snd_ctl_elem_value *ucontrol)
697{
698 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
699 struct cs_spec *spec = codec->spec;
700 unsigned int idx = ucontrol->value.enumerated.item[0];
701
702 if (idx >= spec->num_inputs)
703 return -EINVAL;
704 idx = spec->input_idx[idx];
705 return change_cur_input(codec, idx, 0);
706}
707
708static struct snd_kcontrol_new cs_capture_source = {
709 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
710 .name = "Capture Source",
711 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
712 .info = cs_capture_source_info,
713 .get = cs_capture_source_get,
714 .put = cs_capture_source_put,
715};
716
717static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec,
718 struct hda_ctl_ops *ops)
719{
720 struct cs_spec *spec = codec->spec;
721 struct hda_bind_ctls *bind;
722 int i, n;
723
724 bind = kzalloc(sizeof(*bind) + sizeof(long) * (spec->num_inputs + 1),
725 GFP_KERNEL);
726 if (!bind)
727 return NULL;
728 bind->ops = ops;
729 n = 0;
730 for (i = 0; i < AUTO_PIN_LAST; i++) {
731 if (!spec->adc_nid[i])
732 continue;
733 bind->values[n++] =
734 HDA_COMPOSE_AMP_VAL(spec->adc_nid[i], 3,
735 spec->adc_idx[i], HDA_INPUT);
736 }
737 return bind;
738}
739
740static int build_input(struct hda_codec *codec)
741{
742 struct cs_spec *spec = codec->spec;
743 int i, err;
744
745 if (!spec->num_inputs)
746 return 0;
747
748 /* make bind-capture */
749 spec->capture_bind[0] = make_bind_capture(codec, &snd_hda_bind_sw);
750 spec->capture_bind[1] = make_bind_capture(codec, &snd_hda_bind_vol);
751 for (i = 0; i < 2; i++) {
752 struct snd_kcontrol *kctl;
753 if (!spec->capture_bind[i])
754 return -ENOMEM;
755 kctl = snd_ctl_new1(&cs_capture_ctls[i], codec);
756 if (!kctl)
757 return -ENOMEM;
758 kctl->private_value = (long)spec->capture_bind[i];
759 err = snd_hda_ctl_add(codec, kctl);
760 if (err < 0)
761 return err;
762 }
763
764 if (spec->num_inputs > 1 && !spec->mic_detect) {
765 err = snd_hda_ctl_add(codec,
766 snd_ctl_new1(&cs_capture_source, codec));
767 if (err < 0)
768 return err;
769 }
770
771 return 0;
772}
773
774/*
775 */
776
777static int build_digital_output(struct hda_codec *codec)
778{
779 struct cs_spec *spec = codec->spec;
780 int err;
781
782 if (!spec->multiout.dig_out_nid)
783 return 0;
784
785 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
786 if (err < 0)
787 return err;
788 err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
789 if (err < 0)
790 return err;
791 return 0;
792}
793
794static int build_digital_input(struct hda_codec *codec)
795{
796 struct cs_spec *spec = codec->spec;
797 if (spec->dig_in)
798 return snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
799 return 0;
800}
801
802/*
803 * auto-mute and auto-mic switching
804 */
805
806static void cs_automute(struct hda_codec *codec)
807{
808 struct cs_spec *spec = codec->spec;
809 struct auto_pin_cfg *cfg = &spec->autocfg;
810 unsigned int caps, present, hp_present;
811 hda_nid_t nid;
812 int i;
813
814 hp_present = 0;
815 for (i = 0; i < cfg->hp_outs; i++) {
816 nid = cfg->hp_pins[i];
817 caps = snd_hda_query_pin_caps(codec, nid);
818 if (!(caps & AC_PINCAP_PRES_DETECT))
819 continue;
820 if (caps & AC_PINCAP_TRIG_REQ)
821 snd_hda_codec_read(codec, nid, 0,
822 AC_VERB_SET_PIN_SENSE, 0);
823 present = snd_hda_codec_read(codec, nid, 0,
824 AC_VERB_GET_PIN_SENSE, 0);
825 hp_present |= (present & AC_PINSENSE_PRESENCE) != 0;
826 if (hp_present)
827 break;
828 }
829 for (i = 0; i < cfg->speaker_outs; i++) {
830 nid = cfg->speaker_pins[i];
831 snd_hda_codec_write(codec, nid, 0,
832 AC_VERB_SET_PIN_WIDGET_CONTROL,
833 hp_present ? 0 : PIN_OUT);
834 }
835 if (spec->board_config == CS420X_MBP55) {
836 unsigned int gpio = hp_present ? 0x02 : 0x08;
837 snd_hda_codec_write(codec, 0x01, 0,
838 AC_VERB_SET_GPIO_DATA, gpio);
839 }
840}
841
842static void cs_automic(struct hda_codec *codec)
843{
844 struct cs_spec *spec = codec->spec;
845 struct auto_pin_cfg *cfg = &spec->autocfg;
846 hda_nid_t nid;
847 unsigned int caps, present;
848
849 nid = cfg->input_pins[spec->automic_idx];
850 caps = snd_hda_query_pin_caps(codec, nid);
851 if (caps & AC_PINCAP_TRIG_REQ)
852 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
853 present = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_PIN_SENSE, 0);
855 if (present & AC_PINSENSE_PRESENCE)
856 change_cur_input(codec, spec->automic_idx, 0);
857 else {
858 unsigned int imic = (spec->automic_idx == AUTO_PIN_MIC) ?
859 AUTO_PIN_FRONT_MIC : AUTO_PIN_MIC;
860 change_cur_input(codec, imic, 0);
861 }
862}
863
864/*
865 */
866
867static void init_output(struct hda_codec *codec)
868{
869 struct cs_spec *spec = codec->spec;
870 struct auto_pin_cfg *cfg = &spec->autocfg;
871 int i;
872
873 /* mute first */
874 for (i = 0; i < spec->multiout.num_dacs; i++)
875 snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0,
876 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
877 if (spec->multiout.hp_nid)
878 snd_hda_codec_write(codec, spec->multiout.hp_nid, 0,
879 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
880 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
881 if (!spec->multiout.extra_out_nid[i])
882 break;
883 snd_hda_codec_write(codec, spec->multiout.extra_out_nid[i], 0,
884 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
885 }
886
887 /* set appropriate pin controls */
888 for (i = 0; i < cfg->line_outs; i++)
889 snd_hda_codec_write(codec, cfg->line_out_pins[i], 0,
890 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
891 for (i = 0; i < cfg->hp_outs; i++) {
892 hda_nid_t nid = cfg->hp_pins[i];
893 snd_hda_codec_write(codec, nid, 0,
894 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP);
895 if (!cfg->speaker_outs)
896 continue;
897 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) {
898 snd_hda_codec_write(codec, nid, 0,
899 AC_VERB_SET_UNSOLICITED_ENABLE,
900 AC_USRSP_EN | HP_EVENT);
901 spec->hp_detect = 1;
902 }
903 }
904 for (i = 0; i < cfg->speaker_outs; i++)
905 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
906 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
907 if (spec->hp_detect)
908 cs_automute(codec);
909}
910
911static void init_input(struct hda_codec *codec)
912{
913 struct cs_spec *spec = codec->spec;
914 struct auto_pin_cfg *cfg = &spec->autocfg;
915 unsigned int coef;
916 int i;
917
918 for (i = 0; i < AUTO_PIN_LAST; i++) {
919 unsigned int ctl;
920 hda_nid_t pin = cfg->input_pins[i];
921 if (!pin || !spec->adc_nid[i])
922 continue;
923 /* set appropriate pin control and mute first */
924 ctl = PIN_IN;
925 if (i <= AUTO_PIN_FRONT_MIC) {
926 unsigned int caps = snd_hda_query_pin_caps(codec, pin);
927 caps >>= AC_PINCAP_VREF_SHIFT;
928 if (caps & AC_PINCAP_VREF_80)
929 ctl = PIN_VREF80;
930 }
931 snd_hda_codec_write(codec, pin, 0,
932 AC_VERB_SET_PIN_WIDGET_CONTROL, ctl);
933 snd_hda_codec_write(codec, spec->adc_nid[i], 0,
934 AC_VERB_SET_AMP_GAIN_MUTE,
935 AMP_IN_MUTE(spec->adc_idx[i]));
936 if (spec->mic_detect && spec->automic_idx == i)
937 snd_hda_codec_write(codec, pin, 0,
938 AC_VERB_SET_UNSOLICITED_ENABLE,
939 AC_USRSP_EN | MIC_EVENT);
940 }
941 change_cur_input(codec, spec->cur_input, 1);
942 if (spec->mic_detect)
943 cs_automic(codec);
944
945 coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */
946 if (is_active_pin(codec, CS_DMIC2_PIN_NID))
947 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
948 if (is_active_pin(codec, CS_DMIC1_PIN_NID))
949 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0
950 * No effect if SPDIF_OUT2 is slected in
951 * IDX_SPDIF_CTL.
952 */
953 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
954}
955
956static struct hda_verb cs_coef_init_verbs[] = {
957 {0x11, AC_VERB_SET_PROC_STATE, 1},
958 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
959 {0x11, AC_VERB_SET_PROC_COEF,
960 (0x002a /* DAC1/2/3 SZCMode Soft Ramp */
961 | 0x0040 /* Mute DACs on FIFO error */
962 | 0x1000 /* Enable DACs High Pass Filter */
963 | 0x0400 /* Disable Coefficient Auto increment */
964 )},
965 /* Beep */
966 {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG},
967 {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */
968
969 {} /* terminator */
970};
971
972/* SPDIF setup */
973static void init_digital(struct hda_codec *codec)
974{
975 unsigned int coef;
976
977 coef = 0x0002; /* SRC_MUTE soft-mute on SPDIF (if no lock) */
978 coef |= 0x0008; /* Replace with mute on error */
979 if (is_active_pin(codec, CS_DIG_OUT2_PIN_NID))
980 coef |= 0x4000; /* RX to TX1 or TX2 Loopthru / SPDIF2
981 * SPDIF_OUT2 is shared with GPIO1 and
982 * DMIC_SDA2.
983 */
984 cs_vendor_coef_set(codec, IDX_SPDIF_CTL, coef);
985}
986
987static int cs_init(struct hda_codec *codec)
988{
989 struct cs_spec *spec = codec->spec;
990
991 snd_hda_sequence_write(codec, cs_coef_init_verbs);
992
993 if (spec->gpio_mask) {
994 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK,
995 spec->gpio_mask);
996 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
997 spec->gpio_dir);
998 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
999 spec->gpio_data);
1000 }
1001
1002 init_output(codec);
1003 init_input(codec);
1004 init_digital(codec);
1005 return 0;
1006}
1007
1008static int cs_build_controls(struct hda_codec *codec)
1009{
1010 int err;
1011
1012 err = build_output(codec);
1013 if (err < 0)
1014 return err;
1015 err = build_input(codec);
1016 if (err < 0)
1017 return err;
1018 err = build_digital_output(codec);
1019 if (err < 0)
1020 return err;
1021 err = build_digital_input(codec);
1022 if (err < 0)
1023 return err;
1024 return cs_init(codec);
1025}
1026
1027static void cs_free(struct hda_codec *codec)
1028{
1029 struct cs_spec *spec = codec->spec;
1030 kfree(spec->capture_bind[0]);
1031 kfree(spec->capture_bind[1]);
1032 kfree(codec->spec);
1033}
1034
1035static void cs_unsol_event(struct hda_codec *codec, unsigned int res)
1036{
1037 switch ((res >> 26) & 0x7f) {
1038 case HP_EVENT:
1039 cs_automute(codec);
1040 break;
1041 case MIC_EVENT:
1042 cs_automic(codec);
1043 break;
1044 }
1045}
1046
1047static struct hda_codec_ops cs_patch_ops = {
1048 .build_controls = cs_build_controls,
1049 .build_pcms = cs_build_pcms,
1050 .init = cs_init,
1051 .free = cs_free,
1052 .unsol_event = cs_unsol_event,
1053};
1054
1055static int cs_parse_auto_config(struct hda_codec *codec)
1056{
1057 struct cs_spec *spec = codec->spec;
1058 int err;
1059
1060 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1061 if (err < 0)
1062 return err;
1063
1064 err = parse_output(codec);
1065 if (err < 0)
1066 return err;
1067 err = parse_input(codec);
1068 if (err < 0)
1069 return err;
1070 err = parse_digital_output(codec);
1071 if (err < 0)
1072 return err;
1073 err = parse_digital_input(codec);
1074 if (err < 0)
1075 return err;
1076 return 0;
1077}
1078
1079static const char *cs420x_models[CS420X_MODELS] = {
1080 [CS420X_MBP55] = "mbp55",
1081 [CS420X_AUTO] = "auto",
1082};
1083
1084
1085static struct snd_pci_quirk cs420x_cfg_tbl[] = {
1086 SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55),
1087 {} /* terminator */
1088};
1089
1090struct cs_pincfg {
1091 hda_nid_t nid;
1092 u32 val;
1093};
1094
1095static struct cs_pincfg mbp55_pincfgs[] = {
1096 { 0x09, 0x012b4030 },
1097 { 0x0a, 0x90100121 },
1098 { 0x0b, 0x90100120 },
1099 { 0x0c, 0x400000f0 },
1100 { 0x0d, 0x90a00110 },
1101 { 0x0e, 0x400000f0 },
1102 { 0x0f, 0x400000f0 },
1103 { 0x10, 0x014be040 },
1104 { 0x12, 0x400000f0 },
1105 { 0x15, 0x400000f0 },
1106 {} /* terminator */
1107};
1108
1109static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = {
1110 [CS420X_MBP55] = mbp55_pincfgs,
1111};
1112
1113static void fix_pincfg(struct hda_codec *codec, int model)
1114{
1115 const struct cs_pincfg *cfg = cs_pincfgs[model];
1116 if (!cfg)
1117 return;
1118 for (; cfg->nid; cfg++)
1119 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
1120}
1121
1122
1123static int patch_cs420x(struct hda_codec *codec)
1124{
1125 struct cs_spec *spec;
1126 int err;
1127
1128 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1129 if (!spec)
1130 return -ENOMEM;
1131 codec->spec = spec;
1132
1133 spec->board_config =
1134 snd_hda_check_board_config(codec, CS420X_MODELS,
1135 cs420x_models, cs420x_cfg_tbl);
1136 if (spec->board_config >= 0)
1137 fix_pincfg(codec, spec->board_config);
1138
1139 switch (spec->board_config) {
1140 case CS420X_MBP55:
1141 /* GPIO1 = headphones */
1142 /* GPIO3 = speakers */
1143 spec->gpio_mask = 0x0a;
1144 spec->gpio_dir = 0x0a;
1145 break;
1146 }
1147
1148 err = cs_parse_auto_config(codec);
1149 if (err < 0)
1150 goto error;
1151
1152 codec->patch_ops = cs_patch_ops;
1153
1154 return 0;
1155
1156 error:
1157 kfree(codec->spec);
1158 codec->spec = NULL;
1159 return err;
1160}
1161
1162
1163/*
1164 * patch entries
1165 */
1166static struct hda_codec_preset snd_hda_preset_cirrus[] = {
1167 { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x },
1168 { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x },
1169 {} /* terminator */
1170};
1171
1172MODULE_ALIAS("snd-hda-codec-id:10134206");
1173MODULE_ALIAS("snd-hda-codec-id:10134207");
1174
1175MODULE_LICENSE("GPL");
1176MODULE_DESCRIPTION("Cirrus Logic HD-audio codec");
1177
1178static struct hda_codec_preset_list cirrus_list = {
1179 .preset = snd_hda_preset_cirrus,
1180 .owner = THIS_MODULE,
1181};
1182
1183static int __init patch_cirrus_init(void)
1184{
1185 return snd_hda_add_codec_preset(&cirrus_list);
1186}
1187
1188static void __exit patch_cirrus_exit(void)
1189{
1190 snd_hda_delete_codec_preset(&cirrus_list);
1191}
1192
1193module_init(patch_cirrus_init)
1194module_exit(patch_cirrus_exit)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index c921264bbd71..780e1a72114a 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -635,7 +635,8 @@ static int patch_cmi9880(struct hda_codec *codec)
635 cmi9880_models, 635 cmi9880_models,
636 cmi9880_cfg_tbl); 636 cmi9880_cfg_tbl);
637 if (spec->board_config < 0) { 637 if (spec->board_config < 0) {
638 snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); 638 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
639 codec->chip_name);
639 spec->board_config = CMI_AUTO; /* try everything */ 640 spec->board_config = CMI_AUTO; /* try everything */
640 } 641 }
641 642
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index ac868c59f9e3..9d899eda44d7 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -108,6 +108,8 @@ struct conexant_spec {
108 struct hda_input_mux private_imux; 108 struct hda_input_mux private_imux;
109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 109 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
110 110
111 unsigned int dell_automute;
112 unsigned int port_d_mode;
111}; 113};
112 114
113static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo, 115static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
@@ -1908,6 +1910,480 @@ static int patch_cxt5051(struct hda_codec *codec)
1908 return 0; 1910 return 0;
1909} 1911}
1910 1912
1913/* Conexant 5066 specific */
1914
1915static hda_nid_t cxt5066_dac_nids[1] = { 0x10 };
1916static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 };
1917static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 };
1918#define CXT5066_SPDIF_OUT 0x21
1919
1920static struct hda_channel_mode cxt5066_modes[1] = {
1921 { 2, NULL },
1922};
1923
1924static void cxt5066_update_speaker(struct hda_codec *codec)
1925{
1926 struct conexant_spec *spec = codec->spec;
1927 unsigned int pinctl;
1928
1929 snd_printdd("CXT5066: update speaker, hp_present=%d\n",
1930 spec->hp_present);
1931
1932 /* Port A (HP) */
1933 pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0;
1934 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1935 pinctl);
1936
1937 /* Port D (HP/LO) */
1938 pinctl = ((spec->hp_present & 2) && spec->cur_eapd)
1939 ? spec->port_d_mode : 0;
1940 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1941 pinctl);
1942
1943 /* CLASS_D AMP */
1944 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1945 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1946 pinctl);
1947
1948 if (spec->dell_automute) {
1949 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
1950 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
1951 ? PIN_OUT : 0;
1952 snd_hda_codec_write(codec, 0x1c, 0,
1953 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
1954 }
1955}
1956
1957/* turn on/off EAPD (+ mute HP) as a master switch */
1958static int cxt5066_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1959 struct snd_ctl_elem_value *ucontrol)
1960{
1961 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1962
1963 if (!cxt_eapd_put(kcontrol, ucontrol))
1964 return 0;
1965
1966 cxt5066_update_speaker(codec);
1967 return 1;
1968}
1969
1970/* toggle input of built-in and mic jack appropriately */
1971static void cxt5066_automic(struct hda_codec *codec)
1972{
1973 static struct hda_verb ext_mic_present[] = {
1974 /* enable external mic, port B */
1975 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1976
1977 /* switch to external mic input */
1978 {0x17, AC_VERB_SET_CONNECT_SEL, 0},
1979
1980 /* disable internal mic, port C */
1981 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1982 {}
1983 };
1984 static struct hda_verb ext_mic_absent[] = {
1985 /* enable internal mic, port C */
1986 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1987
1988 /* switch to internal mic input */
1989 {0x17, AC_VERB_SET_CONNECT_SEL, 1},
1990
1991 /* disable external mic, port B */
1992 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
1993 {}
1994 };
1995 unsigned int present;
1996
1997 present = snd_hda_codec_read(codec, 0x1a, 0,
1998 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1999 if (present) {
2000 snd_printdd("CXT5066: external microphone detected\n");
2001 snd_hda_sequence_write(codec, ext_mic_present);
2002 } else {
2003 snd_printdd("CXT5066: external microphone absent\n");
2004 snd_hda_sequence_write(codec, ext_mic_absent);
2005 }
2006}
2007
2008/* mute internal speaker if HP is plugged */
2009static void cxt5066_hp_automute(struct hda_codec *codec)
2010{
2011 struct conexant_spec *spec = codec->spec;
2012 unsigned int portA, portD;
2013
2014 /* Port A */
2015 portA = snd_hda_codec_read(codec, 0x19, 0, AC_VERB_GET_PIN_SENSE, 0)
2016 & AC_PINSENSE_PRESENCE;
2017
2018 /* Port D */
2019 portD = (snd_hda_codec_read(codec, 0x1c, 0, AC_VERB_GET_PIN_SENSE, 0)
2020 & AC_PINSENSE_PRESENCE) << 1;
2021
2022 spec->hp_present = !!(portA | portD);
2023 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2024 portA, portD, spec->hp_present);
2025 cxt5066_update_speaker(codec);
2026}
2027
2028/* unsolicited event for jack sensing */
2029static void cxt5066_unsol_event(struct hda_codec *codec, unsigned int res)
2030{
2031 snd_printdd("CXT5066: unsol event %x (%x)\n", res, res >> 26);
2032 switch (res >> 26) {
2033 case CONEXANT_HP_EVENT:
2034 cxt5066_hp_automute(codec);
2035 break;
2036 case CONEXANT_MIC_EVENT:
2037 cxt5066_automic(codec);
2038 break;
2039 }
2040}
2041
2042static const struct hda_input_mux cxt5066_analog_mic_boost = {
2043 .num_items = 5,
2044 .items = {
2045 { "0dB", 0 },
2046 { "10dB", 1 },
2047 { "20dB", 2 },
2048 { "30dB", 3 },
2049 { "40dB", 4 },
2050 },
2051};
2052
2053static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
2054 struct snd_ctl_elem_info *uinfo)
2055{
2056 return snd_hda_input_mux_info(&cxt5066_analog_mic_boost, uinfo);
2057}
2058
2059static int cxt5066_mic_boost_mux_enum_get(struct snd_kcontrol *kcontrol,
2060 struct snd_ctl_elem_value *ucontrol)
2061{
2062 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2063 int val;
2064
2065 val = snd_hda_codec_read(codec, 0x17, 0,
2066 AC_VERB_GET_AMP_GAIN_MUTE, AC_AMP_GET_OUTPUT);
2067
2068 ucontrol->value.enumerated.item[0] = val & AC_AMP_GAIN;
2069 return 0;
2070}
2071
2072static int cxt5066_mic_boost_mux_enum_put(struct snd_kcontrol *kcontrol,
2073 struct snd_ctl_elem_value *ucontrol)
2074{
2075 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2076 const struct hda_input_mux *imux = &cxt5066_analog_mic_boost;
2077 unsigned int idx;
2078
2079 if (!imux->num_items)
2080 return 0;
2081 idx = ucontrol->value.enumerated.item[0];
2082 if (idx >= imux->num_items)
2083 idx = imux->num_items - 1;
2084
2085 snd_hda_codec_write_cache(codec, 0x17, 0,
2086 AC_VERB_SET_AMP_GAIN_MUTE,
2087 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2088 imux->items[idx].index);
2089
2090 return 1;
2091}
2092
2093static struct hda_input_mux cxt5066_capture_source = {
2094 .num_items = 4,
2095 .items = {
2096 { "Mic B", 0 },
2097 { "Mic C", 1 },
2098 { "Mic E", 2 },
2099 { "Mic F", 3 },
2100 },
2101};
2102
2103static struct hda_bind_ctls cxt5066_bind_capture_vol_others = {
2104 .ops = &snd_hda_bind_vol,
2105 .values = {
2106 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2107 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2108 0
2109 },
2110};
2111
2112static struct hda_bind_ctls cxt5066_bind_capture_sw_others = {
2113 .ops = &snd_hda_bind_sw,
2114 .values = {
2115 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT),
2116 HDA_COMPOSE_AMP_VAL(0x14, 3, 2, HDA_INPUT),
2117 0
2118 },
2119};
2120
2121static struct snd_kcontrol_new cxt5066_mixer_master[] = {
2122 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
2123 {}
2124};
2125
2126static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = {
2127 {
2128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2129 .name = "Master Playback Volume",
2130 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
2131 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
2132 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,
2133 .info = snd_hda_mixer_amp_volume_info,
2134 .get = snd_hda_mixer_amp_volume_get,
2135 .put = snd_hda_mixer_amp_volume_put,
2136 .tlv = { .c = snd_hda_mixer_amp_tlv },
2137 /* offset by 28 volume steps to limit minimum gain to -46dB */
2138 .private_value =
2139 HDA_COMPOSE_AMP_VAL_OFS(0x10, 3, 0, HDA_OUTPUT, 28),
2140 },
2141 {}
2142};
2143
2144static struct snd_kcontrol_new cxt5066_mixers[] = {
2145 {
2146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2147 .name = "Master Playback Switch",
2148 .info = cxt_eapd_info,
2149 .get = cxt_eapd_get,
2150 .put = cxt5066_hp_master_sw_put,
2151 .private_value = 0x1d,
2152 },
2153
2154 {
2155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2156 .name = "Analog Mic Boost Capture Enum",
2157 .info = cxt5066_mic_boost_mux_enum_info,
2158 .get = cxt5066_mic_boost_mux_enum_get,
2159 .put = cxt5066_mic_boost_mux_enum_put,
2160 },
2161
2162 HDA_BIND_VOL("Capture Volume", &cxt5066_bind_capture_vol_others),
2163 HDA_BIND_SW("Capture Switch", &cxt5066_bind_capture_sw_others),
2164 {}
2165};
2166
2167static struct hda_verb cxt5066_init_verbs[] = {
2168 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2169 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2170 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2171 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2172
2173 /* Speakers */
2174 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2175 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2176
2177 /* HP, Amp */
2178 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2179 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2180
2181 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2182 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2183
2184 /* DAC1 */
2185 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2186
2187 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2188 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2189 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2190 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2191 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2192 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2193
2194 /* no digital microphone support yet */
2195 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2196
2197 /* Audio input selector */
2198 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2199
2200 /* SPDIF route: PCM */
2201 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2202 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2203
2204 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2205 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2206
2207 /* EAPD */
2208 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2209
2210 /* not handling these yet */
2211 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2212 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2213 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2214 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2215 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2216 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2217 {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2218 {0x22, AC_VERB_SET_UNSOLICITED_ENABLE, 0},
2219 { } /* end */
2220};
2221
2222static struct hda_verb cxt5066_init_verbs_olpc[] = {
2223 /* Port A: headphones */
2224 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2225 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2226
2227 /* Port B: external microphone */
2228 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2229
2230 /* Port C: internal microphone */
2231 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2232
2233 /* Port D: unused */
2234 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2235
2236 /* Port E: unused, but has primary EAPD */
2237 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2238 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2239
2240 /* Port F: unused */
2241 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2242
2243 /* Port G: internal speakers */
2244 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2245 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2246
2247 /* DAC1 */
2248 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2249
2250 /* DAC2: unused */
2251 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2252
2253 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2254 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2255 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2256 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2257 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2258 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2259 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2260 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2261 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2262 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2263 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2264 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2265
2266 /* Disable digital microphone port */
2267 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2268
2269 /* Audio input selectors */
2270 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x3},
2271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2272
2273 /* Disable SPDIF */
2274 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2275 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2276
2277 /* enable unsolicited events for Port A and B */
2278 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2279 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2280 { } /* end */
2281};
2282
2283static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2284 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2285 { } /* end */
2286};
2287
2288/* initialize jack-sensing, too */
2289static int cxt5066_init(struct hda_codec *codec)
2290{
2291 snd_printdd("CXT5066: init\n");
2292 conexant_init(codec);
2293 if (codec->patch_ops.unsol_event) {
2294 cxt5066_hp_automute(codec);
2295 cxt5066_automic(codec);
2296 }
2297 return 0;
2298}
2299
2300enum {
2301 CXT5066_LAPTOP, /* Laptops w/ EAPD support */
2302 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2303 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2304 CXT5066_MODELS
2305};
2306
2307static const char *cxt5066_models[CXT5066_MODELS] = {
2308 [CXT5066_LAPTOP] = "laptop",
2309 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2310 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2311};
2312
2313static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2314 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
2315 CXT5066_LAPTOP),
2316 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell",
2317 CXT5066_DELL_LAPTOP),
2318 {}
2319};
2320
2321static int patch_cxt5066(struct hda_codec *codec)
2322{
2323 struct conexant_spec *spec;
2324 int board_config;
2325
2326 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2327 if (!spec)
2328 return -ENOMEM;
2329 codec->spec = spec;
2330
2331 codec->patch_ops = conexant_patch_ops;
2332 codec->patch_ops.init = cxt5066_init;
2333
2334 spec->dell_automute = 0;
2335 spec->multiout.max_channels = 2;
2336 spec->multiout.num_dacs = ARRAY_SIZE(cxt5066_dac_nids);
2337 spec->multiout.dac_nids = cxt5066_dac_nids;
2338 spec->multiout.dig_out_nid = CXT5066_SPDIF_OUT;
2339 spec->num_adc_nids = 1;
2340 spec->adc_nids = cxt5066_adc_nids;
2341 spec->capsrc_nids = cxt5066_capsrc_nids;
2342 spec->input_mux = &cxt5066_capture_source;
2343
2344 spec->port_d_mode = PIN_HP;
2345
2346 spec->num_init_verbs = 1;
2347 spec->init_verbs[0] = cxt5066_init_verbs;
2348 spec->num_channel_mode = ARRAY_SIZE(cxt5066_modes);
2349 spec->channel_mode = cxt5066_modes;
2350 spec->cur_adc = 0;
2351 spec->cur_adc_idx = 0;
2352
2353 board_config = snd_hda_check_board_config(codec, CXT5066_MODELS,
2354 cxt5066_models, cxt5066_cfg_tbl);
2355 switch (board_config) {
2356 default:
2357 case CXT5066_LAPTOP:
2358 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2359 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2360 break;
2361 case CXT5066_DELL_LAPTOP:
2362 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2363 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2364
2365 spec->port_d_mode = PIN_OUT;
2366 spec->init_verbs[spec->num_init_verbs] = cxt5066_init_verbs_portd_lo;
2367 spec->num_init_verbs++;
2368 spec->dell_automute = 1;
2369 break;
2370 case CXT5066_OLPC_XO_1_5:
2371 codec->patch_ops.unsol_event = cxt5066_unsol_event;
2372 spec->init_verbs[0] = cxt5066_init_verbs_olpc;
2373 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master_olpc;
2374 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2375 spec->port_d_mode = 0;
2376
2377 /* no S/PDIF out */
2378 spec->multiout.dig_out_nid = 0;
2379
2380 /* input source automatically selected */
2381 spec->input_mux = NULL;
2382 break;
2383 }
2384
2385 return 0;
2386}
1911 2387
1912/* 2388/*
1913 */ 2389 */
@@ -1919,12 +2395,15 @@ static struct hda_codec_preset snd_hda_preset_conexant[] = {
1919 .patch = patch_cxt5047 }, 2395 .patch = patch_cxt5047 },
1920 { .id = 0x14f15051, .name = "CX20561 (Hermosa)", 2396 { .id = 0x14f15051, .name = "CX20561 (Hermosa)",
1921 .patch = patch_cxt5051 }, 2397 .patch = patch_cxt5051 },
2398 { .id = 0x14f15066, .name = "CX20582 (Pebble)",
2399 .patch = patch_cxt5066 },
1922 {} /* terminator */ 2400 {} /* terminator */
1923}; 2401};
1924 2402
1925MODULE_ALIAS("snd-hda-codec-id:14f15045"); 2403MODULE_ALIAS("snd-hda-codec-id:14f15045");
1926MODULE_ALIAS("snd-hda-codec-id:14f15047"); 2404MODULE_ALIAS("snd-hda-codec-id:14f15047");
1927MODULE_ALIAS("snd-hda-codec-id:14f15051"); 2405MODULE_ALIAS("snd-hda-codec-id:14f15051");
2406MODULE_ALIAS("snd-hda-codec-id:14f15066");
1928 2407
1929MODULE_LICENSE("GPL"); 2408MODULE_LICENSE("GPL");
1930MODULE_DESCRIPTION("Conexant HD-audio codec"); 2409MODULE_DESCRIPTION("Conexant HD-audio codec");
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index fcc77fec4487..01a18ed475ac 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -33,8 +33,8 @@
33#include "hda_codec.h" 33#include "hda_codec.h"
34#include "hda_local.h" 34#include "hda_local.h"
35 35
36#define CVT_NID 0x02 /* audio converter */ 36static hda_nid_t cvt_nid; /* audio converter */
37#define PIN_NID 0x03 /* HDMI output pin */ 37static hda_nid_t pin_nid; /* HDMI output pin */
38 38
39#define INTEL_HDMI_EVENT_TAG 0x08 39#define INTEL_HDMI_EVENT_TAG 0x08
40 40
@@ -44,30 +44,6 @@ struct intel_hdmi_spec {
44 struct hdmi_eld sink_eld; 44 struct hdmi_eld sink_eld;
45}; 45};
46 46
47static struct hda_verb pinout_enable_verb[] = {
48 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
49 {} /* terminator */
50};
51
52static struct hda_verb unsolicited_response_verb[] = {
53 {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
54 INTEL_HDMI_EVENT_TAG},
55 {}
56};
57
58static struct hda_verb def_chan_map[] = {
59 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
60 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
61 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
62 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
63 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
64 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
65 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
66 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
67 {}
68};
69
70
71struct hdmi_audio_infoframe { 47struct hdmi_audio_infoframe {
72 u8 type; /* 0x84 */ 48 u8 type; /* 0x84 */
73 u8 ver; /* 0x01 */ 49 u8 ver; /* 0x01 */
@@ -244,11 +220,12 @@ static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
244static void hdmi_enable_output(struct hda_codec *codec) 220static void hdmi_enable_output(struct hda_codec *codec)
245{ 221{
246 /* Unmute */ 222 /* Unmute */
247 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) 223 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
248 snd_hda_codec_write(codec, PIN_NID, 0, 224 snd_hda_codec_write(codec, pin_nid, 0,
249 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); 225 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
250 /* Enable pin out */ 226 /* Enable pin out */
251 snd_hda_sequence_write(codec, pinout_enable_verb); 227 snd_hda_codec_write(codec, pin_nid, 0,
228 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
252} 229}
253 230
254/* 231/*
@@ -256,8 +233,8 @@ static void hdmi_enable_output(struct hda_codec *codec)
256 */ 233 */
257static void hdmi_start_infoframe_trans(struct hda_codec *codec) 234static void hdmi_start_infoframe_trans(struct hda_codec *codec)
258{ 235{
259 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 236 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
260 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, 237 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
261 AC_DIPXMIT_BEST); 238 AC_DIPXMIT_BEST);
262} 239}
263 240
@@ -266,20 +243,20 @@ static void hdmi_start_infoframe_trans(struct hda_codec *codec)
266 */ 243 */
267static void hdmi_stop_infoframe_trans(struct hda_codec *codec) 244static void hdmi_stop_infoframe_trans(struct hda_codec *codec)
268{ 245{
269 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 246 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
270 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, 247 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
271 AC_DIPXMIT_DISABLE); 248 AC_DIPXMIT_DISABLE);
272} 249}
273 250
274static int hdmi_get_channel_count(struct hda_codec *codec) 251static int hdmi_get_channel_count(struct hda_codec *codec)
275{ 252{
276 return 1 + snd_hda_codec_read(codec, CVT_NID, 0, 253 return 1 + snd_hda_codec_read(codec, cvt_nid, 0,
277 AC_VERB_GET_CVT_CHAN_COUNT, 0); 254 AC_VERB_GET_CVT_CHAN_COUNT, 0);
278} 255}
279 256
280static void hdmi_set_channel_count(struct hda_codec *codec, int chs) 257static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
281{ 258{
282 snd_hda_codec_write(codec, CVT_NID, 0, 259 snd_hda_codec_write(codec, cvt_nid, 0,
283 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); 260 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
284 261
285 if (chs != hdmi_get_channel_count(codec)) 262 if (chs != hdmi_get_channel_count(codec))
@@ -294,7 +271,7 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec)
294 int slot; 271 int slot;
295 272
296 for (i = 0; i < 8; i++) { 273 for (i = 0; i < 8; i++) {
297 slot = snd_hda_codec_read(codec, CVT_NID, 0, 274 slot = snd_hda_codec_read(codec, cvt_nid, 0,
298 AC_VERB_GET_HDMI_CHAN_SLOT, i); 275 AC_VERB_GET_HDMI_CHAN_SLOT, i);
299 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", 276 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
300 slot >> 4, slot & 0x7); 277 slot >> 4, slot & 0x7);
@@ -307,7 +284,7 @@ static void hdmi_parse_eld(struct hda_codec *codec)
307 struct intel_hdmi_spec *spec = codec->spec; 284 struct intel_hdmi_spec *spec = codec->spec;
308 struct hdmi_eld *eld = &spec->sink_eld; 285 struct hdmi_eld *eld = &spec->sink_eld;
309 286
310 if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) 287 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
311 snd_hdmi_show_eld(eld); 288 snd_hdmi_show_eld(eld);
312} 289}
313 290
@@ -322,11 +299,11 @@ static void hdmi_debug_dip_size(struct hda_codec *codec)
322 int i; 299 int i;
323 int size; 300 int size;
324 301
325 size = snd_hdmi_get_eld_size(codec, PIN_NID); 302 size = snd_hdmi_get_eld_size(codec, pin_nid);
326 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size); 303 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
327 304
328 for (i = 0; i < 8; i++) { 305 for (i = 0; i < 8; i++) {
329 size = snd_hda_codec_read(codec, PIN_NID, 0, 306 size = snd_hda_codec_read(codec, pin_nid, 0,
330 AC_VERB_GET_HDMI_DIP_SIZE, i); 307 AC_VERB_GET_HDMI_DIP_SIZE, i);
331 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size); 308 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
332 } 309 }
@@ -340,15 +317,15 @@ static void hdmi_clear_dip_buffers(struct hda_codec *codec)
340 int size; 317 int size;
341 int pi, bi; 318 int pi, bi;
342 for (i = 0; i < 8; i++) { 319 for (i = 0; i < 8; i++) {
343 size = snd_hda_codec_read(codec, PIN_NID, 0, 320 size = snd_hda_codec_read(codec, pin_nid, 0,
344 AC_VERB_GET_HDMI_DIP_SIZE, i); 321 AC_VERB_GET_HDMI_DIP_SIZE, i);
345 if (size == 0) 322 if (size == 0)
346 continue; 323 continue;
347 324
348 hdmi_set_dip_index(codec, PIN_NID, i, 0x0); 325 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
349 for (j = 1; j < 1000; j++) { 326 for (j = 1; j < 1000; j++) {
350 hdmi_write_dip_byte(codec, PIN_NID, 0x0); 327 hdmi_write_dip_byte(codec, pin_nid, 0x0);
351 hdmi_get_dip_index(codec, PIN_NID, &pi, &bi); 328 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
352 if (pi != i) 329 if (pi != i)
353 snd_printd(KERN_INFO "dip index %d: %d != %d\n", 330 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
354 bi, pi, i); 331 bi, pi, i);
@@ -376,9 +353,9 @@ static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
376 sum += params[i]; 353 sum += params[i];
377 ai->checksum = - sum; 354 ai->checksum = - sum;
378 355
379 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); 356 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
380 for (i = 0; i < sizeof(ai); i++) 357 for (i = 0; i < sizeof(ai); i++)
381 hdmi_write_dip_byte(codec, PIN_NID, params[i]); 358 hdmi_write_dip_byte(codec, pin_nid, params[i]);
382} 359}
383 360
384/* 361/*
@@ -465,6 +442,8 @@ static int hdmi_setup_channel_allocation(struct hda_codec *codec,
465static void hdmi_setup_channel_mapping(struct hda_codec *codec, 442static void hdmi_setup_channel_mapping(struct hda_codec *codec,
466 struct hdmi_audio_infoframe *ai) 443 struct hdmi_audio_infoframe *ai)
467{ 444{
445 int i;
446
468 if (!ai->CA) 447 if (!ai->CA)
469 return; 448 return;
470 449
@@ -473,7 +452,11 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec,
473 * ALSA sequence is front/surr/clfe/side? 452 * ALSA sequence is front/surr/clfe/side?
474 */ 453 */
475 454
476 snd_hda_sequence_write(codec, def_chan_map); 455 for (i = 0; i < 8; i++)
456 snd_hda_codec_write(codec, cvt_nid, 0,
457 AC_VERB_SET_HDMI_CHAN_SLOT,
458 (i << 4) | i);
459
477 hdmi_debug_channel_mapping(codec); 460 hdmi_debug_channel_mapping(codec);
478} 461}
479 462
@@ -597,7 +580,6 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
597 .substreams = 1, 580 .substreams = 1,
598 .channels_min = 2, 581 .channels_min = 2,
599 .channels_max = 8, 582 .channels_max = 8,
600 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
601 .ops = { 583 .ops = {
602 .open = intel_hdmi_playback_pcm_open, 584 .open = intel_hdmi_playback_pcm_open,
603 .close = intel_hdmi_playback_pcm_close, 585 .close = intel_hdmi_playback_pcm_close,
@@ -613,6 +595,9 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
613 codec->num_pcms = 1; 595 codec->num_pcms = 1;
614 codec->pcm_info = info; 596 codec->pcm_info = info;
615 597
598 /* NID to query formats and rates and setup streams */
599 intel_hdmi_pcm_playback.nid = cvt_nid;
600
616 info->name = "INTEL HDMI"; 601 info->name = "INTEL HDMI";
617 info->pcm_type = HDA_PCM_TYPE_HDMI; 602 info->pcm_type = HDA_PCM_TYPE_HDMI;
618 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; 603 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
@@ -636,8 +621,9 @@ static int intel_hdmi_init(struct hda_codec *codec)
636{ 621{
637 hdmi_enable_output(codec); 622 hdmi_enable_output(codec);
638 623
639 snd_hda_sequence_write(codec, unsolicited_response_verb); 624 snd_hda_codec_write(codec, pin_nid, 0,
640 625 AC_VERB_SET_UNSOLICITED_ENABLE,
626 AC_USRSP_EN | INTEL_HDMI_EVENT_TAG);
641 return 0; 627 return 0;
642} 628}
643 629
@@ -657,7 +643,7 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
657 .unsol_event = intel_hdmi_unsol_event, 643 .unsol_event = intel_hdmi_unsol_event,
658}; 644};
659 645
660static int patch_intel_hdmi(struct hda_codec *codec) 646static int do_patch_intel_hdmi(struct hda_codec *codec)
661{ 647{
662 struct intel_hdmi_spec *spec; 648 struct intel_hdmi_spec *spec;
663 649
@@ -667,7 +653,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
667 653
668 spec->multiout.num_dacs = 0; /* no analog */ 654 spec->multiout.num_dacs = 0; /* no analog */
669 spec->multiout.max_channels = 8; 655 spec->multiout.max_channels = 8;
670 spec->multiout.dig_out_nid = CVT_NID; 656 spec->multiout.dig_out_nid = cvt_nid;
671 657
672 codec->spec = spec; 658 codec->spec = spec;
673 codec->patch_ops = intel_hdmi_patch_ops; 659 codec->patch_ops = intel_hdmi_patch_ops;
@@ -679,12 +665,27 @@ static int patch_intel_hdmi(struct hda_codec *codec)
679 return 0; 665 return 0;
680} 666}
681 667
668static int patch_intel_hdmi(struct hda_codec *codec)
669{
670 cvt_nid = 0x02;
671 pin_nid = 0x03;
672 return do_patch_intel_hdmi(codec);
673}
674
675static int patch_intel_hdmi_ibexpeak(struct hda_codec *codec)
676{
677 cvt_nid = 0x02;
678 pin_nid = 0x04;
679 return do_patch_intel_hdmi(codec);
680}
681
682static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { 682static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
683 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, 683 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
684 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, 684 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, 685 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, 686 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, 687 { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi },
688 { .id = 0x80860054, .name = "Q57 DEVIBX", .patch = patch_intel_hdmi_ibexpeak },
688 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, 689 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
689 {} /* terminator */ 690 {} /* terminator */
690}; 691};
@@ -694,6 +695,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862801");
694MODULE_ALIAS("snd-hda-codec-id:80862802"); 695MODULE_ALIAS("snd-hda-codec-id:80862802");
695MODULE_ALIAS("snd-hda-codec-id:80862803"); 696MODULE_ALIAS("snd-hda-codec-id:80862803");
696MODULE_ALIAS("snd-hda-codec-id:80862804"); 697MODULE_ALIAS("snd-hda-codec-id:80862804");
698MODULE_ALIAS("snd-hda-codec-id:80860054");
697MODULE_ALIAS("snd-hda-codec-id:10951392"); 699MODULE_ALIAS("snd-hda-codec-id:10951392");
698 700
699MODULE_LICENSE("GPL"); 701MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index f5792e2eea82..c8435c9a97f9 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -377,6 +377,7 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
377 */ 377 */
378static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 378static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
379 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 379 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
380 { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
380 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch }, 381 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
381 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch }, 382 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
382 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 383 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
@@ -385,6 +386,7 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
385}; 386};
386 387
387MODULE_ALIAS("snd-hda-codec-id:10de0002"); 388MODULE_ALIAS("snd-hda-codec-id:10de0002");
389MODULE_ALIAS("snd-hda-codec-id:10de0003");
388MODULE_ALIAS("snd-hda-codec-id:10de0006"); 390MODULE_ALIAS("snd-hda-codec-id:10de0006");
389MODULE_ALIAS("snd-hda-codec-id:10de0007"); 391MODULE_ALIAS("snd-hda-codec-id:10de0007");
390MODULE_ALIAS("snd-hda-codec-id:10de0067"); 392MODULE_ALIAS("snd-hda-codec-id:10de0067");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 6f683e451f2b..7ed47f66ddd1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -208,12 +208,6 @@ enum {
208 ALC885_MBP3, 208 ALC885_MBP3,
209 ALC885_MB5, 209 ALC885_MB5,
210 ALC885_IMAC24, 210 ALC885_IMAC24,
211 ALC882_AUTO,
212 ALC882_MODEL_LAST,
213};
214
215/* ALC883 models */
216enum {
217 ALC883_3ST_2ch_DIG, 211 ALC883_3ST_2ch_DIG,
218 ALC883_3ST_6ch_DIG, 212 ALC883_3ST_6ch_DIG,
219 ALC883_3ST_6ch, 213 ALC883_3ST_6ch,
@@ -226,6 +220,7 @@ enum {
226 ALC888_ACER_ASPIRE_4930G, 220 ALC888_ACER_ASPIRE_4930G,
227 ALC888_ACER_ASPIRE_6530G, 221 ALC888_ACER_ASPIRE_6530G,
228 ALC888_ACER_ASPIRE_8930G, 222 ALC888_ACER_ASPIRE_8930G,
223 ALC888_ACER_ASPIRE_7730G,
229 ALC883_MEDION, 224 ALC883_MEDION,
230 ALC883_MEDION_MD2, 225 ALC883_MEDION_MD2,
231 ALC883_LAPTOP_EAPD, 226 ALC883_LAPTOP_EAPD,
@@ -237,17 +232,20 @@ enum {
237 ALC888_3ST_HP, 232 ALC888_3ST_HP,
238 ALC888_6ST_DELL, 233 ALC888_6ST_DELL,
239 ALC883_MITAC, 234 ALC883_MITAC,
235 ALC883_CLEVO_M540R,
240 ALC883_CLEVO_M720, 236 ALC883_CLEVO_M720,
241 ALC883_FUJITSU_PI2515, 237 ALC883_FUJITSU_PI2515,
242 ALC888_FUJITSU_XA3530, 238 ALC888_FUJITSU_XA3530,
243 ALC883_3ST_6ch_INTEL, 239 ALC883_3ST_6ch_INTEL,
240 ALC889A_INTEL,
241 ALC889_INTEL,
244 ALC888_ASUS_M90V, 242 ALC888_ASUS_M90V,
245 ALC888_ASUS_EEE1601, 243 ALC888_ASUS_EEE1601,
246 ALC889A_MB31, 244 ALC889A_MB31,
247 ALC1200_ASUS_P5Q, 245 ALC1200_ASUS_P5Q,
248 ALC883_SONY_VAIO_TT, 246 ALC883_SONY_VAIO_TT,
249 ALC883_AUTO, 247 ALC882_AUTO,
250 ALC883_MODEL_LAST, 248 ALC882_MODEL_LAST,
251}; 249};
252 250
253/* for GPIO Poll */ 251/* for GPIO Poll */
@@ -262,6 +260,14 @@ enum {
262 ALC_INIT_GPIO3, 260 ALC_INIT_GPIO3,
263}; 261};
264 262
263struct alc_mic_route {
264 hda_nid_t pin;
265 unsigned char mux_idx;
266 unsigned char amix_idx;
267};
268
269#define MUX_IDX_UNDEF ((unsigned char)-1)
270
265struct alc_spec { 271struct alc_spec {
266 /* codec parameterization */ 272 /* codec parameterization */
267 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 273 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -304,6 +310,8 @@ struct alc_spec {
304 unsigned int num_mux_defs; 310 unsigned int num_mux_defs;
305 const struct hda_input_mux *input_mux; 311 const struct hda_input_mux *input_mux;
306 unsigned int cur_mux[3]; 312 unsigned int cur_mux[3];
313 struct alc_mic_route ext_mic;
314 struct alc_mic_route int_mic;
307 315
308 /* channel model */ 316 /* channel model */
309 const struct hda_channel_mode *channel_mode; 317 const struct hda_channel_mode *channel_mode;
@@ -320,6 +328,8 @@ struct alc_spec {
320 struct snd_array kctls; 328 struct snd_array kctls;
321 struct hda_input_mux private_imux[3]; 329 struct hda_input_mux private_imux[3];
322 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 330 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
331 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
332 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
323 333
324 /* hooks */ 334 /* hooks */
325 void (*init_hook)(struct hda_codec *codec); 335 void (*init_hook)(struct hda_codec *codec);
@@ -329,6 +339,7 @@ struct alc_spec {
329 unsigned int sense_updated: 1; 339 unsigned int sense_updated: 1;
330 unsigned int jack_present: 1; 340 unsigned int jack_present: 1;
331 unsigned int master_sw: 1; 341 unsigned int master_sw: 1;
342 unsigned int auto_mic:1;
332 343
333 /* other flags */ 344 /* other flags */
334 unsigned int no_analog :1; /* digital I/O only */ 345 unsigned int no_analog :1; /* digital I/O only */
@@ -370,6 +381,7 @@ struct alc_config_preset {
370 unsigned int num_mux_defs; 381 unsigned int num_mux_defs;
371 const struct hda_input_mux *input_mux; 382 const struct hda_input_mux *input_mux;
372 void (*unsol_event)(struct hda_codec *, unsigned int); 383 void (*unsol_event)(struct hda_codec *, unsigned int);
384 void (*setup)(struct hda_codec *);
373 void (*init_hook)(struct hda_codec *); 385 void (*init_hook)(struct hda_codec *);
374#ifdef CONFIG_SND_HDA_POWER_SAVE 386#ifdef CONFIG_SND_HDA_POWER_SAVE
375 struct hda_amp_list *loopbacks; 387 struct hda_amp_list *loopbacks;
@@ -417,7 +429,7 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
417 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 429 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
418 imux = &spec->input_mux[mux_idx]; 430 imux = &spec->input_mux[mux_idx];
419 431
420 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 432 type = get_wcaps_type(get_wcaps(codec, nid));
421 if (type == AC_WID_AUD_MIX) { 433 if (type == AC_WID_AUD_MIX) {
422 /* Matrix-mixer style (e.g. ALC882) */ 434 /* Matrix-mixer style (e.g. ALC882) */
423 unsigned int *cur_val = &spec->cur_mux[adc_idx]; 435 unsigned int *cur_val = &spec->cur_mux[adc_idx];
@@ -842,9 +854,10 @@ static void print_realtek_coef(struct snd_info_buffer *buffer,
842/* 854/*
843 * set up from the preset table 855 * set up from the preset table
844 */ 856 */
845static void setup_preset(struct alc_spec *spec, 857static void setup_preset(struct hda_codec *codec,
846 const struct alc_config_preset *preset) 858 const struct alc_config_preset *preset)
847{ 859{
860 struct alc_spec *spec = codec->spec;
848 int i; 861 int i;
849 862
850 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 863 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
@@ -886,6 +899,9 @@ static void setup_preset(struct alc_spec *spec,
886#ifdef CONFIG_SND_HDA_POWER_SAVE 899#ifdef CONFIG_SND_HDA_POWER_SAVE
887 spec->loopback.amplist = preset->loopbacks; 900 spec->loopback.amplist = preset->loopbacks;
888#endif 901#endif
902
903 if (preset->setup)
904 preset->setup(codec);
889} 905}
890 906
891/* Enable GPIO mask and set output */ 907/* Enable GPIO mask and set output */
@@ -965,30 +981,64 @@ static void alc_automute_pin(struct hda_codec *codec)
965 } 981 }
966} 982}
967 983
968#if 0 /* it's broken in some cases -- temporarily disabled */ 984static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
985 hda_nid_t nid)
986{
987 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
988 int i, nums;
989
990 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
991 for (i = 0; i < nums; i++)
992 if (conn[i] == nid)
993 return i;
994 return -1;
995}
996
969static void alc_mic_automute(struct hda_codec *codec) 997static void alc_mic_automute(struct hda_codec *codec)
970{ 998{
971 struct alc_spec *spec = codec->spec; 999 struct alc_spec *spec = codec->spec;
972 unsigned int present; 1000 struct alc_mic_route *dead, *alive;
973 unsigned int mic_nid = spec->autocfg.input_pins[AUTO_PIN_MIC]; 1001 unsigned int present, type;
974 unsigned int fmic_nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]; 1002 hda_nid_t cap_nid;
975 unsigned int mix_nid = spec->capsrc_nids[0]; 1003
976 unsigned int capsrc_idx_mic, capsrc_idx_fmic; 1004 if (!spec->auto_mic)
977 1005 return;
978 capsrc_idx_mic = mic_nid - 0x18; 1006 if (!spec->int_mic.pin || !spec->ext_mic.pin)
979 capsrc_idx_fmic = fmic_nid - 0x18; 1007 return;
980 present = snd_hda_codec_read(codec, mic_nid, 0, 1008 if (snd_BUG_ON(!spec->adc_nids))
981 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 1009 return;
982 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1010
983 0x7000 | (capsrc_idx_mic << 8) | (present ? 0 : 0x80)); 1011 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
984 snd_hda_codec_write(codec, mix_nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, 1012
985 0x7000 | (capsrc_idx_fmic << 8) | (present ? 0x80 : 0)); 1013 present = snd_hda_codec_read(codec, spec->ext_mic.pin, 0,
986 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, capsrc_idx_fmic, 1014 AC_VERB_GET_PIN_SENSE, 0);
987 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1015 present &= AC_PINSENSE_PRESENCE;
1016 if (present) {
1017 alive = &spec->ext_mic;
1018 dead = &spec->int_mic;
1019 } else {
1020 alive = &spec->int_mic;
1021 dead = &spec->ext_mic;
1022 }
1023
1024 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1025 if (type == AC_WID_AUD_MIX) {
1026 /* Matrix-mixer style (e.g. ALC882) */
1027 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1028 alive->mux_idx,
1029 HDA_AMP_MUTE, 0);
1030 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1031 dead->mux_idx,
1032 HDA_AMP_MUTE, HDA_AMP_MUTE);
1033 } else {
1034 /* MUX style (e.g. ALC880) */
1035 snd_hda_codec_write_cache(codec, cap_nid, 0,
1036 AC_VERB_SET_CONNECT_SEL,
1037 alive->mux_idx);
1038 }
1039
1040 /* FIXME: analog mixer */
988} 1041}
989#else
990#define alc_mic_automute(codec) do {} while(0) /* NOP */
991#endif /* disabled */
992 1042
993/* unsolicited event for HP jack sensing */ 1043/* unsolicited event for HP jack sensing */
994static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 1044static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -1031,6 +1081,16 @@ static void alc888_coef_init(struct hda_codec *codec)
1031 AC_VERB_SET_PROC_COEF, 0x3030); 1081 AC_VERB_SET_PROC_COEF, 0x3030);
1032} 1082}
1033 1083
1084static void alc889_coef_init(struct hda_codec *codec)
1085{
1086 unsigned int tmp;
1087
1088 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1089 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1090 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1091 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1092}
1093
1034static void alc_auto_init_amp(struct hda_codec *codec, int type) 1094static void alc_auto_init_amp(struct hda_codec *codec, int type)
1035{ 1095{
1036 unsigned int tmp; 1096 unsigned int tmp;
@@ -1088,15 +1148,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1088 case 0x10ec0885: 1148 case 0x10ec0885:
1089 case 0x10ec0887: 1149 case 0x10ec0887:
1090 case 0x10ec0889: 1150 case 0x10ec0889:
1091 snd_hda_codec_write(codec, 0x20, 0, 1151 alc889_coef_init(codec);
1092 AC_VERB_SET_COEF_INDEX, 7);
1093 tmp = snd_hda_codec_read(codec, 0x20, 0,
1094 AC_VERB_GET_PROC_COEF, 0);
1095 snd_hda_codec_write(codec, 0x20, 0,
1096 AC_VERB_SET_COEF_INDEX, 7);
1097 snd_hda_codec_write(codec, 0x20, 0,
1098 AC_VERB_SET_PROC_COEF,
1099 tmp | 0x2010);
1100 break; 1152 break;
1101 case 0x10ec0888: 1153 case 0x10ec0888:
1102 alc888_coef_init(codec); 1154 alc888_coef_init(codec);
@@ -1142,6 +1194,55 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1142 spec->unsol_event = alc_sku_unsol_event; 1194 spec->unsol_event = alc_sku_unsol_event;
1143} 1195}
1144 1196
1197static void alc_init_auto_mic(struct hda_codec *codec)
1198{
1199 struct alc_spec *spec = codec->spec;
1200 struct auto_pin_cfg *cfg = &spec->autocfg;
1201 hda_nid_t fixed, ext;
1202 int i;
1203
1204 /* there must be only two mic inputs exclusively */
1205 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++)
1206 if (cfg->input_pins[i])
1207 return;
1208
1209 fixed = ext = 0;
1210 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++) {
1211 hda_nid_t nid = cfg->input_pins[i];
1212 unsigned int defcfg;
1213 if (!nid)
1214 return;
1215 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1216 switch (get_defcfg_connect(defcfg)) {
1217 case AC_JACK_PORT_FIXED:
1218 if (fixed)
1219 return; /* already occupied */
1220 fixed = nid;
1221 break;
1222 case AC_JACK_PORT_COMPLEX:
1223 if (ext)
1224 return; /* already occupied */
1225 ext = nid;
1226 break;
1227 default:
1228 return; /* invalid entry */
1229 }
1230 }
1231 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
1232 return; /* no unsol support */
1233 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n",
1234 ext, fixed);
1235 spec->ext_mic.pin = ext;
1236 spec->int_mic.pin = fixed;
1237 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1238 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1239 spec->auto_mic = 1;
1240 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1241 AC_VERB_SET_UNSOLICITED_ENABLE,
1242 AC_USRSP_EN | ALC880_MIC_EVENT);
1243 spec->unsol_event = alc_sku_unsol_event;
1244}
1245
1145/* check subsystem ID and set up device-specific initialization; 1246/* check subsystem ID and set up device-specific initialization;
1146 * return 1 if initialized, 0 if invalid SSID 1247 * return 1 if initialized, 0 if invalid SSID
1147 */ 1248 */
@@ -1243,6 +1344,7 @@ do_sku:
1243 } 1344 }
1244 1345
1245 alc_init_auto_hp(codec); 1346 alc_init_auto_hp(codec);
1347 alc_init_auto_mic(codec);
1246 return 1; 1348 return 1;
1247} 1349}
1248 1350
@@ -1255,6 +1357,7 @@ static void alc_ssid_check(struct hda_codec *codec,
1255 "Enable default setup for auto mode as fallback\n"); 1357 "Enable default setup for auto mode as fallback\n");
1256 spec->init_amp = ALC_INIT_DEFAULT; 1358 spec->init_amp = ALC_INIT_DEFAULT;
1257 alc_init_auto_hp(codec); 1359 alc_init_auto_hp(codec);
1360 alc_init_auto_mic(codec);
1258 } 1361 }
1259} 1362}
1260 1363
@@ -1436,7 +1539,25 @@ static void alc_automute_amp_unsol_event(struct hda_codec *codec,
1436 alc_automute_amp(codec); 1539 alc_automute_amp(codec);
1437} 1540}
1438 1541
1439static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec) 1542static void alc889_automute_setup(struct hda_codec *codec)
1543{
1544 struct alc_spec *spec = codec->spec;
1545
1546 spec->autocfg.hp_pins[0] = 0x15;
1547 spec->autocfg.speaker_pins[0] = 0x14;
1548 spec->autocfg.speaker_pins[1] = 0x16;
1549 spec->autocfg.speaker_pins[2] = 0x17;
1550 spec->autocfg.speaker_pins[3] = 0x19;
1551 spec->autocfg.speaker_pins[4] = 0x1a;
1552}
1553
1554static void alc889_intel_init_hook(struct hda_codec *codec)
1555{
1556 alc889_coef_init(codec);
1557 alc_automute_amp(codec);
1558}
1559
1560static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
1440{ 1561{
1441 struct alc_spec *spec = codec->spec; 1562 struct alc_spec *spec = codec->spec;
1442 1563
@@ -1444,7 +1565,6 @@ static void alc888_fujitsu_xa3530_init_hook(struct hda_codec *codec)
1444 spec->autocfg.hp_pins[1] = 0x1b; /* hp */ 1565 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
1445 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ 1566 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
1446 spec->autocfg.speaker_pins[1] = 0x15; /* bass */ 1567 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
1447 alc_automute_amp(codec);
1448} 1568}
1449 1569
1450/* 1570/*
@@ -1643,16 +1763,15 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
1643 { } /* end */ 1763 { } /* end */
1644}; 1764};
1645 1765
1646static void alc888_acer_aspire_4930g_init_hook(struct hda_codec *codec) 1766static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
1647{ 1767{
1648 struct alc_spec *spec = codec->spec; 1768 struct alc_spec *spec = codec->spec;
1649 1769
1650 spec->autocfg.hp_pins[0] = 0x15; 1770 spec->autocfg.hp_pins[0] = 0x15;
1651 spec->autocfg.speaker_pins[0] = 0x14; 1771 spec->autocfg.speaker_pins[0] = 0x14;
1652 alc_automute_amp(codec);
1653} 1772}
1654 1773
1655static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec) 1774static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
1656{ 1775{
1657 struct alc_spec *spec = codec->spec; 1776 struct alc_spec *spec = codec->spec;
1658 1777
@@ -1660,10 +1779,9 @@ static void alc888_acer_aspire_6530g_init_hook(struct hda_codec *codec)
1660 spec->autocfg.speaker_pins[0] = 0x14; 1779 spec->autocfg.speaker_pins[0] = 0x14;
1661 spec->autocfg.speaker_pins[1] = 0x16; 1780 spec->autocfg.speaker_pins[1] = 0x16;
1662 spec->autocfg.speaker_pins[2] = 0x17; 1781 spec->autocfg.speaker_pins[2] = 0x17;
1663 alc_automute_amp(codec);
1664} 1782}
1665 1783
1666static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec) 1784static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
1667{ 1785{
1668 struct alc_spec *spec = codec->spec; 1786 struct alc_spec *spec = codec->spec;
1669 1787
@@ -1671,7 +1789,6 @@ static void alc889_acer_aspire_8930g_init_hook(struct hda_codec *codec)
1671 spec->autocfg.speaker_pins[0] = 0x14; 1789 spec->autocfg.speaker_pins[0] = 0x14;
1672 spec->autocfg.speaker_pins[1] = 0x16; 1790 spec->autocfg.speaker_pins[1] = 0x16;
1673 spec->autocfg.speaker_pins[2] = 0x1b; 1791 spec->autocfg.speaker_pins[2] = 0x1b;
1674 alc_automute_amp(codec);
1675} 1792}
1676 1793
1677/* 1794/*
@@ -2651,13 +2768,17 @@ static void alc880_uniwill_mic_automute(struct hda_codec *codec)
2651 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); 2768 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
2652} 2769}
2653 2770
2654static void alc880_uniwill_init_hook(struct hda_codec *codec) 2771static void alc880_uniwill_setup(struct hda_codec *codec)
2655{ 2772{
2656 struct alc_spec *spec = codec->spec; 2773 struct alc_spec *spec = codec->spec;
2657 2774
2658 spec->autocfg.hp_pins[0] = 0x14; 2775 spec->autocfg.hp_pins[0] = 0x14;
2659 spec->autocfg.speaker_pins[0] = 0x15; 2776 spec->autocfg.speaker_pins[0] = 0x15;
2660 spec->autocfg.speaker_pins[0] = 0x16; 2777 spec->autocfg.speaker_pins[0] = 0x16;
2778}
2779
2780static void alc880_uniwill_init_hook(struct hda_codec *codec)
2781{
2661 alc_automute_amp(codec); 2782 alc_automute_amp(codec);
2662 alc880_uniwill_mic_automute(codec); 2783 alc880_uniwill_mic_automute(codec);
2663} 2784}
@@ -2678,13 +2799,12 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
2678 } 2799 }
2679} 2800}
2680 2801
2681static void alc880_uniwill_p53_init_hook(struct hda_codec *codec) 2802static void alc880_uniwill_p53_setup(struct hda_codec *codec)
2682{ 2803{
2683 struct alc_spec *spec = codec->spec; 2804 struct alc_spec *spec = codec->spec;
2684 2805
2685 spec->autocfg.hp_pins[0] = 0x14; 2806 spec->autocfg.hp_pins[0] = 0x14;
2686 spec->autocfg.speaker_pins[0] = 0x15; 2807 spec->autocfg.speaker_pins[0] = 0x15;
2687 alc_automute_amp(codec);
2688} 2808}
2689 2809
2690static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) 2810static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
@@ -2947,13 +3067,12 @@ static struct hda_verb alc880_lg_init_verbs[] = {
2947}; 3067};
2948 3068
2949/* toggle speaker-output according to the hp-jack state */ 3069/* toggle speaker-output according to the hp-jack state */
2950static void alc880_lg_init_hook(struct hda_codec *codec) 3070static void alc880_lg_setup(struct hda_codec *codec)
2951{ 3071{
2952 struct alc_spec *spec = codec->spec; 3072 struct alc_spec *spec = codec->spec;
2953 3073
2954 spec->autocfg.hp_pins[0] = 0x1b; 3074 spec->autocfg.hp_pins[0] = 0x1b;
2955 spec->autocfg.speaker_pins[0] = 0x17; 3075 spec->autocfg.speaker_pins[0] = 0x17;
2956 alc_automute_amp(codec);
2957} 3076}
2958 3077
2959/* 3078/*
@@ -3032,13 +3151,12 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = {
3032}; 3151};
3033 3152
3034/* toggle speaker-output according to the hp-jack state */ 3153/* toggle speaker-output according to the hp-jack state */
3035static void alc880_lg_lw_init_hook(struct hda_codec *codec) 3154static void alc880_lg_lw_setup(struct hda_codec *codec)
3036{ 3155{
3037 struct alc_spec *spec = codec->spec; 3156 struct alc_spec *spec = codec->spec;
3038 3157
3039 spec->autocfg.hp_pins[0] = 0x1b; 3158 spec->autocfg.hp_pins[0] = 0x1b;
3040 spec->autocfg.speaker_pins[0] = 0x14; 3159 spec->autocfg.speaker_pins[0] = 0x14;
3041 alc_automute_amp(codec);
3042} 3160}
3043 3161
3044static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { 3162static struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
@@ -3104,13 +3222,12 @@ static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
3104 alc880_medion_rim_automute(codec); 3222 alc880_medion_rim_automute(codec);
3105} 3223}
3106 3224
3107static void alc880_medion_rim_init_hook(struct hda_codec *codec) 3225static void alc880_medion_rim_setup(struct hda_codec *codec)
3108{ 3226{
3109 struct alc_spec *spec = codec->spec; 3227 struct alc_spec *spec = codec->spec;
3110 3228
3111 spec->autocfg.hp_pins[0] = 0x14; 3229 spec->autocfg.hp_pins[0] = 0x14;
3112 spec->autocfg.speaker_pins[0] = 0x1b; 3230 spec->autocfg.speaker_pins[0] = 0x1b;
3113 alc880_medion_rim_automute(codec);
3114} 3231}
3115 3232
3116#ifdef CONFIG_SND_HDA_POWER_SAVE 3233#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -3977,7 +4094,8 @@ static struct alc_config_preset alc880_presets[] = {
3977 .channel_mode = alc880_2_jack_modes, 4094 .channel_mode = alc880_2_jack_modes,
3978 .input_mux = &alc880_f1734_capture_source, 4095 .input_mux = &alc880_f1734_capture_source,
3979 .unsol_event = alc880_uniwill_p53_unsol_event, 4096 .unsol_event = alc880_uniwill_p53_unsol_event,
3980 .init_hook = alc880_uniwill_p53_init_hook, 4097 .setup = alc880_uniwill_p53_setup,
4098 .init_hook = alc_automute_amp,
3981 }, 4099 },
3982 [ALC880_ASUS] = { 4100 [ALC880_ASUS] = {
3983 .mixers = { alc880_asus_mixer }, 4101 .mixers = { alc880_asus_mixer },
@@ -4054,6 +4172,7 @@ static struct alc_config_preset alc880_presets[] = {
4054 .need_dac_fix = 1, 4172 .need_dac_fix = 1,
4055 .input_mux = &alc880_capture_source, 4173 .input_mux = &alc880_capture_source,
4056 .unsol_event = alc880_uniwill_unsol_event, 4174 .unsol_event = alc880_uniwill_unsol_event,
4175 .setup = alc880_uniwill_setup,
4057 .init_hook = alc880_uniwill_init_hook, 4176 .init_hook = alc880_uniwill_init_hook,
4058 }, 4177 },
4059 [ALC880_UNIWILL_P53] = { 4178 [ALC880_UNIWILL_P53] = {
@@ -4066,7 +4185,8 @@ static struct alc_config_preset alc880_presets[] = {
4066 .channel_mode = alc880_threestack_modes, 4185 .channel_mode = alc880_threestack_modes,
4067 .input_mux = &alc880_capture_source, 4186 .input_mux = &alc880_capture_source,
4068 .unsol_event = alc880_uniwill_p53_unsol_event, 4187 .unsol_event = alc880_uniwill_p53_unsol_event,
4069 .init_hook = alc880_uniwill_p53_init_hook, 4188 .setup = alc880_uniwill_p53_setup,
4189 .init_hook = alc_automute_amp,
4070 }, 4190 },
4071 [ALC880_FUJITSU] = { 4191 [ALC880_FUJITSU] = {
4072 .mixers = { alc880_fujitsu_mixer }, 4192 .mixers = { alc880_fujitsu_mixer },
@@ -4080,7 +4200,8 @@ static struct alc_config_preset alc880_presets[] = {
4080 .channel_mode = alc880_2_jack_modes, 4200 .channel_mode = alc880_2_jack_modes,
4081 .input_mux = &alc880_capture_source, 4201 .input_mux = &alc880_capture_source,
4082 .unsol_event = alc880_uniwill_p53_unsol_event, 4202 .unsol_event = alc880_uniwill_p53_unsol_event,
4083 .init_hook = alc880_uniwill_p53_init_hook, 4203 .setup = alc880_uniwill_p53_setup,
4204 .init_hook = alc_automute_amp,
4084 }, 4205 },
4085 [ALC880_CLEVO] = { 4206 [ALC880_CLEVO] = {
4086 .mixers = { alc880_three_stack_mixer }, 4207 .mixers = { alc880_three_stack_mixer },
@@ -4106,7 +4227,8 @@ static struct alc_config_preset alc880_presets[] = {
4106 .need_dac_fix = 1, 4227 .need_dac_fix = 1,
4107 .input_mux = &alc880_lg_capture_source, 4228 .input_mux = &alc880_lg_capture_source,
4108 .unsol_event = alc_automute_amp_unsol_event, 4229 .unsol_event = alc_automute_amp_unsol_event,
4109 .init_hook = alc880_lg_init_hook, 4230 .setup = alc880_lg_setup,
4231 .init_hook = alc_automute_amp,
4110#ifdef CONFIG_SND_HDA_POWER_SAVE 4232#ifdef CONFIG_SND_HDA_POWER_SAVE
4111 .loopbacks = alc880_lg_loopbacks, 4233 .loopbacks = alc880_lg_loopbacks,
4112#endif 4234#endif
@@ -4122,7 +4244,8 @@ static struct alc_config_preset alc880_presets[] = {
4122 .channel_mode = alc880_lg_lw_modes, 4244 .channel_mode = alc880_lg_lw_modes,
4123 .input_mux = &alc880_lg_lw_capture_source, 4245 .input_mux = &alc880_lg_lw_capture_source,
4124 .unsol_event = alc_automute_amp_unsol_event, 4246 .unsol_event = alc_automute_amp_unsol_event,
4125 .init_hook = alc880_lg_lw_init_hook, 4247 .setup = alc880_lg_lw_setup,
4248 .init_hook = alc_automute_amp,
4126 }, 4249 },
4127 [ALC880_MEDION_RIM] = { 4250 [ALC880_MEDION_RIM] = {
4128 .mixers = { alc880_medion_rim_mixer }, 4251 .mixers = { alc880_medion_rim_mixer },
@@ -4136,7 +4259,8 @@ static struct alc_config_preset alc880_presets[] = {
4136 .channel_mode = alc880_2_jack_modes, 4259 .channel_mode = alc880_2_jack_modes,
4137 .input_mux = &alc880_medion_rim_capture_source, 4260 .input_mux = &alc880_medion_rim_capture_source,
4138 .unsol_event = alc880_medion_rim_unsol_event, 4261 .unsol_event = alc880_medion_rim_unsol_event,
4139 .init_hook = alc880_medion_rim_init_hook, 4262 .setup = alc880_medion_rim_setup,
4263 .init_hook = alc880_medion_rim_automute,
4140 }, 4264 },
4141#ifdef CONFIG_SND_DEBUG 4265#ifdef CONFIG_SND_DEBUG
4142 [ALC880_TEST] = { 4266 [ALC880_TEST] = {
@@ -4189,8 +4313,6 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
4189#define alc880_fixed_pin_idx(nid) ((nid) - 0x14) 4313#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
4190#define alc880_is_multi_pin(nid) ((nid) >= 0x18) 4314#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
4191#define alc880_multi_pin_idx(nid) ((nid) - 0x18) 4315#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
4192#define alc880_is_input_pin(nid) ((nid) >= 0x18)
4193#define alc880_input_pin_idx(nid) ((nid) - 0x18)
4194#define alc880_idx_to_dac(nid) ((nid) + 0x02) 4316#define alc880_idx_to_dac(nid) ((nid) + 0x02)
4195#define alc880_dac_to_idx(nid) ((nid) - 0x02) 4317#define alc880_dac_to_idx(nid) ((nid) - 0x02)
4196#define alc880_idx_to_mixer(nid) ((nid) + 0x0c) 4318#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
@@ -4278,13 +4400,19 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
4278 if (err < 0) 4400 if (err < 0)
4279 return err; 4401 return err;
4280 } else { 4402 } else {
4281 sprintf(name, "%s Playback Volume", chname[i]); 4403 const char *pfx;
4404 if (cfg->line_outs == 1 &&
4405 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
4406 pfx = "Speaker";
4407 else
4408 pfx = chname[i];
4409 sprintf(name, "%s Playback Volume", pfx);
4282 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 4410 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
4283 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 4411 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
4284 HDA_OUTPUT)); 4412 HDA_OUTPUT));
4285 if (err < 0) 4413 if (err < 0)
4286 return err; 4414 return err;
4287 sprintf(name, "%s Playback Switch", chname[i]); 4415 sprintf(name, "%s Playback Switch", pfx);
4288 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 4416 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
4289 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 4417 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
4290 HDA_INPUT)); 4418 HDA_INPUT));
@@ -4358,31 +4486,61 @@ static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
4358 return 0; 4486 return 0;
4359} 4487}
4360 4488
4489static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
4490{
4491 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
4492 return (pincap & AC_PINCAP_IN) != 0;
4493}
4494
4361/* create playback/capture controls for input pins */ 4495/* create playback/capture controls for input pins */
4362static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, 4496static int alc_auto_create_input_ctls(struct hda_codec *codec,
4363 const struct auto_pin_cfg *cfg) 4497 const struct auto_pin_cfg *cfg,
4498 hda_nid_t mixer,
4499 hda_nid_t cap1, hda_nid_t cap2)
4364{ 4500{
4501 struct alc_spec *spec = codec->spec;
4365 struct hda_input_mux *imux = &spec->private_imux[0]; 4502 struct hda_input_mux *imux = &spec->private_imux[0];
4366 int i, err, idx; 4503 int i, err, idx;
4367 4504
4368 for (i = 0; i < AUTO_PIN_LAST; i++) { 4505 for (i = 0; i < AUTO_PIN_LAST; i++) {
4369 if (alc880_is_input_pin(cfg->input_pins[i])) { 4506 hda_nid_t pin;
4370 idx = alc880_input_pin_idx(cfg->input_pins[i]); 4507
4371 err = new_analog_input(spec, cfg->input_pins[i], 4508 pin = cfg->input_pins[i];
4372 auto_pin_cfg_labels[i], 4509 if (!alc_is_input_pin(codec, pin))
4373 idx, 0x0b); 4510 continue;
4374 if (err < 0) 4511
4375 return err; 4512 if (mixer) {
4513 idx = get_connection_index(codec, mixer, pin);
4514 if (idx >= 0) {
4515 err = new_analog_input(spec, pin,
4516 auto_pin_cfg_labels[i],
4517 idx, mixer);
4518 if (err < 0)
4519 return err;
4520 }
4521 }
4522
4523 if (!cap1)
4524 continue;
4525 idx = get_connection_index(codec, cap1, pin);
4526 if (idx < 0 && cap2)
4527 idx = get_connection_index(codec, cap2, pin);
4528 if (idx >= 0) {
4376 imux->items[imux->num_items].label = 4529 imux->items[imux->num_items].label =
4377 auto_pin_cfg_labels[i]; 4530 auto_pin_cfg_labels[i];
4378 imux->items[imux->num_items].index = 4531 imux->items[imux->num_items].index = idx;
4379 alc880_input_pin_idx(cfg->input_pins[i]);
4380 imux->num_items++; 4532 imux->num_items++;
4381 } 4533 }
4382 } 4534 }
4383 return 0; 4535 return 0;
4384} 4536}
4385 4537
4538static int alc880_auto_create_input_ctls(struct hda_codec *codec,
4539 const struct auto_pin_cfg *cfg)
4540{
4541 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
4542}
4543
4386static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 4544static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
4387 unsigned int pin_type) 4545 unsigned int pin_type)
4388{ 4546{
@@ -4448,7 +4606,7 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec)
4448 4606
4449 for (i = 0; i < AUTO_PIN_LAST; i++) { 4607 for (i = 0; i < AUTO_PIN_LAST; i++) {
4450 hda_nid_t nid = spec->autocfg.input_pins[i]; 4608 hda_nid_t nid = spec->autocfg.input_pins[i];
4451 if (alc880_is_input_pin(nid)) { 4609 if (alc_is_input_pin(codec, nid)) {
4452 alc_set_input_pin(codec, nid, i); 4610 alc_set_input_pin(codec, nid, i);
4453 if (nid != ALC880_PIN_CD_NID && 4611 if (nid != ALC880_PIN_CD_NID &&
4454 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 4612 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
@@ -4491,7 +4649,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4491 "Headphone"); 4649 "Headphone");
4492 if (err < 0) 4650 if (err < 0)
4493 return err; 4651 return err;
4494 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 4652 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
4495 if (err < 0) 4653 if (err < 0)
4496 return err; 4654 return err;
4497 4655
@@ -4505,12 +4663,6 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4505 &dig_nid, 1); 4663 &dig_nid, 1);
4506 if (err < 0) 4664 if (err < 0)
4507 continue; 4665 continue;
4508 if (dig_nid > 0x7f) {
4509 printk(KERN_ERR "alc880_auto: invalid dig_nid "
4510 "connection 0x%x for NID 0x%x\n", dig_nid,
4511 spec->autocfg.dig_out_pins[i]);
4512 continue;
4513 }
4514 if (!i) 4666 if (!i)
4515 spec->multiout.dig_out_nid = dig_nid; 4667 spec->multiout.dig_out_nid = dig_nid;
4516 else { 4668 else {
@@ -4547,8 +4699,42 @@ static void alc880_auto_init(struct hda_codec *codec)
4547 alc_inithook(codec); 4699 alc_inithook(codec);
4548} 4700}
4549 4701
4550static void set_capture_mixer(struct alc_spec *spec) 4702/* check the ADC/MUX contains all input pins; some ADC/MUX contains only
4703 * one of two digital mic pins, e.g. on ALC272
4704 */
4705static void fixup_automic_adc(struct hda_codec *codec)
4551{ 4706{
4707 struct alc_spec *spec = codec->spec;
4708 int i;
4709
4710 for (i = 0; i < spec->num_adc_nids; i++) {
4711 hda_nid_t cap = spec->capsrc_nids ?
4712 spec->capsrc_nids[i] : spec->adc_nids[i];
4713 int iidx, eidx;
4714
4715 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
4716 if (iidx < 0)
4717 continue;
4718 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
4719 if (eidx < 0)
4720 continue;
4721 spec->int_mic.mux_idx = iidx;
4722 spec->ext_mic.mux_idx = eidx;
4723 if (spec->capsrc_nids)
4724 spec->capsrc_nids += i;
4725 spec->adc_nids += i;
4726 spec->num_adc_nids = 1;
4727 return;
4728 }
4729 snd_printd(KERN_INFO "hda_codec: %s: "
4730 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
4731 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
4732 spec->auto_mic = 0; /* disable auto-mic to be sure */
4733}
4734
4735static void set_capture_mixer(struct hda_codec *codec)
4736{
4737 struct alc_spec *spec = codec->spec;
4552 static struct snd_kcontrol_new *caps[2][3] = { 4738 static struct snd_kcontrol_new *caps[2][3] = {
4553 { alc_capture_mixer_nosrc1, 4739 { alc_capture_mixer_nosrc1,
4554 alc_capture_mixer_nosrc2, 4740 alc_capture_mixer_nosrc2,
@@ -4559,7 +4745,10 @@ static void set_capture_mixer(struct alc_spec *spec)
4559 }; 4745 };
4560 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { 4746 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
4561 int mux; 4747 int mux;
4562 if (spec->input_mux && spec->input_mux->num_items > 1) 4748 if (spec->auto_mic) {
4749 mux = 0;
4750 fixup_automic_adc(codec);
4751 } else if (spec->input_mux && spec->input_mux->num_items > 1)
4563 mux = 1; 4752 mux = 1;
4564 else 4753 else
4565 mux = 0; 4754 mux = 0;
@@ -4590,8 +4779,8 @@ static int patch_alc880(struct hda_codec *codec)
4590 alc880_models, 4779 alc880_models,
4591 alc880_cfg_tbl); 4780 alc880_cfg_tbl);
4592 if (board_config < 0) { 4781 if (board_config < 0) {
4593 printk(KERN_INFO "hda_codec: Unknown model for %s, " 4782 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4594 "trying auto-probe from BIOS...\n", codec->chip_name); 4783 codec->chip_name);
4595 board_config = ALC880_AUTO; 4784 board_config = ALC880_AUTO;
4596 } 4785 }
4597 4786
@@ -4616,7 +4805,7 @@ static int patch_alc880(struct hda_codec *codec)
4616 } 4805 }
4617 4806
4618 if (board_config != ALC880_AUTO) 4807 if (board_config != ALC880_AUTO)
4619 setup_preset(spec, &alc880_presets[board_config]); 4808 setup_preset(codec, &alc880_presets[board_config]);
4620 4809
4621 spec->stream_analog_playback = &alc880_pcm_analog_playback; 4810 spec->stream_analog_playback = &alc880_pcm_analog_playback;
4622 spec->stream_analog_capture = &alc880_pcm_analog_capture; 4811 spec->stream_analog_capture = &alc880_pcm_analog_capture;
@@ -4629,7 +4818,7 @@ static int patch_alc880(struct hda_codec *codec)
4629 /* check whether NID 0x07 is valid */ 4818 /* check whether NID 0x07 is valid */
4630 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); 4819 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
4631 /* get type */ 4820 /* get type */
4632 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 4821 wcap = get_wcaps_type(wcap);
4633 if (wcap != AC_WID_AUD_IN) { 4822 if (wcap != AC_WID_AUD_IN) {
4634 spec->adc_nids = alc880_adc_nids_alt; 4823 spec->adc_nids = alc880_adc_nids_alt;
4635 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4824 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
@@ -4638,7 +4827,7 @@ static int patch_alc880(struct hda_codec *codec)
4638 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 4827 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
4639 } 4828 }
4640 } 4829 }
4641 set_capture_mixer(spec); 4830 set_capture_mixer(codec);
4642 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 4831 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
4643 4832
4644 spec->vmaster_nid = 0x0c; 4833 spec->vmaster_nid = 0x0c;
@@ -5830,7 +6019,14 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5830 6019
5831 nid = cfg->line_out_pins[0]; 6020 nid = cfg->line_out_pins[0];
5832 if (nid) { 6021 if (nid) {
5833 err = alc260_add_playback_controls(spec, nid, "Front", &vols); 6022 const char *pfx;
6023 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
6024 pfx = "Master";
6025 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
6026 pfx = "Speaker";
6027 else
6028 pfx = "Front";
6029 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
5834 if (err < 0) 6030 if (err < 0)
5835 return err; 6031 return err;
5836 } 6032 }
@@ -5853,39 +6049,10 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
5853} 6049}
5854 6050
5855/* create playback/capture controls for input pins */ 6051/* create playback/capture controls for input pins */
5856static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, 6052static int alc260_auto_create_input_ctls(struct hda_codec *codec,
5857 const struct auto_pin_cfg *cfg) 6053 const struct auto_pin_cfg *cfg)
5858{ 6054{
5859 struct hda_input_mux *imux = &spec->private_imux[0]; 6055 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
5860 int i, err, idx;
5861
5862 for (i = 0; i < AUTO_PIN_LAST; i++) {
5863 if (cfg->input_pins[i] >= 0x12) {
5864 idx = cfg->input_pins[i] - 0x12;
5865 err = new_analog_input(spec, cfg->input_pins[i],
5866 auto_pin_cfg_labels[i], idx,
5867 0x07);
5868 if (err < 0)
5869 return err;
5870 imux->items[imux->num_items].label =
5871 auto_pin_cfg_labels[i];
5872 imux->items[imux->num_items].index = idx;
5873 imux->num_items++;
5874 }
5875 if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){
5876 idx = cfg->input_pins[i] - 0x09;
5877 err = new_analog_input(spec, cfg->input_pins[i],
5878 auto_pin_cfg_labels[i], idx,
5879 0x07);
5880 if (err < 0)
5881 return err;
5882 imux->items[imux->num_items].label =
5883 auto_pin_cfg_labels[i];
5884 imux->items[imux->num_items].index = idx;
5885 imux->num_items++;
5886 }
5887 }
5888 return 0;
5889} 6056}
5890 6057
5891static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, 6058static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
@@ -5999,7 +6166,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5999 return err; 6166 return err;
6000 if (!spec->kctls.list) 6167 if (!spec->kctls.list)
6001 return 0; /* can't find valid BIOS pin config */ 6168 return 0; /* can't find valid BIOS pin config */
6002 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 6169 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
6003 if (err < 0) 6170 if (err < 0)
6004 return err; 6171 return err;
6005 6172
@@ -6234,8 +6401,7 @@ static int patch_alc260(struct hda_codec *codec)
6234 alc260_models, 6401 alc260_models,
6235 alc260_cfg_tbl); 6402 alc260_cfg_tbl);
6236 if (board_config < 0) { 6403 if (board_config < 0) {
6237 snd_printd(KERN_INFO "hda_codec: Unknown model for %s, " 6404 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
6238 "trying auto-probe from BIOS...\n",
6239 codec->chip_name); 6405 codec->chip_name);
6240 board_config = ALC260_AUTO; 6406 board_config = ALC260_AUTO;
6241 } 6407 }
@@ -6261,7 +6427,7 @@ static int patch_alc260(struct hda_codec *codec)
6261 } 6427 }
6262 6428
6263 if (board_config != ALC260_AUTO) 6429 if (board_config != ALC260_AUTO)
6264 setup_preset(spec, &alc260_presets[board_config]); 6430 setup_preset(codec, &alc260_presets[board_config]);
6265 6431
6266 spec->stream_analog_playback = &alc260_pcm_analog_playback; 6432 spec->stream_analog_playback = &alc260_pcm_analog_playback;
6267 spec->stream_analog_capture = &alc260_pcm_analog_capture; 6433 spec->stream_analog_capture = &alc260_pcm_analog_capture;
@@ -6272,7 +6438,7 @@ static int patch_alc260(struct hda_codec *codec)
6272 if (!spec->adc_nids && spec->input_mux) { 6438 if (!spec->adc_nids && spec->input_mux) {
6273 /* check whether NID 0x04 is valid */ 6439 /* check whether NID 0x04 is valid */
6274 unsigned int wcap = get_wcaps(codec, 0x04); 6440 unsigned int wcap = get_wcaps(codec, 0x04);
6275 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 6441 wcap = get_wcaps_type(wcap);
6276 /* get type */ 6442 /* get type */
6277 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 6443 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
6278 spec->adc_nids = alc260_adc_nids_alt; 6444 spec->adc_nids = alc260_adc_nids_alt;
@@ -6282,7 +6448,7 @@ static int patch_alc260(struct hda_codec *codec)
6282 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids); 6448 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
6283 } 6449 }
6284 } 6450 }
6285 set_capture_mixer(spec); 6451 set_capture_mixer(codec);
6286 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 6452 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
6287 6453
6288 spec->vmaster_nid = 0x08; 6454 spec->vmaster_nid = 0x08;
@@ -6301,7 +6467,7 @@ static int patch_alc260(struct hda_codec *codec)
6301 6467
6302 6468
6303/* 6469/*
6304 * ALC882 support 6470 * ALC882/883/885/888/889 support
6305 * 6471 *
6306 * ALC882 is almost identical with ALC880 but has cleaner and more flexible 6472 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
6307 * configuration. Each pin widget can choose any input DACs and a mixer. 6473 * configuration. Each pin widget can choose any input DACs and a mixer.
@@ -6313,22 +6479,35 @@ static int patch_alc260(struct hda_codec *codec)
6313 */ 6479 */
6314#define ALC882_DIGOUT_NID 0x06 6480#define ALC882_DIGOUT_NID 0x06
6315#define ALC882_DIGIN_NID 0x0a 6481#define ALC882_DIGIN_NID 0x0a
6482#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
6483#define ALC883_DIGIN_NID ALC882_DIGIN_NID
6484#define ALC1200_DIGOUT_NID 0x10
6485
6316 6486
6317static struct hda_channel_mode alc882_ch_modes[1] = { 6487static struct hda_channel_mode alc882_ch_modes[1] = {
6318 { 8, NULL } 6488 { 8, NULL }
6319}; 6489};
6320 6490
6491/* DACs */
6321static hda_nid_t alc882_dac_nids[4] = { 6492static hda_nid_t alc882_dac_nids[4] = {
6322 /* front, rear, clfe, rear_surr */ 6493 /* front, rear, clfe, rear_surr */
6323 0x02, 0x03, 0x04, 0x05 6494 0x02, 0x03, 0x04, 0x05
6324}; 6495};
6496#define alc883_dac_nids alc882_dac_nids
6325 6497
6326/* identical with ALC880 */ 6498/* ADCs */
6327#define alc882_adc_nids alc880_adc_nids 6499#define alc882_adc_nids alc880_adc_nids
6328#define alc882_adc_nids_alt alc880_adc_nids_alt 6500#define alc882_adc_nids_alt alc880_adc_nids_alt
6501#define alc883_adc_nids alc882_adc_nids_alt
6502static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
6503static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
6504#define alc889_adc_nids alc880_adc_nids
6329 6505
6330static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; 6506static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
6331static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; 6507static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
6508#define alc883_capsrc_nids alc882_capsrc_nids_alt
6509static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
6510#define alc889_capsrc_nids alc882_capsrc_nids
6332 6511
6333/* input MUX */ 6512/* input MUX */
6334/* FIXME: should be a matrix-type input source selection */ 6513/* FIXME: should be a matrix-type input source selection */
@@ -6343,6 +6522,17 @@ static struct hda_input_mux alc882_capture_source = {
6343 }, 6522 },
6344}; 6523};
6345 6524
6525#define alc883_capture_source alc882_capture_source
6526
6527static struct hda_input_mux alc889_capture_source = {
6528 .num_items = 3,
6529 .items = {
6530 { "Front Mic", 0x0 },
6531 { "Mic", 0x3 },
6532 { "Line", 0x2 },
6533 },
6534};
6535
6346static struct hda_input_mux mb5_capture_source = { 6536static struct hda_input_mux mb5_capture_source = {
6347 .num_items = 3, 6537 .num_items = 3,
6348 .items = { 6538 .items = {
@@ -6352,6 +6542,77 @@ static struct hda_input_mux mb5_capture_source = {
6352 }, 6542 },
6353}; 6543};
6354 6544
6545static struct hda_input_mux alc883_3stack_6ch_intel = {
6546 .num_items = 4,
6547 .items = {
6548 { "Mic", 0x1 },
6549 { "Front Mic", 0x0 },
6550 { "Line", 0x2 },
6551 { "CD", 0x4 },
6552 },
6553};
6554
6555static struct hda_input_mux alc883_lenovo_101e_capture_source = {
6556 .num_items = 2,
6557 .items = {
6558 { "Mic", 0x1 },
6559 { "Line", 0x2 },
6560 },
6561};
6562
6563static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
6564 .num_items = 4,
6565 .items = {
6566 { "Mic", 0x0 },
6567 { "iMic", 0x1 },
6568 { "Line", 0x2 },
6569 { "CD", 0x4 },
6570 },
6571};
6572
6573static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
6574 .num_items = 2,
6575 .items = {
6576 { "Mic", 0x0 },
6577 { "Int Mic", 0x1 },
6578 },
6579};
6580
6581static struct hda_input_mux alc883_lenovo_sky_capture_source = {
6582 .num_items = 3,
6583 .items = {
6584 { "Mic", 0x0 },
6585 { "Front Mic", 0x1 },
6586 { "Line", 0x4 },
6587 },
6588};
6589
6590static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6591 .num_items = 2,
6592 .items = {
6593 { "Mic", 0x0 },
6594 { "Line", 0x2 },
6595 },
6596};
6597
6598static struct hda_input_mux alc889A_mb31_capture_source = {
6599 .num_items = 2,
6600 .items = {
6601 { "Mic", 0x0 },
6602 /* Front Mic (0x01) unused */
6603 { "Line", 0x2 },
6604 /* Line 2 (0x03) unused */
6605 /* CD (0x04) unsused? */
6606 },
6607};
6608
6609/*
6610 * 2ch mode
6611 */
6612static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
6613 { 2, NULL }
6614};
6615
6355/* 6616/*
6356 * 2ch mode 6617 * 2ch mode
6357 */ 6618 */
@@ -6364,6 +6625,18 @@ static struct hda_verb alc882_3ST_ch2_init[] = {
6364}; 6625};
6365 6626
6366/* 6627/*
6628 * 4ch mode
6629 */
6630static struct hda_verb alc882_3ST_ch4_init[] = {
6631 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6632 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6633 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6634 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6635 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6636 { } /* end */
6637};
6638
6639/*
6367 * 6ch mode 6640 * 6ch mode
6368 */ 6641 */
6369static struct hda_verb alc882_3ST_ch6_init[] = { 6642static struct hda_verb alc882_3ST_ch6_init[] = {
@@ -6376,11 +6649,60 @@ static struct hda_verb alc882_3ST_ch6_init[] = {
6376 { } /* end */ 6649 { } /* end */
6377}; 6650};
6378 6651
6379static struct hda_channel_mode alc882_3ST_6ch_modes[2] = { 6652static struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
6380 { 2, alc882_3ST_ch2_init }, 6653 { 2, alc882_3ST_ch2_init },
6654 { 4, alc882_3ST_ch4_init },
6381 { 6, alc882_3ST_ch6_init }, 6655 { 6, alc882_3ST_ch6_init },
6382}; 6656};
6383 6657
6658#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
6659
6660/*
6661 * 2ch mode
6662 */
6663static struct hda_verb alc883_3ST_ch2_clevo_init[] = {
6664 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
6665 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6666 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6667 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6668 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6669 { } /* end */
6670};
6671
6672/*
6673 * 4ch mode
6674 */
6675static struct hda_verb alc883_3ST_ch4_clevo_init[] = {
6676 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6677 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6678 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6679 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6680 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6681 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6682 { } /* end */
6683};
6684
6685/*
6686 * 6ch mode
6687 */
6688static struct hda_verb alc883_3ST_ch6_clevo_init[] = {
6689 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6690 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6691 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6692 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6693 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6694 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6695 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6696 { } /* end */
6697};
6698
6699static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
6700 { 2, alc883_3ST_ch2_clevo_init },
6701 { 4, alc883_3ST_ch4_clevo_init },
6702 { 6, alc883_3ST_ch6_clevo_init },
6703};
6704
6705
6384/* 6706/*
6385 * 6ch mode 6707 * 6ch mode
6386 */ 6708 */
@@ -6423,9 +6745,9 @@ static struct hda_verb alc885_mbp_ch2_init[] = {
6423}; 6745};
6424 6746
6425/* 6747/*
6426 * 6ch mode 6748 * 4ch mode
6427 */ 6749 */
6428static struct hda_verb alc885_mbp_ch6_init[] = { 6750static struct hda_verb alc885_mbp_ch4_init[] = {
6429 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 6751 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6430 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 6752 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6431 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, 6753 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
@@ -6434,9 +6756,9 @@ static struct hda_verb alc885_mbp_ch6_init[] = {
6434 { } /* end */ 6756 { } /* end */
6435}; 6757};
6436 6758
6437static struct hda_channel_mode alc885_mbp_6ch_modes[2] = { 6759static struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
6438 { 2, alc885_mbp_ch2_init }, 6760 { 2, alc885_mbp_ch2_init },
6439 { 6, alc885_mbp_ch6_init }, 6761 { 4, alc885_mbp_ch4_init },
6440}; 6762};
6441 6763
6442/* 6764/*
@@ -6468,6 +6790,189 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
6468 { 6, alc885_mb5_ch6_init }, 6790 { 6, alc885_mb5_ch6_init },
6469}; 6791};
6470 6792
6793
6794/*
6795 * 2ch mode
6796 */
6797static struct hda_verb alc883_4ST_ch2_init[] = {
6798 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6799 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6800 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6801 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6802 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6803 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6804 { } /* end */
6805};
6806
6807/*
6808 * 4ch mode
6809 */
6810static struct hda_verb alc883_4ST_ch4_init[] = {
6811 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6812 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6813 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6814 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6815 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6816 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6817 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6818 { } /* end */
6819};
6820
6821/*
6822 * 6ch mode
6823 */
6824static struct hda_verb alc883_4ST_ch6_init[] = {
6825 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6826 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6827 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6828 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6829 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6830 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6831 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6832 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6833 { } /* end */
6834};
6835
6836/*
6837 * 8ch mode
6838 */
6839static struct hda_verb alc883_4ST_ch8_init[] = {
6840 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6841 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6842 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6843 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6844 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6845 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
6846 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6847 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6848 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6849 { } /* end */
6850};
6851
6852static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
6853 { 2, alc883_4ST_ch2_init },
6854 { 4, alc883_4ST_ch4_init },
6855 { 6, alc883_4ST_ch6_init },
6856 { 8, alc883_4ST_ch8_init },
6857};
6858
6859
6860/*
6861 * 2ch mode
6862 */
6863static struct hda_verb alc883_3ST_ch2_intel_init[] = {
6864 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6865 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6866 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6867 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6868 { } /* end */
6869};
6870
6871/*
6872 * 4ch mode
6873 */
6874static struct hda_verb alc883_3ST_ch4_intel_init[] = {
6875 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
6876 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6877 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6878 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6879 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6880 { } /* end */
6881};
6882
6883/*
6884 * 6ch mode
6885 */
6886static struct hda_verb alc883_3ST_ch6_intel_init[] = {
6887 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6888 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6889 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
6890 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6891 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6892 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
6893 { } /* end */
6894};
6895
6896static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
6897 { 2, alc883_3ST_ch2_intel_init },
6898 { 4, alc883_3ST_ch4_intel_init },
6899 { 6, alc883_3ST_ch6_intel_init },
6900};
6901
6902/*
6903 * 2ch mode
6904 */
6905static struct hda_verb alc889_ch2_intel_init[] = {
6906 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6907 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
6908 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
6909 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
6910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6912 { } /* end */
6913};
6914
6915/*
6916 * 6ch mode
6917 */
6918static struct hda_verb alc889_ch6_intel_init[] = {
6919 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6920 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6921 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6922 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6923 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
6924 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
6925 { } /* end */
6926};
6927
6928/*
6929 * 8ch mode
6930 */
6931static struct hda_verb alc889_ch8_intel_init[] = {
6932 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
6933 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
6934 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
6935 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
6936 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
6937 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6938 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6939 { } /* end */
6940};
6941
6942static struct hda_channel_mode alc889_8ch_intel_modes[3] = {
6943 { 2, alc889_ch2_intel_init },
6944 { 6, alc889_ch6_intel_init },
6945 { 8, alc889_ch8_intel_init },
6946};
6947
6948/*
6949 * 6ch mode
6950 */
6951static struct hda_verb alc883_sixstack_ch6_init[] = {
6952 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
6953 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6954 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6956 { } /* end */
6957};
6958
6959/*
6960 * 8ch mode
6961 */
6962static struct hda_verb alc883_sixstack_ch8_init[] = {
6963 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6964 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6965 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6966 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
6967 { } /* end */
6968};
6969
6970static struct hda_channel_mode alc883_sixstack_modes[2] = {
6971 { 6, alc883_sixstack_ch6_init },
6972 { 8, alc883_sixstack_ch8_init },
6973};
6974
6975
6471/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 6976/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
6472 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 6977 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
6473 */ 6978 */
@@ -6497,10 +7002,11 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
6497}; 7002};
6498 7003
6499static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7004static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
6500 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7005 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
6501 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), 7006 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
6502 HDA_CODEC_MUTE ("Speaker Playback Switch", 0x14, 0x00, HDA_OUTPUT), 7007 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
6503 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0d, 0x00, HDA_OUTPUT), 7008 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
7009 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
6504 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7010 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
6505 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7011 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
6506 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7012 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
@@ -6603,7 +7109,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
6603 { } /* end */ 7109 { } /* end */
6604}; 7110};
6605 7111
6606static struct hda_verb alc882_init_verbs[] = { 7112static struct hda_verb alc882_base_init_verbs[] = {
6607 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7113 /* Front mixer: unmute input/output amp left and right (volume = 0) */
6608 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7114 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6609 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7115 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -6621,6 +7127,13 @@ static struct hda_verb alc882_init_verbs[] = {
6621 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7127 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6622 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7128 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6623 7129
7130 /* mute analog input loopbacks */
7131 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7132 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7133 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7134 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7135 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7136
6624 /* Front Pin: output 0 (0x0c) */ 7137 /* Front Pin: output 0 (0x0c) */
6625 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6626 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -6655,11 +7168,6 @@ static struct hda_verb alc882_init_verbs[] = {
6655 7168
6656 /* FIXME: use matrix-type input source selection */ 7169 /* FIXME: use matrix-type input source selection */
6657 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7170 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6658 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6659 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6660 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6661 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6662 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6663 /* Input mixer2 */ 7171 /* Input mixer2 */
6664 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7172 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6665 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7173 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
@@ -6670,9 +7178,6 @@ static struct hda_verb alc882_init_verbs[] = {
6670 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 7178 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6671 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 7179 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6672 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 7180 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6673 /* ADC1: mute amp left and right */
6674 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6675 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6676 /* ADC2: mute amp left and right */ 7181 /* ADC2: mute amp left and right */
6677 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7182 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6678 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7183 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -6683,6 +7188,18 @@ static struct hda_verb alc882_init_verbs[] = {
6683 { } 7188 { }
6684}; 7189};
6685 7190
7191static struct hda_verb alc882_adc1_init_verbs[] = {
7192 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7193 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7194 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7195 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7196 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7197 /* ADC1: mute amp left and right */
7198 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7199 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7200 { }
7201};
7202
6686static struct hda_verb alc882_eapd_verbs[] = { 7203static struct hda_verb alc882_eapd_verbs[] = {
6687 /* change to EAPD mode */ 7204 /* change to EAPD mode */
6688 {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, 7205 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
@@ -6690,6 +7207,110 @@ static struct hda_verb alc882_eapd_verbs[] = {
6690 { } 7207 { }
6691}; 7208};
6692 7209
7210static struct hda_verb alc889_eapd_verbs[] = {
7211 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
7212 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
7213 { }
7214};
7215
7216static struct hda_verb alc_hp15_unsol_verbs[] = {
7217 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7218 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7219 {}
7220};
7221
7222static struct hda_verb alc885_init_verbs[] = {
7223 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7224 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7225 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7226 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7227 /* Rear mixer */
7228 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7229 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7230 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7231 /* CLFE mixer */
7232 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7233 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7234 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7235 /* Side mixer */
7236 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7237 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7238 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7239
7240 /* mute analog input loopbacks */
7241 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7242 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7243 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7244
7245 /* Front HP Pin: output 0 (0x0c) */
7246 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
7247 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7248 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
7249 /* Front Pin: output 0 (0x0c) */
7250 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7251 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7252 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7253 /* Rear Pin: output 1 (0x0d) */
7254 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7255 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7256 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
7257 /* CLFE Pin: output 2 (0x0e) */
7258 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7259 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7260 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
7261 /* Side Pin: output 3 (0x0f) */
7262 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7263 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7264 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
7265 /* Mic (rear) pin: input vref at 80% */
7266 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7267 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7268 /* Front Mic pin: input vref at 80% */
7269 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
7270 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7271 /* Line In pin: input */
7272 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7273 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7274
7275 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7276 /* Input mixer1 */
7277 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7278 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7279 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7280 /* Input mixer2 */
7281 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7282 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7283 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7284 /* Input mixer3 */
7285 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7288 /* ADC2: mute amp left and right */
7289 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7290 /* ADC3: mute amp left and right */
7291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7292
7293 { }
7294};
7295
7296static struct hda_verb alc885_init_input_verbs[] = {
7297 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7298 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7299 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
7300 { }
7301};
7302
7303
7304/* Unmute Selector 24h and set the default input to front mic */
7305static struct hda_verb alc889_init_input_verbs[] = {
7306 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
7307 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7308 { }
7309};
7310
7311
7312#define alc883_init_verbs alc882_base_init_verbs
7313
6693/* Mac Pro test */ 7314/* Mac Pro test */
6694static struct snd_kcontrol_new alc882_macpro_mixer[] = { 7315static struct snd_kcontrol_new alc882_macpro_mixer[] = {
6695 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7316 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -6814,14 +7435,18 @@ static struct hda_verb alc885_mbp3_init_verbs[] = {
6814 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7435 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6815 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6816 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7438 /* HP mixer */
7439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7440 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7441 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6817 /* Front Pin: output 0 (0x0c) */ 7442 /* Front Pin: output 0 (0x0c) */
6818 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7443 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7444 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6820 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 7445 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
6821 /* HP Pin: output 0 (0x0d) */ 7446 /* HP Pin: output 0 (0x0e) */
6822 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, 7447 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
6823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 7448 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6824 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 7449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
6825 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 7450 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
6826 /* Mic (rear) pin: input vref at 80% */ 7451 /* Mic (rear) pin: input vref at 80% */
6827 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 7452 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
@@ -6893,23 +7518,21 @@ static struct hda_verb alc885_imac24_init_verbs[] = {
6893}; 7518};
6894 7519
6895/* Toggle speaker-output according to the hp-jack state */ 7520/* Toggle speaker-output according to the hp-jack state */
6896static void alc885_imac24_automute_init_hook(struct hda_codec *codec) 7521static void alc885_imac24_setup(struct hda_codec *codec)
6897{ 7522{
6898 struct alc_spec *spec = codec->spec; 7523 struct alc_spec *spec = codec->spec;
6899 7524
6900 spec->autocfg.hp_pins[0] = 0x14; 7525 spec->autocfg.hp_pins[0] = 0x14;
6901 spec->autocfg.speaker_pins[0] = 0x18; 7526 spec->autocfg.speaker_pins[0] = 0x18;
6902 spec->autocfg.speaker_pins[1] = 0x1a; 7527 spec->autocfg.speaker_pins[1] = 0x1a;
6903 alc_automute_amp(codec);
6904} 7528}
6905 7529
6906static void alc885_mbp3_init_hook(struct hda_codec *codec) 7530static void alc885_mbp3_setup(struct hda_codec *codec)
6907{ 7531{
6908 struct alc_spec *spec = codec->spec; 7532 struct alc_spec *spec = codec->spec;
6909 7533
6910 spec->autocfg.hp_pins[0] = 0x15; 7534 spec->autocfg.hp_pins[0] = 0x15;
6911 spec->autocfg.speaker_pins[0] = 0x14; 7535 spec->autocfg.speaker_pins[0] = 0x14;
6912 alc_automute_amp(codec);
6913} 7536}
6914 7537
6915 7538
@@ -6937,13 +7560,12 @@ static void alc882_targa_automute(struct hda_codec *codec)
6937 spec->jack_present ? 1 : 3); 7560 spec->jack_present ? 1 : 3);
6938} 7561}
6939 7562
6940static void alc882_targa_init_hook(struct hda_codec *codec) 7563static void alc882_targa_setup(struct hda_codec *codec)
6941{ 7564{
6942 struct alc_spec *spec = codec->spec; 7565 struct alc_spec *spec = codec->spec;
6943 7566
6944 spec->autocfg.hp_pins[0] = 0x14; 7567 spec->autocfg.hp_pins[0] = 0x14;
6945 spec->autocfg.speaker_pins[0] = 0x1b; 7568 spec->autocfg.speaker_pins[0] = 0x1b;
6946 alc882_targa_automute(codec);
6947} 7569}
6948 7570
6949static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) 7571static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
@@ -7031,18 +7653,16 @@ static void alc885_macpro_init_hook(struct hda_codec *codec)
7031static void alc885_imac24_init_hook(struct hda_codec *codec) 7653static void alc885_imac24_init_hook(struct hda_codec *codec)
7032{ 7654{
7033 alc885_macpro_init_hook(codec); 7655 alc885_macpro_init_hook(codec);
7034 alc885_imac24_automute_init_hook(codec); 7656 alc_automute_amp(codec);
7035} 7657}
7036 7658
7037/* 7659/*
7038 * generic initialization of ADC, input mixers and output mixers 7660 * generic initialization of ADC, input mixers and output mixers
7039 */ 7661 */
7040static struct hda_verb alc882_auto_init_verbs[] = { 7662static struct hda_verb alc883_auto_init_verbs[] = {
7041 /* 7663 /*
7042 * Unmute ADC0-2 and set the default input to mic-in 7664 * Unmute ADC0-2 and set the default input to mic-in
7043 */ 7665 */
7044 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7046 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7666 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7047 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7048 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 7668 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7083,11 +7703,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7083 7703
7084 /* FIXME: use matrix-type input source selection */ 7704 /* FIXME: use matrix-type input source selection */
7085 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7705 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7086 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
7087 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7088 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
7089 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
7090 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
7091 /* Input mixer2 */ 7706 /* Input mixer2 */
7092 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 7707 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
7093 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, 7708 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
@@ -7102,820 +7717,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
7102 { } 7717 { }
7103}; 7718};
7104 7719
7105#ifdef CONFIG_SND_HDA_POWER_SAVE
7106#define alc882_loopbacks alc880_loopbacks
7107#endif
7108
7109/* pcm configuration: identical with ALC880 */
7110#define alc882_pcm_analog_playback alc880_pcm_analog_playback
7111#define alc882_pcm_analog_capture alc880_pcm_analog_capture
7112#define alc882_pcm_digital_playback alc880_pcm_digital_playback
7113#define alc882_pcm_digital_capture alc880_pcm_digital_capture
7114
7115/*
7116 * configuration and preset
7117 */
7118static const char *alc882_models[ALC882_MODEL_LAST] = {
7119 [ALC882_3ST_DIG] = "3stack-dig",
7120 [ALC882_6ST_DIG] = "6stack-dig",
7121 [ALC882_ARIMA] = "arima",
7122 [ALC882_W2JC] = "w2jc",
7123 [ALC882_TARGA] = "targa",
7124 [ALC882_ASUS_A7J] = "asus-a7j",
7125 [ALC882_ASUS_A7M] = "asus-a7m",
7126 [ALC885_MACPRO] = "macpro",
7127 [ALC885_MB5] = "mb5",
7128 [ALC885_MBP3] = "mbp3",
7129 [ALC885_IMAC24] = "imac24",
7130 [ALC882_AUTO] = "auto",
7131};
7132
7133static struct snd_pci_quirk alc882_cfg_tbl[] = {
7134 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
7135 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
7136 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
7137 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
7138 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
7139 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
7140 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
7141 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
7142 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
7143 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
7144 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
7145 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
7146 {}
7147};
7148
7149static struct alc_config_preset alc882_presets[] = {
7150 [ALC882_3ST_DIG] = {
7151 .mixers = { alc882_base_mixer },
7152 .init_verbs = { alc882_init_verbs },
7153 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7154 .dac_nids = alc882_dac_nids,
7155 .dig_out_nid = ALC882_DIGOUT_NID,
7156 .dig_in_nid = ALC882_DIGIN_NID,
7157 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7158 .channel_mode = alc882_ch_modes,
7159 .need_dac_fix = 1,
7160 .input_mux = &alc882_capture_source,
7161 },
7162 [ALC882_6ST_DIG] = {
7163 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7164 .init_verbs = { alc882_init_verbs },
7165 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7166 .dac_nids = alc882_dac_nids,
7167 .dig_out_nid = ALC882_DIGOUT_NID,
7168 .dig_in_nid = ALC882_DIGIN_NID,
7169 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7170 .channel_mode = alc882_sixstack_modes,
7171 .input_mux = &alc882_capture_source,
7172 },
7173 [ALC882_ARIMA] = {
7174 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
7175 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs },
7176 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7177 .dac_nids = alc882_dac_nids,
7178 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
7179 .channel_mode = alc882_sixstack_modes,
7180 .input_mux = &alc882_capture_source,
7181 },
7182 [ALC882_W2JC] = {
7183 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
7184 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7185 alc880_gpio1_init_verbs },
7186 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7187 .dac_nids = alc882_dac_nids,
7188 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7189 .channel_mode = alc880_threestack_modes,
7190 .need_dac_fix = 1,
7191 .input_mux = &alc882_capture_source,
7192 .dig_out_nid = ALC882_DIGOUT_NID,
7193 },
7194 [ALC885_MBP3] = {
7195 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
7196 .init_verbs = { alc885_mbp3_init_verbs,
7197 alc880_gpio1_init_verbs },
7198 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7199 .dac_nids = alc882_dac_nids,
7200 .channel_mode = alc885_mbp_6ch_modes,
7201 .num_channel_mode = ARRAY_SIZE(alc885_mbp_6ch_modes),
7202 .input_mux = &alc882_capture_source,
7203 .dig_out_nid = ALC882_DIGOUT_NID,
7204 .dig_in_nid = ALC882_DIGIN_NID,
7205 .unsol_event = alc_automute_amp_unsol_event,
7206 .init_hook = alc885_mbp3_init_hook,
7207 },
7208 [ALC885_MB5] = {
7209 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
7210 .init_verbs = { alc885_mb5_init_verbs,
7211 alc880_gpio1_init_verbs },
7212 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7213 .dac_nids = alc882_dac_nids,
7214 .channel_mode = alc885_mb5_6ch_modes,
7215 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
7216 .input_mux = &mb5_capture_source,
7217 .dig_out_nid = ALC882_DIGOUT_NID,
7218 .dig_in_nid = ALC882_DIGIN_NID,
7219 },
7220 [ALC885_MACPRO] = {
7221 .mixers = { alc882_macpro_mixer },
7222 .init_verbs = { alc882_macpro_init_verbs },
7223 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7224 .dac_nids = alc882_dac_nids,
7225 .dig_out_nid = ALC882_DIGOUT_NID,
7226 .dig_in_nid = ALC882_DIGIN_NID,
7227 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7228 .channel_mode = alc882_ch_modes,
7229 .input_mux = &alc882_capture_source,
7230 .init_hook = alc885_macpro_init_hook,
7231 },
7232 [ALC885_IMAC24] = {
7233 .mixers = { alc885_imac24_mixer },
7234 .init_verbs = { alc885_imac24_init_verbs },
7235 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7236 .dac_nids = alc882_dac_nids,
7237 .dig_out_nid = ALC882_DIGOUT_NID,
7238 .dig_in_nid = ALC882_DIGIN_NID,
7239 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
7240 .channel_mode = alc882_ch_modes,
7241 .input_mux = &alc882_capture_source,
7242 .unsol_event = alc_automute_amp_unsol_event,
7243 .init_hook = alc885_imac24_init_hook,
7244 },
7245 [ALC882_TARGA] = {
7246 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
7247 .init_verbs = { alc882_init_verbs, alc880_gpio3_init_verbs,
7248 alc882_targa_verbs},
7249 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7250 .dac_nids = alc882_dac_nids,
7251 .dig_out_nid = ALC882_DIGOUT_NID,
7252 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7253 .adc_nids = alc882_adc_nids,
7254 .capsrc_nids = alc882_capsrc_nids,
7255 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7256 .channel_mode = alc882_3ST_6ch_modes,
7257 .need_dac_fix = 1,
7258 .input_mux = &alc882_capture_source,
7259 .unsol_event = alc882_targa_unsol_event,
7260 .init_hook = alc882_targa_init_hook,
7261 },
7262 [ALC882_ASUS_A7J] = {
7263 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
7264 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
7265 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7266 .dac_nids = alc882_dac_nids,
7267 .dig_out_nid = ALC882_DIGOUT_NID,
7268 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
7269 .adc_nids = alc882_adc_nids,
7270 .capsrc_nids = alc882_capsrc_nids,
7271 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
7272 .channel_mode = alc882_3ST_6ch_modes,
7273 .need_dac_fix = 1,
7274 .input_mux = &alc882_capture_source,
7275 },
7276 [ALC882_ASUS_A7M] = {
7277 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
7278 .init_verbs = { alc882_init_verbs, alc882_eapd_verbs,
7279 alc880_gpio1_init_verbs,
7280 alc882_asus_a7m_verbs },
7281 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
7282 .dac_nids = alc882_dac_nids,
7283 .dig_out_nid = ALC882_DIGOUT_NID,
7284 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
7285 .channel_mode = alc880_threestack_modes,
7286 .need_dac_fix = 1,
7287 .input_mux = &alc882_capture_source,
7288 },
7289};
7290
7291
7292/*
7293 * Pin config fixes
7294 */
7295enum {
7296 PINFIX_ABIT_AW9D_MAX
7297};
7298
7299static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
7300 { 0x15, 0x01080104 }, /* side */
7301 { 0x16, 0x01011012 }, /* rear */
7302 { 0x17, 0x01016011 }, /* clfe */
7303 { }
7304};
7305
7306static const struct alc_pincfg *alc882_pin_fixes[] = {
7307 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
7308};
7309
7310static struct snd_pci_quirk alc882_pinfix_tbl[] = {
7311 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
7312 {}
7313};
7314
7315/*
7316 * BIOS auto configuration
7317 */
7318static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
7319 hda_nid_t nid, int pin_type,
7320 int dac_idx)
7321{
7322 /* set as output */
7323 struct alc_spec *spec = codec->spec;
7324 int idx;
7325
7326 alc_set_pin_output(codec, nid, pin_type);
7327 if (spec->multiout.dac_nids[dac_idx] == 0x25)
7328 idx = 4;
7329 else
7330 idx = spec->multiout.dac_nids[dac_idx] - 2;
7331 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
7332
7333}
7334
7335static void alc882_auto_init_multi_out(struct hda_codec *codec)
7336{
7337 struct alc_spec *spec = codec->spec;
7338 int i;
7339
7340 for (i = 0; i <= HDA_SIDE; i++) {
7341 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7342 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7343 if (nid)
7344 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
7345 i);
7346 }
7347}
7348
7349static void alc882_auto_init_hp_out(struct hda_codec *codec)
7350{
7351 struct alc_spec *spec = codec->spec;
7352 hda_nid_t pin;
7353
7354 pin = spec->autocfg.hp_pins[0];
7355 if (pin) /* connect to front */
7356 /* use dac 0 */
7357 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
7358 pin = spec->autocfg.speaker_pins[0];
7359 if (pin)
7360 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
7361}
7362
7363#define alc882_is_input_pin(nid) alc880_is_input_pin(nid)
7364#define ALC882_PIN_CD_NID ALC880_PIN_CD_NID
7365
7366static void alc882_auto_init_analog_input(struct hda_codec *codec)
7367{
7368 struct alc_spec *spec = codec->spec;
7369 int i;
7370
7371 for (i = 0; i < AUTO_PIN_LAST; i++) {
7372 hda_nid_t nid = spec->autocfg.input_pins[i];
7373 if (!nid)
7374 continue;
7375 alc_set_input_pin(codec, nid, AUTO_PIN_FRONT_MIC /*i*/);
7376 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
7377 snd_hda_codec_write(codec, nid, 0,
7378 AC_VERB_SET_AMP_GAIN_MUTE,
7379 AMP_OUT_MUTE);
7380 }
7381}
7382
7383static void alc882_auto_init_input_src(struct hda_codec *codec)
7384{
7385 struct alc_spec *spec = codec->spec;
7386 int c;
7387
7388 for (c = 0; c < spec->num_adc_nids; c++) {
7389 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
7390 hda_nid_t nid = spec->capsrc_nids[c];
7391 unsigned int mux_idx;
7392 const struct hda_input_mux *imux;
7393 int conns, mute, idx, item;
7394
7395 conns = snd_hda_get_connections(codec, nid, conn_list,
7396 ARRAY_SIZE(conn_list));
7397 if (conns < 0)
7398 continue;
7399 mux_idx = c >= spec->num_mux_defs ? 0 : c;
7400 imux = &spec->input_mux[mux_idx];
7401 for (idx = 0; idx < conns; idx++) {
7402 /* if the current connection is the selected one,
7403 * unmute it as default - otherwise mute it
7404 */
7405 mute = AMP_IN_MUTE(idx);
7406 for (item = 0; item < imux->num_items; item++) {
7407 if (imux->items[item].index == idx) {
7408 if (spec->cur_mux[c] == item)
7409 mute = AMP_IN_UNMUTE(idx);
7410 break;
7411 }
7412 }
7413 /* check if we have a selector or mixer
7414 * we could check for the widget type instead, but
7415 * just check for Amp-In presence (in case of mixer
7416 * without amp-in there is something wrong, this
7417 * function shouldn't be used or capsrc nid is wrong)
7418 */
7419 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
7420 snd_hda_codec_write(codec, nid, 0,
7421 AC_VERB_SET_AMP_GAIN_MUTE,
7422 mute);
7423 else if (mute != AMP_IN_MUTE(idx))
7424 snd_hda_codec_write(codec, nid, 0,
7425 AC_VERB_SET_CONNECT_SEL,
7426 idx);
7427 }
7428 }
7429}
7430
7431/* add mic boosts if needed */
7432static int alc_auto_add_mic_boost(struct hda_codec *codec)
7433{
7434 struct alc_spec *spec = codec->spec;
7435 int err;
7436 hda_nid_t nid;
7437
7438 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
7439 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7440 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7441 "Mic Boost",
7442 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7443 if (err < 0)
7444 return err;
7445 }
7446 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
7447 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
7448 err = add_control(spec, ALC_CTL_WIDGET_VOL,
7449 "Front Mic Boost",
7450 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
7451 if (err < 0)
7452 return err;
7453 }
7454 return 0;
7455}
7456
7457/* almost identical with ALC880 parser... */
7458static int alc882_parse_auto_config(struct hda_codec *codec)
7459{
7460 struct alc_spec *spec = codec->spec;
7461 int err = alc880_parse_auto_config(codec);
7462
7463 if (err < 0)
7464 return err;
7465 else if (!err)
7466 return 0; /* no config found */
7467
7468 err = alc_auto_add_mic_boost(codec);
7469 if (err < 0)
7470 return err;
7471
7472 /* hack - override the init verbs */
7473 spec->init_verbs[0] = alc882_auto_init_verbs;
7474
7475 return 1; /* config found */
7476}
7477
7478/* additional initialization for auto-configuration model */
7479static void alc882_auto_init(struct hda_codec *codec)
7480{
7481 struct alc_spec *spec = codec->spec;
7482 alc882_auto_init_multi_out(codec);
7483 alc882_auto_init_hp_out(codec);
7484 alc882_auto_init_analog_input(codec);
7485 alc882_auto_init_input_src(codec);
7486 if (spec->unsol_event)
7487 alc_inithook(codec);
7488}
7489
7490static int patch_alc883(struct hda_codec *codec); /* called in patch_alc882() */
7491
7492static int patch_alc882(struct hda_codec *codec)
7493{
7494 struct alc_spec *spec;
7495 int err, board_config;
7496
7497 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7498 if (spec == NULL)
7499 return -ENOMEM;
7500
7501 codec->spec = spec;
7502
7503 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
7504 alc882_models,
7505 alc882_cfg_tbl);
7506
7507 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
7508 /* Pick up systems that don't supply PCI SSID */
7509 switch (codec->subsystem_id) {
7510 case 0x106b0c00: /* Mac Pro */
7511 board_config = ALC885_MACPRO;
7512 break;
7513 case 0x106b1000: /* iMac 24 */
7514 case 0x106b2800: /* AppleTV */
7515 case 0x106b3e00: /* iMac 24 Aluminium */
7516 board_config = ALC885_IMAC24;
7517 break;
7518 case 0x106b00a0: /* MacBookPro3,1 - Another revision */
7519 case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */
7520 case 0x106b00a4: /* MacbookPro4,1 */
7521 case 0x106b2c00: /* Macbook Pro rev3 */
7522 /* Macbook 3.1 (0x106b3600) is handled by patch_alc883() */
7523 case 0x106b3800: /* MacbookPro4,1 - latter revision */
7524 board_config = ALC885_MBP3;
7525 break;
7526 case 0x106b3f00: /* Macbook 5,1 */
7527 case 0x106b4000: /* Macbook Pro 5,1 - FIXME: HP jack sense
7528 * seems not working, so apparently
7529 * no perfect solution yet
7530 */
7531 board_config = ALC885_MB5;
7532 break;
7533 default:
7534 /* ALC889A is handled better as ALC888-compatible */
7535 if (codec->revision_id == 0x100101 ||
7536 codec->revision_id == 0x100103) {
7537 alc_free(codec);
7538 return patch_alc883(codec);
7539 }
7540 printk(KERN_INFO "hda_codec: Unknown model for %s, "
7541 "trying auto-probe from BIOS...\n",
7542 codec->chip_name);
7543 board_config = ALC882_AUTO;
7544 }
7545 }
7546
7547 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
7548
7549 if (board_config == ALC882_AUTO) {
7550 /* automatic parse from the BIOS config */
7551 err = alc882_parse_auto_config(codec);
7552 if (err < 0) {
7553 alc_free(codec);
7554 return err;
7555 } else if (!err) {
7556 printk(KERN_INFO
7557 "hda_codec: Cannot set up configuration "
7558 "from BIOS. Using base mode...\n");
7559 board_config = ALC882_3ST_DIG;
7560 }
7561 }
7562
7563 err = snd_hda_attach_beep_device(codec, 0x1);
7564 if (err < 0) {
7565 alc_free(codec);
7566 return err;
7567 }
7568
7569 if (board_config != ALC882_AUTO)
7570 setup_preset(spec, &alc882_presets[board_config]);
7571
7572 spec->stream_analog_playback = &alc882_pcm_analog_playback;
7573 spec->stream_analog_capture = &alc882_pcm_analog_capture;
7574 /* FIXME: setup DAC5 */
7575 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
7576 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
7577
7578 spec->stream_digital_playback = &alc882_pcm_digital_playback;
7579 spec->stream_digital_capture = &alc882_pcm_digital_capture;
7580
7581 if (!spec->adc_nids && spec->input_mux) {
7582 /* check whether NID 0x07 is valid */
7583 unsigned int wcap = get_wcaps(codec, 0x07);
7584 /* get type */
7585 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
7586 if (wcap != AC_WID_AUD_IN) {
7587 spec->adc_nids = alc882_adc_nids_alt;
7588 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
7589 spec->capsrc_nids = alc882_capsrc_nids_alt;
7590 } else {
7591 spec->adc_nids = alc882_adc_nids;
7592 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
7593 spec->capsrc_nids = alc882_capsrc_nids;
7594 }
7595 }
7596 set_capture_mixer(spec);
7597 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
7598
7599 spec->vmaster_nid = 0x0c;
7600
7601 codec->patch_ops = alc_patch_ops;
7602 if (board_config == ALC882_AUTO)
7603 spec->init_hook = alc882_auto_init;
7604#ifdef CONFIG_SND_HDA_POWER_SAVE
7605 if (!spec->loopback.amplist)
7606 spec->loopback.amplist = alc882_loopbacks;
7607#endif
7608 codec->proc_widget_hook = print_realtek_coef;
7609
7610 return 0;
7611}
7612
7613/*
7614 * ALC883 support
7615 *
7616 * ALC883 is almost identical with ALC880 but has cleaner and more flexible
7617 * configuration. Each pin widget can choose any input DACs and a mixer.
7618 * Each ADC is connected from a mixer of all inputs. This makes possible
7619 * 6-channel independent captures.
7620 *
7621 * In addition, an independent DAC for the multi-playback (not used in this
7622 * driver yet).
7623 */
7624#define ALC883_DIGOUT_NID 0x06
7625#define ALC883_DIGIN_NID 0x0a
7626
7627#define ALC1200_DIGOUT_NID 0x10
7628
7629static hda_nid_t alc883_dac_nids[4] = {
7630 /* front, rear, clfe, rear_surr */
7631 0x02, 0x03, 0x04, 0x05
7632};
7633
7634static hda_nid_t alc883_adc_nids[2] = {
7635 /* ADC1-2 */
7636 0x08, 0x09,
7637};
7638
7639static hda_nid_t alc883_adc_nids_alt[1] = {
7640 /* ADC1 */
7641 0x08,
7642};
7643
7644static hda_nid_t alc883_adc_nids_rev[2] = {
7645 /* ADC2-1 */
7646 0x09, 0x08
7647};
7648
7649#define alc889_adc_nids alc880_adc_nids
7650
7651static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
7652
7653static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7654
7655#define alc889_capsrc_nids alc882_capsrc_nids
7656
7657/* input MUX */
7658/* FIXME: should be a matrix-type input source selection */
7659
7660static struct hda_input_mux alc883_capture_source = {
7661 .num_items = 4,
7662 .items = {
7663 { "Mic", 0x0 },
7664 { "Front Mic", 0x1 },
7665 { "Line", 0x2 },
7666 { "CD", 0x4 },
7667 },
7668};
7669
7670static struct hda_input_mux alc883_3stack_6ch_intel = {
7671 .num_items = 4,
7672 .items = {
7673 { "Mic", 0x1 },
7674 { "Front Mic", 0x0 },
7675 { "Line", 0x2 },
7676 { "CD", 0x4 },
7677 },
7678};
7679
7680static struct hda_input_mux alc883_lenovo_101e_capture_source = {
7681 .num_items = 2,
7682 .items = {
7683 { "Mic", 0x1 },
7684 { "Line", 0x2 },
7685 },
7686};
7687
7688static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7689 .num_items = 4,
7690 .items = {
7691 { "Mic", 0x0 },
7692 { "iMic", 0x1 },
7693 { "Line", 0x2 },
7694 { "CD", 0x4 },
7695 },
7696};
7697
7698static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7699 .num_items = 2,
7700 .items = {
7701 { "Mic", 0x0 },
7702 { "Int Mic", 0x1 },
7703 },
7704};
7705
7706static struct hda_input_mux alc883_lenovo_sky_capture_source = {
7707 .num_items = 3,
7708 .items = {
7709 { "Mic", 0x0 },
7710 { "Front Mic", 0x1 },
7711 { "Line", 0x4 },
7712 },
7713};
7714
7715static struct hda_input_mux alc883_asus_eee1601_capture_source = {
7716 .num_items = 2,
7717 .items = {
7718 { "Mic", 0x0 },
7719 { "Line", 0x2 },
7720 },
7721};
7722
7723static struct hda_input_mux alc889A_mb31_capture_source = {
7724 .num_items = 2,
7725 .items = {
7726 { "Mic", 0x0 },
7727 /* Front Mic (0x01) unused */
7728 { "Line", 0x2 },
7729 /* Line 2 (0x03) unused */
7730 /* CD (0x04) unsused? */
7731 },
7732};
7733
7734/*
7735 * 2ch mode
7736 */
7737static struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7738 { 2, NULL }
7739};
7740
7741/*
7742 * 2ch mode
7743 */
7744static struct hda_verb alc883_3ST_ch2_init[] = {
7745 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7746 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7747 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7748 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7749 { } /* end */
7750};
7751
7752/*
7753 * 4ch mode
7754 */
7755static struct hda_verb alc883_3ST_ch4_init[] = {
7756 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7757 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7761 { } /* end */
7762};
7763
7764/*
7765 * 6ch mode
7766 */
7767static struct hda_verb alc883_3ST_ch6_init[] = {
7768 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7769 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7770 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7771 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7772 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7773 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7774 { } /* end */
7775};
7776
7777static struct hda_channel_mode alc883_3ST_6ch_modes[3] = {
7778 { 2, alc883_3ST_ch2_init },
7779 { 4, alc883_3ST_ch4_init },
7780 { 6, alc883_3ST_ch6_init },
7781};
7782
7783
7784/*
7785 * 2ch mode
7786 */
7787static struct hda_verb alc883_4ST_ch2_init[] = {
7788 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7790 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7791 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7792 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7793 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7794 { } /* end */
7795};
7796
7797/*
7798 * 4ch mode
7799 */
7800static struct hda_verb alc883_4ST_ch4_init[] = {
7801 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7802 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7803 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7804 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7805 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7806 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7807 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7808 { } /* end */
7809};
7810
7811/*
7812 * 6ch mode
7813 */
7814static struct hda_verb alc883_4ST_ch6_init[] = {
7815 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7816 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7817 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7818 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7819 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7820 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7821 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7822 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7823 { } /* end */
7824};
7825
7826/*
7827 * 8ch mode
7828 */
7829static struct hda_verb alc883_4ST_ch8_init[] = {
7830 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7831 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7832 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7833 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7834 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7835 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7836 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7837 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7838 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7839 { } /* end */
7840};
7841
7842static struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7843 { 2, alc883_4ST_ch2_init },
7844 { 4, alc883_4ST_ch4_init },
7845 { 6, alc883_4ST_ch6_init },
7846 { 8, alc883_4ST_ch8_init },
7847};
7848
7849
7850/*
7851 * 2ch mode
7852 */
7853static struct hda_verb alc883_3ST_ch2_intel_init[] = {
7854 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7855 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7856 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7857 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7858 { } /* end */
7859};
7860
7861/*
7862 * 4ch mode
7863 */
7864static struct hda_verb alc883_3ST_ch4_intel_init[] = {
7865 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7866 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7867 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7868 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7869 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7870 { } /* end */
7871};
7872
7873/*
7874 * 6ch mode
7875 */
7876static struct hda_verb alc883_3ST_ch6_intel_init[] = {
7877 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7878 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7879 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7880 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7881 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7882 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7883 { } /* end */
7884};
7885
7886static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7887 { 2, alc883_3ST_ch2_intel_init },
7888 { 4, alc883_3ST_ch4_intel_init },
7889 { 6, alc883_3ST_ch6_intel_init },
7890};
7891
7892/*
7893 * 6ch mode
7894 */
7895static struct hda_verb alc883_sixstack_ch6_init[] = {
7896 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7900 { } /* end */
7901};
7902
7903/*
7904 * 8ch mode
7905 */
7906static struct hda_verb alc883_sixstack_ch8_init[] = {
7907 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7909 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7910 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { } /* end */
7912};
7913
7914static struct hda_channel_mode alc883_sixstack_modes[2] = {
7915 { 6, alc883_sixstack_ch6_init },
7916 { 8, alc883_sixstack_ch8_init },
7917};
7918
7919/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ 7720/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
7920static struct hda_verb alc889A_mb31_ch2_init[] = { 7721static struct hda_verb alc889A_mb31_ch2_init[] = {
7921 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ 7722 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
@@ -7966,34 +7767,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = {
7966 { } 7767 { }
7967}; 7768};
7968 7769
7969/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 7770#define alc883_base_mixer alc882_base_mixer
7970 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
7971 */
7972
7973static struct snd_kcontrol_new alc883_base_mixer[] = {
7974 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7975 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7976 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7977 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7978 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
7979 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7980 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7981 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7982 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7983 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
7984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7985 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
7986 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
7987 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7988 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7990 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7992 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7993 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7994 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7995 { } /* end */
7996};
7997 7771
7998static struct snd_kcontrol_new alc883_mitac_mixer[] = { 7772static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7999 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7773 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
@@ -8104,6 +7878,30 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8104 { } /* end */ 7878 { } /* end */
8105}; 7879};
8106 7880
7881static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
7882 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7883 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
7884 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
7885 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
7886 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
7887 HDA_OUTPUT),
7888 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
7889 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
7890 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
7891 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
7892 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
7893 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7894 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7895 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
7897 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT),
7898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
7899 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7900 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT),
7901 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7902 { } /* end */
7903};
7904
8107static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 7905static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8108 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 7906 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8109 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 7907 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
@@ -8344,93 +8142,14 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = {
8344 { } /* end */ 8142 { } /* end */
8345}; 8143};
8346 8144
8347static struct hda_verb alc883_init_verbs[] = {
8348 /* ADC1: mute amp left and right */
8349 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8350 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8351 /* ADC2: mute amp left and right */
8352 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8353 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8354 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8355 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8356 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8357 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8358 /* Rear mixer */
8359 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8360 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8361 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8362 /* CLFE mixer */
8363 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8364 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8365 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8366 /* Side mixer */
8367 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8368 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8369 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8370
8371 /* mute analog input loopbacks */
8372 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8373 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8374 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8375 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8377
8378 /* Front Pin: output 0 (0x0c) */
8379 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8380 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8381 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8382 /* Rear Pin: output 1 (0x0d) */
8383 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8386 /* CLFE Pin: output 2 (0x0e) */
8387 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8390 /* Side Pin: output 3 (0x0f) */
8391 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8394 /* Mic (rear) pin: input vref at 80% */
8395 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8396 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8397 /* Front Mic pin: input vref at 80% */
8398 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8399 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8400 /* Line In pin: input */
8401 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8402 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8403 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8404 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8405 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8406 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8407 /* CD pin widget for input */
8408 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8409
8410 /* FIXME: use matrix-type input source selection */
8411 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8412 /* Input mixer2 */
8413 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8414 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8415 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8416 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8417 /* Input mixer3 */
8418 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8420 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8421 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8422 { }
8423};
8424
8425/* toggle speaker-output according to the hp-jack state */ 8145/* toggle speaker-output according to the hp-jack state */
8426static void alc883_mitac_init_hook(struct hda_codec *codec) 8146static void alc883_mitac_setup(struct hda_codec *codec)
8427{ 8147{
8428 struct alc_spec *spec = codec->spec; 8148 struct alc_spec *spec = codec->spec;
8429 8149
8430 spec->autocfg.hp_pins[0] = 0x15; 8150 spec->autocfg.hp_pins[0] = 0x15;
8431 spec->autocfg.speaker_pins[0] = 0x14; 8151 spec->autocfg.speaker_pins[0] = 0x14;
8432 spec->autocfg.speaker_pins[1] = 0x17; 8152 spec->autocfg.speaker_pins[1] = 0x17;
8433 alc_automute_amp(codec);
8434} 8153}
8435 8154
8436/* auto-toggle front mic */ 8155/* auto-toggle front mic */
@@ -8462,6 +8181,22 @@ static struct hda_verb alc883_mitac_verbs[] = {
8462 { } /* end */ 8181 { } /* end */
8463}; 8182};
8464 8183
8184static struct hda_verb alc883_clevo_m540r_verbs[] = {
8185 /* HP */
8186 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8187 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8188 /* Int speaker */
8189 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
8190
8191 /* enable unsolicited event */
8192 /*
8193 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8194 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
8195 */
8196
8197 { } /* end */
8198};
8199
8465static struct hda_verb alc883_clevo_m720_verbs[] = { 8200static struct hda_verb alc883_clevo_m720_verbs[] = {
8466 /* HP */ 8201 /* HP */
8467 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 8202 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -8585,7 +8320,7 @@ static struct hda_verb alc883_vaiott_verbs[] = {
8585 { } /* end */ 8320 { } /* end */
8586}; 8321};
8587 8322
8588static void alc888_3st_hp_init_hook(struct hda_codec *codec) 8323static void alc888_3st_hp_setup(struct hda_codec *codec)
8589{ 8324{
8590 struct alc_spec *spec = codec->spec; 8325 struct alc_spec *spec = codec->spec;
8591 8326
@@ -8593,7 +8328,6 @@ static void alc888_3st_hp_init_hook(struct hda_codec *codec)
8593 spec->autocfg.speaker_pins[0] = 0x14; 8328 spec->autocfg.speaker_pins[0] = 0x14;
8594 spec->autocfg.speaker_pins[1] = 0x16; 8329 spec->autocfg.speaker_pins[1] = 0x16;
8595 spec->autocfg.speaker_pins[2] = 0x18; 8330 spec->autocfg.speaker_pins[2] = 0x18;
8596 alc_automute_amp(codec);
8597} 8331}
8598 8332
8599static struct hda_verb alc888_3st_hp_verbs[] = { 8333static struct hda_verb alc888_3st_hp_verbs[] = {
@@ -8690,13 +8424,12 @@ static struct hda_verb alc883_medion_md2_verbs[] = {
8690}; 8424};
8691 8425
8692/* toggle speaker-output according to the hp-jack state */ 8426/* toggle speaker-output according to the hp-jack state */
8693static void alc883_medion_md2_init_hook(struct hda_codec *codec) 8427static void alc883_medion_md2_setup(struct hda_codec *codec)
8694{ 8428{
8695 struct alc_spec *spec = codec->spec; 8429 struct alc_spec *spec = codec->spec;
8696 8430
8697 spec->autocfg.hp_pins[0] = 0x14; 8431 spec->autocfg.hp_pins[0] = 0x14;
8698 spec->autocfg.speaker_pins[0] = 0x15; 8432 spec->autocfg.speaker_pins[0] = 0x15;
8699 alc_automute_amp(codec);
8700} 8433}
8701 8434
8702/* toggle speaker-output according to the hp-jack state */ 8435/* toggle speaker-output according to the hp-jack state */
@@ -8713,12 +8446,16 @@ static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
8713 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 8446 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
8714} 8447}
8715 8448
8716static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 8449static void alc883_clevo_m720_setup(struct hda_codec *codec)
8717{ 8450{
8718 struct alc_spec *spec = codec->spec; 8451 struct alc_spec *spec = codec->spec;
8719 8452
8720 spec->autocfg.hp_pins[0] = 0x15; 8453 spec->autocfg.hp_pins[0] = 0x15;
8721 spec->autocfg.speaker_pins[0] = 0x14; 8454 spec->autocfg.speaker_pins[0] = 0x14;
8455}
8456
8457static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
8458{
8722 alc_automute_amp(codec); 8459 alc_automute_amp(codec);
8723 alc883_clevo_m720_mic_automute(codec); 8460 alc883_clevo_m720_mic_automute(codec);
8724} 8461}
@@ -8737,22 +8474,20 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
8737} 8474}
8738 8475
8739/* toggle speaker-output according to the hp-jack state */ 8476/* toggle speaker-output according to the hp-jack state */
8740static void alc883_2ch_fujitsu_pi2515_init_hook(struct hda_codec *codec) 8477static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
8741{ 8478{
8742 struct alc_spec *spec = codec->spec; 8479 struct alc_spec *spec = codec->spec;
8743 8480
8744 spec->autocfg.hp_pins[0] = 0x14; 8481 spec->autocfg.hp_pins[0] = 0x14;
8745 spec->autocfg.speaker_pins[0] = 0x15; 8482 spec->autocfg.speaker_pins[0] = 0x15;
8746 alc_automute_amp(codec);
8747} 8483}
8748 8484
8749static void alc883_haier_w66_init_hook(struct hda_codec *codec) 8485static void alc883_haier_w66_setup(struct hda_codec *codec)
8750{ 8486{
8751 struct alc_spec *spec = codec->spec; 8487 struct alc_spec *spec = codec->spec;
8752 8488
8753 spec->autocfg.hp_pins[0] = 0x1b; 8489 spec->autocfg.hp_pins[0] = 0x1b;
8754 spec->autocfg.speaker_pins[0] = 0x14; 8490 spec->autocfg.speaker_pins[0] = 0x14;
8755 alc_automute_amp(codec);
8756} 8491}
8757 8492
8758static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) 8493static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec)
@@ -8791,14 +8526,13 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec,
8791} 8526}
8792 8527
8793/* toggle speaker-output according to the hp-jack state */ 8528/* toggle speaker-output according to the hp-jack state */
8794static void alc883_acer_aspire_init_hook(struct hda_codec *codec) 8529static void alc883_acer_aspire_setup(struct hda_codec *codec)
8795{ 8530{
8796 struct alc_spec *spec = codec->spec; 8531 struct alc_spec *spec = codec->spec;
8797 8532
8798 spec->autocfg.hp_pins[0] = 0x14; 8533 spec->autocfg.hp_pins[0] = 0x14;
8799 spec->autocfg.speaker_pins[0] = 0x15; 8534 spec->autocfg.speaker_pins[0] = 0x15;
8800 spec->autocfg.speaker_pins[1] = 0x16; 8535 spec->autocfg.speaker_pins[1] = 0x16;
8801 alc_automute_amp(codec);
8802} 8536}
8803 8537
8804static struct hda_verb alc883_acer_eapd_verbs[] = { 8538static struct hda_verb alc883_acer_eapd_verbs[] = {
@@ -8819,7 +8553,14 @@ static struct hda_verb alc883_acer_eapd_verbs[] = {
8819 { } 8553 { }
8820}; 8554};
8821 8555
8822static void alc888_6st_dell_init_hook(struct hda_codec *codec) 8556static struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
8557 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8558 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
8559 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8560 { } /* end */
8561};
8562
8563static void alc888_6st_dell_setup(struct hda_codec *codec)
8823{ 8564{
8824 struct alc_spec *spec = codec->spec; 8565 struct alc_spec *spec = codec->spec;
8825 8566
@@ -8828,10 +8569,9 @@ static void alc888_6st_dell_init_hook(struct hda_codec *codec)
8828 spec->autocfg.speaker_pins[1] = 0x15; 8569 spec->autocfg.speaker_pins[1] = 0x15;
8829 spec->autocfg.speaker_pins[2] = 0x16; 8570 spec->autocfg.speaker_pins[2] = 0x16;
8830 spec->autocfg.speaker_pins[3] = 0x17; 8571 spec->autocfg.speaker_pins[3] = 0x17;
8831 alc_automute_amp(codec);
8832} 8572}
8833 8573
8834static void alc888_lenovo_sky_init_hook(struct hda_codec *codec) 8574static void alc888_lenovo_sky_setup(struct hda_codec *codec)
8835{ 8575{
8836 struct alc_spec *spec = codec->spec; 8576 struct alc_spec *spec = codec->spec;
8837 8577
@@ -8841,82 +8581,17 @@ static void alc888_lenovo_sky_init_hook(struct hda_codec *codec)
8841 spec->autocfg.speaker_pins[2] = 0x16; 8581 spec->autocfg.speaker_pins[2] = 0x16;
8842 spec->autocfg.speaker_pins[3] = 0x17; 8582 spec->autocfg.speaker_pins[3] = 0x17;
8843 spec->autocfg.speaker_pins[4] = 0x1a; 8583 spec->autocfg.speaker_pins[4] = 0x1a;
8844 alc_automute_amp(codec);
8845} 8584}
8846 8585
8847static void alc883_vaiott_init_hook(struct hda_codec *codec) 8586static void alc883_vaiott_setup(struct hda_codec *codec)
8848{ 8587{
8849 struct alc_spec *spec = codec->spec; 8588 struct alc_spec *spec = codec->spec;
8850 8589
8851 spec->autocfg.hp_pins[0] = 0x15; 8590 spec->autocfg.hp_pins[0] = 0x15;
8852 spec->autocfg.speaker_pins[0] = 0x14; 8591 spec->autocfg.speaker_pins[0] = 0x14;
8853 spec->autocfg.speaker_pins[1] = 0x17; 8592 spec->autocfg.speaker_pins[1] = 0x17;
8854 alc_automute_amp(codec);
8855} 8593}
8856 8594
8857/*
8858 * generic initialization of ADC, input mixers and output mixers
8859 */
8860static struct hda_verb alc883_auto_init_verbs[] = {
8861 /*
8862 * Unmute ADC0-2 and set the default input to mic-in
8863 */
8864 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8865 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8866 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8867 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8868
8869 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8870 * mixer widget
8871 * Note: PASD motherboards uses the Line In 2 as the input for
8872 * front panel mic (mic 2)
8873 */
8874 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8875 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8876 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8877 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8878 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8879 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8880
8881 /*
8882 * Set up output mixers (0x0c - 0x0f)
8883 */
8884 /* set vol=0 to output mixers */
8885 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8886 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8887 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8888 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8889 /* set up input amps for analog loopback */
8890 /* Amp Indices: DAC = 0, mixer = 1 */
8891 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8892 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8893 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8894 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8895 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8896 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8897 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8898 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8899 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8900 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8901
8902 /* FIXME: use matrix-type input source selection */
8903 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8904 /* Input mixer1 */
8905 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8906 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8907 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8908 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8909 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8910 /* Input mixer2 */
8911 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8912 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8914 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */
8915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8916
8917 { }
8918};
8919
8920static struct hda_verb alc888_asus_m90v_verbs[] = { 8595static struct hda_verb alc888_asus_m90v_verbs[] = {
8921 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8596 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8922 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8597 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8927,19 +8602,7 @@ static struct hda_verb alc888_asus_m90v_verbs[] = {
8927 { } /* end */ 8602 { } /* end */
8928}; 8603};
8929 8604
8930static void alc883_nb_mic_automute(struct hda_codec *codec) 8605static void alc883_mode2_setup(struct hda_codec *codec)
8931{
8932 unsigned int present;
8933
8934 present = snd_hda_codec_read(codec, 0x18, 0,
8935 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
8936 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8937 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
8938 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8939 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
8940}
8941
8942static void alc883_M90V_init_hook(struct hda_codec *codec)
8943{ 8606{
8944 struct alc_spec *spec = codec->spec; 8607 struct alc_spec *spec = codec->spec;
8945 8608
@@ -8947,26 +8610,11 @@ static void alc883_M90V_init_hook(struct hda_codec *codec)
8947 spec->autocfg.speaker_pins[0] = 0x14; 8610 spec->autocfg.speaker_pins[0] = 0x14;
8948 spec->autocfg.speaker_pins[1] = 0x15; 8611 spec->autocfg.speaker_pins[1] = 0x15;
8949 spec->autocfg.speaker_pins[2] = 0x16; 8612 spec->autocfg.speaker_pins[2] = 0x16;
8950 alc_automute_pin(codec); 8613 spec->ext_mic.pin = 0x18;
8951} 8614 spec->int_mic.pin = 0x19;
8952 8615 spec->ext_mic.mux_idx = 0;
8953static void alc883_mode2_unsol_event(struct hda_codec *codec, 8616 spec->int_mic.mux_idx = 1;
8954 unsigned int res) 8617 spec->auto_mic = 1;
8955{
8956 switch (res >> 26) {
8957 case ALC880_MIC_EVENT:
8958 alc883_nb_mic_automute(codec);
8959 break;
8960 default:
8961 alc_sku_unsol_event(codec, res);
8962 break;
8963 }
8964}
8965
8966static void alc883_mode2_inithook(struct hda_codec *codec)
8967{
8968 alc883_M90V_init_hook(codec);
8969 alc883_nb_mic_automute(codec);
8970} 8618}
8971 8619
8972static struct hda_verb alc888_asus_eee1601_verbs[] = { 8620static struct hda_verb alc888_asus_eee1601_verbs[] = {
@@ -9027,25 +8675,44 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9027 alc889A_mb31_automute(codec); 8675 alc889A_mb31_automute(codec);
9028} 8676}
9029 8677
8678
9030#ifdef CONFIG_SND_HDA_POWER_SAVE 8679#ifdef CONFIG_SND_HDA_POWER_SAVE
9031#define alc883_loopbacks alc880_loopbacks 8680#define alc882_loopbacks alc880_loopbacks
9032#endif 8681#endif
9033 8682
9034/* pcm configuration: identical with ALC880 */ 8683/* pcm configuration: identical with ALC880 */
9035#define alc883_pcm_analog_playback alc880_pcm_analog_playback 8684#define alc882_pcm_analog_playback alc880_pcm_analog_playback
9036#define alc883_pcm_analog_capture alc880_pcm_analog_capture 8685#define alc882_pcm_analog_capture alc880_pcm_analog_capture
9037#define alc883_pcm_analog_alt_capture alc880_pcm_analog_alt_capture 8686#define alc882_pcm_digital_playback alc880_pcm_digital_playback
9038#define alc883_pcm_digital_playback alc880_pcm_digital_playback 8687#define alc882_pcm_digital_capture alc880_pcm_digital_capture
9039#define alc883_pcm_digital_capture alc880_pcm_digital_capture 8688
8689static hda_nid_t alc883_slave_dig_outs[] = {
8690 ALC1200_DIGOUT_NID, 0,
8691};
8692
8693static hda_nid_t alc1200_slave_dig_outs[] = {
8694 ALC883_DIGOUT_NID, 0,
8695};
9040 8696
9041/* 8697/*
9042 * configuration and preset 8698 * configuration and preset
9043 */ 8699 */
9044static const char *alc883_models[ALC883_MODEL_LAST] = { 8700static const char *alc882_models[ALC882_MODEL_LAST] = {
9045 [ALC883_3ST_2ch_DIG] = "3stack-dig", 8701 [ALC882_3ST_DIG] = "3stack-dig",
8702 [ALC882_6ST_DIG] = "6stack-dig",
8703 [ALC882_ARIMA] = "arima",
8704 [ALC882_W2JC] = "w2jc",
8705 [ALC882_TARGA] = "targa",
8706 [ALC882_ASUS_A7J] = "asus-a7j",
8707 [ALC882_ASUS_A7M] = "asus-a7m",
8708 [ALC885_MACPRO] = "macpro",
8709 [ALC885_MB5] = "mb5",
8710 [ALC885_MBP3] = "mbp3",
8711 [ALC885_IMAC24] = "imac24",
8712 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9046 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig", 8713 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9047 [ALC883_3ST_6ch] = "3stack-6ch", 8714 [ALC883_3ST_6ch] = "3stack-6ch",
9048 [ALC883_6ST_DIG] = "6stack-dig", 8715 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9049 [ALC883_TARGA_DIG] = "targa-dig", 8716 [ALC883_TARGA_DIG] = "targa-dig",
9050 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8717 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9051 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig", 8718 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
@@ -9054,6 +8721,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
9054 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g", 8721 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9055 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g", 8722 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9056 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 8723 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
8724 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9057 [ALC883_MEDION] = "medion", 8725 [ALC883_MEDION] = "medion",
9058 [ALC883_MEDION_MD2] = "medion-md2", 8726 [ALC883_MEDION_MD2] = "medion-md2",
9059 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8727 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
@@ -9065,18 +8733,22 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
9065 [ALC888_3ST_HP] = "3stack-hp", 8733 [ALC888_3ST_HP] = "3stack-hp",
9066 [ALC888_6ST_DELL] = "6stack-dell", 8734 [ALC888_6ST_DELL] = "6stack-dell",
9067 [ALC883_MITAC] = "mitac", 8735 [ALC883_MITAC] = "mitac",
8736 [ALC883_CLEVO_M540R] = "clevo-m540r",
9068 [ALC883_CLEVO_M720] = "clevo-m720", 8737 [ALC883_CLEVO_M720] = "clevo-m720",
9069 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8738 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9070 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530", 8739 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9071 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8740 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8741 [ALC889A_INTEL] = "intel-alc889a",
8742 [ALC889_INTEL] = "intel-x58",
9072 [ALC1200_ASUS_P5Q] = "asus-p5q", 8743 [ALC1200_ASUS_P5Q] = "asus-p5q",
9073 [ALC889A_MB31] = "mb31", 8744 [ALC889A_MB31] = "mb31",
9074 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt", 8745 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9075 [ALC883_AUTO] = "auto", 8746 [ALC882_AUTO] = "auto",
9076}; 8747};
9077 8748
9078static struct snd_pci_quirk alc883_cfg_tbl[] = { 8749static struct snd_pci_quirk alc882_cfg_tbl[] = {
9079 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), 8750 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
8751
9080 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), 8752 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9081 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), 8753 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9082 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE), 8754 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
@@ -9091,40 +8763,56 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9091 ALC888_ACER_ASPIRE_8930G), 8763 ALC888_ACER_ASPIRE_8930G),
9092 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", 8764 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9093 ALC888_ACER_ASPIRE_8930G), 8765 ALC888_ACER_ASPIRE_8930G),
9094 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC883_AUTO), 8766 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9095 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC883_AUTO), 8767 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9096 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", 8768 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9097 ALC888_ACER_ASPIRE_6530G), 8769 ALC888_ACER_ASPIRE_6530G),
9098 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", 8770 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9099 ALC888_ACER_ASPIRE_6530G), 8771 ALC888_ACER_ASPIRE_6530G),
8772 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
8773 ALC888_ACER_ASPIRE_7730G),
9100 /* default Acer -- disabled as it causes more problems. 8774 /* default Acer -- disabled as it causes more problems.
9101 * model=auto should work fine now 8775 * model=auto should work fine now
9102 */ 8776 */
9103 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */ 8777 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
8778
9104 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8779 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8780
9105 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8781 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
9106 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), 8782 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9107 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), 8783 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9108 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8784 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9109 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), 8785 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9110 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), 8786 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
8787
8788 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
8789 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
8790 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9111 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8791 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8792 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
8793 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
8794 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9112 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8795 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9113 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), 8796 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9114 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), 8797 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9115 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8798 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8799
8800 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9116 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8801 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9117 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8802 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9118 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC), 8803 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9119 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), 8804 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9120 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), 8805 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9121 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), 8806 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9122 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), 8807 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9123 SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), 8808 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
8809
9124 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), 8810 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9125 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), 8811 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9126 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG), 8812 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
8813 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9127 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG), 8814 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC883_TARGA_2ch_DIG),
8815 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9128 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG), 8816 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9129 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG), 8817 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9130 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG), 8818 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
@@ -9133,6 +8821,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9133 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG), 8821 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9134 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG), 8822 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9135 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG), 8823 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
8824 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9136 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG), 8825 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9137 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG), 8826 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9138 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG), 8827 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
@@ -9146,11 +8835,15 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9146 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8835 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9147 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG), 8836 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9148 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG), 8837 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
8838 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
8839
9149 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), 8840 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9150 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), 8841 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9151 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), 8842 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
8843 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9152 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD), 8844 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9153 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8845 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8846 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9154 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8847 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9155 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx", 8848 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9156 ALC883_FUJITSU_PI2515), 8849 ALC883_FUJITSU_PI2515),
@@ -9165,24 +8858,186 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
9165 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG), 8858 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9166 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), 8859 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9167 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), 8860 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
8861
9168 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), 8862 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9169 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), 8863 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9170 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC), 8864 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
9171 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL), 8865 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
8866 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
8867 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
9172 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), 8868 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
9173 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9174 {}
9175};
9176 8869
9177static hda_nid_t alc883_slave_dig_outs[] = { 8870 {}
9178 ALC1200_DIGOUT_NID, 0,
9179}; 8871};
9180 8872
9181static hda_nid_t alc1200_slave_dig_outs[] = { 8873/* codec SSID table for Intel Mac */
9182 ALC883_DIGOUT_NID, 0, 8874static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
8875 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
8876 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
8877 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
8878 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
8879 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
8880 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
8881 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
8882 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
8883 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
8884 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
8885 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
8886 /* FIXME: HP jack sense seems not working for MBP 5,1, so apparently
8887 * no perfect solution yet
8888 */
8889 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
8890 {} /* terminator */
9183}; 8891};
9184 8892
9185static struct alc_config_preset alc883_presets[] = { 8893static struct alc_config_preset alc882_presets[] = {
8894 [ALC882_3ST_DIG] = {
8895 .mixers = { alc882_base_mixer },
8896 .init_verbs = { alc882_base_init_verbs,
8897 alc882_adc1_init_verbs },
8898 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8899 .dac_nids = alc882_dac_nids,
8900 .dig_out_nid = ALC882_DIGOUT_NID,
8901 .dig_in_nid = ALC882_DIGIN_NID,
8902 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8903 .channel_mode = alc882_ch_modes,
8904 .need_dac_fix = 1,
8905 .input_mux = &alc882_capture_source,
8906 },
8907 [ALC882_6ST_DIG] = {
8908 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8909 .init_verbs = { alc882_base_init_verbs,
8910 alc882_adc1_init_verbs },
8911 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8912 .dac_nids = alc882_dac_nids,
8913 .dig_out_nid = ALC882_DIGOUT_NID,
8914 .dig_in_nid = ALC882_DIGIN_NID,
8915 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8916 .channel_mode = alc882_sixstack_modes,
8917 .input_mux = &alc882_capture_source,
8918 },
8919 [ALC882_ARIMA] = {
8920 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
8921 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8922 alc882_eapd_verbs },
8923 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8924 .dac_nids = alc882_dac_nids,
8925 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
8926 .channel_mode = alc882_sixstack_modes,
8927 .input_mux = &alc882_capture_source,
8928 },
8929 [ALC882_W2JC] = {
8930 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
8931 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8932 alc882_eapd_verbs, alc880_gpio1_init_verbs },
8933 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8934 .dac_nids = alc882_dac_nids,
8935 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
8936 .channel_mode = alc880_threestack_modes,
8937 .need_dac_fix = 1,
8938 .input_mux = &alc882_capture_source,
8939 .dig_out_nid = ALC882_DIGOUT_NID,
8940 },
8941 [ALC885_MBP3] = {
8942 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
8943 .init_verbs = { alc885_mbp3_init_verbs,
8944 alc880_gpio1_init_verbs },
8945 .num_dacs = 2,
8946 .dac_nids = alc882_dac_nids,
8947 .hp_nid = 0x04,
8948 .channel_mode = alc885_mbp_4ch_modes,
8949 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
8950 .input_mux = &alc882_capture_source,
8951 .dig_out_nid = ALC882_DIGOUT_NID,
8952 .dig_in_nid = ALC882_DIGIN_NID,
8953 .unsol_event = alc_automute_amp_unsol_event,
8954 .setup = alc885_mbp3_setup,
8955 .init_hook = alc_automute_amp,
8956 },
8957 [ALC885_MB5] = {
8958 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
8959 .init_verbs = { alc885_mb5_init_verbs,
8960 alc880_gpio1_init_verbs },
8961 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8962 .dac_nids = alc882_dac_nids,
8963 .channel_mode = alc885_mb5_6ch_modes,
8964 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
8965 .input_mux = &mb5_capture_source,
8966 .dig_out_nid = ALC882_DIGOUT_NID,
8967 .dig_in_nid = ALC882_DIGIN_NID,
8968 },
8969 [ALC885_MACPRO] = {
8970 .mixers = { alc882_macpro_mixer },
8971 .init_verbs = { alc882_macpro_init_verbs },
8972 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8973 .dac_nids = alc882_dac_nids,
8974 .dig_out_nid = ALC882_DIGOUT_NID,
8975 .dig_in_nid = ALC882_DIGIN_NID,
8976 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8977 .channel_mode = alc882_ch_modes,
8978 .input_mux = &alc882_capture_source,
8979 .init_hook = alc885_macpro_init_hook,
8980 },
8981 [ALC885_IMAC24] = {
8982 .mixers = { alc885_imac24_mixer },
8983 .init_verbs = { alc885_imac24_init_verbs },
8984 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
8985 .dac_nids = alc882_dac_nids,
8986 .dig_out_nid = ALC882_DIGOUT_NID,
8987 .dig_in_nid = ALC882_DIGIN_NID,
8988 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
8989 .channel_mode = alc882_ch_modes,
8990 .input_mux = &alc882_capture_source,
8991 .unsol_event = alc_automute_amp_unsol_event,
8992 .setup = alc885_imac24_setup,
8993 .init_hook = alc885_imac24_init_hook,
8994 },
8995 [ALC882_TARGA] = {
8996 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
8997 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
8998 alc880_gpio3_init_verbs, alc882_targa_verbs},
8999 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9000 .dac_nids = alc882_dac_nids,
9001 .dig_out_nid = ALC882_DIGOUT_NID,
9002 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9003 .adc_nids = alc882_adc_nids,
9004 .capsrc_nids = alc882_capsrc_nids,
9005 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9006 .channel_mode = alc882_3ST_6ch_modes,
9007 .need_dac_fix = 1,
9008 .input_mux = &alc882_capture_source,
9009 .unsol_event = alc882_targa_unsol_event,
9010 .setup = alc882_targa_setup,
9011 .init_hook = alc882_targa_automute,
9012 },
9013 [ALC882_ASUS_A7J] = {
9014 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
9015 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9016 alc882_asus_a7j_verbs},
9017 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9018 .dac_nids = alc882_dac_nids,
9019 .dig_out_nid = ALC882_DIGOUT_NID,
9020 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
9021 .adc_nids = alc882_adc_nids,
9022 .capsrc_nids = alc882_capsrc_nids,
9023 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
9024 .channel_mode = alc882_3ST_6ch_modes,
9025 .need_dac_fix = 1,
9026 .input_mux = &alc882_capture_source,
9027 },
9028 [ALC882_ASUS_A7M] = {
9029 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
9030 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
9031 alc882_eapd_verbs, alc880_gpio1_init_verbs,
9032 alc882_asus_a7m_verbs },
9033 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9034 .dac_nids = alc882_dac_nids,
9035 .dig_out_nid = ALC882_DIGOUT_NID,
9036 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
9037 .channel_mode = alc880_threestack_modes,
9038 .need_dac_fix = 1,
9039 .input_mux = &alc882_capture_source,
9040 },
9186 [ALC883_3ST_2ch_DIG] = { 9041 [ALC883_3ST_2ch_DIG] = {
9187 .mixers = { alc883_3ST_2ch_mixer }, 9042 .mixers = { alc883_3ST_2ch_mixer },
9188 .init_verbs = { alc883_init_verbs }, 9043 .init_verbs = { alc883_init_verbs },
@@ -9229,6 +9084,46 @@ static struct alc_config_preset alc883_presets[] = {
9229 .need_dac_fix = 1, 9084 .need_dac_fix = 1,
9230 .input_mux = &alc883_3stack_6ch_intel, 9085 .input_mux = &alc883_3stack_6ch_intel,
9231 }, 9086 },
9087 [ALC889A_INTEL] = {
9088 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9089 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
9090 alc_hp15_unsol_verbs },
9091 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9092 .dac_nids = alc883_dac_nids,
9093 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9094 .adc_nids = alc889_adc_nids,
9095 .dig_out_nid = ALC883_DIGOUT_NID,
9096 .dig_in_nid = ALC883_DIGIN_NID,
9097 .slave_dig_outs = alc883_slave_dig_outs,
9098 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9099 .channel_mode = alc889_8ch_intel_modes,
9100 .capsrc_nids = alc889_capsrc_nids,
9101 .input_mux = &alc889_capture_source,
9102 .setup = alc889_automute_setup,
9103 .init_hook = alc_automute_amp,
9104 .unsol_event = alc_automute_amp_unsol_event,
9105 .need_dac_fix = 1,
9106 },
9107 [ALC889_INTEL] = {
9108 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
9109 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
9110 alc889_eapd_verbs, alc_hp15_unsol_verbs},
9111 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9112 .dac_nids = alc883_dac_nids,
9113 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9114 .adc_nids = alc889_adc_nids,
9115 .dig_out_nid = ALC883_DIGOUT_NID,
9116 .dig_in_nid = ALC883_DIGIN_NID,
9117 .slave_dig_outs = alc883_slave_dig_outs,
9118 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
9119 .channel_mode = alc889_8ch_intel_modes,
9120 .capsrc_nids = alc889_capsrc_nids,
9121 .input_mux = &alc889_capture_source,
9122 .setup = alc889_automute_setup,
9123 .init_hook = alc889_intel_init_hook,
9124 .unsol_event = alc_automute_amp_unsol_event,
9125 .need_dac_fix = 1,
9126 },
9232 [ALC883_6ST_DIG] = { 9127 [ALC883_6ST_DIG] = {
9233 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9128 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
9234 .init_verbs = { alc883_init_verbs }, 9129 .init_verbs = { alc883_init_verbs },
@@ -9252,7 +9147,8 @@ static struct alc_config_preset alc883_presets[] = {
9252 .need_dac_fix = 1, 9147 .need_dac_fix = 1,
9253 .input_mux = &alc883_capture_source, 9148 .input_mux = &alc883_capture_source,
9254 .unsol_event = alc883_targa_unsol_event, 9149 .unsol_event = alc883_targa_unsol_event,
9255 .init_hook = alc883_targa_init_hook, 9150 .setup = alc882_targa_setup,
9151 .init_hook = alc882_targa_automute,
9256 }, 9152 },
9257 [ALC883_TARGA_2ch_DIG] = { 9153 [ALC883_TARGA_2ch_DIG] = {
9258 .mixers = { alc883_targa_2ch_mixer}, 9154 .mixers = { alc883_targa_2ch_mixer},
@@ -9267,7 +9163,8 @@ static struct alc_config_preset alc883_presets[] = {
9267 .channel_mode = alc883_3ST_2ch_modes, 9163 .channel_mode = alc883_3ST_2ch_modes,
9268 .input_mux = &alc883_capture_source, 9164 .input_mux = &alc883_capture_source,
9269 .unsol_event = alc883_targa_unsol_event, 9165 .unsol_event = alc883_targa_unsol_event,
9270 .init_hook = alc883_targa_init_hook, 9166 .setup = alc882_targa_setup,
9167 .init_hook = alc882_targa_automute,
9271 }, 9168 },
9272 [ALC883_TARGA_8ch_DIG] = { 9169 [ALC883_TARGA_8ch_DIG] = {
9273 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9170 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -9285,7 +9182,8 @@ static struct alc_config_preset alc883_presets[] = {
9285 .need_dac_fix = 1, 9182 .need_dac_fix = 1,
9286 .input_mux = &alc883_capture_source, 9183 .input_mux = &alc883_capture_source,
9287 .unsol_event = alc883_targa_unsol_event, 9184 .unsol_event = alc883_targa_unsol_event,
9288 .init_hook = alc883_targa_init_hook, 9185 .setup = alc882_targa_setup,
9186 .init_hook = alc882_targa_automute,
9289 }, 9187 },
9290 [ALC883_ACER] = { 9188 [ALC883_ACER] = {
9291 .mixers = { alc883_base_mixer }, 9189 .mixers = { alc883_base_mixer },
@@ -9311,7 +9209,8 @@ static struct alc_config_preset alc883_presets[] = {
9311 .channel_mode = alc883_3ST_2ch_modes, 9209 .channel_mode = alc883_3ST_2ch_modes,
9312 .input_mux = &alc883_capture_source, 9210 .input_mux = &alc883_capture_source,
9313 .unsol_event = alc_automute_amp_unsol_event, 9211 .unsol_event = alc_automute_amp_unsol_event,
9314 .init_hook = alc883_acer_aspire_init_hook, 9212 .setup = alc883_acer_aspire_setup,
9213 .init_hook = alc_automute_amp,
9315 }, 9214 },
9316 [ALC888_ACER_ASPIRE_4930G] = { 9215 [ALC888_ACER_ASPIRE_4930G] = {
9317 .mixers = { alc888_base_mixer, 9216 .mixers = { alc888_base_mixer,
@@ -9331,7 +9230,8 @@ static struct alc_config_preset alc883_presets[] = {
9331 ARRAY_SIZE(alc888_2_capture_sources), 9230 ARRAY_SIZE(alc888_2_capture_sources),
9332 .input_mux = alc888_2_capture_sources, 9231 .input_mux = alc888_2_capture_sources,
9333 .unsol_event = alc_automute_amp_unsol_event, 9232 .unsol_event = alc_automute_amp_unsol_event,
9334 .init_hook = alc888_acer_aspire_4930g_init_hook, 9233 .setup = alc888_acer_aspire_4930g_setup,
9234 .init_hook = alc_automute_amp,
9335 }, 9235 },
9336 [ALC888_ACER_ASPIRE_6530G] = { 9236 [ALC888_ACER_ASPIRE_6530G] = {
9337 .mixers = { alc888_acer_aspire_6530_mixer }, 9237 .mixers = { alc888_acer_aspire_6530_mixer },
@@ -9349,7 +9249,8 @@ static struct alc_config_preset alc883_presets[] = {
9349 ARRAY_SIZE(alc888_2_capture_sources), 9249 ARRAY_SIZE(alc888_2_capture_sources),
9350 .input_mux = alc888_acer_aspire_6530_sources, 9250 .input_mux = alc888_acer_aspire_6530_sources,
9351 .unsol_event = alc_automute_amp_unsol_event, 9251 .unsol_event = alc_automute_amp_unsol_event,
9352 .init_hook = alc888_acer_aspire_6530g_init_hook, 9252 .setup = alc888_acer_aspire_6530g_setup,
9253 .init_hook = alc_automute_amp,
9353 }, 9254 },
9354 [ALC888_ACER_ASPIRE_8930G] = { 9255 [ALC888_ACER_ASPIRE_8930G] = {
9355 .mixers = { alc888_base_mixer, 9256 .mixers = { alc888_base_mixer,
@@ -9370,7 +9271,28 @@ static struct alc_config_preset alc883_presets[] = {
9370 ARRAY_SIZE(alc889_capture_sources), 9271 ARRAY_SIZE(alc889_capture_sources),
9371 .input_mux = alc889_capture_sources, 9272 .input_mux = alc889_capture_sources,
9372 .unsol_event = alc_automute_amp_unsol_event, 9273 .unsol_event = alc_automute_amp_unsol_event,
9373 .init_hook = alc889_acer_aspire_8930g_init_hook, 9274 .setup = alc889_acer_aspire_8930g_setup,
9275 .init_hook = alc_automute_amp,
9276 },
9277 [ALC888_ACER_ASPIRE_7730G] = {
9278 .mixers = { alc883_3ST_6ch_mixer,
9279 alc883_chmode_mixer },
9280 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
9281 alc888_acer_aspire_7730G_verbs },
9282 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9283 .dac_nids = alc883_dac_nids,
9284 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
9285 .adc_nids = alc883_adc_nids_rev,
9286 .capsrc_nids = alc883_capsrc_nids_rev,
9287 .dig_out_nid = ALC883_DIGOUT_NID,
9288 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
9289 .channel_mode = alc883_3ST_6ch_modes,
9290 .need_dac_fix = 1,
9291 .const_channel_count = 6,
9292 .input_mux = &alc883_capture_source,
9293 .unsol_event = alc_automute_amp_unsol_event,
9294 .setup = alc888_acer_aspire_6530g_setup,
9295 .init_hook = alc_automute_amp,
9374 }, 9296 },
9375 [ALC883_MEDION] = { 9297 [ALC883_MEDION] = {
9376 .mixers = { alc883_fivestack_mixer, 9298 .mixers = { alc883_fivestack_mixer,
@@ -9395,7 +9317,8 @@ static struct alc_config_preset alc883_presets[] = {
9395 .channel_mode = alc883_3ST_2ch_modes, 9317 .channel_mode = alc883_3ST_2ch_modes,
9396 .input_mux = &alc883_capture_source, 9318 .input_mux = &alc883_capture_source,
9397 .unsol_event = alc_automute_amp_unsol_event, 9319 .unsol_event = alc_automute_amp_unsol_event,
9398 .init_hook = alc883_medion_md2_init_hook, 9320 .setup = alc883_medion_md2_setup,
9321 .init_hook = alc_automute_amp,
9399 }, 9322 },
9400 [ALC883_LAPTOP_EAPD] = { 9323 [ALC883_LAPTOP_EAPD] = {
9401 .mixers = { alc883_base_mixer }, 9324 .mixers = { alc883_base_mixer },
@@ -9406,6 +9329,21 @@ static struct alc_config_preset alc883_presets[] = {
9406 .channel_mode = alc883_3ST_2ch_modes, 9329 .channel_mode = alc883_3ST_2ch_modes,
9407 .input_mux = &alc883_capture_source, 9330 .input_mux = &alc883_capture_source,
9408 }, 9331 },
9332 [ALC883_CLEVO_M540R] = {
9333 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
9334 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
9335 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
9336 .dac_nids = alc883_dac_nids,
9337 .dig_out_nid = ALC883_DIGOUT_NID,
9338 .dig_in_nid = ALC883_DIGIN_NID,
9339 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
9340 .channel_mode = alc883_3ST_6ch_clevo_modes,
9341 .need_dac_fix = 1,
9342 .input_mux = &alc883_capture_source,
9343 /* This machine has the hardware HP auto-muting, thus
9344 * we need no software mute via unsol event
9345 */
9346 },
9409 [ALC883_CLEVO_M720] = { 9347 [ALC883_CLEVO_M720] = {
9410 .mixers = { alc883_clevo_m720_mixer }, 9348 .mixers = { alc883_clevo_m720_mixer },
9411 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs }, 9349 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
@@ -9416,6 +9354,7 @@ static struct alc_config_preset alc883_presets[] = {
9416 .channel_mode = alc883_3ST_2ch_modes, 9354 .channel_mode = alc883_3ST_2ch_modes,
9417 .input_mux = &alc883_capture_source, 9355 .input_mux = &alc883_capture_source,
9418 .unsol_event = alc883_clevo_m720_unsol_event, 9356 .unsol_event = alc883_clevo_m720_unsol_event,
9357 .setup = alc883_clevo_m720_setup,
9419 .init_hook = alc883_clevo_m720_init_hook, 9358 .init_hook = alc883_clevo_m720_init_hook,
9420 }, 9359 },
9421 [ALC883_LENOVO_101E_2ch] = { 9360 [ALC883_LENOVO_101E_2ch] = {
@@ -9441,7 +9380,8 @@ static struct alc_config_preset alc883_presets[] = {
9441 .need_dac_fix = 1, 9380 .need_dac_fix = 1,
9442 .input_mux = &alc883_lenovo_nb0763_capture_source, 9381 .input_mux = &alc883_lenovo_nb0763_capture_source,
9443 .unsol_event = alc_automute_amp_unsol_event, 9382 .unsol_event = alc_automute_amp_unsol_event,
9444 .init_hook = alc883_medion_md2_init_hook, 9383 .setup = alc883_medion_md2_setup,
9384 .init_hook = alc_automute_amp,
9445 }, 9385 },
9446 [ALC888_LENOVO_MS7195_DIG] = { 9386 [ALC888_LENOVO_MS7195_DIG] = {
9447 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9387 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9466,7 +9406,8 @@ static struct alc_config_preset alc883_presets[] = {
9466 .channel_mode = alc883_3ST_2ch_modes, 9406 .channel_mode = alc883_3ST_2ch_modes,
9467 .input_mux = &alc883_capture_source, 9407 .input_mux = &alc883_capture_source,
9468 .unsol_event = alc_automute_amp_unsol_event, 9408 .unsol_event = alc_automute_amp_unsol_event,
9469 .init_hook = alc883_haier_w66_init_hook, 9409 .setup = alc883_haier_w66_setup,
9410 .init_hook = alc_automute_amp,
9470 }, 9411 },
9471 [ALC888_3ST_HP] = { 9412 [ALC888_3ST_HP] = {
9472 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9413 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9478,7 +9419,8 @@ static struct alc_config_preset alc883_presets[] = {
9478 .need_dac_fix = 1, 9419 .need_dac_fix = 1,
9479 .input_mux = &alc883_capture_source, 9420 .input_mux = &alc883_capture_source,
9480 .unsol_event = alc_automute_amp_unsol_event, 9421 .unsol_event = alc_automute_amp_unsol_event,
9481 .init_hook = alc888_3st_hp_init_hook, 9422 .setup = alc888_3st_hp_setup,
9423 .init_hook = alc_automute_amp,
9482 }, 9424 },
9483 [ALC888_6ST_DELL] = { 9425 [ALC888_6ST_DELL] = {
9484 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 9426 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
@@ -9491,7 +9433,8 @@ static struct alc_config_preset alc883_presets[] = {
9491 .channel_mode = alc883_sixstack_modes, 9433 .channel_mode = alc883_sixstack_modes,
9492 .input_mux = &alc883_capture_source, 9434 .input_mux = &alc883_capture_source,
9493 .unsol_event = alc_automute_amp_unsol_event, 9435 .unsol_event = alc_automute_amp_unsol_event,
9494 .init_hook = alc888_6st_dell_init_hook, 9436 .setup = alc888_6st_dell_setup,
9437 .init_hook = alc_automute_amp,
9495 }, 9438 },
9496 [ALC883_MITAC] = { 9439 [ALC883_MITAC] = {
9497 .mixers = { alc883_mitac_mixer }, 9440 .mixers = { alc883_mitac_mixer },
@@ -9502,7 +9445,8 @@ static struct alc_config_preset alc883_presets[] = {
9502 .channel_mode = alc883_3ST_2ch_modes, 9445 .channel_mode = alc883_3ST_2ch_modes,
9503 .input_mux = &alc883_capture_source, 9446 .input_mux = &alc883_capture_source,
9504 .unsol_event = alc_automute_amp_unsol_event, 9447 .unsol_event = alc_automute_amp_unsol_event,
9505 .init_hook = alc883_mitac_init_hook, 9448 .setup = alc883_mitac_setup,
9449 .init_hook = alc_automute_amp,
9506 }, 9450 },
9507 [ALC883_FUJITSU_PI2515] = { 9451 [ALC883_FUJITSU_PI2515] = {
9508 .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, 9452 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
@@ -9515,7 +9459,8 @@ static struct alc_config_preset alc883_presets[] = {
9515 .channel_mode = alc883_3ST_2ch_modes, 9459 .channel_mode = alc883_3ST_2ch_modes,
9516 .input_mux = &alc883_fujitsu_pi2515_capture_source, 9460 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9517 .unsol_event = alc_automute_amp_unsol_event, 9461 .unsol_event = alc_automute_amp_unsol_event,
9518 .init_hook = alc883_2ch_fujitsu_pi2515_init_hook, 9462 .setup = alc883_2ch_fujitsu_pi2515_setup,
9463 .init_hook = alc_automute_amp,
9519 }, 9464 },
9520 [ALC888_FUJITSU_XA3530] = { 9465 [ALC888_FUJITSU_XA3530] = {
9521 .mixers = { alc888_base_mixer, alc883_chmode_mixer }, 9466 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
@@ -9533,7 +9478,8 @@ static struct alc_config_preset alc883_presets[] = {
9533 ARRAY_SIZE(alc888_2_capture_sources), 9478 ARRAY_SIZE(alc888_2_capture_sources),
9534 .input_mux = alc888_2_capture_sources, 9479 .input_mux = alc888_2_capture_sources,
9535 .unsol_event = alc_automute_amp_unsol_event, 9480 .unsol_event = alc_automute_amp_unsol_event,
9536 .init_hook = alc888_fujitsu_xa3530_init_hook, 9481 .setup = alc888_fujitsu_xa3530_setup,
9482 .init_hook = alc_automute_amp,
9537 }, 9483 },
9538 [ALC888_LENOVO_SKY] = { 9484 [ALC888_LENOVO_SKY] = {
9539 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 9485 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
@@ -9546,7 +9492,8 @@ static struct alc_config_preset alc883_presets[] = {
9546 .need_dac_fix = 1, 9492 .need_dac_fix = 1,
9547 .input_mux = &alc883_lenovo_sky_capture_source, 9493 .input_mux = &alc883_lenovo_sky_capture_source,
9548 .unsol_event = alc_automute_amp_unsol_event, 9494 .unsol_event = alc_automute_amp_unsol_event,
9549 .init_hook = alc888_lenovo_sky_init_hook, 9495 .setup = alc888_lenovo_sky_setup,
9496 .init_hook = alc_automute_amp,
9550 }, 9497 },
9551 [ALC888_ASUS_M90V] = { 9498 [ALC888_ASUS_M90V] = {
9552 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, 9499 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
@@ -9559,8 +9506,9 @@ static struct alc_config_preset alc883_presets[] = {
9559 .channel_mode = alc883_3ST_6ch_modes, 9506 .channel_mode = alc883_3ST_6ch_modes,
9560 .need_dac_fix = 1, 9507 .need_dac_fix = 1,
9561 .input_mux = &alc883_fujitsu_pi2515_capture_source, 9508 .input_mux = &alc883_fujitsu_pi2515_capture_source,
9562 .unsol_event = alc883_mode2_unsol_event, 9509 .unsol_event = alc_sku_unsol_event,
9563 .init_hook = alc883_mode2_inithook, 9510 .setup = alc883_mode2_setup,
9511 .init_hook = alc_inithook,
9564 }, 9512 },
9565 [ALC888_ASUS_EEE1601] = { 9513 [ALC888_ASUS_EEE1601] = {
9566 .mixers = { alc883_asus_eee1601_mixer }, 9514 .mixers = { alc883_asus_eee1601_mixer },
@@ -9613,15 +9561,45 @@ static struct alc_config_preset alc883_presets[] = {
9613 .channel_mode = alc883_3ST_2ch_modes, 9561 .channel_mode = alc883_3ST_2ch_modes,
9614 .input_mux = &alc883_capture_source, 9562 .input_mux = &alc883_capture_source,
9615 .unsol_event = alc_automute_amp_unsol_event, 9563 .unsol_event = alc_automute_amp_unsol_event,
9616 .init_hook = alc883_vaiott_init_hook, 9564 .setup = alc883_vaiott_setup,
9565 .init_hook = alc_automute_amp,
9617 }, 9566 },
9618}; 9567};
9619 9568
9620 9569
9621/* 9570/*
9571 * Pin config fixes
9572 */
9573enum {
9574 PINFIX_ABIT_AW9D_MAX
9575};
9576
9577static struct alc_pincfg alc882_abit_aw9d_pinfix[] = {
9578 { 0x15, 0x01080104 }, /* side */
9579 { 0x16, 0x01011012 }, /* rear */
9580 { 0x17, 0x01016011 }, /* clfe */
9581 { }
9582};
9583
9584static const struct alc_pincfg *alc882_pin_fixes[] = {
9585 [PINFIX_ABIT_AW9D_MAX] = alc882_abit_aw9d_pinfix,
9586};
9587
9588static struct snd_pci_quirk alc882_pinfix_tbl[] = {
9589 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
9590 {}
9591};
9592
9593/*
9622 * BIOS auto configuration 9594 * BIOS auto configuration
9623 */ 9595 */
9624static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, 9596static int alc882_auto_create_input_ctls(struct hda_codec *codec,
9597 const struct auto_pin_cfg *cfg)
9598{
9599 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
9600}
9601
9602static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
9625 hda_nid_t nid, int pin_type, 9603 hda_nid_t nid, int pin_type,
9626 int dac_idx) 9604 int dac_idx)
9627{ 9605{
@@ -9638,7 +9616,7 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec,
9638 9616
9639} 9617}
9640 9618
9641static void alc883_auto_init_multi_out(struct hda_codec *codec) 9619static void alc882_auto_init_multi_out(struct hda_codec *codec)
9642{ 9620{
9643 struct alc_spec *spec = codec->spec; 9621 struct alc_spec *spec = codec->spec;
9644 int i; 9622 int i;
@@ -9647,12 +9625,12 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
9647 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9625 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9648 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9626 int pin_type = get_pin_type(spec->autocfg.line_out_type);
9649 if (nid) 9627 if (nid)
9650 alc883_auto_set_output_and_unmute(codec, nid, pin_type, 9628 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
9651 i); 9629 i);
9652 } 9630 }
9653} 9631}
9654 9632
9655static void alc883_auto_init_hp_out(struct hda_codec *codec) 9633static void alc882_auto_init_hp_out(struct hda_codec *codec)
9656{ 9634{
9657 struct alc_spec *spec = codec->spec; 9635 struct alc_spec *spec = codec->spec;
9658 hda_nid_t pin; 9636 hda_nid_t pin;
@@ -9660,91 +9638,191 @@ static void alc883_auto_init_hp_out(struct hda_codec *codec)
9660 pin = spec->autocfg.hp_pins[0]; 9638 pin = spec->autocfg.hp_pins[0];
9661 if (pin) /* connect to front */ 9639 if (pin) /* connect to front */
9662 /* use dac 0 */ 9640 /* use dac 0 */
9663 alc883_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); 9641 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
9664 pin = spec->autocfg.speaker_pins[0]; 9642 pin = spec->autocfg.speaker_pins[0];
9665 if (pin) 9643 if (pin)
9666 alc883_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 9644 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
9667} 9645}
9668 9646
9669#define alc883_is_input_pin(nid) alc880_is_input_pin(nid) 9647static void alc882_auto_init_analog_input(struct hda_codec *codec)
9670#define ALC883_PIN_CD_NID ALC880_PIN_CD_NID
9671
9672static void alc883_auto_init_analog_input(struct hda_codec *codec)
9673{ 9648{
9674 struct alc_spec *spec = codec->spec; 9649 struct alc_spec *spec = codec->spec;
9675 int i; 9650 int i;
9676 9651
9677 for (i = 0; i < AUTO_PIN_LAST; i++) { 9652 for (i = 0; i < AUTO_PIN_LAST; i++) {
9678 hda_nid_t nid = spec->autocfg.input_pins[i]; 9653 hda_nid_t nid = spec->autocfg.input_pins[i];
9679 if (alc883_is_input_pin(nid)) { 9654 if (!nid)
9680 alc_set_input_pin(codec, nid, i); 9655 continue;
9681 if (nid != ALC883_PIN_CD_NID && 9656 alc_set_input_pin(codec, nid, i);
9682 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 9657 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
9658 snd_hda_codec_write(codec, nid, 0,
9659 AC_VERB_SET_AMP_GAIN_MUTE,
9660 AMP_OUT_MUTE);
9661 }
9662}
9663
9664static void alc882_auto_init_input_src(struct hda_codec *codec)
9665{
9666 struct alc_spec *spec = codec->spec;
9667 int c;
9668
9669 for (c = 0; c < spec->num_adc_nids; c++) {
9670 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
9671 hda_nid_t nid = spec->capsrc_nids[c];
9672 unsigned int mux_idx;
9673 const struct hda_input_mux *imux;
9674 int conns, mute, idx, item;
9675
9676 conns = snd_hda_get_connections(codec, nid, conn_list,
9677 ARRAY_SIZE(conn_list));
9678 if (conns < 0)
9679 continue;
9680 mux_idx = c >= spec->num_mux_defs ? 0 : c;
9681 imux = &spec->input_mux[mux_idx];
9682 for (idx = 0; idx < conns; idx++) {
9683 /* if the current connection is the selected one,
9684 * unmute it as default - otherwise mute it
9685 */
9686 mute = AMP_IN_MUTE(idx);
9687 for (item = 0; item < imux->num_items; item++) {
9688 if (imux->items[item].index == idx) {
9689 if (spec->cur_mux[c] == item)
9690 mute = AMP_IN_UNMUTE(idx);
9691 break;
9692 }
9693 }
9694 /* check if we have a selector or mixer
9695 * we could check for the widget type instead, but
9696 * just check for Amp-In presence (in case of mixer
9697 * without amp-in there is something wrong, this
9698 * function shouldn't be used or capsrc nid is wrong)
9699 */
9700 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
9683 snd_hda_codec_write(codec, nid, 0, 9701 snd_hda_codec_write(codec, nid, 0,
9684 AC_VERB_SET_AMP_GAIN_MUTE, 9702 AC_VERB_SET_AMP_GAIN_MUTE,
9685 AMP_OUT_MUTE); 9703 mute);
9704 else if (mute != AMP_IN_MUTE(idx))
9705 snd_hda_codec_write(codec, nid, 0,
9706 AC_VERB_SET_CONNECT_SEL,
9707 idx);
9686 } 9708 }
9687 } 9709 }
9688} 9710}
9689 9711
9690#define alc883_auto_init_input_src alc882_auto_init_input_src 9712/* add mic boosts if needed */
9713static int alc_auto_add_mic_boost(struct hda_codec *codec)
9714{
9715 struct alc_spec *spec = codec->spec;
9716 int err;
9717 hda_nid_t nid;
9718
9719 nid = spec->autocfg.input_pins[AUTO_PIN_MIC];
9720 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9721 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9722 "Mic Boost",
9723 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9724 if (err < 0)
9725 return err;
9726 }
9727 nid = spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC];
9728 if (nid && (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) {
9729 err = add_control(spec, ALC_CTL_WIDGET_VOL,
9730 "Front Mic Boost",
9731 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
9732 if (err < 0)
9733 return err;
9734 }
9735 return 0;
9736}
9691 9737
9692/* almost identical with ALC880 parser... */ 9738/* almost identical with ALC880 parser... */
9693static int alc883_parse_auto_config(struct hda_codec *codec) 9739static int alc882_parse_auto_config(struct hda_codec *codec)
9694{ 9740{
9695 struct alc_spec *spec = codec->spec; 9741 struct alc_spec *spec = codec->spec;
9696 int err = alc880_parse_auto_config(codec); 9742 static hda_nid_t alc882_ignore[] = { 0x1d, 0 };
9697 struct auto_pin_cfg *cfg = &spec->autocfg; 9743 int i, err;
9698 int i;
9699 9744
9745 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
9746 alc882_ignore);
9700 if (err < 0) 9747 if (err < 0)
9701 return err; 9748 return err;
9702 else if (!err) 9749 if (!spec->autocfg.line_outs)
9703 return 0; /* no config found */ 9750 return 0; /* can't find valid BIOS pin config */
9704 9751
9705 err = alc_auto_add_mic_boost(codec); 9752 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
9753 if (err < 0)
9754 return err;
9755 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
9756 if (err < 0)
9757 return err;
9758 err = alc880_auto_create_extra_out(spec,
9759 spec->autocfg.speaker_pins[0],
9760 "Speaker");
9761 if (err < 0)
9762 return err;
9763 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
9764 "Headphone");
9765 if (err < 0)
9766 return err;
9767 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
9706 if (err < 0) 9768 if (err < 0)
9707 return err; 9769 return err;
9708 9770
9709 /* hack - override the init verbs */ 9771 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
9710 spec->init_verbs[0] = alc883_auto_init_verbs;
9711 9772
9712 /* setup input_mux for ALC889 */ 9773 /* check multiple SPDIF-out (for recent codecs) */
9713 if (codec->vendor_id == 0x10ec0889) { 9774 for (i = 0; i < spec->autocfg.dig_outs; i++) {
9714 /* digital-mic input pin is excluded in alc880_auto_create..() 9775 hda_nid_t dig_nid;
9715 * because it's under 0x18 9776 err = snd_hda_get_connections(codec,
9716 */ 9777 spec->autocfg.dig_out_pins[i],
9717 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || 9778 &dig_nid, 1);
9718 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { 9779 if (err < 0)
9719 struct hda_input_mux *imux = &spec->private_imux[0]; 9780 continue;
9720 for (i = 1; i < 3; i++) 9781 if (!i)
9721 memcpy(&spec->private_imux[i], 9782 spec->multiout.dig_out_nid = dig_nid;
9722 &spec->private_imux[0], 9783 else {
9723 sizeof(spec->private_imux[0])); 9784 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
9724 imux->items[imux->num_items].label = "Int DMic"; 9785 spec->slave_dig_outs[i - 1] = dig_nid;
9725 imux->items[imux->num_items].index = 0x0b; 9786 if (i == ARRAY_SIZE(spec->slave_dig_outs) - 1)
9726 imux->num_items++; 9787 break;
9727 spec->num_mux_defs = 3;
9728 spec->input_mux = spec->private_imux;
9729 } 9788 }
9730 } 9789 }
9790 if (spec->autocfg.dig_in_pin)
9791 spec->dig_in_nid = ALC880_DIGIN_NID;
9792
9793 if (spec->kctls.list)
9794 add_mixer(spec, spec->kctls.list);
9795
9796 add_verb(spec, alc883_auto_init_verbs);
9797 /* if ADC 0x07 is available, initialize it, too */
9798 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
9799 add_verb(spec, alc882_adc1_init_verbs);
9800
9801 spec->num_mux_defs = 1;
9802 spec->input_mux = &spec->private_imux[0];
9803
9804 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
9805
9806 err = alc_auto_add_mic_boost(codec);
9807 if (err < 0)
9808 return err;
9731 9809
9732 return 1; /* config found */ 9810 return 1; /* config found */
9733} 9811}
9734 9812
9735/* additional initialization for auto-configuration model */ 9813/* additional initialization for auto-configuration model */
9736static void alc883_auto_init(struct hda_codec *codec) 9814static void alc882_auto_init(struct hda_codec *codec)
9737{ 9815{
9738 struct alc_spec *spec = codec->spec; 9816 struct alc_spec *spec = codec->spec;
9739 alc883_auto_init_multi_out(codec); 9817 alc882_auto_init_multi_out(codec);
9740 alc883_auto_init_hp_out(codec); 9818 alc882_auto_init_hp_out(codec);
9741 alc883_auto_init_analog_input(codec); 9819 alc882_auto_init_analog_input(codec);
9742 alc883_auto_init_input_src(codec); 9820 alc882_auto_init_input_src(codec);
9743 if (spec->unsol_event) 9821 if (spec->unsol_event)
9744 alc_inithook(codec); 9822 alc_inithook(codec);
9745} 9823}
9746 9824
9747static int patch_alc883(struct hda_codec *codec) 9825static int patch_alc882(struct hda_codec *codec)
9748{ 9826{
9749 struct alc_spec *spec; 9827 struct alc_spec *spec;
9750 int err, board_config; 9828 int err, board_config;
@@ -9755,28 +9833,35 @@ static int patch_alc883(struct hda_codec *codec)
9755 9833
9756 codec->spec = spec; 9834 codec->spec = spec;
9757 9835
9758 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 9836 switch (codec->vendor_id) {
9837 case 0x10ec0882:
9838 case 0x10ec0885:
9839 break;
9840 default:
9841 /* ALC883 and variants */
9842 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
9843 break;
9844 }
9759 9845
9760 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST, 9846 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
9761 alc883_models, 9847 alc882_models,
9762 alc883_cfg_tbl); 9848 alc882_cfg_tbl);
9763 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { 9849
9764 /* Pick up systems that don't supply PCI SSID */ 9850 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
9765 switch (codec->subsystem_id) { 9851 board_config = snd_hda_check_board_codec_sid_config(codec,
9766 case 0x106b3600: /* Macbook 3.1 */ 9852 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
9767 board_config = ALC889A_MB31; 9853
9768 break; 9854 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
9769 default: 9855 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
9770 printk(KERN_INFO 9856 codec->chip_name);
9771 "hda_codec: Unknown model for %s, trying " 9857 board_config = ALC882_AUTO;
9772 "auto-probe from BIOS...\n", codec->chip_name);
9773 board_config = ALC883_AUTO;
9774 }
9775 } 9858 }
9776 9859
9777 if (board_config == ALC883_AUTO) { 9860 alc_fix_pincfg(codec, alc882_pinfix_tbl, alc882_pin_fixes);
9861
9862 if (board_config == ALC882_AUTO) {
9778 /* automatic parse from the BIOS config */ 9863 /* automatic parse from the BIOS config */
9779 err = alc883_parse_auto_config(codec); 9864 err = alc882_parse_auto_config(codec);
9780 if (err < 0) { 9865 if (err < 0) {
9781 alc_free(codec); 9866 alc_free(codec);
9782 return err; 9867 return err;
@@ -9784,7 +9869,7 @@ static int patch_alc883(struct hda_codec *codec)
9784 printk(KERN_INFO 9869 printk(KERN_INFO
9785 "hda_codec: Cannot set up configuration " 9870 "hda_codec: Cannot set up configuration "
9786 "from BIOS. Using base mode...\n"); 9871 "from BIOS. Using base mode...\n");
9787 board_config = ALC883_3ST_2ch_DIG; 9872 board_config = ALC882_3ST_DIG;
9788 } 9873 }
9789 } 9874 }
9790 9875
@@ -9794,63 +9879,61 @@ static int patch_alc883(struct hda_codec *codec)
9794 return err; 9879 return err;
9795 } 9880 }
9796 9881
9797 if (board_config != ALC883_AUTO) 9882 if (board_config != ALC882_AUTO)
9798 setup_preset(spec, &alc883_presets[board_config]); 9883 setup_preset(codec, &alc882_presets[board_config]);
9799 9884
9800 switch (codec->vendor_id) { 9885 spec->stream_analog_playback = &alc882_pcm_analog_playback;
9801 case 0x10ec0888: 9886 spec->stream_analog_capture = &alc882_pcm_analog_capture;
9802 if (!spec->num_adc_nids) { 9887 /* FIXME: setup DAC5 */
9803 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9888 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
9804 spec->adc_nids = alc883_adc_nids; 9889 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
9805 } 9890
9806 if (!spec->capsrc_nids) 9891 spec->stream_digital_playback = &alc882_pcm_digital_playback;
9807 spec->capsrc_nids = alc883_capsrc_nids; 9892 spec->stream_digital_capture = &alc882_pcm_digital_capture;
9893
9894 if (codec->vendor_id == 0x10ec0888)
9808 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */ 9895 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9809 break; 9896
9810 case 0x10ec0889: 9897 if (!spec->adc_nids && spec->input_mux) {
9811 if (!spec->num_adc_nids) { 9898 int i;
9812 spec->num_adc_nids = ARRAY_SIZE(alc889_adc_nids); 9899 spec->num_adc_nids = 0;
9813 spec->adc_nids = alc889_adc_nids; 9900 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
9814 } 9901 hda_nid_t cap;
9815 if (!spec->capsrc_nids) 9902 hda_nid_t nid = alc882_adc_nids[i];
9816 spec->capsrc_nids = alc889_capsrc_nids; 9903 unsigned int wcap = get_wcaps(codec, nid);
9817 break; 9904 /* get type */
9818 default: 9905 wcap = get_wcaps_type(wcap);
9819 if (!spec->num_adc_nids) { 9906 if (wcap != AC_WID_AUD_IN)
9820 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9907 continue;
9821 spec->adc_nids = alc883_adc_nids; 9908 spec->private_adc_nids[spec->num_adc_nids] = nid;
9909 err = snd_hda_get_connections(codec, nid, &cap, 1);
9910 if (err < 0)
9911 continue;
9912 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
9913 spec->num_adc_nids++;
9822 } 9914 }
9823 if (!spec->capsrc_nids) 9915 spec->adc_nids = spec->private_adc_nids;
9824 spec->capsrc_nids = alc883_capsrc_nids; 9916 spec->capsrc_nids = spec->private_capsrc_nids;
9825 break;
9826 } 9917 }
9827 9918
9828 spec->stream_analog_playback = &alc883_pcm_analog_playback; 9919 set_capture_mixer(codec);
9829 spec->stream_analog_capture = &alc883_pcm_analog_capture;
9830 spec->stream_analog_alt_capture = &alc883_pcm_analog_alt_capture;
9831
9832 spec->stream_digital_playback = &alc883_pcm_digital_playback;
9833 spec->stream_digital_capture = &alc883_pcm_digital_capture;
9834
9835 if (!spec->cap_mixer)
9836 set_capture_mixer(spec);
9837 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 9920 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
9838 9921
9839 spec->vmaster_nid = 0x0c; 9922 spec->vmaster_nid = 0x0c;
9840 9923
9841 codec->patch_ops = alc_patch_ops; 9924 codec->patch_ops = alc_patch_ops;
9842 if (board_config == ALC883_AUTO) 9925 if (board_config == ALC882_AUTO)
9843 spec->init_hook = alc883_auto_init; 9926 spec->init_hook = alc882_auto_init;
9844
9845#ifdef CONFIG_SND_HDA_POWER_SAVE 9927#ifdef CONFIG_SND_HDA_POWER_SAVE
9846 if (!spec->loopback.amplist) 9928 if (!spec->loopback.amplist)
9847 spec->loopback.amplist = alc883_loopbacks; 9929 spec->loopback.amplist = alc882_loopbacks;
9848#endif 9930#endif
9849 codec->proc_widget_hook = print_realtek_coef; 9931 codec->proc_widget_hook = print_realtek_coef;
9850 9932
9851 return 0; 9933 return 0;
9852} 9934}
9853 9935
9936
9854/* 9937/*
9855 * ALC262 support 9938 * ALC262 support
9856 */ 9939 */
@@ -10026,13 +10109,12 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
10026}; 10109};
10027 10110
10028/* mute/unmute internal speaker according to the hp jack and mute state */ 10111/* mute/unmute internal speaker according to the hp jack and mute state */
10029static void alc262_hp_t5735_init_hook(struct hda_codec *codec) 10112static void alc262_hp_t5735_setup(struct hda_codec *codec)
10030{ 10113{
10031 struct alc_spec *spec = codec->spec; 10114 struct alc_spec *spec = codec->spec;
10032 10115
10033 spec->autocfg.hp_pins[0] = 0x15; 10116 spec->autocfg.hp_pins[0] = 0x15;
10034 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */ 10117 spec->autocfg.speaker_pins[0] = 0x0c; /* HACK: not actually a pin */
10035 alc_automute_amp(codec);
10036} 10118}
10037 10119
10038static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { 10120static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
@@ -10189,22 +10271,20 @@ static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res)
10189 alc262_hippo_automute(codec); 10271 alc262_hippo_automute(codec);
10190} 10272}
10191 10273
10192static void alc262_hippo_init_hook(struct hda_codec *codec) 10274static void alc262_hippo_setup(struct hda_codec *codec)
10193{ 10275{
10194 struct alc_spec *spec = codec->spec; 10276 struct alc_spec *spec = codec->spec;
10195 10277
10196 spec->autocfg.hp_pins[0] = 0x15; 10278 spec->autocfg.hp_pins[0] = 0x15;
10197 spec->autocfg.speaker_pins[0] = 0x14; 10279 spec->autocfg.speaker_pins[0] = 0x14;
10198 alc262_hippo_automute(codec);
10199} 10280}
10200 10281
10201static void alc262_hippo1_init_hook(struct hda_codec *codec) 10282static void alc262_hippo1_setup(struct hda_codec *codec)
10202{ 10283{
10203 struct alc_spec *spec = codec->spec; 10284 struct alc_spec *spec = codec->spec;
10204 10285
10205 spec->autocfg.hp_pins[0] = 0x1b; 10286 spec->autocfg.hp_pins[0] = 0x1b;
10206 spec->autocfg.speaker_pins[0] = 0x14; 10287 spec->autocfg.speaker_pins[0] = 0x14;
10207 alc262_hippo_automute(codec);
10208} 10288}
10209 10289
10210 10290
@@ -10261,13 +10341,12 @@ static struct hda_verb alc262_tyan_verbs[] = {
10261}; 10341};
10262 10342
10263/* unsolicited event for HP jack sensing */ 10343/* unsolicited event for HP jack sensing */
10264static void alc262_tyan_init_hook(struct hda_codec *codec) 10344static void alc262_tyan_setup(struct hda_codec *codec)
10265{ 10345{
10266 struct alc_spec *spec = codec->spec; 10346 struct alc_spec *spec = codec->spec;
10267 10347
10268 spec->autocfg.hp_pins[0] = 0x1b; 10348 spec->autocfg.hp_pins[0] = 0x1b;
10269 spec->autocfg.speaker_pins[0] = 0x15; 10349 spec->autocfg.speaker_pins[0] = 0x15;
10270 alc_automute_amp(codec);
10271} 10350}
10272 10351
10273 10352
@@ -10359,12 +10438,6 @@ static struct hda_verb alc262_eapd_verbs[] = {
10359 { } 10438 { }
10360}; 10439};
10361 10440
10362static struct hda_verb alc262_hippo_unsol_verbs[] = {
10363 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
10364 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
10365 {}
10366};
10367
10368static struct hda_verb alc262_hippo1_unsol_verbs[] = { 10441static struct hda_verb alc262_hippo1_unsol_verbs[] = {
10369 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, 10442 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
10370 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, 10443 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -10385,14 +10458,6 @@ static struct hda_verb alc262_sony_unsol_verbs[] = {
10385 {} 10458 {}
10386}; 10459};
10387 10460
10388static struct hda_input_mux alc262_dmic_capture_source = {
10389 .num_items = 2,
10390 .items = {
10391 { "Int DMic", 0x9 },
10392 { "Mic", 0x0 },
10393 },
10394};
10395
10396static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 10461static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
10397 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 10462 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
10398 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 10463 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
@@ -10414,35 +10479,17 @@ static struct hda_verb alc262_toshiba_s06_verbs[] = {
10414 {} 10479 {}
10415}; 10480};
10416 10481
10417static void alc262_dmic_automute(struct hda_codec *codec) 10482static void alc262_toshiba_s06_setup(struct hda_codec *codec)
10418{
10419 unsigned int present;
10420
10421 present = snd_hda_codec_read(codec, 0x18, 0,
10422 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
10423 snd_hda_codec_write(codec, 0x22, 0,
10424 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09);
10425}
10426
10427
10428/* unsolicited event for HP jack sensing */
10429static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec,
10430 unsigned int res)
10431{
10432 if ((res >> 26) == ALC880_MIC_EVENT)
10433 alc262_dmic_automute(codec);
10434 else
10435 alc_sku_unsol_event(codec, res);
10436}
10437
10438static void alc262_toshiba_s06_init_hook(struct hda_codec *codec)
10439{ 10483{
10440 struct alc_spec *spec = codec->spec; 10484 struct alc_spec *spec = codec->spec;
10441 10485
10442 spec->autocfg.hp_pins[0] = 0x15; 10486 spec->autocfg.hp_pins[0] = 0x15;
10443 spec->autocfg.speaker_pins[0] = 0x14; 10487 spec->autocfg.speaker_pins[0] = 0x14;
10444 alc_automute_pin(codec); 10488 spec->ext_mic.pin = 0x18;
10445 alc262_dmic_automute(codec); 10489 spec->ext_mic.mux_idx = 0;
10490 spec->int_mic.pin = 0x12;
10491 spec->int_mic.mux_idx = 9;
10492 spec->auto_mic = 1;
10446} 10493}
10447 10494
10448/* 10495/*
@@ -10860,104 +10907,111 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
10860 { } /* end */ 10907 { } /* end */
10861}; 10908};
10862 10909
10910/* We use two mixers depending on the output pin; 0x16 is a mono output
10911 * and thus it's bound with a different mixer.
10912 * This function returns which mixer amp should be used.
10913 */
10914static int alc262_check_volbit(hda_nid_t nid)
10915{
10916 if (!nid)
10917 return 0;
10918 else if (nid == 0x16)
10919 return 2;
10920 else
10921 return 1;
10922}
10923
10924static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
10925 const char *pfx, int *vbits)
10926{
10927 char name[32];
10928 unsigned long val;
10929 int vbit;
10930
10931 vbit = alc262_check_volbit(nid);
10932 if (!vbit)
10933 return 0;
10934 if (*vbits & vbit) /* a volume control for this mixer already there */
10935 return 0;
10936 *vbits |= vbit;
10937 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
10938 if (vbit == 2)
10939 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
10940 else
10941 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
10942 return add_control(spec, ALC_CTL_WIDGET_VOL, name, val);
10943}
10944
10945static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
10946 const char *pfx)
10947{
10948 char name[32];
10949 unsigned long val;
10950
10951 if (!nid)
10952 return 0;
10953 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
10954 if (nid == 0x16)
10955 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
10956 else
10957 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
10958 return add_control(spec, ALC_CTL_WIDGET_MUTE, name, val);
10959}
10960
10863/* add playback controls from the parsed DAC table */ 10961/* add playback controls from the parsed DAC table */
10864static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, 10962static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
10865 const struct auto_pin_cfg *cfg) 10963 const struct auto_pin_cfg *cfg)
10866{ 10964{
10867 hda_nid_t nid; 10965 const char *pfx;
10966 int vbits;
10868 int err; 10967 int err;
10869 10968
10870 spec->multiout.num_dacs = 1; /* only use one dac */ 10969 spec->multiout.num_dacs = 1; /* only use one dac */
10871 spec->multiout.dac_nids = spec->private_dac_nids; 10970 spec->multiout.dac_nids = spec->private_dac_nids;
10872 spec->multiout.dac_nids[0] = 2; 10971 spec->multiout.dac_nids[0] = 2;
10873 10972
10874 nid = cfg->line_out_pins[0]; 10973 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
10875 if (nid) { 10974 pfx = "Master";
10876 err = add_control(spec, ALC_CTL_WIDGET_VOL, 10975 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10877 "Front Playback Volume", 10976 pfx = "Speaker";
10878 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); 10977 else
10879 if (err < 0) 10978 pfx = "Front";
10880 return err; 10979 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[0], pfx);
10881 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 10980 if (err < 0)
10882 "Front Playback Switch", 10981 return err;
10883 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 10982 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[0], "Speaker");
10884 if (err < 0) 10983 if (err < 0)
10885 return err; 10984 return err;
10886 } 10985 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[0], "Headphone");
10887 10986 if (err < 0)
10888 nid = cfg->speaker_pins[0]; 10987 return err;
10889 if (nid) {
10890 if (nid == 0x16) {
10891 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10892 "Speaker Playback Volume",
10893 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10894 HDA_OUTPUT));
10895 if (err < 0)
10896 return err;
10897 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10898 "Speaker Playback Switch",
10899 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10900 HDA_OUTPUT));
10901 if (err < 0)
10902 return err;
10903 } else {
10904 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10905 "Speaker Playback Switch",
10906 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10907 HDA_OUTPUT));
10908 if (err < 0)
10909 return err;
10910 }
10911 }
10912 nid = cfg->hp_pins[0];
10913 if (nid) {
10914 /* spec->multiout.hp_nid = 2; */
10915 if (nid == 0x16) {
10916 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10917 "Headphone Playback Volume",
10918 HDA_COMPOSE_AMP_VAL(0x0e, 2, 0,
10919 HDA_OUTPUT));
10920 if (err < 0)
10921 return err;
10922 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10923 "Headphone Playback Switch",
10924 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
10925 HDA_OUTPUT));
10926 if (err < 0)
10927 return err;
10928 } else {
10929 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
10930 "Headphone Playback Switch",
10931 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
10932 HDA_OUTPUT));
10933 if (err < 0)
10934 return err;
10935 }
10936 }
10937 return 0;
10938}
10939
10940static int alc262_auto_create_analog_input_ctls(struct alc_spec *spec,
10941 const struct auto_pin_cfg *cfg)
10942{
10943 int err;
10944 10988
10945 err = alc880_auto_create_analog_input_ctls(spec, cfg); 10989 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
10990 alc262_check_volbit(cfg->speaker_pins[0]) |
10991 alc262_check_volbit(cfg->hp_pins[0]);
10992 if (vbits == 1 || vbits == 2)
10993 pfx = "Master"; /* only one mixer is used */
10994 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
10995 pfx = "Speaker";
10996 else
10997 pfx = "Front";
10998 vbits = 0;
10999 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[0], pfx, &vbits);
11000 if (err < 0)
11001 return err;
11002 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[0], "Speaker",
11003 &vbits);
11004 if (err < 0)
11005 return err;
11006 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[0], "Headphone",
11007 &vbits);
10946 if (err < 0) 11008 if (err < 0)
10947 return err; 11009 return err;
10948 /* digital-mic input pin is excluded in alc880_auto_create..()
10949 * because it's under 0x18
10950 */
10951 if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 ||
10952 cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) {
10953 struct hda_input_mux *imux = &spec->private_imux[0];
10954 imux->items[imux->num_items].label = "Int Mic";
10955 imux->items[imux->num_items].index = 0x09;
10956 imux->num_items++;
10957 }
10958 return 0; 11010 return 0;
10959} 11011}
10960 11012
11013#define alc262_auto_create_input_ctls \
11014 alc880_auto_create_input_ctls
10961 11015
10962/* 11016/*
10963 * generic initialization of ADC, input mixers and output mixers 11017 * generic initialization of ADC, input mixers and output mixers
@@ -11275,7 +11329,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11275 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 11329 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
11276 if (err < 0) 11330 if (err < 0)
11277 return err; 11331 return err;
11278 err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); 11332 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
11279 if (err < 0) 11333 if (err < 0)
11280 return err; 11334 return err;
11281 11335
@@ -11406,7 +11460,7 @@ static struct alc_config_preset alc262_presets[] = {
11406 }, 11460 },
11407 [ALC262_HIPPO] = { 11461 [ALC262_HIPPO] = {
11408 .mixers = { alc262_hippo_mixer }, 11462 .mixers = { alc262_hippo_mixer },
11409 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs}, 11463 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
11410 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11464 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11411 .dac_nids = alc262_dac_nids, 11465 .dac_nids = alc262_dac_nids,
11412 .hp_nid = 0x03, 11466 .hp_nid = 0x03,
@@ -11415,7 +11469,8 @@ static struct alc_config_preset alc262_presets[] = {
11415 .channel_mode = alc262_modes, 11469 .channel_mode = alc262_modes,
11416 .input_mux = &alc262_capture_source, 11470 .input_mux = &alc262_capture_source,
11417 .unsol_event = alc262_hippo_unsol_event, 11471 .unsol_event = alc262_hippo_unsol_event,
11418 .init_hook = alc262_hippo_init_hook, 11472 .setup = alc262_hippo_setup,
11473 .init_hook = alc262_hippo_automute,
11419 }, 11474 },
11420 [ALC262_HIPPO_1] = { 11475 [ALC262_HIPPO_1] = {
11421 .mixers = { alc262_hippo1_mixer }, 11476 .mixers = { alc262_hippo1_mixer },
@@ -11428,7 +11483,8 @@ static struct alc_config_preset alc262_presets[] = {
11428 .channel_mode = alc262_modes, 11483 .channel_mode = alc262_modes,
11429 .input_mux = &alc262_capture_source, 11484 .input_mux = &alc262_capture_source,
11430 .unsol_event = alc262_hippo_unsol_event, 11485 .unsol_event = alc262_hippo_unsol_event,
11431 .init_hook = alc262_hippo1_init_hook, 11486 .setup = alc262_hippo1_setup,
11487 .init_hook = alc262_hippo_automute,
11432 }, 11488 },
11433 [ALC262_FUJITSU] = { 11489 [ALC262_FUJITSU] = {
11434 .mixers = { alc262_fujitsu_mixer }, 11490 .mixers = { alc262_fujitsu_mixer },
@@ -11491,7 +11547,8 @@ static struct alc_config_preset alc262_presets[] = {
11491 .channel_mode = alc262_modes, 11547 .channel_mode = alc262_modes,
11492 .input_mux = &alc262_capture_source, 11548 .input_mux = &alc262_capture_source,
11493 .unsol_event = alc_automute_amp_unsol_event, 11549 .unsol_event = alc_automute_amp_unsol_event,
11494 .init_hook = alc262_hp_t5735_init_hook, 11550 .setup = alc262_hp_t5735_setup,
11551 .init_hook = alc_automute_amp,
11495 }, 11552 },
11496 [ALC262_HP_RP5700] = { 11553 [ALC262_HP_RP5700] = {
11497 .mixers = { alc262_hp_rp5700_mixer }, 11554 .mixers = { alc262_hp_rp5700_mixer },
@@ -11522,11 +11579,13 @@ static struct alc_config_preset alc262_presets[] = {
11522 .channel_mode = alc262_modes, 11579 .channel_mode = alc262_modes,
11523 .input_mux = &alc262_capture_source, 11580 .input_mux = &alc262_capture_source,
11524 .unsol_event = alc262_hippo_unsol_event, 11581 .unsol_event = alc262_hippo_unsol_event,
11525 .init_hook = alc262_hippo_init_hook, 11582 .setup = alc262_hippo_setup,
11583 .init_hook = alc262_hippo_automute,
11526 }, 11584 },
11527 [ALC262_BENQ_T31] = { 11585 [ALC262_BENQ_T31] = {
11528 .mixers = { alc262_benq_t31_mixer }, 11586 .mixers = { alc262_benq_t31_mixer },
11529 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, alc262_hippo_unsol_verbs }, 11587 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
11588 alc_hp15_unsol_verbs },
11530 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 11589 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
11531 .dac_nids = alc262_dac_nids, 11590 .dac_nids = alc262_dac_nids,
11532 .hp_nid = 0x03, 11591 .hp_nid = 0x03,
@@ -11534,7 +11593,8 @@ static struct alc_config_preset alc262_presets[] = {
11534 .channel_mode = alc262_modes, 11593 .channel_mode = alc262_modes,
11535 .input_mux = &alc262_capture_source, 11594 .input_mux = &alc262_capture_source,
11536 .unsol_event = alc262_hippo_unsol_event, 11595 .unsol_event = alc262_hippo_unsol_event,
11537 .init_hook = alc262_hippo_init_hook, 11596 .setup = alc262_hippo_setup,
11597 .init_hook = alc262_hippo_automute,
11538 }, 11598 },
11539 [ALC262_ULTRA] = { 11599 [ALC262_ULTRA] = {
11540 .mixers = { alc262_ultra_mixer }, 11600 .mixers = { alc262_ultra_mixer },
@@ -11586,9 +11646,9 @@ static struct alc_config_preset alc262_presets[] = {
11586 .dig_out_nid = ALC262_DIGOUT_NID, 11646 .dig_out_nid = ALC262_DIGOUT_NID,
11587 .num_channel_mode = ARRAY_SIZE(alc262_modes), 11647 .num_channel_mode = ARRAY_SIZE(alc262_modes),
11588 .channel_mode = alc262_modes, 11648 .channel_mode = alc262_modes,
11589 .input_mux = &alc262_dmic_capture_source, 11649 .unsol_event = alc_sku_unsol_event,
11590 .unsol_event = alc262_toshiba_s06_unsol_event, 11650 .setup = alc262_toshiba_s06_setup,
11591 .init_hook = alc262_toshiba_s06_init_hook, 11651 .init_hook = alc_inithook,
11592 }, 11652 },
11593 [ALC262_TOSHIBA_RX1] = { 11653 [ALC262_TOSHIBA_RX1] = {
11594 .mixers = { alc262_toshiba_rx1_mixer }, 11654 .mixers = { alc262_toshiba_rx1_mixer },
@@ -11600,7 +11660,8 @@ static struct alc_config_preset alc262_presets[] = {
11600 .channel_mode = alc262_modes, 11660 .channel_mode = alc262_modes,
11601 .input_mux = &alc262_capture_source, 11661 .input_mux = &alc262_capture_source,
11602 .unsol_event = alc262_hippo_unsol_event, 11662 .unsol_event = alc262_hippo_unsol_event,
11603 .init_hook = alc262_hippo_init_hook, 11663 .setup = alc262_hippo_setup,
11664 .init_hook = alc262_hippo_automute,
11604 }, 11665 },
11605 [ALC262_TYAN] = { 11666 [ALC262_TYAN] = {
11606 .mixers = { alc262_tyan_mixer }, 11667 .mixers = { alc262_tyan_mixer },
@@ -11613,7 +11674,8 @@ static struct alc_config_preset alc262_presets[] = {
11613 .channel_mode = alc262_modes, 11674 .channel_mode = alc262_modes,
11614 .input_mux = &alc262_capture_source, 11675 .input_mux = &alc262_capture_source,
11615 .unsol_event = alc_automute_amp_unsol_event, 11676 .unsol_event = alc_automute_amp_unsol_event,
11616 .init_hook = alc262_tyan_init_hook, 11677 .setup = alc262_tyan_setup,
11678 .init_hook = alc_automute_amp,
11617 }, 11679 },
11618}; 11680};
11619 11681
@@ -11648,8 +11710,8 @@ static int patch_alc262(struct hda_codec *codec)
11648 alc262_cfg_tbl); 11710 alc262_cfg_tbl);
11649 11711
11650 if (board_config < 0) { 11712 if (board_config < 0) {
11651 printk(KERN_INFO "hda_codec: Unknown model for %s, " 11713 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11652 "trying auto-probe from BIOS...\n", codec->chip_name); 11714 codec->chip_name);
11653 board_config = ALC262_AUTO; 11715 board_config = ALC262_AUTO;
11654 } 11716 }
11655 11717
@@ -11676,7 +11738,7 @@ static int patch_alc262(struct hda_codec *codec)
11676 } 11738 }
11677 11739
11678 if (board_config != ALC262_AUTO) 11740 if (board_config != ALC262_AUTO)
11679 setup_preset(spec, &alc262_presets[board_config]); 11741 setup_preset(codec, &alc262_presets[board_config]);
11680 11742
11681 spec->stream_analog_playback = &alc262_pcm_analog_playback; 11743 spec->stream_analog_playback = &alc262_pcm_analog_playback;
11682 spec->stream_analog_capture = &alc262_pcm_analog_capture; 11744 spec->stream_analog_capture = &alc262_pcm_analog_capture;
@@ -11702,7 +11764,7 @@ static int patch_alc262(struct hda_codec *codec)
11702 unsigned int wcap = get_wcaps(codec, 0x07); 11764 unsigned int wcap = get_wcaps(codec, 0x07);
11703 11765
11704 /* get type */ 11766 /* get type */
11705 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 11767 wcap = get_wcaps_type(wcap);
11706 if (wcap != AC_WID_AUD_IN) { 11768 if (wcap != AC_WID_AUD_IN) {
11707 spec->adc_nids = alc262_adc_nids_alt; 11769 spec->adc_nids = alc262_adc_nids_alt;
11708 spec->num_adc_nids = 11770 spec->num_adc_nids =
@@ -11717,7 +11779,7 @@ static int patch_alc262(struct hda_codec *codec)
11717 } 11779 }
11718 } 11780 }
11719 if (!spec->cap_mixer && !spec->no_analog) 11781 if (!spec->cap_mixer && !spec->no_analog)
11720 set_capture_mixer(spec); 11782 set_capture_mixer(codec);
11721 if (!spec->no_analog) 11783 if (!spec->no_analog)
11722 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11784 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11723 11785
@@ -11809,14 +11871,6 @@ static struct hda_verb alc268_toshiba_verbs[] = {
11809 { } /* end */ 11871 { } /* end */
11810}; 11872};
11811 11873
11812static struct hda_input_mux alc268_acer_lc_capture_source = {
11813 .num_items = 2,
11814 .items = {
11815 { "i-Mic", 0x6 },
11816 { "E-Mic", 0x0 },
11817 },
11818};
11819
11820/* Acer specific */ 11874/* Acer specific */
11821/* bind volumes of both NID 0x02 and 0x03 */ 11875/* bind volumes of both NID 0x02 and 0x03 */
11822static struct hda_bind_ctls alc268_acer_bind_master_vol = { 11876static struct hda_bind_ctls alc268_acer_bind_master_vol = {
@@ -11935,7 +11989,8 @@ static struct hda_verb alc268_acer_verbs[] = {
11935 11989
11936/* unsolicited event for HP jack sensing */ 11990/* unsolicited event for HP jack sensing */
11937#define alc268_toshiba_unsol_event alc262_hippo_unsol_event 11991#define alc268_toshiba_unsol_event alc262_hippo_unsol_event
11938#define alc268_toshiba_init_hook alc262_hippo_init_hook 11992#define alc268_toshiba_setup alc262_hippo_setup
11993#define alc268_toshiba_automute alc262_hippo_automute
11939 11994
11940static void alc268_acer_unsol_event(struct hda_codec *codec, 11995static void alc268_acer_unsol_event(struct hda_codec *codec,
11941 unsigned int res) 11996 unsigned int res)
@@ -11965,30 +12020,33 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec)
11965 AMP_IN_MUTE(0), bits); 12020 AMP_IN_MUTE(0), bits);
11966} 12021}
11967 12022
11968
11969static void alc268_acer_mic_automute(struct hda_codec *codec)
11970{
11971 unsigned int present;
11972
11973 present = snd_hda_codec_read(codec, 0x18, 0,
11974 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
11975 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL,
11976 present ? 0x0 : 0x6);
11977}
11978
11979static void alc268_acer_lc_unsol_event(struct hda_codec *codec, 12023static void alc268_acer_lc_unsol_event(struct hda_codec *codec,
11980 unsigned int res) 12024 unsigned int res)
11981{ 12025{
11982 if ((res >> 26) == ALC880_HP_EVENT) 12026 switch (res >> 26) {
12027 case ALC880_HP_EVENT:
11983 alc268_aspire_one_speaker_automute(codec); 12028 alc268_aspire_one_speaker_automute(codec);
11984 if ((res >> 26) == ALC880_MIC_EVENT) 12029 break;
11985 alc268_acer_mic_automute(codec); 12030 case ALC880_MIC_EVENT:
12031 alc_mic_automute(codec);
12032 break;
12033 }
12034}
12035
12036static void alc268_acer_lc_setup(struct hda_codec *codec)
12037{
12038 struct alc_spec *spec = codec->spec;
12039 spec->ext_mic.pin = 0x18;
12040 spec->ext_mic.mux_idx = 0;
12041 spec->int_mic.pin = 0x12;
12042 spec->int_mic.mux_idx = 6;
12043 spec->auto_mic = 1;
11986} 12044}
11987 12045
11988static void alc268_acer_lc_init_hook(struct hda_codec *codec) 12046static void alc268_acer_lc_init_hook(struct hda_codec *codec)
11989{ 12047{
11990 alc268_aspire_one_speaker_automute(codec); 12048 alc268_aspire_one_speaker_automute(codec);
11991 alc268_acer_mic_automute(codec); 12049 alc_mic_automute(codec);
11992} 12050}
11993 12051
11994static struct snd_kcontrol_new alc268_dell_mixer[] = { 12052static struct snd_kcontrol_new alc268_dell_mixer[] = {
@@ -12006,17 +12064,22 @@ static struct hda_verb alc268_dell_verbs[] = {
12006 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12064 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 12065 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12008 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, 12066 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12067 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12009 { } 12068 { }
12010}; 12069};
12011 12070
12012/* mute/unmute internal speaker according to the hp jack and mute state */ 12071/* mute/unmute internal speaker according to the hp jack and mute state */
12013static void alc268_dell_init_hook(struct hda_codec *codec) 12072static void alc268_dell_setup(struct hda_codec *codec)
12014{ 12073{
12015 struct alc_spec *spec = codec->spec; 12074 struct alc_spec *spec = codec->spec;
12016 12075
12017 spec->autocfg.hp_pins[0] = 0x15; 12076 spec->autocfg.hp_pins[0] = 0x15;
12018 spec->autocfg.speaker_pins[0] = 0x14; 12077 spec->autocfg.speaker_pins[0] = 0x14;
12019 alc_automute_pin(codec); 12078 spec->ext_mic.pin = 0x18;
12079 spec->ext_mic.mux_idx = 0;
12080 spec->int_mic.pin = 0x19;
12081 spec->int_mic.mux_idx = 1;
12082 spec->auto_mic = 1;
12020} 12083}
12021 12084
12022static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { 12085static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
@@ -12037,38 +12100,16 @@ static struct hda_verb alc267_quanta_il1_verbs[] = {
12037 { } 12100 { }
12038}; 12101};
12039 12102
12040static void alc267_quanta_il1_mic_automute(struct hda_codec *codec) 12103static void alc267_quanta_il1_setup(struct hda_codec *codec)
12041{
12042 unsigned int present;
12043
12044 present = snd_hda_codec_read(codec, 0x18, 0,
12045 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12046 snd_hda_codec_write(codec, 0x23, 0,
12047 AC_VERB_SET_CONNECT_SEL,
12048 present ? 0x00 : 0x01);
12049}
12050
12051static void alc267_quanta_il1_init_hook(struct hda_codec *codec)
12052{ 12104{
12053 struct alc_spec *spec = codec->spec; 12105 struct alc_spec *spec = codec->spec;
12054
12055 spec->autocfg.hp_pins[0] = 0x15; 12106 spec->autocfg.hp_pins[0] = 0x15;
12056 spec->autocfg.speaker_pins[0] = 0x14; 12107 spec->autocfg.speaker_pins[0] = 0x14;
12057 alc_automute_pin(codec); 12108 spec->ext_mic.pin = 0x18;
12058 alc267_quanta_il1_mic_automute(codec); 12109 spec->ext_mic.mux_idx = 0;
12059} 12110 spec->int_mic.pin = 0x19;
12060 12111 spec->int_mic.mux_idx = 1;
12061static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, 12112 spec->auto_mic = 1;
12062 unsigned int res)
12063{
12064 switch (res >> 26) {
12065 case ALC880_MIC_EVENT:
12066 alc267_quanta_il1_mic_automute(codec);
12067 break;
12068 default:
12069 alc_sku_unsol_event(codec, res);
12070 break;
12071 }
12072} 12113}
12073 12114
12074/* 12115/*
@@ -12148,21 +12189,16 @@ static struct hda_verb alc268_volume_init_verbs[] = {
12148 { } 12189 { }
12149}; 12190};
12150 12191
12192static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
12193 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12194 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12195 { } /* end */
12196};
12197
12151static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 12198static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
12152 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 12199 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12153 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 12200 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12154 { 12201 _DEFINE_CAPSRC(1),
12155 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12156 /* The multiple "Capture Source" controls confuse alsamixer
12157 * So call somewhat different..
12158 */
12159 /* .name = "Capture Source", */
12160 .name = "Input Source",
12161 .count = 1,
12162 .info = alc_mux_enum_info,
12163 .get = alc_mux_enum_get,
12164 .put = alc_mux_enum_put,
12165 },
12166 { } /* end */ 12202 { } /* end */
12167}; 12203};
12168 12204
@@ -12171,18 +12207,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
12171 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 12207 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
12172 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), 12208 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
12173 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), 12209 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
12174 { 12210 _DEFINE_CAPSRC(2),
12175 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12176 /* The multiple "Capture Source" controls confuse alsamixer
12177 * So call somewhat different..
12178 */
12179 /* .name = "Capture Source", */
12180 .name = "Input Source",
12181 .count = 2,
12182 .info = alc_mux_enum_info,
12183 .get = alc_mux_enum_get,
12184 .put = alc_mux_enum_put,
12185 },
12186 { } /* end */ 12211 { } /* end */
12187}; 12212};
12188 12213
@@ -12269,26 +12294,38 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12269 const char *ctlname, int idx) 12294 const char *ctlname, int idx)
12270{ 12295{
12271 char name[32]; 12296 char name[32];
12297 hda_nid_t dac;
12272 int err; 12298 int err;
12273 12299
12274 sprintf(name, "%s Playback Volume", ctlname); 12300 sprintf(name, "%s Playback Volume", ctlname);
12275 if (nid == 0x14) { 12301 switch (nid) {
12276 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12302 case 0x14:
12277 HDA_COMPOSE_AMP_VAL(0x02, 3, idx, 12303 case 0x16:
12278 HDA_OUTPUT)); 12304 dac = 0x02;
12279 if (err < 0) 12305 break;
12280 return err; 12306 case 0x15:
12281 } else if (nid == 0x15) { 12307 dac = 0x03;
12308 break;
12309 default:
12310 return 0;
12311 }
12312 if (spec->multiout.dac_nids[0] != dac &&
12313 spec->multiout.dac_nids[1] != dac) {
12282 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 12314 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
12283 HDA_COMPOSE_AMP_VAL(0x03, 3, idx, 12315 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
12284 HDA_OUTPUT)); 12316 HDA_OUTPUT));
12285 if (err < 0) 12317 if (err < 0)
12286 return err; 12318 return err;
12287 } else 12319 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
12288 return -1; 12320 }
12321
12289 sprintf(name, "%s Playback Switch", ctlname); 12322 sprintf(name, "%s Playback Switch", ctlname);
12290 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 12323 if (nid != 0x16)
12324 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12291 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT)); 12325 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
12326 else /* mono */
12327 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
12328 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
12292 if (err < 0) 12329 if (err < 0)
12293 return err; 12330 return err;
12294 return 0; 12331 return 0;
@@ -12301,14 +12338,19 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12301 hda_nid_t nid; 12338 hda_nid_t nid;
12302 int err; 12339 int err;
12303 12340
12304 spec->multiout.num_dacs = 2; /* only use one dac */
12305 spec->multiout.dac_nids = spec->private_dac_nids; 12341 spec->multiout.dac_nids = spec->private_dac_nids;
12306 spec->multiout.dac_nids[0] = 2;
12307 spec->multiout.dac_nids[1] = 3;
12308 12342
12309 nid = cfg->line_out_pins[0]; 12343 nid = cfg->line_out_pins[0];
12310 if (nid) 12344 if (nid) {
12311 alc268_new_analog_output(spec, nid, "Front", 0); 12345 const char *name;
12346 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12347 name = "Speaker";
12348 else
12349 name = "Front";
12350 err = alc268_new_analog_output(spec, nid, name, 0);
12351 if (err < 0)
12352 return err;
12353 }
12312 12354
12313 nid = cfg->speaker_pins[0]; 12355 nid = cfg->speaker_pins[0];
12314 if (nid == 0x1d) { 12356 if (nid == 0x1d) {
@@ -12317,16 +12359,23 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12317 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 12359 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
12318 if (err < 0) 12360 if (err < 0)
12319 return err; 12361 return err;
12362 } else {
12363 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
12364 if (err < 0)
12365 return err;
12320 } 12366 }
12321 nid = cfg->hp_pins[0]; 12367 nid = cfg->hp_pins[0];
12322 if (nid) 12368 if (nid) {
12323 alc268_new_analog_output(spec, nid, "Headphone", 0); 12369 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
12370 if (err < 0)
12371 return err;
12372 }
12324 12373
12325 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2]; 12374 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
12326 if (nid == 0x16) { 12375 if (nid == 0x16) {
12327 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 12376 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
12328 "Mono Playback Switch", 12377 "Mono Playback Switch",
12329 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_INPUT)); 12378 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
12330 if (err < 0) 12379 if (err < 0)
12331 return err; 12380 return err;
12332 } 12381 }
@@ -12334,38 +12383,46 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
12334} 12383}
12335 12384
12336/* create playback/capture controls for input pins */ 12385/* create playback/capture controls for input pins */
12337static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, 12386static int alc268_auto_create_input_ctls(struct hda_codec *codec,
12338 const struct auto_pin_cfg *cfg) 12387 const struct auto_pin_cfg *cfg)
12339{ 12388{
12340 struct hda_input_mux *imux = &spec->private_imux[0]; 12389 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
12341 int i, idx1; 12390}
12342 12391
12343 for (i = 0; i < AUTO_PIN_LAST; i++) { 12392static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
12344 switch(cfg->input_pins[i]) { 12393 hda_nid_t nid, int pin_type)
12345 case 0x18: 12394{
12346 idx1 = 0; /* Mic 1 */ 12395 int idx;
12347 break; 12396
12348 case 0x19: 12397 alc_set_pin_output(codec, nid, pin_type);
12349 idx1 = 1; /* Mic 2 */ 12398 if (nid == 0x14 || nid == 0x16)
12350 break; 12399 idx = 0;
12351 case 0x1a: 12400 else
12352 idx1 = 2; /* Line In */ 12401 idx = 1;
12353 break; 12402 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
12354 case 0x1c: 12403}
12355 idx1 = 3; /* CD */ 12404
12356 break; 12405static void alc268_auto_init_multi_out(struct hda_codec *codec)
12357 case 0x12: 12406{
12358 case 0x13: 12407 struct alc_spec *spec = codec->spec;
12359 idx1 = 6; /* digital mics */ 12408 hda_nid_t nid = spec->autocfg.line_out_pins[0];
12360 break; 12409 if (nid) {
12361 default: 12410 int pin_type = get_pin_type(spec->autocfg.line_out_type);
12362 continue; 12411 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
12363 }
12364 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
12365 imux->items[imux->num_items].index = idx1;
12366 imux->num_items++;
12367 } 12412 }
12368 return 0; 12413}
12414
12415static void alc268_auto_init_hp_out(struct hda_codec *codec)
12416{
12417 struct alc_spec *spec = codec->spec;
12418 hda_nid_t pin;
12419
12420 pin = spec->autocfg.hp_pins[0];
12421 if (pin)
12422 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
12423 pin = spec->autocfg.speaker_pins[0];
12424 if (pin)
12425 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
12369} 12426}
12370 12427
12371static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) 12428static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
@@ -12376,9 +12433,10 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12376 hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; 12433 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
12377 unsigned int dac_vol1, dac_vol2; 12434 unsigned int dac_vol1, dac_vol2;
12378 12435
12379 if (speaker_nid) { 12436 if (line_nid == 0x1d || speaker_nid == 0x1d) {
12380 snd_hda_codec_write(codec, speaker_nid, 0, 12437 snd_hda_codec_write(codec, speaker_nid, 0,
12381 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 12438 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
12439 /* mute mixer inputs from 0x1d */
12382 snd_hda_codec_write(codec, 0x0f, 0, 12440 snd_hda_codec_write(codec, 0x0f, 0,
12383 AC_VERB_SET_AMP_GAIN_MUTE, 12441 AC_VERB_SET_AMP_GAIN_MUTE,
12384 AMP_IN_UNMUTE(1)); 12442 AMP_IN_UNMUTE(1));
@@ -12386,6 +12444,7 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
12386 AC_VERB_SET_AMP_GAIN_MUTE, 12444 AC_VERB_SET_AMP_GAIN_MUTE,
12387 AMP_IN_UNMUTE(1)); 12445 AMP_IN_UNMUTE(1));
12388 } else { 12446 } else {
12447 /* unmute mixer inputs from 0x1d */
12389 snd_hda_codec_write(codec, 0x0f, 0, 12448 snd_hda_codec_write(codec, 0x0f, 0,
12390 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)); 12449 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
12391 snd_hda_codec_write(codec, 0x10, 0, 12450 snd_hda_codec_write(codec, 0x10, 0,
@@ -12442,7 +12501,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12442 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); 12501 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
12443 if (err < 0) 12502 if (err < 0)
12444 return err; 12503 return err;
12445 err = alc268_auto_create_analog_input_ctls(spec, &spec->autocfg); 12504 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
12446 if (err < 0) 12505 if (err < 0)
12447 return err; 12506 return err;
12448 12507
@@ -12461,7 +12520,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12461 add_mixer(spec, alc268_beep_mixer); 12520 add_mixer(spec, alc268_beep_mixer);
12462 12521
12463 add_verb(spec, alc268_volume_init_verbs); 12522 add_verb(spec, alc268_volume_init_verbs);
12464 spec->num_mux_defs = 1; 12523 spec->num_mux_defs = 2;
12465 spec->input_mux = &spec->private_imux[0]; 12524 spec->input_mux = &spec->private_imux[0];
12466 12525
12467 err = alc_auto_add_mic_boost(codec); 12526 err = alc_auto_add_mic_boost(codec);
@@ -12473,8 +12532,6 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12473 return 1; 12532 return 1;
12474} 12533}
12475 12534
12476#define alc268_auto_init_multi_out alc882_auto_init_multi_out
12477#define alc268_auto_init_hp_out alc882_auto_init_hp_out
12478#define alc268_auto_init_analog_input alc882_auto_init_analog_input 12535#define alc268_auto_init_analog_input alc882_auto_init_analog_input
12479 12536
12480/* init callback for auto-configuration model -- overriding the default init */ 12537/* init callback for auto-configuration model -- overriding the default init */
@@ -12517,8 +12574,11 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
12517 ALC268_ACER_ASPIRE_ONE), 12574 ALC268_ACER_ASPIRE_ONE),
12518 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), 12575 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
12519 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL), 12576 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
12577 /* almost compatible with toshiba but with optional digital outs;
12578 * auto-probing seems working fine
12579 */
12520 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", 12580 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
12521 ALC268_TOSHIBA), 12581 ALC268_AUTO),
12522 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), 12582 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
12523 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), 12583 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
12524 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), 12584 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
@@ -12539,7 +12599,8 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
12539 12599
12540static struct alc_config_preset alc268_presets[] = { 12600static struct alc_config_preset alc268_presets[] = {
12541 [ALC267_QUANTA_IL1] = { 12601 [ALC267_QUANTA_IL1] = {
12542 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, 12602 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
12603 alc268_capture_nosrc_mixer },
12543 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12604 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12544 alc267_quanta_il1_verbs }, 12605 alc267_quanta_il1_verbs },
12545 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12606 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -12549,9 +12610,9 @@ static struct alc_config_preset alc268_presets[] = {
12549 .hp_nid = 0x03, 12610 .hp_nid = 0x03,
12550 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12611 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12551 .channel_mode = alc268_modes, 12612 .channel_mode = alc268_modes,
12552 .input_mux = &alc268_capture_source, 12613 .unsol_event = alc_sku_unsol_event,
12553 .unsol_event = alc267_quanta_il1_unsol_event, 12614 .setup = alc267_quanta_il1_setup,
12554 .init_hook = alc267_quanta_il1_init_hook, 12615 .init_hook = alc_inithook,
12555 }, 12616 },
12556 [ALC268_3ST] = { 12617 [ALC268_3ST] = {
12557 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12618 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
@@ -12583,10 +12644,11 @@ static struct alc_config_preset alc268_presets[] = {
12583 .channel_mode = alc268_modes, 12644 .channel_mode = alc268_modes,
12584 .input_mux = &alc268_capture_source, 12645 .input_mux = &alc268_capture_source,
12585 .unsol_event = alc268_toshiba_unsol_event, 12646 .unsol_event = alc268_toshiba_unsol_event,
12586 .init_hook = alc268_toshiba_init_hook, 12647 .setup = alc268_toshiba_setup,
12648 .init_hook = alc268_toshiba_automute,
12587 }, 12649 },
12588 [ALC268_ACER] = { 12650 [ALC268_ACER] = {
12589 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, 12651 .mixers = { alc268_acer_mixer, alc268_capture_nosrc_mixer,
12590 alc268_beep_mixer }, 12652 alc268_beep_mixer },
12591 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12653 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12592 alc268_acer_verbs }, 12654 alc268_acer_verbs },
@@ -12622,7 +12684,7 @@ static struct alc_config_preset alc268_presets[] = {
12622 [ALC268_ACER_ASPIRE_ONE] = { 12684 [ALC268_ACER_ASPIRE_ONE] = {
12623 .mixers = { alc268_acer_aspire_one_mixer, 12685 .mixers = { alc268_acer_aspire_one_mixer,
12624 alc268_beep_mixer, 12686 alc268_beep_mixer,
12625 alc268_capture_alt_mixer }, 12687 alc268_capture_nosrc_mixer },
12626 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12688 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12627 alc268_acer_aspire_one_verbs }, 12689 alc268_acer_aspire_one_verbs },
12628 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12690 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
@@ -12633,22 +12695,26 @@ static struct alc_config_preset alc268_presets[] = {
12633 .hp_nid = 0x03, 12695 .hp_nid = 0x03,
12634 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12696 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12635 .channel_mode = alc268_modes, 12697 .channel_mode = alc268_modes,
12636 .input_mux = &alc268_acer_lc_capture_source,
12637 .unsol_event = alc268_acer_lc_unsol_event, 12698 .unsol_event = alc268_acer_lc_unsol_event,
12699 .setup = alc268_acer_lc_setup,
12638 .init_hook = alc268_acer_lc_init_hook, 12700 .init_hook = alc268_acer_lc_init_hook,
12639 }, 12701 },
12640 [ALC268_DELL] = { 12702 [ALC268_DELL] = {
12641 .mixers = { alc268_dell_mixer, alc268_beep_mixer }, 12703 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
12704 alc268_capture_nosrc_mixer },
12642 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, 12705 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
12643 alc268_dell_verbs }, 12706 alc268_dell_verbs },
12644 .num_dacs = ARRAY_SIZE(alc268_dac_nids), 12707 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
12645 .dac_nids = alc268_dac_nids, 12708 .dac_nids = alc268_dac_nids,
12709 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
12710 .adc_nids = alc268_adc_nids_alt,
12711 .capsrc_nids = alc268_capsrc_nids,
12646 .hp_nid = 0x02, 12712 .hp_nid = 0x02,
12647 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12713 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12648 .channel_mode = alc268_modes, 12714 .channel_mode = alc268_modes,
12649 .unsol_event = alc_sku_unsol_event, 12715 .unsol_event = alc_sku_unsol_event,
12650 .init_hook = alc268_dell_init_hook, 12716 .setup = alc268_dell_setup,
12651 .input_mux = &alc268_capture_source, 12717 .init_hook = alc_inithook,
12652 }, 12718 },
12653 [ALC268_ZEPTO] = { 12719 [ALC268_ZEPTO] = {
12654 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer, 12720 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
@@ -12665,8 +12731,8 @@ static struct alc_config_preset alc268_presets[] = {
12665 .num_channel_mode = ARRAY_SIZE(alc268_modes), 12731 .num_channel_mode = ARRAY_SIZE(alc268_modes),
12666 .channel_mode = alc268_modes, 12732 .channel_mode = alc268_modes,
12667 .input_mux = &alc268_capture_source, 12733 .input_mux = &alc268_capture_source,
12668 .unsol_event = alc268_toshiba_unsol_event, 12734 .setup = alc268_toshiba_setup,
12669 .init_hook = alc268_toshiba_init_hook 12735 .init_hook = alc268_toshiba_automute,
12670 }, 12736 },
12671#ifdef CONFIG_SND_DEBUG 12737#ifdef CONFIG_SND_DEBUG
12672 [ALC268_TEST] = { 12738 [ALC268_TEST] = {
@@ -12708,8 +12774,8 @@ static int patch_alc268(struct hda_codec *codec)
12708 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 12774 ALC882_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
12709 12775
12710 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 12776 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
12711 printk(KERN_INFO "hda_codec: Unknown model for %s, " 12777 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12712 "trying auto-probe from BIOS...\n", codec->chip_name); 12778 codec->chip_name);
12713 board_config = ALC268_AUTO; 12779 board_config = ALC268_AUTO;
12714 } 12780 }
12715 12781
@@ -12728,7 +12794,7 @@ static int patch_alc268(struct hda_codec *codec)
12728 } 12794 }
12729 12795
12730 if (board_config != ALC268_AUTO) 12796 if (board_config != ALC268_AUTO)
12731 setup_preset(spec, &alc268_presets[board_config]); 12797 setup_preset(codec, &alc268_presets[board_config]);
12732 12798
12733 spec->stream_analog_playback = &alc268_pcm_analog_playback; 12799 spec->stream_analog_playback = &alc268_pcm_analog_playback;
12734 spec->stream_analog_capture = &alc268_pcm_analog_capture; 12800 spec->stream_analog_capture = &alc268_pcm_analog_capture;
@@ -12765,11 +12831,15 @@ static int patch_alc268(struct hda_codec *codec)
12765 int i; 12831 int i;
12766 12832
12767 /* get type */ 12833 /* get type */
12768 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 12834 wcap = get_wcaps_type(wcap);
12769 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 12835 if (spec->auto_mic ||
12836 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
12770 spec->adc_nids = alc268_adc_nids_alt; 12837 spec->adc_nids = alc268_adc_nids_alt;
12771 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 12838 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
12772 add_mixer(spec, alc268_capture_alt_mixer); 12839 if (spec->auto_mic || spec->input_mux->num_items == 1)
12840 add_mixer(spec, alc268_capture_nosrc_mixer);
12841 else
12842 add_mixer(spec, alc268_capture_alt_mixer);
12773 } else { 12843 } else {
12774 spec->adc_nids = alc268_adc_nids; 12844 spec->adc_nids = alc268_adc_nids;
12775 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 12845 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
@@ -12780,6 +12850,8 @@ static int patch_alc268(struct hda_codec *codec)
12780 for (i = 0; i < spec->num_adc_nids; i++) 12850 for (i = 0; i < spec->num_adc_nids; i++)
12781 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i], 12851 snd_hda_codec_write_cache(codec, alc268_capsrc_nids[i],
12782 0, AC_VERB_SET_CONNECT_SEL, 12852 0, AC_VERB_SET_CONNECT_SEL,
12853 i < spec->num_mux_defs ?
12854 spec->input_mux[i].items[0].index :
12783 spec->input_mux->items[0].index); 12855 spec->input_mux->items[0].index);
12784 } 12856 }
12785 12857
@@ -12814,22 +12886,6 @@ static hda_nid_t alc269_capsrc_nids[1] = {
12814 * not a mux! 12886 * not a mux!
12815 */ 12887 */
12816 12888
12817static struct hda_input_mux alc269_eeepc_dmic_capture_source = {
12818 .num_items = 2,
12819 .items = {
12820 { "i-Mic", 0x5 },
12821 { "e-Mic", 0x0 },
12822 },
12823};
12824
12825static struct hda_input_mux alc269_eeepc_amic_capture_source = {
12826 .num_items = 2,
12827 .items = {
12828 { "i-Mic", 0x1 },
12829 { "e-Mic", 0x0 },
12830 },
12831};
12832
12833#define alc269_modes alc260_modes 12889#define alc269_modes alc260_modes
12834#define alc269_capture_source alc880_lg_lw_capture_source 12890#define alc269_capture_source alc880_lg_lw_capture_source
12835 12891
@@ -12991,16 +13047,6 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12991 AC_VERB_SET_PROC_COEF, 0x480); 13047 AC_VERB_SET_PROC_COEF, 0x480);
12992} 13048}
12993 13049
12994static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
12995{
12996 unsigned int present;
12997
12998 present = snd_hda_codec_read(codec, 0x18, 0,
12999 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13000 snd_hda_codec_write(codec, 0x23, 0,
13001 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
13002}
13003
13004static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) 13050static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13005{ 13051{
13006 unsigned int present_laptop; 13052 unsigned int present_laptop;
@@ -13027,10 +13073,14 @@ static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13027static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 13073static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13028 unsigned int res) 13074 unsigned int res)
13029{ 13075{
13030 if ((res >> 26) == ALC880_HP_EVENT) 13076 switch (res >> 26) {
13077 case ALC880_HP_EVENT:
13031 alc269_quanta_fl1_speaker_automute(codec); 13078 alc269_quanta_fl1_speaker_automute(codec);
13032 if ((res >> 26) == ALC880_MIC_EVENT) 13079 break;
13033 alc269_quanta_fl1_mic_automute(codec); 13080 case ALC880_MIC_EVENT:
13081 alc_mic_automute(codec);
13082 break;
13083 }
13034} 13084}
13035 13085
13036static void alc269_lifebook_unsol_event(struct hda_codec *codec, 13086static void alc269_lifebook_unsol_event(struct hda_codec *codec,
@@ -13042,10 +13092,20 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13042 alc269_lifebook_mic_autoswitch(codec); 13092 alc269_lifebook_mic_autoswitch(codec);
13043} 13093}
13044 13094
13095static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13096{
13097 struct alc_spec *spec = codec->spec;
13098 spec->ext_mic.pin = 0x18;
13099 spec->ext_mic.mux_idx = 0;
13100 spec->int_mic.pin = 0x19;
13101 spec->int_mic.mux_idx = 1;
13102 spec->auto_mic = 1;
13103}
13104
13045static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 13105static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13046{ 13106{
13047 alc269_quanta_fl1_speaker_automute(codec); 13107 alc269_quanta_fl1_speaker_automute(codec);
13048 alc269_quanta_fl1_mic_automute(codec); 13108 alc_mic_automute(codec);
13049} 13109}
13050 13110
13051static void alc269_lifebook_init_hook(struct hda_codec *codec) 13111static void alc269_lifebook_init_hook(struct hda_codec *codec)
@@ -13090,60 +13150,44 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13090 AMP_IN_MUTE(0), bits); 13150 AMP_IN_MUTE(0), bits);
13091} 13151}
13092 13152
13093static void alc269_eeepc_dmic_automute(struct hda_codec *codec)
13094{
13095 unsigned int present;
13096
13097 present = snd_hda_codec_read(codec, 0x18, 0,
13098 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13099 snd_hda_codec_write(codec, 0x23, 0,
13100 AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5));
13101}
13102
13103static void alc269_eeepc_amic_automute(struct hda_codec *codec)
13104{
13105 unsigned int present;
13106
13107 present = snd_hda_codec_read(codec, 0x18, 0,
13108 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
13109 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13110 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
13111 snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE,
13112 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
13113}
13114
13115/* unsolicited event for HP jack sensing */ 13153/* unsolicited event for HP jack sensing */
13116static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, 13154static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13117 unsigned int res) 13155 unsigned int res)
13118{ 13156{
13119 if ((res >> 26) == ALC880_HP_EVENT) 13157 switch (res >> 26) {
13158 case ALC880_HP_EVENT:
13120 alc269_speaker_automute(codec); 13159 alc269_speaker_automute(codec);
13121 13160 break;
13122 if ((res >> 26) == ALC880_MIC_EVENT) 13161 case ALC880_MIC_EVENT:
13123 alc269_eeepc_dmic_automute(codec); 13162 alc_mic_automute(codec);
13163 break;
13164 }
13124} 13165}
13125 13166
13126static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) 13167static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13127{ 13168{
13128 alc269_speaker_automute(codec); 13169 struct alc_spec *spec = codec->spec;
13129 alc269_eeepc_dmic_automute(codec); 13170 spec->ext_mic.pin = 0x18;
13171 spec->ext_mic.mux_idx = 0;
13172 spec->int_mic.pin = 0x12;
13173 spec->int_mic.mux_idx = 5;
13174 spec->auto_mic = 1;
13130} 13175}
13131 13176
13132/* unsolicited event for HP jack sensing */ 13177static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13133static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec,
13134 unsigned int res)
13135{ 13178{
13136 if ((res >> 26) == ALC880_HP_EVENT) 13179 struct alc_spec *spec = codec->spec;
13137 alc269_speaker_automute(codec); 13180 spec->ext_mic.pin = 0x18;
13138 13181 spec->ext_mic.mux_idx = 0;
13139 if ((res >> 26) == ALC880_MIC_EVENT) 13182 spec->int_mic.pin = 0x19;
13140 alc269_eeepc_amic_automute(codec); 13183 spec->int_mic.mux_idx = 1;
13184 spec->auto_mic = 1;
13141} 13185}
13142 13186
13143static void alc269_eeepc_amic_inithook(struct hda_codec *codec) 13187static void alc269_eeepc_inithook(struct hda_codec *codec)
13144{ 13188{
13145 alc269_speaker_automute(codec); 13189 alc269_speaker_automute(codec);
13146 alc269_eeepc_amic_automute(codec); 13190 alc_mic_automute(codec);
13147} 13191}
13148 13192
13149/* 13193/*
@@ -13216,89 +13260,10 @@ static struct hda_verb alc269_init_verbs[] = {
13216 { } 13260 { }
13217}; 13261};
13218 13262
13219/* add playback controls from the parsed DAC table */ 13263#define alc269_auto_create_multi_out_ctls \
13220static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, 13264 alc268_auto_create_multi_out_ctls
13221 const struct auto_pin_cfg *cfg) 13265#define alc269_auto_create_input_ctls \
13222{ 13266 alc268_auto_create_input_ctls
13223 hda_nid_t nid;
13224 int err;
13225
13226 spec->multiout.num_dacs = 1; /* only use one dac */
13227 spec->multiout.dac_nids = spec->private_dac_nids;
13228 spec->multiout.dac_nids[0] = 2;
13229
13230 nid = cfg->line_out_pins[0];
13231 if (nid) {
13232 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13233 "Front Playback Volume",
13234 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT));
13235 if (err < 0)
13236 return err;
13237 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13238 "Front Playback Switch",
13239 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
13240 if (err < 0)
13241 return err;
13242 }
13243
13244 nid = cfg->speaker_pins[0];
13245 if (nid) {
13246 if (!cfg->line_out_pins[0]) {
13247 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13248 "Speaker Playback Volume",
13249 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
13250 HDA_OUTPUT));
13251 if (err < 0)
13252 return err;
13253 }
13254 if (nid == 0x16) {
13255 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13256 "Speaker Playback Switch",
13257 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13258 HDA_OUTPUT));
13259 if (err < 0)
13260 return err;
13261 } else {
13262 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13263 "Speaker Playback Switch",
13264 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13265 HDA_OUTPUT));
13266 if (err < 0)
13267 return err;
13268 }
13269 }
13270 nid = cfg->hp_pins[0];
13271 if (nid) {
13272 /* spec->multiout.hp_nid = 2; */
13273 if (!cfg->line_out_pins[0] && !cfg->speaker_pins[0]) {
13274 err = add_control(spec, ALC_CTL_WIDGET_VOL,
13275 "Headphone Playback Volume",
13276 HDA_COMPOSE_AMP_VAL(0x02, 3, 0,
13277 HDA_OUTPUT));
13278 if (err < 0)
13279 return err;
13280 }
13281 if (nid == 0x16) {
13282 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13283 "Headphone Playback Switch",
13284 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
13285 HDA_OUTPUT));
13286 if (err < 0)
13287 return err;
13288 } else {
13289 err = add_control(spec, ALC_CTL_WIDGET_MUTE,
13290 "Headphone Playback Switch",
13291 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
13292 HDA_OUTPUT));
13293 if (err < 0)
13294 return err;
13295 }
13296 }
13297 return 0;
13298}
13299
13300#define alc269_auto_create_analog_input_ctls \
13301 alc262_auto_create_analog_input_ctls
13302 13267
13303#ifdef CONFIG_SND_HDA_POWER_SAVE 13268#ifdef CONFIG_SND_HDA_POWER_SAVE
13304#define alc269_loopbacks alc880_loopbacks 13269#define alc269_loopbacks alc880_loopbacks
@@ -13348,7 +13313,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13348 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg); 13313 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
13349 if (err < 0) 13314 if (err < 0)
13350 return err; 13315 return err;
13351 err = alc269_auto_create_analog_input_ctls(spec, &spec->autocfg); 13316 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
13352 if (err < 0) 13317 if (err < 0)
13353 return err; 13318 return err;
13354 13319
@@ -13373,15 +13338,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13373 return err; 13338 return err;
13374 13339
13375 if (!spec->cap_mixer && !spec->no_analog) 13340 if (!spec->cap_mixer && !spec->no_analog)
13376 set_capture_mixer(spec); 13341 set_capture_mixer(codec);
13377 13342
13378 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 13343 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13379 13344
13380 return 1; 13345 return 1;
13381} 13346}
13382 13347
13383#define alc269_auto_init_multi_out alc882_auto_init_multi_out 13348#define alc269_auto_init_multi_out alc268_auto_init_multi_out
13384#define alc269_auto_init_hp_out alc882_auto_init_hp_out 13349#define alc269_auto_init_hp_out alc268_auto_init_hp_out
13385#define alc269_auto_init_analog_input alc882_auto_init_analog_input 13350#define alc269_auto_init_analog_input alc882_auto_init_analog_input
13386 13351
13387 13352
@@ -13449,6 +13414,7 @@ static struct alc_config_preset alc269_presets[] = {
13449 .channel_mode = alc269_modes, 13414 .channel_mode = alc269_modes,
13450 .input_mux = &alc269_capture_source, 13415 .input_mux = &alc269_capture_source,
13451 .unsol_event = alc269_quanta_fl1_unsol_event, 13416 .unsol_event = alc269_quanta_fl1_unsol_event,
13417 .setup = alc269_quanta_fl1_setup,
13452 .init_hook = alc269_quanta_fl1_init_hook, 13418 .init_hook = alc269_quanta_fl1_init_hook,
13453 }, 13419 },
13454 [ALC269_ASUS_EEEPC_P703] = { 13420 [ALC269_ASUS_EEEPC_P703] = {
@@ -13461,9 +13427,9 @@ static struct alc_config_preset alc269_presets[] = {
13461 .hp_nid = 0x03, 13427 .hp_nid = 0x03,
13462 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13428 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13463 .channel_mode = alc269_modes, 13429 .channel_mode = alc269_modes,
13464 .input_mux = &alc269_eeepc_amic_capture_source, 13430 .unsol_event = alc269_eeepc_unsol_event,
13465 .unsol_event = alc269_eeepc_amic_unsol_event, 13431 .setup = alc269_eeepc_amic_setup,
13466 .init_hook = alc269_eeepc_amic_inithook, 13432 .init_hook = alc269_eeepc_inithook,
13467 }, 13433 },
13468 [ALC269_ASUS_EEEPC_P901] = { 13434 [ALC269_ASUS_EEEPC_P901] = {
13469 .mixers = { alc269_eeepc_mixer }, 13435 .mixers = { alc269_eeepc_mixer },
@@ -13475,9 +13441,9 @@ static struct alc_config_preset alc269_presets[] = {
13475 .hp_nid = 0x03, 13441 .hp_nid = 0x03,
13476 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13442 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13477 .channel_mode = alc269_modes, 13443 .channel_mode = alc269_modes,
13478 .input_mux = &alc269_eeepc_dmic_capture_source, 13444 .unsol_event = alc269_eeepc_unsol_event,
13479 .unsol_event = alc269_eeepc_dmic_unsol_event, 13445 .setup = alc269_eeepc_dmic_setup,
13480 .init_hook = alc269_eeepc_dmic_inithook, 13446 .init_hook = alc269_eeepc_inithook,
13481 }, 13447 },
13482 [ALC269_FUJITSU] = { 13448 [ALC269_FUJITSU] = {
13483 .mixers = { alc269_fujitsu_mixer }, 13449 .mixers = { alc269_fujitsu_mixer },
@@ -13489,9 +13455,9 @@ static struct alc_config_preset alc269_presets[] = {
13489 .hp_nid = 0x03, 13455 .hp_nid = 0x03,
13490 .num_channel_mode = ARRAY_SIZE(alc269_modes), 13456 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13491 .channel_mode = alc269_modes, 13457 .channel_mode = alc269_modes,
13492 .input_mux = &alc269_eeepc_dmic_capture_source, 13458 .unsol_event = alc269_eeepc_unsol_event,
13493 .unsol_event = alc269_eeepc_dmic_unsol_event, 13459 .setup = alc269_eeepc_dmic_setup,
13494 .init_hook = alc269_eeepc_dmic_inithook, 13460 .init_hook = alc269_eeepc_inithook,
13495 }, 13461 },
13496 [ALC269_LIFEBOOK] = { 13462 [ALC269_LIFEBOOK] = {
13497 .mixers = { alc269_lifebook_mixer }, 13463 .mixers = { alc269_lifebook_mixer },
@@ -13526,8 +13492,8 @@ static int patch_alc269(struct hda_codec *codec)
13526 alc269_cfg_tbl); 13492 alc269_cfg_tbl);
13527 13493
13528 if (board_config < 0) { 13494 if (board_config < 0) {
13529 printk(KERN_INFO "hda_codec: Unknown model for %s, " 13495 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13530 "trying auto-probe from BIOS...\n", codec->chip_name); 13496 codec->chip_name);
13531 board_config = ALC269_AUTO; 13497 board_config = ALC269_AUTO;
13532 } 13498 }
13533 13499
@@ -13552,7 +13518,7 @@ static int patch_alc269(struct hda_codec *codec)
13552 } 13518 }
13553 13519
13554 if (board_config != ALC269_AUTO) 13520 if (board_config != ALC269_AUTO)
13555 setup_preset(spec, &alc269_presets[board_config]); 13521 setup_preset(codec, &alc269_presets[board_config]);
13556 13522
13557 if (codec->subsystem_id == 0x17aa3bf8) { 13523 if (codec->subsystem_id == 0x17aa3bf8) {
13558 /* Due to a hardware problem on Lenovo Ideadpad, we need to 13524 /* Due to a hardware problem on Lenovo Ideadpad, we need to
@@ -13571,7 +13537,7 @@ static int patch_alc269(struct hda_codec *codec)
13571 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 13537 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
13572 spec->capsrc_nids = alc269_capsrc_nids; 13538 spec->capsrc_nids = alc269_capsrc_nids;
13573 if (!spec->cap_mixer) 13539 if (!spec->cap_mixer)
13574 set_capture_mixer(spec); 13540 set_capture_mixer(codec);
13575 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 13541 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
13576 13542
13577 spec->vmaster_nid = 0x02; 13543 spec->vmaster_nid = 0x02;
@@ -14121,23 +14087,23 @@ static struct hda_verb alc861_auto_init_verbs[] = {
14121 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14087 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
14122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, 14088 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
14123 14089
14124 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14125 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14091 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14126 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14092 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14127 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14093 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14094 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14129 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14130 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 14096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14131 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 14097 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14132 14098
14133 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14099 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14134 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14100 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14135 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14101 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14136 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 14102 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14137 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 14103 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
14138 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 14104 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
14139 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 14105 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
14140 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 14106 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
14141 14107
14142 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ 14108 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
14143 14109
@@ -14209,64 +14175,96 @@ static struct hda_input_mux alc861_capture_source = {
14209 }, 14175 },
14210}; 14176};
14211 14177
14178static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
14179{
14180 struct alc_spec *spec = codec->spec;
14181 hda_nid_t mix, srcs[5];
14182 int i, j, num;
14183
14184 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
14185 return 0;
14186 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14187 if (num < 0)
14188 return 0;
14189 for (i = 0; i < num; i++) {
14190 unsigned int type;
14191 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
14192 if (type != AC_WID_AUD_OUT)
14193 continue;
14194 for (j = 0; j < spec->multiout.num_dacs; j++)
14195 if (spec->multiout.dac_nids[j] == srcs[i])
14196 break;
14197 if (j >= spec->multiout.num_dacs)
14198 return srcs[i];
14199 }
14200 return 0;
14201}
14202
14212/* fill in the dac_nids table from the parsed pin configuration */ 14203/* fill in the dac_nids table from the parsed pin configuration */
14213static int alc861_auto_fill_dac_nids(struct alc_spec *spec, 14204static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
14214 const struct auto_pin_cfg *cfg) 14205 const struct auto_pin_cfg *cfg)
14215{ 14206{
14207 struct alc_spec *spec = codec->spec;
14216 int i; 14208 int i;
14217 hda_nid_t nid; 14209 hda_nid_t nid, dac;
14218 14210
14219 spec->multiout.dac_nids = spec->private_dac_nids; 14211 spec->multiout.dac_nids = spec->private_dac_nids;
14220 for (i = 0; i < cfg->line_outs; i++) { 14212 for (i = 0; i < cfg->line_outs; i++) {
14221 nid = cfg->line_out_pins[i]; 14213 nid = cfg->line_out_pins[i];
14222 if (nid) { 14214 dac = alc861_look_for_dac(codec, nid);
14223 if (i >= ARRAY_SIZE(alc861_dac_nids)) 14215 if (!dac)
14224 continue; 14216 continue;
14225 spec->multiout.dac_nids[i] = alc861_dac_nids[i]; 14217 spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac;
14226 }
14227 } 14218 }
14228 spec->multiout.num_dacs = cfg->line_outs;
14229 return 0; 14219 return 0;
14230} 14220}
14231 14221
14222static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
14223 hda_nid_t nid, unsigned int chs)
14224{
14225 char name[32];
14226 snprintf(name, sizeof(name), "%s Playback Switch", pfx);
14227 return add_control(codec->spec, ALC_CTL_WIDGET_MUTE, name,
14228 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
14229}
14230
14232/* add playback controls from the parsed DAC table */ 14231/* add playback controls from the parsed DAC table */
14233static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, 14232static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
14234 const struct auto_pin_cfg *cfg) 14233 const struct auto_pin_cfg *cfg)
14235{ 14234{
14236 char name[32]; 14235 struct alc_spec *spec = codec->spec;
14237 static const char *chname[4] = { 14236 static const char *chname[4] = {
14238 "Front", "Surround", NULL /*CLFE*/, "Side" 14237 "Front", "Surround", NULL /*CLFE*/, "Side"
14239 }; 14238 };
14240 hda_nid_t nid; 14239 hda_nid_t nid;
14241 int i, idx, err; 14240 int i, err;
14241
14242 if (cfg->line_outs == 1) {
14243 const char *pfx = NULL;
14244 if (!cfg->hp_outs)
14245 pfx = "Master";
14246 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
14247 pfx = "Speaker";
14248 if (pfx) {
14249 nid = spec->multiout.dac_nids[0];
14250 return alc861_create_out_sw(codec, pfx, nid, 3);
14251 }
14252 }
14242 14253
14243 for (i = 0; i < cfg->line_outs; i++) { 14254 for (i = 0; i < cfg->line_outs; i++) {
14244 nid = spec->multiout.dac_nids[i]; 14255 nid = spec->multiout.dac_nids[i];
14245 if (!nid) 14256 if (!nid)
14246 continue; 14257 continue;
14247 if (nid == 0x05) { 14258 if (i == 2) {
14248 /* Center/LFE */ 14259 /* Center/LFE */
14249 err = add_control(spec, ALC_CTL_BIND_MUTE, 14260 err = alc861_create_out_sw(codec, "Center", nid, 1);
14250 "Center Playback Switch",
14251 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
14252 HDA_OUTPUT));
14253 if (err < 0) 14261 if (err < 0)
14254 return err; 14262 return err;
14255 err = add_control(spec, ALC_CTL_BIND_MUTE, 14263 err = alc861_create_out_sw(codec, "LFE", nid, 2);
14256 "LFE Playback Switch",
14257 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
14258 HDA_OUTPUT));
14259 if (err < 0) 14264 if (err < 0)
14260 return err; 14265 return err;
14261 } else { 14266 } else {
14262 for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; 14267 err = alc861_create_out_sw(codec, chname[i], nid, 3);
14263 idx++)
14264 if (nid == alc861_dac_nids[idx])
14265 break;
14266 sprintf(name, "%s Playback Switch", chname[idx]);
14267 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
14268 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
14269 HDA_OUTPUT));
14270 if (err < 0) 14268 if (err < 0)
14271 return err; 14269 return err;
14272 } 14270 }
@@ -14274,8 +14272,9 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec,
14274 return 0; 14272 return 0;
14275} 14273}
14276 14274
14277static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) 14275static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
14278{ 14276{
14277 struct alc_spec *spec = codec->spec;
14279 int err; 14278 int err;
14280 hda_nid_t nid; 14279 hda_nid_t nid;
14281 14280
@@ -14283,70 +14282,49 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin)
14283 return 0; 14282 return 0;
14284 14283
14285 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { 14284 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
14286 nid = 0x03; 14285 nid = alc861_look_for_dac(codec, pin);
14287 err = add_control(spec, ALC_CTL_WIDGET_MUTE, 14286 if (nid) {
14288 "Headphone Playback Switch", 14287 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
14289 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 14288 if (err < 0)
14290 if (err < 0) 14289 return err;
14291 return err; 14290 spec->multiout.hp_nid = nid;
14292 spec->multiout.hp_nid = nid; 14291 }
14293 } 14292 }
14294 return 0; 14293 return 0;
14295} 14294}
14296 14295
14297/* create playback/capture controls for input pins */ 14296/* create playback/capture controls for input pins */
14298static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, 14297static int alc861_auto_create_input_ctls(struct hda_codec *codec,
14299 const struct auto_pin_cfg *cfg) 14298 const struct auto_pin_cfg *cfg)
14300{ 14299{
14301 struct hda_input_mux *imux = &spec->private_imux[0]; 14300 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
14302 int i, err, idx, idx1;
14303
14304 for (i = 0; i < AUTO_PIN_LAST; i++) {
14305 switch (cfg->input_pins[i]) {
14306 case 0x0c:
14307 idx1 = 1;
14308 idx = 2; /* Line In */
14309 break;
14310 case 0x0f:
14311 idx1 = 2;
14312 idx = 2; /* Line In */
14313 break;
14314 case 0x0d:
14315 idx1 = 0;
14316 idx = 1; /* Mic In */
14317 break;
14318 case 0x10:
14319 idx1 = 3;
14320 idx = 1; /* Mic In */
14321 break;
14322 case 0x11:
14323 idx1 = 4;
14324 idx = 0; /* CD */
14325 break;
14326 default:
14327 continue;
14328 }
14329
14330 err = new_analog_input(spec, cfg->input_pins[i],
14331 auto_pin_cfg_labels[i], idx, 0x15);
14332 if (err < 0)
14333 return err;
14334
14335 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
14336 imux->items[imux->num_items].index = idx1;
14337 imux->num_items++;
14338 }
14339 return 0;
14340} 14301}
14341 14302
14342static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 14303static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
14343 hda_nid_t nid, 14304 hda_nid_t nid,
14344 int pin_type, int dac_idx) 14305 int pin_type, hda_nid_t dac)
14345{ 14306{
14307 hda_nid_t mix, srcs[5];
14308 int i, num;
14309
14346 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 14310 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
14347 pin_type); 14311 pin_type);
14348 snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, 14312 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14349 AMP_OUT_UNMUTE); 14313 AMP_OUT_UNMUTE);
14314 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
14315 return;
14316 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
14317 if (num < 0)
14318 return;
14319 for (i = 0; i < num; i++) {
14320 unsigned int mute;
14321 if (srcs[i] == dac || srcs[i] == 0x15)
14322 mute = AMP_IN_UNMUTE(i);
14323 else
14324 mute = AMP_IN_MUTE(i);
14325 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
14326 mute);
14327 }
14350} 14328}
14351 14329
14352static void alc861_auto_init_multi_out(struct hda_codec *codec) 14330static void alc861_auto_init_multi_out(struct hda_codec *codec)
@@ -14369,12 +14347,13 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec)
14369 hda_nid_t pin; 14347 hda_nid_t pin;
14370 14348
14371 pin = spec->autocfg.hp_pins[0]; 14349 pin = spec->autocfg.hp_pins[0];
14372 if (pin) /* connect to front */ 14350 if (pin)
14373 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, 14351 alc861_auto_set_output_and_unmute(codec, pin, PIN_HP,
14374 spec->multiout.dac_nids[0]); 14352 spec->multiout.hp_nid);
14375 pin = spec->autocfg.speaker_pins[0]; 14353 pin = spec->autocfg.speaker_pins[0];
14376 if (pin) 14354 if (pin)
14377 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 14355 alc861_auto_set_output_and_unmute(codec, pin, PIN_OUT,
14356 spec->multiout.dac_nids[0]);
14378} 14357}
14379 14358
14380static void alc861_auto_init_analog_input(struct hda_codec *codec) 14359static void alc861_auto_init_analog_input(struct hda_codec *codec)
@@ -14406,16 +14385,16 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14406 if (!spec->autocfg.line_outs) 14385 if (!spec->autocfg.line_outs)
14407 return 0; /* can't find valid BIOS pin config */ 14386 return 0; /* can't find valid BIOS pin config */
14408 14387
14409 err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); 14388 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
14410 if (err < 0) 14389 if (err < 0)
14411 return err; 14390 return err;
14412 err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); 14391 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
14413 if (err < 0) 14392 if (err < 0)
14414 return err; 14393 return err;
14415 err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 14394 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
14416 if (err < 0) 14395 if (err < 0)
14417 return err; 14396 return err;
14418 err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); 14397 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
14419 if (err < 0) 14398 if (err < 0)
14420 return err; 14399 return err;
14421 14400
@@ -14434,7 +14413,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14434 14413
14435 spec->adc_nids = alc861_adc_nids; 14414 spec->adc_nids = alc861_adc_nids;
14436 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 14415 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14437 set_capture_mixer(spec); 14416 set_capture_mixer(codec);
14438 14417
14439 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 14418 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14440 14419
@@ -14627,8 +14606,8 @@ static int patch_alc861(struct hda_codec *codec)
14627 alc861_cfg_tbl); 14606 alc861_cfg_tbl);
14628 14607
14629 if (board_config < 0) { 14608 if (board_config < 0) {
14630 printk(KERN_INFO "hda_codec: Unknown model for %s, " 14609 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14631 "trying auto-probe from BIOS...\n", codec->chip_name); 14610 codec->chip_name);
14632 board_config = ALC861_AUTO; 14611 board_config = ALC861_AUTO;
14633 } 14612 }
14634 14613
@@ -14653,7 +14632,7 @@ static int patch_alc861(struct hda_codec *codec)
14653 } 14632 }
14654 14633
14655 if (board_config != ALC861_AUTO) 14634 if (board_config != ALC861_AUTO)
14656 setup_preset(spec, &alc861_presets[board_config]); 14635 setup_preset(codec, &alc861_presets[board_config]);
14657 14636
14658 spec->stream_analog_playback = &alc861_pcm_analog_playback; 14637 spec->stream_analog_playback = &alc861_pcm_analog_playback;
14659 spec->stream_analog_capture = &alc861_pcm_analog_capture; 14638 spec->stream_analog_capture = &alc861_pcm_analog_capture;
@@ -15056,12 +15035,15 @@ static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
15056 HDA_AMP_MUTE, bits); 15035 HDA_AMP_MUTE, bits);
15057} 15036}
15058 15037
15059static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 15038static void alc861vd_lenovo_setup(struct hda_codec *codec)
15060{ 15039{
15061 struct alc_spec *spec = codec->spec; 15040 struct alc_spec *spec = codec->spec;
15062
15063 spec->autocfg.hp_pins[0] = 0x1b; 15041 spec->autocfg.hp_pins[0] = 0x1b;
15064 spec->autocfg.speaker_pins[0] = 0x14; 15042 spec->autocfg.speaker_pins[0] = 0x14;
15043}
15044
15045static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
15046{
15065 alc_automute_amp(codec); 15047 alc_automute_amp(codec);
15066 alc861vd_lenovo_mic_automute(codec); 15048 alc861vd_lenovo_mic_automute(codec);
15067} 15049}
@@ -15125,13 +15107,12 @@ static struct hda_verb alc861vd_dallas_verbs[] = {
15125}; 15107};
15126 15108
15127/* toggle speaker-output according to the hp-jack state */ 15109/* toggle speaker-output according to the hp-jack state */
15128static void alc861vd_dallas_init_hook(struct hda_codec *codec) 15110static void alc861vd_dallas_setup(struct hda_codec *codec)
15129{ 15111{
15130 struct alc_spec *spec = codec->spec; 15112 struct alc_spec *spec = codec->spec;
15131 15113
15132 spec->autocfg.hp_pins[0] = 0x15; 15114 spec->autocfg.hp_pins[0] = 0x15;
15133 spec->autocfg.speaker_pins[0] = 0x14; 15115 spec->autocfg.speaker_pins[0] = 0x14;
15134 alc_automute_amp(codec);
15135} 15116}
15136 15117
15137#ifdef CONFIG_SND_HDA_POWER_SAVE 15118#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -15245,6 +15226,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15245 .channel_mode = alc861vd_3stack_2ch_modes, 15226 .channel_mode = alc861vd_3stack_2ch_modes,
15246 .input_mux = &alc861vd_capture_source, 15227 .input_mux = &alc861vd_capture_source,
15247 .unsol_event = alc861vd_lenovo_unsol_event, 15228 .unsol_event = alc861vd_lenovo_unsol_event,
15229 .setup = alc861vd_lenovo_setup,
15248 .init_hook = alc861vd_lenovo_init_hook, 15230 .init_hook = alc861vd_lenovo_init_hook,
15249 }, 15231 },
15250 [ALC861VD_DALLAS] = { 15232 [ALC861VD_DALLAS] = {
@@ -15256,7 +15238,8 @@ static struct alc_config_preset alc861vd_presets[] = {
15256 .channel_mode = alc861vd_3stack_2ch_modes, 15238 .channel_mode = alc861vd_3stack_2ch_modes,
15257 .input_mux = &alc861vd_dallas_capture_source, 15239 .input_mux = &alc861vd_dallas_capture_source,
15258 .unsol_event = alc_automute_amp_unsol_event, 15240 .unsol_event = alc_automute_amp_unsol_event,
15259 .init_hook = alc861vd_dallas_init_hook, 15241 .setup = alc861vd_dallas_setup,
15242 .init_hook = alc_automute_amp,
15260 }, 15243 },
15261 [ALC861VD_HP] = { 15244 [ALC861VD_HP] = {
15262 .mixers = { alc861vd_hp_mixer }, 15245 .mixers = { alc861vd_hp_mixer },
@@ -15268,7 +15251,8 @@ static struct alc_config_preset alc861vd_presets[] = {
15268 .channel_mode = alc861vd_3stack_2ch_modes, 15251 .channel_mode = alc861vd_3stack_2ch_modes,
15269 .input_mux = &alc861vd_hp_capture_source, 15252 .input_mux = &alc861vd_hp_capture_source,
15270 .unsol_event = alc_automute_amp_unsol_event, 15253 .unsol_event = alc_automute_amp_unsol_event,
15271 .init_hook = alc861vd_dallas_init_hook, 15254 .setup = alc861vd_dallas_setup,
15255 .init_hook = alc_automute_amp,
15272 }, 15256 },
15273 [ALC660VD_ASUS_V1S] = { 15257 [ALC660VD_ASUS_V1S] = {
15274 .mixers = { alc861vd_lenovo_mixer }, 15258 .mixers = { alc861vd_lenovo_mixer },
@@ -15283,6 +15267,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15283 .channel_mode = alc861vd_3stack_2ch_modes, 15267 .channel_mode = alc861vd_3stack_2ch_modes,
15284 .input_mux = &alc861vd_capture_source, 15268 .input_mux = &alc861vd_capture_source,
15285 .unsol_event = alc861vd_lenovo_unsol_event, 15269 .unsol_event = alc861vd_lenovo_unsol_event,
15270 .setup = alc861vd_lenovo_setup,
15286 .init_hook = alc861vd_lenovo_init_hook, 15271 .init_hook = alc861vd_lenovo_init_hook,
15287 }, 15272 },
15288}; 15273};
@@ -15290,6 +15275,13 @@ static struct alc_config_preset alc861vd_presets[] = {
15290/* 15275/*
15291 * BIOS auto configuration 15276 * BIOS auto configuration
15292 */ 15277 */
15278static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15279 const struct auto_pin_cfg *cfg)
15280{
15281 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15282}
15283
15284
15293static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec, 15285static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
15294 hda_nid_t nid, int pin_type, int dac_idx) 15286 hda_nid_t nid, int pin_type, int dac_idx)
15295{ 15287{
@@ -15324,7 +15316,6 @@ static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
15324 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); 15316 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
15325} 15317}
15326 15318
15327#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
15328#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID 15319#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
15329 15320
15330static void alc861vd_auto_init_analog_input(struct hda_codec *codec) 15321static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
@@ -15334,7 +15325,7 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
15334 15325
15335 for (i = 0; i < AUTO_PIN_LAST; i++) { 15326 for (i = 0; i < AUTO_PIN_LAST; i++) {
15336 hda_nid_t nid = spec->autocfg.input_pins[i]; 15327 hda_nid_t nid = spec->autocfg.input_pins[i];
15337 if (alc861vd_is_input_pin(nid)) { 15328 if (alc_is_input_pin(codec, nid)) {
15338 alc_set_input_pin(codec, nid, i); 15329 alc_set_input_pin(codec, nid, i);
15339 if (nid != ALC861VD_PIN_CD_NID && 15330 if (nid != ALC861VD_PIN_CD_NID &&
15340 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 15331 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
@@ -15398,13 +15389,25 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
15398 if (err < 0) 15389 if (err < 0)
15399 return err; 15390 return err;
15400 } else { 15391 } else {
15401 sprintf(name, "%s Playback Volume", chname[i]); 15392 const char *pfx;
15393 if (cfg->line_outs == 1 &&
15394 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
15395 if (!cfg->hp_pins)
15396 pfx = "Speaker";
15397 else
15398 pfx = "PCM";
15399 } else
15400 pfx = chname[i];
15401 sprintf(name, "%s Playback Volume", pfx);
15402 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 15402 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
15403 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 15403 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
15404 HDA_OUTPUT)); 15404 HDA_OUTPUT));
15405 if (err < 0) 15405 if (err < 0)
15406 return err; 15406 return err;
15407 sprintf(name, "%s Playback Switch", chname[i]); 15407 if (cfg->line_outs == 1 &&
15408 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15409 pfx = "Speaker";
15410 sprintf(name, "%s Playback Switch", pfx);
15408 err = add_control(spec, ALC_CTL_BIND_MUTE, name, 15411 err = add_control(spec, ALC_CTL_BIND_MUTE, name,
15409 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 15412 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
15410 HDA_INPUT)); 15413 HDA_INPUT));
@@ -15497,7 +15500,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15497 "Headphone"); 15500 "Headphone");
15498 if (err < 0) 15501 if (err < 0)
15499 return err; 15502 return err;
15500 err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); 15503 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
15501 if (err < 0) 15504 if (err < 0)
15502 return err; 15505 return err;
15503 15506
@@ -15551,8 +15554,8 @@ static int patch_alc861vd(struct hda_codec *codec)
15551 alc861vd_cfg_tbl); 15554 alc861vd_cfg_tbl);
15552 15555
15553 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 15556 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
15554 printk(KERN_INFO "hda_codec: Unknown model for %s, " 15557 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15555 "trying auto-probe from BIOS...\n", codec->chip_name); 15558 codec->chip_name);
15556 board_config = ALC861VD_AUTO; 15559 board_config = ALC861VD_AUTO;
15557 } 15560 }
15558 15561
@@ -15577,7 +15580,7 @@ static int patch_alc861vd(struct hda_codec *codec)
15577 } 15580 }
15578 15581
15579 if (board_config != ALC861VD_AUTO) 15582 if (board_config != ALC861VD_AUTO)
15580 setup_preset(spec, &alc861vd_presets[board_config]); 15583 setup_preset(codec, &alc861vd_presets[board_config]);
15581 15584
15582 if (codec->vendor_id == 0x10ec0660) { 15585 if (codec->vendor_id == 0x10ec0660) {
15583 /* always turn on EAPD */ 15586 /* always turn on EAPD */
@@ -15597,7 +15600,7 @@ static int patch_alc861vd(struct hda_codec *codec)
15597 if (!spec->capsrc_nids) 15600 if (!spec->capsrc_nids)
15598 spec->capsrc_nids = alc861vd_capsrc_nids; 15601 spec->capsrc_nids = alc861vd_capsrc_nids;
15599 15602
15600 set_capture_mixer(spec); 15603 set_capture_mixer(codec);
15601 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 15604 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
15602 15605
15603 spec->vmaster_nid = 0x02; 15606 spec->vmaster_nid = 0x02;
@@ -15638,9 +15641,9 @@ static hda_nid_t alc272_dac_nids[2] = {
15638 0x02, 0x03 15641 0x02, 0x03
15639}; 15642};
15640 15643
15641static hda_nid_t alc662_adc_nids[1] = { 15644static hda_nid_t alc662_adc_nids[2] = {
15642 /* ADC1-2 */ 15645 /* ADC1-2 */
15643 0x09, 15646 0x09, 0x08
15644}; 15647};
15645 15648
15646static hda_nid_t alc272_adc_nids[1] = { 15649static hda_nid_t alc272_adc_nids[1] = {
@@ -15648,7 +15651,7 @@ static hda_nid_t alc272_adc_nids[1] = {
15648 0x08, 15651 0x08,
15649}; 15652};
15650 15653
15651static hda_nid_t alc662_capsrc_nids[1] = { 0x22 }; 15654static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
15652static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; 15655static hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
15653 15656
15654 15657
@@ -15672,14 +15675,6 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = {
15672 }, 15675 },
15673}; 15676};
15674 15677
15675static struct hda_input_mux alc662_eeepc_capture_source = {
15676 .num_items = 2,
15677 .items = {
15678 { "i-Mic", 0x1 },
15679 { "e-Mic", 0x0 },
15680 },
15681};
15682
15683static struct hda_input_mux alc663_capture_source = { 15678static struct hda_input_mux alc663_capture_source = {
15684 .num_items = 3, 15679 .num_items = 3,
15685 .items = { 15680 .items = {
@@ -15689,23 +15684,7 @@ static struct hda_input_mux alc663_capture_source = {
15689 }, 15684 },
15690}; 15685};
15691 15686
15692static struct hda_input_mux alc663_m51va_capture_source = { 15687#if 0 /* set to 1 for testing other input sources below */
15693 .num_items = 2,
15694 .items = {
15695 { "Ext-Mic", 0x0 },
15696 { "D-Mic", 0x9 },
15697 },
15698};
15699
15700#if 1 /* set to 0 for testing other input sources below */
15701static struct hda_input_mux alc272_nc10_capture_source = {
15702 .num_items = 2,
15703 .items = {
15704 { "Autoselect Mic", 0x0 },
15705 { "Internal Mic", 0x1 },
15706 },
15707};
15708#else
15709static struct hda_input_mux alc272_nc10_capture_source = { 15688static struct hda_input_mux alc272_nc10_capture_source = {
15710 .num_items = 16, 15689 .num_items = 16,
15711 .items = { 15690 .items = {
@@ -16374,47 +16353,44 @@ static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec,
16374 alc662_lenovo_101e_ispeaker_automute(codec); 16353 alc662_lenovo_101e_ispeaker_automute(codec);
16375} 16354}
16376 16355
16377static void alc662_eeepc_mic_automute(struct hda_codec *codec)
16378{
16379 unsigned int present;
16380
16381 present = snd_hda_codec_read(codec, 0x18, 0,
16382 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
16383 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16384 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16385 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16386 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16387 snd_hda_codec_write(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16388 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16389 snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16390 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
16391}
16392
16393/* unsolicited event for HP jack sensing */ 16356/* unsolicited event for HP jack sensing */
16394static void alc662_eeepc_unsol_event(struct hda_codec *codec, 16357static void alc662_eeepc_unsol_event(struct hda_codec *codec,
16395 unsigned int res) 16358 unsigned int res)
16396{ 16359{
16397 if ((res >> 26) == ALC880_MIC_EVENT) 16360 if ((res >> 26) == ALC880_MIC_EVENT)
16398 alc662_eeepc_mic_automute(codec); 16361 alc_mic_automute(codec);
16399 else 16362 else
16400 alc262_hippo_unsol_event(codec, res); 16363 alc262_hippo_unsol_event(codec, res);
16401} 16364}
16402 16365
16366static void alc662_eeepc_setup(struct hda_codec *codec)
16367{
16368 struct alc_spec *spec = codec->spec;
16369
16370 alc262_hippo1_setup(codec);
16371 spec->ext_mic.pin = 0x18;
16372 spec->ext_mic.mux_idx = 0;
16373 spec->int_mic.pin = 0x19;
16374 spec->int_mic.mux_idx = 1;
16375 spec->auto_mic = 1;
16376}
16377
16403static void alc662_eeepc_inithook(struct hda_codec *codec) 16378static void alc662_eeepc_inithook(struct hda_codec *codec)
16404{ 16379{
16405 alc262_hippo1_init_hook(codec); 16380 alc262_hippo_automute(codec);
16406 alc662_eeepc_mic_automute(codec); 16381 alc_mic_automute(codec);
16407} 16382}
16408 16383
16409static void alc662_eeepc_ep20_inithook(struct hda_codec *codec) 16384static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
16410{ 16385{
16411 struct alc_spec *spec = codec->spec; 16386 struct alc_spec *spec = codec->spec;
16412 16387
16413 spec->autocfg.hp_pins[0] = 0x14; 16388 spec->autocfg.hp_pins[0] = 0x14;
16414 spec->autocfg.speaker_pins[0] = 0x1b; 16389 spec->autocfg.speaker_pins[0] = 0x1b;
16415 alc262_hippo_master_update(codec);
16416} 16390}
16417 16391
16392#define alc662_eeepc_ep20_inithook alc262_hippo_master_update
16393
16418static void alc663_m51va_speaker_automute(struct hda_codec *codec) 16394static void alc663_m51va_speaker_automute(struct hda_codec *codec)
16419{ 16395{
16420 unsigned int present; 16396 unsigned int present;
@@ -16525,23 +16501,6 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec)
16525 } 16501 }
16526} 16502}
16527 16503
16528static void alc663_m51va_mic_automute(struct hda_codec *codec)
16529{
16530 unsigned int present;
16531
16532 present = snd_hda_codec_read(codec, 0x18, 0,
16533 AC_VERB_GET_PIN_SENSE, 0)
16534 & AC_PINSENSE_PRESENCE;
16535 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16536 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16537 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16538 0x7000 | (0x00 << 8) | (present ? 0 : 0x80));
16539 snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16540 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16541 snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16542 0x7000 | (0x09 << 8) | (present ? 0x80 : 0));
16543}
16544
16545static void alc663_m51va_unsol_event(struct hda_codec *codec, 16504static void alc663_m51va_unsol_event(struct hda_codec *codec,
16546 unsigned int res) 16505 unsigned int res)
16547{ 16506{
@@ -16550,36 +16509,32 @@ static void alc663_m51va_unsol_event(struct hda_codec *codec,
16550 alc663_m51va_speaker_automute(codec); 16509 alc663_m51va_speaker_automute(codec);
16551 break; 16510 break;
16552 case ALC880_MIC_EVENT: 16511 case ALC880_MIC_EVENT:
16553 alc663_m51va_mic_automute(codec); 16512 alc_mic_automute(codec);
16554 break; 16513 break;
16555 } 16514 }
16556} 16515}
16557 16516
16517static void alc663_m51va_setup(struct hda_codec *codec)
16518{
16519 struct alc_spec *spec = codec->spec;
16520 spec->ext_mic.pin = 0x18;
16521 spec->ext_mic.mux_idx = 0;
16522 spec->int_mic.pin = 0x12;
16523 spec->int_mic.mux_idx = 1;
16524 spec->auto_mic = 1;
16525}
16526
16558static void alc663_m51va_inithook(struct hda_codec *codec) 16527static void alc663_m51va_inithook(struct hda_codec *codec)
16559{ 16528{
16560 alc663_m51va_speaker_automute(codec); 16529 alc663_m51va_speaker_automute(codec);
16561 alc663_m51va_mic_automute(codec); 16530 alc_mic_automute(codec);
16562} 16531}
16563 16532
16564/* ***************** Mode1 ******************************/ 16533/* ***************** Mode1 ******************************/
16565static void alc663_mode1_unsol_event(struct hda_codec *codec, 16534#define alc663_mode1_unsol_event alc663_m51va_unsol_event
16566 unsigned int res) 16535#define alc663_mode1_setup alc663_m51va_setup
16567{ 16536#define alc663_mode1_inithook alc663_m51va_inithook
16568 switch (res >> 26) {
16569 case ALC880_HP_EVENT:
16570 alc663_m51va_speaker_automute(codec);
16571 break;
16572 case ALC880_MIC_EVENT:
16573 alc662_eeepc_mic_automute(codec);
16574 break;
16575 }
16576}
16577 16537
16578static void alc663_mode1_inithook(struct hda_codec *codec)
16579{
16580 alc663_m51va_speaker_automute(codec);
16581 alc662_eeepc_mic_automute(codec);
16582}
16583/* ***************** Mode2 ******************************/ 16538/* ***************** Mode2 ******************************/
16584static void alc662_mode2_unsol_event(struct hda_codec *codec, 16539static void alc662_mode2_unsol_event(struct hda_codec *codec,
16585 unsigned int res) 16540 unsigned int res)
@@ -16589,15 +16544,17 @@ static void alc662_mode2_unsol_event(struct hda_codec *codec,
16589 alc662_f5z_speaker_automute(codec); 16544 alc662_f5z_speaker_automute(codec);
16590 break; 16545 break;
16591 case ALC880_MIC_EVENT: 16546 case ALC880_MIC_EVENT:
16592 alc662_eeepc_mic_automute(codec); 16547 alc_mic_automute(codec);
16593 break; 16548 break;
16594 } 16549 }
16595} 16550}
16596 16551
16552#define alc662_mode2_setup alc663_m51va_setup
16553
16597static void alc662_mode2_inithook(struct hda_codec *codec) 16554static void alc662_mode2_inithook(struct hda_codec *codec)
16598{ 16555{
16599 alc662_f5z_speaker_automute(codec); 16556 alc662_f5z_speaker_automute(codec);
16600 alc662_eeepc_mic_automute(codec); 16557 alc_mic_automute(codec);
16601} 16558}
16602/* ***************** Mode3 ******************************/ 16559/* ***************** Mode3 ******************************/
16603static void alc663_mode3_unsol_event(struct hda_codec *codec, 16560static void alc663_mode3_unsol_event(struct hda_codec *codec,
@@ -16608,15 +16565,17 @@ static void alc663_mode3_unsol_event(struct hda_codec *codec,
16608 alc663_two_hp_m1_speaker_automute(codec); 16565 alc663_two_hp_m1_speaker_automute(codec);
16609 break; 16566 break;
16610 case ALC880_MIC_EVENT: 16567 case ALC880_MIC_EVENT:
16611 alc662_eeepc_mic_automute(codec); 16568 alc_mic_automute(codec);
16612 break; 16569 break;
16613 } 16570 }
16614} 16571}
16615 16572
16573#define alc663_mode3_setup alc663_m51va_setup
16574
16616static void alc663_mode3_inithook(struct hda_codec *codec) 16575static void alc663_mode3_inithook(struct hda_codec *codec)
16617{ 16576{
16618 alc663_two_hp_m1_speaker_automute(codec); 16577 alc663_two_hp_m1_speaker_automute(codec);
16619 alc662_eeepc_mic_automute(codec); 16578 alc_mic_automute(codec);
16620} 16579}
16621/* ***************** Mode4 ******************************/ 16580/* ***************** Mode4 ******************************/
16622static void alc663_mode4_unsol_event(struct hda_codec *codec, 16581static void alc663_mode4_unsol_event(struct hda_codec *codec,
@@ -16627,15 +16586,17 @@ static void alc663_mode4_unsol_event(struct hda_codec *codec,
16627 alc663_21jd_two_speaker_automute(codec); 16586 alc663_21jd_two_speaker_automute(codec);
16628 break; 16587 break;
16629 case ALC880_MIC_EVENT: 16588 case ALC880_MIC_EVENT:
16630 alc662_eeepc_mic_automute(codec); 16589 alc_mic_automute(codec);
16631 break; 16590 break;
16632 } 16591 }
16633} 16592}
16634 16593
16594#define alc663_mode4_setup alc663_m51va_setup
16595
16635static void alc663_mode4_inithook(struct hda_codec *codec) 16596static void alc663_mode4_inithook(struct hda_codec *codec)
16636{ 16597{
16637 alc663_21jd_two_speaker_automute(codec); 16598 alc663_21jd_two_speaker_automute(codec);
16638 alc662_eeepc_mic_automute(codec); 16599 alc_mic_automute(codec);
16639} 16600}
16640/* ***************** Mode5 ******************************/ 16601/* ***************** Mode5 ******************************/
16641static void alc663_mode5_unsol_event(struct hda_codec *codec, 16602static void alc663_mode5_unsol_event(struct hda_codec *codec,
@@ -16646,15 +16607,17 @@ static void alc663_mode5_unsol_event(struct hda_codec *codec,
16646 alc663_15jd_two_speaker_automute(codec); 16607 alc663_15jd_two_speaker_automute(codec);
16647 break; 16608 break;
16648 case ALC880_MIC_EVENT: 16609 case ALC880_MIC_EVENT:
16649 alc662_eeepc_mic_automute(codec); 16610 alc_mic_automute(codec);
16650 break; 16611 break;
16651 } 16612 }
16652} 16613}
16653 16614
16615#define alc663_mode5_setup alc663_m51va_setup
16616
16654static void alc663_mode5_inithook(struct hda_codec *codec) 16617static void alc663_mode5_inithook(struct hda_codec *codec)
16655{ 16618{
16656 alc663_15jd_two_speaker_automute(codec); 16619 alc663_15jd_two_speaker_automute(codec);
16657 alc662_eeepc_mic_automute(codec); 16620 alc_mic_automute(codec);
16658} 16621}
16659/* ***************** Mode6 ******************************/ 16622/* ***************** Mode6 ******************************/
16660static void alc663_mode6_unsol_event(struct hda_codec *codec, 16623static void alc663_mode6_unsol_event(struct hda_codec *codec,
@@ -16665,15 +16628,17 @@ static void alc663_mode6_unsol_event(struct hda_codec *codec,
16665 alc663_two_hp_m2_speaker_automute(codec); 16628 alc663_two_hp_m2_speaker_automute(codec);
16666 break; 16629 break;
16667 case ALC880_MIC_EVENT: 16630 case ALC880_MIC_EVENT:
16668 alc662_eeepc_mic_automute(codec); 16631 alc_mic_automute(codec);
16669 break; 16632 break;
16670 } 16633 }
16671} 16634}
16672 16635
16636#define alc663_mode6_setup alc663_m51va_setup
16637
16673static void alc663_mode6_inithook(struct hda_codec *codec) 16638static void alc663_mode6_inithook(struct hda_codec *codec)
16674{ 16639{
16675 alc663_two_hp_m2_speaker_automute(codec); 16640 alc663_two_hp_m2_speaker_automute(codec);
16676 alc662_eeepc_mic_automute(codec); 16641 alc_mic_automute(codec);
16677} 16642}
16678 16643
16679static void alc663_g71v_hp_automute(struct hda_codec *codec) 16644static void alc663_g71v_hp_automute(struct hda_codec *codec)
@@ -16715,16 +16680,18 @@ static void alc663_g71v_unsol_event(struct hda_codec *codec,
16715 alc663_g71v_front_automute(codec); 16680 alc663_g71v_front_automute(codec);
16716 break; 16681 break;
16717 case ALC880_MIC_EVENT: 16682 case ALC880_MIC_EVENT:
16718 alc662_eeepc_mic_automute(codec); 16683 alc_mic_automute(codec);
16719 break; 16684 break;
16720 } 16685 }
16721} 16686}
16722 16687
16688#define alc663_g71v_setup alc663_m51va_setup
16689
16723static void alc663_g71v_inithook(struct hda_codec *codec) 16690static void alc663_g71v_inithook(struct hda_codec *codec)
16724{ 16691{
16725 alc663_g71v_front_automute(codec); 16692 alc663_g71v_front_automute(codec);
16726 alc663_g71v_hp_automute(codec); 16693 alc663_g71v_hp_automute(codec);
16727 alc662_eeepc_mic_automute(codec); 16694 alc_mic_automute(codec);
16728} 16695}
16729 16696
16730static void alc663_g50v_unsol_event(struct hda_codec *codec, 16697static void alc663_g50v_unsol_event(struct hda_codec *codec,
@@ -16735,15 +16702,17 @@ static void alc663_g50v_unsol_event(struct hda_codec *codec,
16735 alc663_m51va_speaker_automute(codec); 16702 alc663_m51va_speaker_automute(codec);
16736 break; 16703 break;
16737 case ALC880_MIC_EVENT: 16704 case ALC880_MIC_EVENT:
16738 alc662_eeepc_mic_automute(codec); 16705 alc_mic_automute(codec);
16739 break; 16706 break;
16740 } 16707 }
16741} 16708}
16742 16709
16710#define alc663_g50v_setup alc663_m51va_setup
16711
16743static void alc663_g50v_inithook(struct hda_codec *codec) 16712static void alc663_g50v_inithook(struct hda_codec *codec)
16744{ 16713{
16745 alc663_m51va_speaker_automute(codec); 16714 alc663_m51va_speaker_automute(codec);
16746 alc662_eeepc_mic_automute(codec); 16715 alc_mic_automute(codec);
16747} 16716}
16748 16717
16749static struct snd_kcontrol_new alc662_ecs_mixer[] = { 16718static struct snd_kcontrol_new alc662_ecs_mixer[] = {
@@ -16947,8 +16916,8 @@ static struct alc_config_preset alc662_presets[] = {
16947 .dac_nids = alc662_dac_nids, 16916 .dac_nids = alc662_dac_nids,
16948 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16917 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16949 .channel_mode = alc662_3ST_2ch_modes, 16918 .channel_mode = alc662_3ST_2ch_modes,
16950 .input_mux = &alc662_eeepc_capture_source,
16951 .unsol_event = alc662_eeepc_unsol_event, 16919 .unsol_event = alc662_eeepc_unsol_event,
16920 .setup = alc662_eeepc_setup,
16952 .init_hook = alc662_eeepc_inithook, 16921 .init_hook = alc662_eeepc_inithook,
16953 }, 16922 },
16954 [ALC662_ASUS_EEEPC_EP20] = { 16923 [ALC662_ASUS_EEEPC_EP20] = {
@@ -16962,6 +16931,7 @@ static struct alc_config_preset alc662_presets[] = {
16962 .channel_mode = alc662_3ST_6ch_modes, 16931 .channel_mode = alc662_3ST_6ch_modes,
16963 .input_mux = &alc662_lenovo_101e_capture_source, 16932 .input_mux = &alc662_lenovo_101e_capture_source,
16964 .unsol_event = alc662_eeepc_unsol_event, 16933 .unsol_event = alc662_eeepc_unsol_event,
16934 .setup = alc662_eeepc_ep20_setup,
16965 .init_hook = alc662_eeepc_ep20_inithook, 16935 .init_hook = alc662_eeepc_ep20_inithook,
16966 }, 16936 },
16967 [ALC662_ECS] = { 16937 [ALC662_ECS] = {
@@ -16972,8 +16942,8 @@ static struct alc_config_preset alc662_presets[] = {
16972 .dac_nids = alc662_dac_nids, 16942 .dac_nids = alc662_dac_nids,
16973 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16943 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16974 .channel_mode = alc662_3ST_2ch_modes, 16944 .channel_mode = alc662_3ST_2ch_modes,
16975 .input_mux = &alc662_eeepc_capture_source,
16976 .unsol_event = alc662_eeepc_unsol_event, 16945 .unsol_event = alc662_eeepc_unsol_event,
16946 .setup = alc662_eeepc_setup,
16977 .init_hook = alc662_eeepc_inithook, 16947 .init_hook = alc662_eeepc_inithook,
16978 }, 16948 },
16979 [ALC663_ASUS_M51VA] = { 16949 [ALC663_ASUS_M51VA] = {
@@ -16984,8 +16954,8 @@ static struct alc_config_preset alc662_presets[] = {
16984 .dig_out_nid = ALC662_DIGOUT_NID, 16954 .dig_out_nid = ALC662_DIGOUT_NID,
16985 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16955 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16986 .channel_mode = alc662_3ST_2ch_modes, 16956 .channel_mode = alc662_3ST_2ch_modes,
16987 .input_mux = &alc663_m51va_capture_source,
16988 .unsol_event = alc663_m51va_unsol_event, 16957 .unsol_event = alc663_m51va_unsol_event,
16958 .setup = alc663_m51va_setup,
16989 .init_hook = alc663_m51va_inithook, 16959 .init_hook = alc663_m51va_inithook,
16990 }, 16960 },
16991 [ALC663_ASUS_G71V] = { 16961 [ALC663_ASUS_G71V] = {
@@ -16996,8 +16966,8 @@ static struct alc_config_preset alc662_presets[] = {
16996 .dig_out_nid = ALC662_DIGOUT_NID, 16966 .dig_out_nid = ALC662_DIGOUT_NID,
16997 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16967 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
16998 .channel_mode = alc662_3ST_2ch_modes, 16968 .channel_mode = alc662_3ST_2ch_modes,
16999 .input_mux = &alc662_eeepc_capture_source,
17000 .unsol_event = alc663_g71v_unsol_event, 16969 .unsol_event = alc663_g71v_unsol_event,
16970 .setup = alc663_g71v_setup,
17001 .init_hook = alc663_g71v_inithook, 16971 .init_hook = alc663_g71v_inithook,
17002 }, 16972 },
17003 [ALC663_ASUS_H13] = { 16973 [ALC663_ASUS_H13] = {
@@ -17007,7 +16977,6 @@ static struct alc_config_preset alc662_presets[] = {
17007 .dac_nids = alc662_dac_nids, 16977 .dac_nids = alc662_dac_nids,
17008 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 16978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17009 .channel_mode = alc662_3ST_2ch_modes, 16979 .channel_mode = alc662_3ST_2ch_modes,
17010 .input_mux = &alc663_m51va_capture_source,
17011 .unsol_event = alc663_m51va_unsol_event, 16980 .unsol_event = alc663_m51va_unsol_event,
17012 .init_hook = alc663_m51va_inithook, 16981 .init_hook = alc663_m51va_inithook,
17013 }, 16982 },
@@ -17021,6 +16990,7 @@ static struct alc_config_preset alc662_presets[] = {
17021 .channel_mode = alc662_3ST_6ch_modes, 16990 .channel_mode = alc662_3ST_6ch_modes,
17022 .input_mux = &alc663_capture_source, 16991 .input_mux = &alc663_capture_source,
17023 .unsol_event = alc663_g50v_unsol_event, 16992 .unsol_event = alc663_g50v_unsol_event,
16993 .setup = alc663_g50v_setup,
17024 .init_hook = alc663_g50v_inithook, 16994 .init_hook = alc663_g50v_inithook,
17025 }, 16995 },
17026 [ALC663_ASUS_MODE1] = { 16996 [ALC663_ASUS_MODE1] = {
@@ -17034,8 +17004,8 @@ static struct alc_config_preset alc662_presets[] = {
17034 .dig_out_nid = ALC662_DIGOUT_NID, 17004 .dig_out_nid = ALC662_DIGOUT_NID,
17035 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17005 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17036 .channel_mode = alc662_3ST_2ch_modes, 17006 .channel_mode = alc662_3ST_2ch_modes,
17037 .input_mux = &alc662_eeepc_capture_source,
17038 .unsol_event = alc663_mode1_unsol_event, 17007 .unsol_event = alc663_mode1_unsol_event,
17008 .setup = alc663_mode1_setup,
17039 .init_hook = alc663_mode1_inithook, 17009 .init_hook = alc663_mode1_inithook,
17040 }, 17010 },
17041 [ALC662_ASUS_MODE2] = { 17011 [ALC662_ASUS_MODE2] = {
@@ -17048,8 +17018,8 @@ static struct alc_config_preset alc662_presets[] = {
17048 .dig_out_nid = ALC662_DIGOUT_NID, 17018 .dig_out_nid = ALC662_DIGOUT_NID,
17049 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17019 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17050 .channel_mode = alc662_3ST_2ch_modes, 17020 .channel_mode = alc662_3ST_2ch_modes,
17051 .input_mux = &alc662_eeepc_capture_source,
17052 .unsol_event = alc662_mode2_unsol_event, 17021 .unsol_event = alc662_mode2_unsol_event,
17022 .setup = alc662_mode2_setup,
17053 .init_hook = alc662_mode2_inithook, 17023 .init_hook = alc662_mode2_inithook,
17054 }, 17024 },
17055 [ALC663_ASUS_MODE3] = { 17025 [ALC663_ASUS_MODE3] = {
@@ -17063,8 +17033,8 @@ static struct alc_config_preset alc662_presets[] = {
17063 .dig_out_nid = ALC662_DIGOUT_NID, 17033 .dig_out_nid = ALC662_DIGOUT_NID,
17064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17034 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17065 .channel_mode = alc662_3ST_2ch_modes, 17035 .channel_mode = alc662_3ST_2ch_modes,
17066 .input_mux = &alc662_eeepc_capture_source,
17067 .unsol_event = alc663_mode3_unsol_event, 17036 .unsol_event = alc663_mode3_unsol_event,
17037 .setup = alc663_mode3_setup,
17068 .init_hook = alc663_mode3_inithook, 17038 .init_hook = alc663_mode3_inithook,
17069 }, 17039 },
17070 [ALC663_ASUS_MODE4] = { 17040 [ALC663_ASUS_MODE4] = {
@@ -17078,8 +17048,8 @@ static struct alc_config_preset alc662_presets[] = {
17078 .dig_out_nid = ALC662_DIGOUT_NID, 17048 .dig_out_nid = ALC662_DIGOUT_NID,
17079 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17049 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17080 .channel_mode = alc662_3ST_2ch_modes, 17050 .channel_mode = alc662_3ST_2ch_modes,
17081 .input_mux = &alc662_eeepc_capture_source,
17082 .unsol_event = alc663_mode4_unsol_event, 17051 .unsol_event = alc663_mode4_unsol_event,
17052 .setup = alc663_mode4_setup,
17083 .init_hook = alc663_mode4_inithook, 17053 .init_hook = alc663_mode4_inithook,
17084 }, 17054 },
17085 [ALC663_ASUS_MODE5] = { 17055 [ALC663_ASUS_MODE5] = {
@@ -17093,8 +17063,8 @@ static struct alc_config_preset alc662_presets[] = {
17093 .dig_out_nid = ALC662_DIGOUT_NID, 17063 .dig_out_nid = ALC662_DIGOUT_NID,
17094 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17064 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17095 .channel_mode = alc662_3ST_2ch_modes, 17065 .channel_mode = alc662_3ST_2ch_modes,
17096 .input_mux = &alc662_eeepc_capture_source,
17097 .unsol_event = alc663_mode5_unsol_event, 17066 .unsol_event = alc663_mode5_unsol_event,
17067 .setup = alc663_mode5_setup,
17098 .init_hook = alc663_mode5_inithook, 17068 .init_hook = alc663_mode5_inithook,
17099 }, 17069 },
17100 [ALC663_ASUS_MODE6] = { 17070 [ALC663_ASUS_MODE6] = {
@@ -17108,8 +17078,8 @@ static struct alc_config_preset alc662_presets[] = {
17108 .dig_out_nid = ALC662_DIGOUT_NID, 17078 .dig_out_nid = ALC662_DIGOUT_NID,
17109 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17079 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17110 .channel_mode = alc662_3ST_2ch_modes, 17080 .channel_mode = alc662_3ST_2ch_modes,
17111 .input_mux = &alc662_eeepc_capture_source,
17112 .unsol_event = alc663_mode6_unsol_event, 17081 .unsol_event = alc663_mode6_unsol_event,
17082 .setup = alc663_mode6_setup,
17113 .init_hook = alc663_mode6_inithook, 17083 .init_hook = alc663_mode6_inithook,
17114 }, 17084 },
17115 [ALC272_DELL] = { 17085 [ALC272_DELL] = {
@@ -17123,8 +17093,8 @@ static struct alc_config_preset alc662_presets[] = {
17123 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), 17093 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
17124 .capsrc_nids = alc272_capsrc_nids, 17094 .capsrc_nids = alc272_capsrc_nids,
17125 .channel_mode = alc662_3ST_2ch_modes, 17095 .channel_mode = alc662_3ST_2ch_modes,
17126 .input_mux = &alc663_m51va_capture_source,
17127 .unsol_event = alc663_m51va_unsol_event, 17096 .unsol_event = alc663_m51va_unsol_event,
17097 .setup = alc663_m51va_setup,
17128 .init_hook = alc663_m51va_inithook, 17098 .init_hook = alc663_m51va_inithook,
17129 }, 17099 },
17130 [ALC272_DELL_ZM1] = { 17100 [ALC272_DELL_ZM1] = {
@@ -17135,11 +17105,11 @@ static struct alc_config_preset alc662_presets[] = {
17135 .dac_nids = alc662_dac_nids, 17105 .dac_nids = alc662_dac_nids,
17136 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17106 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17137 .adc_nids = alc662_adc_nids, 17107 .adc_nids = alc662_adc_nids,
17138 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), 17108 .num_adc_nids = 1,
17139 .capsrc_nids = alc662_capsrc_nids, 17109 .capsrc_nids = alc662_capsrc_nids,
17140 .channel_mode = alc662_3ST_2ch_modes, 17110 .channel_mode = alc662_3ST_2ch_modes,
17141 .input_mux = &alc663_m51va_capture_source,
17142 .unsol_event = alc663_m51va_unsol_event, 17111 .unsol_event = alc663_m51va_unsol_event,
17112 .setup = alc663_m51va_setup,
17143 .init_hook = alc663_m51va_inithook, 17113 .init_hook = alc663_m51va_inithook,
17144 }, 17114 },
17145 [ALC272_SAMSUNG_NC10] = { 17115 [ALC272_SAMSUNG_NC10] = {
@@ -17150,8 +17120,9 @@ static struct alc_config_preset alc662_presets[] = {
17150 .dac_nids = alc272_dac_nids, 17120 .dac_nids = alc272_dac_nids,
17151 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), 17121 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17152 .channel_mode = alc662_3ST_2ch_modes, 17122 .channel_mode = alc662_3ST_2ch_modes,
17153 .input_mux = &alc272_nc10_capture_source, 17123 /*.input_mux = &alc272_nc10_capture_source,*/
17154 .unsol_event = alc663_mode4_unsol_event, 17124 .unsol_event = alc663_mode4_unsol_event,
17125 .setup = alc663_mode4_setup,
17155 .init_hook = alc663_mode4_inithook, 17126 .init_hook = alc663_mode4_inithook,
17156 }, 17127 },
17157}; 17128};
@@ -17203,13 +17174,25 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec,
17203 if (err < 0) 17174 if (err < 0)
17204 return err; 17175 return err;
17205 } else { 17176 } else {
17206 sprintf(name, "%s Playback Volume", chname[i]); 17177 const char *pfx;
17178 if (cfg->line_outs == 1 &&
17179 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
17180 if (!cfg->hp_pins)
17181 pfx = "Speaker";
17182 else
17183 pfx = "PCM";
17184 } else
17185 pfx = chname[i];
17186 sprintf(name, "%s Playback Volume", pfx);
17207 err = add_control(spec, ALC_CTL_WIDGET_VOL, name, 17187 err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
17208 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 17188 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
17209 HDA_OUTPUT)); 17189 HDA_OUTPUT));
17210 if (err < 0) 17190 if (err < 0)
17211 return err; 17191 return err;
17212 sprintf(name, "%s Playback Switch", chname[i]); 17192 if (cfg->line_outs == 1 &&
17193 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
17194 pfx = "Speaker";
17195 sprintf(name, "%s Playback Switch", pfx);
17213 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, 17196 err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
17214 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i), 17197 HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i),
17215 3, 0, HDA_INPUT)); 17198 3, 0, HDA_INPUT));
@@ -17271,62 +17254,9 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
17271 return 0; 17254 return 0;
17272} 17255}
17273 17256
17274/* return the index of the src widget from the connection list of the nid.
17275 * return -1 if not found
17276 */
17277static int alc662_input_pin_idx(struct hda_codec *codec, hda_nid_t nid,
17278 hda_nid_t src)
17279{
17280 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
17281 int i, conns;
17282
17283 conns = snd_hda_get_connections(codec, nid, conn_list,
17284 ARRAY_SIZE(conn_list));
17285 if (conns < 0)
17286 return -1;
17287 for (i = 0; i < conns; i++)
17288 if (conn_list[i] == src)
17289 return i;
17290 return -1;
17291}
17292
17293static int alc662_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
17294{
17295 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
17296 return (pincap & AC_PINCAP_IN) != 0;
17297}
17298
17299/* create playback/capture controls for input pins */ 17257/* create playback/capture controls for input pins */
17300static int alc662_auto_create_analog_input_ctls(struct hda_codec *codec, 17258#define alc662_auto_create_input_ctls \
17301 const struct auto_pin_cfg *cfg) 17259 alc880_auto_create_input_ctls
17302{
17303 struct alc_spec *spec = codec->spec;
17304 struct hda_input_mux *imux = &spec->private_imux[0];
17305 int i, err, idx;
17306
17307 for (i = 0; i < AUTO_PIN_LAST; i++) {
17308 if (alc662_is_input_pin(codec, cfg->input_pins[i])) {
17309 idx = alc662_input_pin_idx(codec, 0x0b,
17310 cfg->input_pins[i]);
17311 if (idx >= 0) {
17312 err = new_analog_input(spec, cfg->input_pins[i],
17313 auto_pin_cfg_labels[i],
17314 idx, 0x0b);
17315 if (err < 0)
17316 return err;
17317 }
17318 idx = alc662_input_pin_idx(codec, 0x22,
17319 cfg->input_pins[i]);
17320 if (idx >= 0) {
17321 imux->items[imux->num_items].label =
17322 auto_pin_cfg_labels[i];
17323 imux->items[imux->num_items].index = idx;
17324 imux->num_items++;
17325 }
17326 }
17327 }
17328 return 0;
17329}
17330 17260
17331static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, 17261static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
17332 hda_nid_t nid, int pin_type, 17262 hda_nid_t nid, int pin_type,
@@ -17380,7 +17310,7 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec)
17380 17310
17381 for (i = 0; i < AUTO_PIN_LAST; i++) { 17311 for (i = 0; i < AUTO_PIN_LAST; i++) {
17382 hda_nid_t nid = spec->autocfg.input_pins[i]; 17312 hda_nid_t nid = spec->autocfg.input_pins[i];
17383 if (alc662_is_input_pin(codec, nid)) { 17313 if (alc_is_input_pin(codec, nid)) {
17384 alc_set_input_pin(codec, nid, i); 17314 alc_set_input_pin(codec, nid, i);
17385 if (nid != ALC662_PIN_CD_NID && 17315 if (nid != ALC662_PIN_CD_NID &&
17386 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) 17316 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
@@ -17421,7 +17351,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17421 "Headphone"); 17351 "Headphone");
17422 if (err < 0) 17352 if (err < 0)
17423 return err; 17353 return err;
17424 err = alc662_auto_create_analog_input_ctls(codec, &spec->autocfg); 17354 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
17425 if (err < 0) 17355 if (err < 0)
17426 return err; 17356 return err;
17427 17357
@@ -17478,8 +17408,8 @@ static int patch_alc662(struct hda_codec *codec)
17478 alc662_models, 17408 alc662_models,
17479 alc662_cfg_tbl); 17409 alc662_cfg_tbl);
17480 if (board_config < 0) { 17410 if (board_config < 0) {
17481 printk(KERN_INFO "hda_codec: Unknown model for %s, " 17411 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17482 "trying auto-probe from BIOS...\n", codec->chip_name); 17412 codec->chip_name);
17483 board_config = ALC662_AUTO; 17413 board_config = ALC662_AUTO;
17484 } 17414 }
17485 17415
@@ -17504,7 +17434,7 @@ static int patch_alc662(struct hda_codec *codec)
17504 } 17434 }
17505 17435
17506 if (board_config != ALC662_AUTO) 17436 if (board_config != ALC662_AUTO)
17507 setup_preset(spec, &alc662_presets[board_config]); 17437 setup_preset(codec, &alc662_presets[board_config]);
17508 17438
17509 spec->stream_analog_playback = &alc662_pcm_analog_playback; 17439 spec->stream_analog_playback = &alc662_pcm_analog_playback;
17510 spec->stream_analog_capture = &alc662_pcm_analog_capture; 17440 spec->stream_analog_capture = &alc662_pcm_analog_capture;
@@ -17520,7 +17450,7 @@ static int patch_alc662(struct hda_codec *codec)
17520 spec->capsrc_nids = alc662_capsrc_nids; 17450 spec->capsrc_nids = alc662_capsrc_nids;
17521 17451
17522 if (!spec->cap_mixer) 17452 if (!spec->cap_mixer)
17523 set_capture_mixer(spec); 17453 set_capture_mixer(codec);
17524 if (codec->vendor_id == 0x10ec0662) 17454 if (codec->vendor_id == 0x10ec0662)
17525 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 17455 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17526 else 17456 else
@@ -17556,23 +17486,23 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
17556 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, 17486 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
17557 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, 17487 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
17558 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", 17488 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
17559 .patch = patch_alc883 }, 17489 .patch = patch_alc882 },
17560 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 17490 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
17561 .patch = patch_alc662 }, 17491 .patch = patch_alc662 },
17562 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 17492 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
17563 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 17493 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
17564 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 17494 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
17565 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 17495 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
17566 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", 17496 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
17567 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17497 .patch = patch_alc882 },
17568 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", 17498 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
17569 .patch = patch_alc882 }, /* should be patch_alc883() in future */ 17499 .patch = patch_alc882 },
17570 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 17500 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
17571 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, 17501 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 },
17572 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", 17502 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
17573 .patch = patch_alc883 }, 17503 .patch = patch_alc882 },
17574 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 17504 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 },
17575 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 17505 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
17576 {} /* terminator */ 17506 {} /* terminator */
17577}; 17507};
17578 17508
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6990cfcb6a38..e31e53dc6962 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -40,6 +40,8 @@ enum {
40 STAC_INSERT_EVENT, 40 STAC_INSERT_EVENT,
41 STAC_PWR_EVENT, 41 STAC_PWR_EVENT,
42 STAC_HP_EVENT, 42 STAC_HP_EVENT,
43 STAC_LO_EVENT,
44 STAC_MIC_EVENT,
43}; 45};
44 46
45enum { 47enum {
@@ -81,6 +83,7 @@ enum {
81 STAC_DELL_M6_DMIC, 83 STAC_DELL_M6_DMIC,
82 STAC_DELL_M6_BOTH, 84 STAC_DELL_M6_BOTH,
83 STAC_DELL_EQ, 85 STAC_DELL_EQ,
86 STAC_ALIENWARE_M17X,
84 STAC_92HD73XX_MODELS 87 STAC_92HD73XX_MODELS
85}; 88};
86 89
@@ -177,6 +180,12 @@ struct sigmatel_jack {
177 struct snd_jack *jack; 180 struct snd_jack *jack;
178}; 181};
179 182
183struct sigmatel_mic_route {
184 hda_nid_t pin;
185 unsigned char mux_idx;
186 unsigned char dmux_idx;
187};
188
180struct sigmatel_spec { 189struct sigmatel_spec {
181 struct snd_kcontrol_new *mixers[4]; 190 struct snd_kcontrol_new *mixers[4];
182 unsigned int num_mixers; 191 unsigned int num_mixers;
@@ -188,6 +197,7 @@ struct sigmatel_spec {
188 unsigned int hp_detect: 1; 197 unsigned int hp_detect: 1;
189 unsigned int spdif_mute: 1; 198 unsigned int spdif_mute: 1;
190 unsigned int check_volume_offset:1; 199 unsigned int check_volume_offset:1;
200 unsigned int auto_mic:1;
191 201
192 /* gpio lines */ 202 /* gpio lines */
193 unsigned int eapd_mask; 203 unsigned int eapd_mask;
@@ -219,7 +229,6 @@ struct sigmatel_spec {
219 229
220 /* playback */ 230 /* playback */
221 struct hda_input_mux *mono_mux; 231 struct hda_input_mux *mono_mux;
222 struct hda_input_mux *amp_mux;
223 unsigned int cur_mmux; 232 unsigned int cur_mmux;
224 struct hda_multi_out multiout; 233 struct hda_multi_out multiout;
225 hda_nid_t dac_nids[5]; 234 hda_nid_t dac_nids[5];
@@ -239,6 +248,15 @@ struct sigmatel_spec {
239 unsigned int num_dmuxes; 248 unsigned int num_dmuxes;
240 hda_nid_t *smux_nids; 249 hda_nid_t *smux_nids;
241 unsigned int num_smuxes; 250 unsigned int num_smuxes;
251 unsigned int num_analog_muxes;
252
253 unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */
254 unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */
255 unsigned int num_caps; /* number of capture volume/switch elements */
256
257 struct sigmatel_mic_route ext_mic;
258 struct sigmatel_mic_route int_mic;
259
242 const char **spdif_labels; 260 const char **spdif_labels;
243 261
244 hda_nid_t dig_in_nid; 262 hda_nid_t dig_in_nid;
@@ -263,7 +281,6 @@ struct sigmatel_spec {
263 unsigned int cur_smux[2]; 281 unsigned int cur_smux[2];
264 unsigned int cur_amux; 282 unsigned int cur_amux;
265 hda_nid_t *amp_nids; 283 hda_nid_t *amp_nids;
266 unsigned int num_amps;
267 unsigned int powerdown_adcs; 284 unsigned int powerdown_adcs;
268 285
269 /* i/o switches */ 286 /* i/o switches */
@@ -282,7 +299,6 @@ struct sigmatel_spec {
282 struct hda_input_mux private_dimux; 299 struct hda_input_mux private_dimux;
283 struct hda_input_mux private_imux; 300 struct hda_input_mux private_imux;
284 struct hda_input_mux private_smux; 301 struct hda_input_mux private_smux;
285 struct hda_input_mux private_amp_mux;
286 struct hda_input_mux private_mono_mux; 302 struct hda_input_mux private_mono_mux;
287}; 303};
288 304
@@ -311,11 +327,6 @@ static hda_nid_t stac92hd73xx_adc_nids[2] = {
311 0x1a, 0x1b 327 0x1a, 0x1b
312}; 328};
313 329
314#define DELL_M6_AMP 2
315static hda_nid_t stac92hd73xx_amp_nids[3] = {
316 0x0b, 0x0c, 0x0e
317};
318
319#define STAC92HD73XX_NUM_DMICS 2 330#define STAC92HD73XX_NUM_DMICS 2
320static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 331static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
321 0x13, 0x14, 0 332 0x13, 0x14, 0
@@ -323,8 +334,8 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
323 334
324#define STAC92HD73_DAC_COUNT 5 335#define STAC92HD73_DAC_COUNT 5
325 336
326static hda_nid_t stac92hd73xx_mux_nids[4] = { 337static hda_nid_t stac92hd73xx_mux_nids[2] = {
327 0x28, 0x29, 0x2a, 0x2b, 338 0x20, 0x21,
328}; 339};
329 340
330static hda_nid_t stac92hd73xx_dmux_nids[2] = { 341static hda_nid_t stac92hd73xx_dmux_nids[2] = {
@@ -335,14 +346,16 @@ static hda_nid_t stac92hd73xx_smux_nids[2] = {
335 0x22, 0x23, 346 0x22, 0x23,
336}; 347};
337 348
338#define STAC92HD83XXX_NUM_DMICS 2 349#define STAC92HD73XX_NUM_CAPS 2
339static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 350static unsigned long stac92hd73xx_capvols[] = {
340 0x11, 0x12, 0 351 HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT),
352 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
341}; 353};
354#define stac92hd73xx_capsws stac92hd73xx_capvols
342 355
343#define STAC92HD83_DAC_COUNT 3 356#define STAC92HD83_DAC_COUNT 3
344 357
345static hda_nid_t stac92hd83xxx_dmux_nids[2] = { 358static hda_nid_t stac92hd83xxx_mux_nids[2] = {
346 0x17, 0x18, 359 0x17, 0x18,
347}; 360};
348 361
@@ -362,9 +375,12 @@ static unsigned int stac92hd83xxx_pwr_mapping[4] = {
362 0x03, 0x0c, 0x20, 0x40, 375 0x03, 0x0c, 0x20, 0x40,
363}; 376};
364 377
365static hda_nid_t stac92hd83xxx_amp_nids[1] = { 378#define STAC92HD83XXX_NUM_CAPS 2
366 0xc, 379static unsigned long stac92hd83xxx_capvols[] = {
380 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
381 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_OUTPUT),
367}; 382};
383#define stac92hd83xxx_capsws stac92hd83xxx_capvols
368 384
369static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 385static hda_nid_t stac92hd71bxx_pwr_nids[3] = {
370 0x0a, 0x0d, 0x0f 386 0x0a, 0x0d, 0x0f
@@ -395,6 +411,13 @@ static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = {
395 0x22, 0 411 0x22, 0
396}; 412};
397 413
414#define STAC92HD71BXX_NUM_CAPS 2
415static unsigned long stac92hd71bxx_capvols[] = {
416 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
417 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
418};
419#define stac92hd71bxx_capsws stac92hd71bxx_capvols
420
398static hda_nid_t stac925x_adc_nids[1] = { 421static hda_nid_t stac925x_adc_nids[1] = {
399 0x03, 422 0x03,
400}; 423};
@@ -416,6 +439,13 @@ static hda_nid_t stac925x_dmux_nids[1] = {
416 0x14, 439 0x14,
417}; 440};
418 441
442static unsigned long stac925x_capvols[] = {
443 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
444};
445static unsigned long stac925x_capsws[] = {
446 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
447};
448
419static hda_nid_t stac922x_adc_nids[2] = { 449static hda_nid_t stac922x_adc_nids[2] = {
420 0x06, 0x07, 450 0x06, 0x07,
421}; 451};
@@ -424,6 +454,13 @@ static hda_nid_t stac922x_mux_nids[2] = {
424 0x12, 0x13, 454 0x12, 0x13,
425}; 455};
426 456
457#define STAC922X_NUM_CAPS 2
458static unsigned long stac922x_capvols[] = {
459 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT),
460 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
461};
462#define stac922x_capsws stac922x_capvols
463
427static hda_nid_t stac927x_slave_dig_outs[2] = { 464static hda_nid_t stac927x_slave_dig_outs[2] = {
428 0x1f, 0, 465 0x1f, 0,
429}; 466};
@@ -453,6 +490,18 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = {
453 0x13, 0x14, 0 490 0x13, 0x14, 0
454}; 491};
455 492
493#define STAC927X_NUM_CAPS 3
494static unsigned long stac927x_capvols[] = {
495 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT),
496 HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT),
497 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT),
498};
499static unsigned long stac927x_capsws[] = {
500 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
501 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT),
502 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
503};
504
456static const char *stac927x_spdif_labels[5] = { 505static const char *stac927x_spdif_labels[5] = {
457 "Digital Playback", "ADAT", "Analog Mux 1", 506 "Digital Playback", "ADAT", "Analog Mux 1",
458 "Analog Mux 2", "Analog Mux 3" 507 "Analog Mux 2", "Analog Mux 3"
@@ -479,6 +528,16 @@ static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
479 0x17, 0x18, 0 528 0x17, 0x18, 0
480}; 529};
481 530
531#define STAC9205_NUM_CAPS 2
532static unsigned long stac9205_capvols[] = {
533 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT),
534 HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT),
535};
536static unsigned long stac9205_capsws[] = {
537 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
538 HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT),
539};
540
482static hda_nid_t stac9200_pin_nids[8] = { 541static hda_nid_t stac9200_pin_nids[8] = {
483 0x08, 0x09, 0x0d, 0x0e, 542 0x08, 0x09, 0x0d, 0x0e,
484 0x0f, 0x10, 0x11, 0x12, 543 0x0f, 0x10, 0x11, 0x12,
@@ -529,34 +588,6 @@ static hda_nid_t stac9205_pin_nids[12] = {
529 0x21, 0x22, 588 0x21, 0x22,
530}; 589};
531 590
532#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info
533
534static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol,
535 struct snd_ctl_elem_value *ucontrol)
536{
537 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
538 struct sigmatel_spec *spec = codec->spec;
539 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
540
541 kcontrol->private_value ^= get_amp_nid(kcontrol);
542 kcontrol->private_value |= nid;
543
544 return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol);
545}
546
547static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol,
548 struct snd_ctl_elem_value *ucontrol)
549{
550 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
551 struct sigmatel_spec *spec = codec->spec;
552 hda_nid_t nid = spec->amp_nids[spec->cur_amux];
553
554 kcontrol->private_value ^= get_amp_nid(kcontrol);
555 kcontrol->private_value |= nid;
556
557 return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
558}
559
560static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, 591static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
561 struct snd_ctl_elem_info *uinfo) 592 struct snd_ctl_elem_info *uinfo)
562{ 593{
@@ -693,9 +724,35 @@ static int stac92xx_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
693 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 724 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
694 struct sigmatel_spec *spec = codec->spec; 725 struct sigmatel_spec *spec = codec->spec;
695 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 726 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
696 727 const struct hda_input_mux *imux = spec->input_mux;
697 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 728 unsigned int idx, prev_idx;
698 spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); 729
730 idx = ucontrol->value.enumerated.item[0];
731 if (idx >= imux->num_items)
732 idx = imux->num_items - 1;
733 prev_idx = spec->cur_mux[adc_idx];
734 if (prev_idx == idx)
735 return 0;
736 if (idx < spec->num_analog_muxes) {
737 snd_hda_codec_write_cache(codec, spec->mux_nids[adc_idx], 0,
738 AC_VERB_SET_CONNECT_SEL,
739 imux->items[idx].index);
740 if (prev_idx >= spec->num_analog_muxes) {
741 imux = spec->dinput_mux;
742 /* 0 = analog */
743 snd_hda_codec_write_cache(codec,
744 spec->dmux_nids[adc_idx], 0,
745 AC_VERB_SET_CONNECT_SEL,
746 imux->items[0].index);
747 }
748 } else {
749 imux = spec->dinput_mux;
750 snd_hda_codec_write_cache(codec, spec->dmux_nids[adc_idx], 0,
751 AC_VERB_SET_CONNECT_SEL,
752 imux->items[idx - 1].index);
753 }
754 spec->cur_mux[adc_idx] = idx;
755 return 1;
699} 756}
700 757
701static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol, 758static int stac92xx_mono_mux_enum_info(struct snd_kcontrol *kcontrol,
@@ -726,41 +783,6 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol,
726 spec->mono_nid, &spec->cur_mmux); 783 spec->mono_nid, &spec->cur_mmux);
727} 784}
728 785
729static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol,
730 struct snd_ctl_elem_info *uinfo)
731{
732 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
733 struct sigmatel_spec *spec = codec->spec;
734 return snd_hda_input_mux_info(spec->amp_mux, uinfo);
735}
736
737static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
739{
740 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
741 struct sigmatel_spec *spec = codec->spec;
742
743 ucontrol->value.enumerated.item[0] = spec->cur_amux;
744 return 0;
745}
746
747static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol,
748 struct snd_ctl_elem_value *ucontrol)
749{
750 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
751 struct sigmatel_spec *spec = codec->spec;
752 struct snd_kcontrol *ctl =
753 snd_hda_find_mixer_ctl(codec, "Amp Capture Volume");
754 if (!ctl)
755 return -EINVAL;
756
757 snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE |
758 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
759
760 return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol,
761 0, &spec->cur_amux);
762}
763
764#define stac92xx_aloopback_info snd_ctl_boolean_mono_info 786#define stac92xx_aloopback_info snd_ctl_boolean_mono_info
765 787
766static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, 788static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol,
@@ -828,84 +850,16 @@ static struct hda_verb stac9200_eapd_init[] = {
828 {} 850 {}
829}; 851};
830 852
831static struct hda_verb stac92hd73xx_6ch_core_init[] = {
832 /* set master volume and direct control */
833 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
834 /* setup adcs to point to mixer */
835 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
836 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
837 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
838 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
839 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
840 /* setup import muxs */
841 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
842 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
843 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
844 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
845 {}
846};
847
848static struct hda_verb dell_eq_core_init[] = { 853static struct hda_verb dell_eq_core_init[] = {
849 /* set master volume to max value without distortion 854 /* set master volume to max value without distortion
850 * and direct control */ 855 * and direct control */
851 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 856 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
852 /* setup adcs to point to mixer */
853 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
854 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
855 /* setup import muxs */
856 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
857 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
858 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
859 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
860 {}
861};
862
863static struct hda_verb dell_m6_core_init[] = {
864 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
865 /* setup adcs to point to mixer */
866 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
867 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
868 /* setup import muxs */
869 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
870 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
871 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
872 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00},
873 {}
874};
875
876static struct hda_verb stac92hd73xx_8ch_core_init[] = {
877 /* set master volume and direct control */
878 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
879 /* setup adcs to point to mixer */
880 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
881 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
882 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
883 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
884 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
885 /* setup import muxs */
886 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
887 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
888 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
889 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
890 {} 857 {}
891}; 858};
892 859
893static struct hda_verb stac92hd73xx_10ch_core_init[] = { 860static struct hda_verb stac92hd73xx_core_init[] = {
894 /* set master volume and direct control */ 861 /* set master volume and direct control */
895 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 862 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
896 /* dac3 is connected to import3 mux */
897 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
898 /* setup adcs to point to mixer */
899 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
900 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
901 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
902 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
903 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
904 /* setup import muxs */
905 { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01},
906 { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01},
907 { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01},
908 { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x03},
909 {} 863 {}
910}; 864};
911 865
@@ -925,19 +879,6 @@ static struct hda_verb stac92hd71bxx_core_init[] = {
925 {} 879 {}
926}; 880};
927 881
928#define HD_DISABLE_PORTF 1
929static struct hda_verb stac92hd71bxx_analog_core_init[] = {
930 /* start of config #1 */
931
932 /* connect port 0f to audio mixer */
933 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2},
934 /* start of config #2 */
935
936 /* set master volume and direct control */
937 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
938 {}
939};
940
941static struct hda_verb stac92hd71bxx_unmute_core_init[] = { 882static struct hda_verb stac92hd71bxx_unmute_core_init[] = {
942 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 883 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
943 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 884 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -996,31 +937,6 @@ static struct hda_verb stac9205_core_init[] = {
996 .put = stac92xx_mono_mux_enum_put, \ 937 .put = stac92xx_mono_mux_enum_put, \
997 } 938 }
998 939
999#define STAC_AMP_MUX \
1000 { \
1001 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1002 .name = "Amp Selector Capture Switch", \
1003 .count = 1, \
1004 .info = stac92xx_amp_mux_enum_info, \
1005 .get = stac92xx_amp_mux_enum_get, \
1006 .put = stac92xx_amp_mux_enum_put, \
1007 }
1008
1009#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \
1010 { \
1011 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1012 .name = xname, \
1013 .index = 0, \
1014 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1015 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1016 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
1017 .info = stac92xx_amp_volume_info, \
1018 .get = stac92xx_amp_volume_get, \
1019 .put = stac92xx_amp_volume_put, \
1020 .tlv = { .c = snd_hda_mixer_amp_tlv }, \
1021 .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \
1022 }
1023
1024#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ 940#define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \
1025 { \ 941 { \
1026 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 942 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -1051,34 +967,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
1051 { } /* end */ 967 { } /* end */
1052}; 968};
1053 969
1054#define DELL_M6_MIXER 6
1055static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = {
1056 /* start of config #1 */
1057 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1058 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1059
1060 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1061 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1062
1063 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1064 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1065
1066 /* start of config #2 */
1067 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1068 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1069
1070 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1071 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1072
1073 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1074 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1075
1076 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1077 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1078
1079 { } /* end */
1080};
1081
1082static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { 970static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = {
1083 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), 971 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3),
1084 {} 972 {}
@@ -1094,134 +982,14 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = {
1094 {} 982 {}
1095}; 983};
1096 984
1097static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = {
1098 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1099 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1100
1101 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1102 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1103
1104 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1105 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1106
1107 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1108 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1109
1110 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1111 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1112
1113 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1114 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1115
1116 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1117 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1118 { } /* end */
1119};
1120
1121static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = {
1122 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT),
1123 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT),
1124
1125 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT),
1126 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT),
1127
1128 HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT),
1129 HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT),
1130
1131 HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT),
1132 HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT),
1133
1134 HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT),
1135 HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT),
1136
1137 HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT),
1138 HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT),
1139
1140 HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT),
1141 HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT),
1142 { } /* end */
1143};
1144
1145
1146static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1147 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT),
1148 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT),
1149
1150 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1151 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1152
1153 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
1154 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
1155
1156 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
1157 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
1158
1159 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
1160 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
1161
1162 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
1163 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
1164
1165 /*
1166 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
1167 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
1168 */
1169 { } /* end */
1170};
1171
1172static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = {
1173 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1174 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1175
1176 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1177 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1178 /* analog pc-beep replaced with digital beep support */
1179 /*
1180 HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT),
1181 HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT),
1182 */
1183
1184 HDA_CODEC_MUTE("Import0 Mux Capture Switch", 0x17, 0x0, HDA_INPUT),
1185 HDA_CODEC_VOLUME("Import0 Mux Capture Volume", 0x17, 0x0, HDA_INPUT),
1186
1187 HDA_CODEC_MUTE("Import1 Mux Capture Switch", 0x17, 0x1, HDA_INPUT),
1188 HDA_CODEC_VOLUME("Import1 Mux Capture Volume", 0x17, 0x1, HDA_INPUT),
1189
1190 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x17, 0x3, HDA_INPUT),
1191 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x17, 0x3, HDA_INPUT),
1192
1193 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x17, 0x4, HDA_INPUT),
1194 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x17, 0x4, HDA_INPUT),
1195 { } /* end */
1196};
1197 985
1198static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { 986static struct snd_kcontrol_new stac92hd71bxx_loopback[] = {
1199 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) 987 STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2)
1200}; 988};
1201 989
1202static struct snd_kcontrol_new stac92hd71bxx_mixer[] = {
1203 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1204 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT),
1205
1206 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1207 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT),
1208 { } /* end */
1209};
1210
1211static struct snd_kcontrol_new stac925x_mixer[] = { 990static struct snd_kcontrol_new stac925x_mixer[] = {
1212 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), 991 HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT),
1213 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), 992 HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT),
1214 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
1215 HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT),
1216 { } /* end */
1217};
1218
1219static struct snd_kcontrol_new stac9205_mixer[] = {
1220 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT),
1221 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT),
1222
1223 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT),
1224 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT),
1225 { } /* end */ 993 { } /* end */
1226}; 994};
1227 995
@@ -1230,29 +998,6 @@ static struct snd_kcontrol_new stac9205_loopback[] = {
1230 {} 998 {}
1231}; 999};
1232 1000
1233/* This needs to be generated dynamically based on sequence */
1234static struct snd_kcontrol_new stac922x_mixer[] = {
1235 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT),
1236 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT),
1237
1238 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT),
1239 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT),
1240 { } /* end */
1241};
1242
1243
1244static struct snd_kcontrol_new stac927x_mixer[] = {
1245 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT),
1246 HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT),
1247
1248 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT),
1249 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT),
1250
1251 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT),
1252 HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT),
1253 { } /* end */
1254};
1255
1256static struct snd_kcontrol_new stac927x_loopback[] = { 1001static struct snd_kcontrol_new stac927x_loopback[] = {
1257 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), 1002 STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1),
1258 {} 1003 {}
@@ -1310,16 +1055,19 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1310 int err; 1055 int err;
1311 int i; 1056 int i;
1312 1057
1313 err = snd_hda_add_new_ctls(codec, spec->mixer); 1058 if (spec->mixer) {
1314 if (err < 0) 1059 err = snd_hda_add_new_ctls(codec, spec->mixer);
1315 return err; 1060 if (err < 0)
1061 return err;
1062 }
1316 1063
1317 for (i = 0; i < spec->num_mixers; i++) { 1064 for (i = 0; i < spec->num_mixers; i++) {
1318 err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 1065 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
1319 if (err < 0) 1066 if (err < 0)
1320 return err; 1067 return err;
1321 } 1068 }
1322 if (spec->num_dmuxes > 0) { 1069 if (!spec->auto_mic && spec->num_dmuxes > 0 &&
1070 snd_hda_get_bool_hint(codec, "separate_dmux") == 1) {
1323 stac_dmux_mixer.count = spec->num_dmuxes; 1071 stac_dmux_mixer.count = spec->num_dmuxes;
1324 err = snd_hda_ctl_add(codec, 1072 err = snd_hda_ctl_add(codec,
1325 snd_ctl_new1(&stac_dmux_mixer, codec)); 1073 snd_ctl_new1(&stac_dmux_mixer, codec));
@@ -1766,12 +1514,20 @@ static unsigned int dell_m6_pin_configs[13] = {
1766 0x4f0000f0, 1514 0x4f0000f0,
1767}; 1515};
1768 1516
1517static unsigned int alienware_m17x_pin_configs[13] = {
1518 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020,
1519 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0,
1520 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0,
1521 0x904601b0,
1522};
1523
1769static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { 1524static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1770 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, 1525 [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs,
1771 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, 1526 [STAC_DELL_M6_AMIC] = dell_m6_pin_configs,
1772 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, 1527 [STAC_DELL_M6_DMIC] = dell_m6_pin_configs,
1773 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs, 1528 [STAC_DELL_M6_BOTH] = dell_m6_pin_configs,
1774 [STAC_DELL_EQ] = dell_m6_pin_configs, 1529 [STAC_DELL_EQ] = dell_m6_pin_configs,
1530 [STAC_ALIENWARE_M17X] = alienware_m17x_pin_configs,
1775}; 1531};
1776 1532
1777static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1533static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
@@ -1783,6 +1539,7 @@ static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1783 [STAC_DELL_M6_DMIC] = "dell-m6-dmic", 1539 [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
1784 [STAC_DELL_M6_BOTH] = "dell-m6", 1540 [STAC_DELL_M6_BOTH] = "dell-m6",
1785 [STAC_DELL_EQ] = "dell-eq", 1541 [STAC_DELL_EQ] = "dell-eq",
1542 [STAC_ALIENWARE_M17X] = "alienware",
1786}; 1543};
1787 1544
1788static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { 1545static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
@@ -1820,6 +1577,12 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1820 {} /* terminator */ 1577 {} /* terminator */
1821}; 1578};
1822 1579
1580static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = {
1581 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1,
1582 "Alienware M17x", STAC_ALIENWARE_M17X),
1583 {} /* terminator */
1584};
1585
1823static unsigned int ref92hd83xxx_pin_configs[10] = { 1586static unsigned int ref92hd83xxx_pin_configs[10] = {
1824 0x02214030, 0x02211010, 0x02a19020, 0x02170130, 1587 0x02214030, 0x02211010, 0x02a19020, 0x02170130,
1825 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, 1588 0x01014050, 0x01819040, 0x01014020, 0x90a3014e,
@@ -1927,6 +1690,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1927 "HP mini 1000", STAC_HP_M4), 1690 "HP mini 1000", STAC_HP_M4),
1928 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, 1691 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b,
1929 "HP HDX", STAC_HP_HDX), /* HDX16 */ 1692 "HP HDX", STAC_HP_HDX), /* HDX16 */
1693 SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x7010,
1694 "HP", STAC_HP_DV5),
1930 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1695 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
1931 "unknown Dell", STAC_DELL_M4_1), 1696 "unknown Dell", STAC_DELL_M4_1),
1932 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, 1697 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234,
@@ -2642,8 +2407,7 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2642 return 0; 2407 return 0;
2643} 2408}
2644 2409
2645static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 2410static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid);
2646 unsigned char type);
2647 2411
2648static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, 2412static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2649 struct snd_ctl_elem_value *ucontrol) 2413 struct snd_ctl_elem_value *ucontrol)
@@ -2657,7 +2421,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2657 /* check to be sure that the ports are upto date with 2421 /* check to be sure that the ports are upto date with
2658 * switch changes 2422 * switch changes
2659 */ 2423 */
2660 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2424 stac_issue_unsol_event(codec, nid);
2661 2425
2662 return 1; 2426 return 1;
2663} 2427}
@@ -2790,7 +2554,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2790 * appropriately according to the pin direction 2554 * appropriately according to the pin direction
2791 */ 2555 */
2792 if (spec->hp_detect) 2556 if (spec->hp_detect)
2793 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); 2557 stac_issue_unsol_event(codec, nid);
2794 2558
2795 return 1; 2559 return 1;
2796} 2560}
@@ -2859,8 +2623,6 @@ enum {
2859 STAC_CTL_WIDGET_VOL, 2623 STAC_CTL_WIDGET_VOL,
2860 STAC_CTL_WIDGET_MUTE, 2624 STAC_CTL_WIDGET_MUTE,
2861 STAC_CTL_WIDGET_MONO_MUX, 2625 STAC_CTL_WIDGET_MONO_MUX,
2862 STAC_CTL_WIDGET_AMP_MUX,
2863 STAC_CTL_WIDGET_AMP_VOL,
2864 STAC_CTL_WIDGET_HP_SWITCH, 2626 STAC_CTL_WIDGET_HP_SWITCH,
2865 STAC_CTL_WIDGET_IO_SWITCH, 2627 STAC_CTL_WIDGET_IO_SWITCH,
2866 STAC_CTL_WIDGET_CLFE_SWITCH, 2628 STAC_CTL_WIDGET_CLFE_SWITCH,
@@ -2871,8 +2633,6 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = {
2871 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2633 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
2872 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2634 HDA_CODEC_MUTE(NULL, 0, 0, 0),
2873 STAC_MONO_MUX, 2635 STAC_MONO_MUX,
2874 STAC_AMP_MUX,
2875 STAC_AMP_VOL(NULL, 0, 0, 0, 0),
2876 STAC_CODEC_HP_SWITCH(NULL), 2636 STAC_CODEC_HP_SWITCH(NULL),
2877 STAC_CODEC_IO_SWITCH(NULL, 0), 2637 STAC_CODEC_IO_SWITCH(NULL, 0),
2878 STAC_CODEC_CLFE_SWITCH(NULL, 0), 2638 STAC_CODEC_CLFE_SWITCH(NULL, 0),
@@ -2973,6 +2733,8 @@ static int stac92xx_add_input_source(struct sigmatel_spec *spec)
2973 struct snd_kcontrol_new *knew; 2733 struct snd_kcontrol_new *knew;
2974 struct hda_input_mux *imux = &spec->private_imux; 2734 struct hda_input_mux *imux = &spec->private_imux;
2975 2735
2736 if (spec->auto_mic)
2737 return 0; /* no need for input source */
2976 if (!spec->num_adcs || imux->num_items <= 1) 2738 if (!spec->num_adcs || imux->num_items <= 1)
2977 return 0; /* no need for input source control */ 2739 return 0; /* no need for input source control */
2978 knew = stac_control_new(spec, &stac_input_src_temp, 2740 knew = stac_control_new(spec, &stac_input_src_temp,
@@ -3066,7 +2828,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
3066 HDA_MAX_CONNECTIONS); 2828 HDA_MAX_CONNECTIONS);
3067 for (j = 0; j < conn_len; j++) { 2829 for (j = 0; j < conn_len; j++) {
3068 wcaps = get_wcaps(codec, conn[j]); 2830 wcaps = get_wcaps(codec, conn[j]);
3069 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; 2831 wtype = get_wcaps_type(wcaps);
3070 /* we check only analog outputs */ 2832 /* we check only analog outputs */
3071 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) 2833 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
3072 continue; 2834 continue;
@@ -3325,6 +3087,21 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3325 return 0; 3087 return 0;
3326} 3088}
3327 3089
3090static int stac92xx_add_capvol_ctls(struct hda_codec *codec, unsigned long vol,
3091 unsigned long sw, int idx)
3092{
3093 int err;
3094 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_VOL, idx,
3095 "Capture Volume", vol);
3096 if (err < 0)
3097 return err;
3098 err = stac92xx_add_control_idx(codec->spec, STAC_CTL_WIDGET_MUTE, idx,
3099 "Capture Switch", sw);
3100 if (err < 0)
3101 return err;
3102 return 0;
3103}
3104
3328/* add playback controls from the parsed DAC table */ 3105/* add playback controls from the parsed DAC table */
3329static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, 3106static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
3330 const struct auto_pin_cfg *cfg) 3107 const struct auto_pin_cfg *cfg)
@@ -3398,7 +3175,7 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3398 spec->mono_nid, 3175 spec->mono_nid,
3399 con_lst, 3176 con_lst,
3400 HDA_MAX_NUM_INPUTS); 3177 HDA_MAX_NUM_INPUTS);
3401 if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_mono_labels)) 3178 if (num_cons <= 0 || num_cons > ARRAY_SIZE(stac92xx_mono_labels))
3402 return -EINVAL; 3179 return -EINVAL;
3403 3180
3404 for (i = 0; i < num_cons; i++) { 3181 for (i = 0; i < num_cons; i++) {
@@ -3412,37 +3189,6 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec)
3412 "Mono Mux", spec->mono_nid); 3189 "Mono Mux", spec->mono_nid);
3413} 3190}
3414 3191
3415/* labels for amp mux outputs */
3416static const char *stac92xx_amp_labels[3] = {
3417 "Front Microphone", "Microphone", "Line In",
3418};
3419
3420/* create amp out controls mux on capable codecs */
3421static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec)
3422{
3423 struct sigmatel_spec *spec = codec->spec;
3424 struct hda_input_mux *amp_mux = &spec->private_amp_mux;
3425 int i, err;
3426
3427 for (i = 0; i < spec->num_amps; i++) {
3428 amp_mux->items[amp_mux->num_items].label =
3429 stac92xx_amp_labels[i];
3430 amp_mux->items[amp_mux->num_items].index = i;
3431 amp_mux->num_items++;
3432 }
3433
3434 if (spec->num_amps > 1) {
3435 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX,
3436 "Amp Selector Capture Switch", 0);
3437 if (err < 0)
3438 return err;
3439 }
3440 return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL,
3441 "Amp Capture Volume",
3442 HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT));
3443}
3444
3445
3446/* create PC beep volume controls */ 3192/* create PC beep volume controls */
3447static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, 3193static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec,
3448 hda_nid_t nid) 3194 hda_nid_t nid)
@@ -3511,19 +3257,33 @@ static int stac92xx_beep_switch_ctl(struct hda_codec *codec)
3511static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) 3257static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3512{ 3258{
3513 struct sigmatel_spec *spec = codec->spec; 3259 struct sigmatel_spec *spec = codec->spec;
3514 int wcaps, nid, i, err = 0; 3260 int i, j, err = 0;
3515 3261
3516 for (i = 0; i < spec->num_muxes; i++) { 3262 for (i = 0; i < spec->num_muxes; i++) {
3263 hda_nid_t nid;
3264 unsigned int wcaps;
3265 unsigned long val;
3266
3517 nid = spec->mux_nids[i]; 3267 nid = spec->mux_nids[i];
3518 wcaps = get_wcaps(codec, nid); 3268 wcaps = get_wcaps(codec, nid);
3269 if (!(wcaps & AC_WCAP_OUT_AMP))
3270 continue;
3519 3271
3520 if (wcaps & AC_WCAP_OUT_AMP) { 3272 /* check whether already the same control was created as
3521 err = stac92xx_add_control_idx(spec, 3273 * normal Capture Volume.
3522 STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", 3274 */
3523 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); 3275 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3524 if (err < 0) 3276 for (j = 0; j < spec->num_caps; j++) {
3525 return err; 3277 if (spec->capvols[j] == val)
3278 break;
3526 } 3279 }
3280 if (j < spec->num_caps)
3281 continue;
3282
3283 err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, i,
3284 "Mux Capture Volume", val);
3285 if (err < 0)
3286 return err;
3527 } 3287 }
3528 return 0; 3288 return 0;
3529}; 3289};
@@ -3544,7 +3304,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3544 spec->smux_nids[0], 3304 spec->smux_nids[0],
3545 con_lst, 3305 con_lst,
3546 HDA_MAX_NUM_INPUTS); 3306 HDA_MAX_NUM_INPUTS);
3547 if (!num_cons) 3307 if (num_cons <= 0)
3548 return -EINVAL; 3308 return -EINVAL;
3549 3309
3550 if (!labels) 3310 if (!labels)
@@ -3565,101 +3325,231 @@ static const char *stac92xx_dmic_labels[5] = {
3565 "Digital Mic 3", "Digital Mic 4" 3325 "Digital Mic 3", "Digital Mic 4"
3566}; 3326};
3567 3327
3328static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3329 hda_nid_t nid)
3330{
3331 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3332 int i, nums;
3333
3334 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3335 for (i = 0; i < nums; i++)
3336 if (conn[i] == nid)
3337 return i;
3338 return -1;
3339}
3340
3341/* create a volume assigned to the given pin (only if supported) */
3342/* return 1 if the volume control is created */
3343static int create_elem_capture_vol(struct hda_codec *codec, hda_nid_t nid,
3344 const char *label, int direction)
3345{
3346 unsigned int caps, nums;
3347 char name[32];
3348 int err;
3349
3350 if (direction == HDA_OUTPUT)
3351 caps = AC_WCAP_OUT_AMP;
3352 else
3353 caps = AC_WCAP_IN_AMP;
3354 if (!(get_wcaps(codec, nid) & caps))
3355 return 0;
3356 caps = query_amp_caps(codec, nid, direction);
3357 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
3358 if (!nums)
3359 return 0;
3360 snprintf(name, sizeof(name), "%s Capture Volume", label);
3361 err = stac92xx_add_control(codec->spec, STAC_CTL_WIDGET_VOL, name,
3362 HDA_COMPOSE_AMP_VAL(nid, 3, 0, direction));
3363 if (err < 0)
3364 return err;
3365 return 1;
3366}
3367
3568/* create playback/capture controls for input pins on dmic capable codecs */ 3368/* create playback/capture controls for input pins on dmic capable codecs */
3569static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, 3369static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3570 const struct auto_pin_cfg *cfg) 3370 const struct auto_pin_cfg *cfg)
3571{ 3371{
3572 struct sigmatel_spec *spec = codec->spec; 3372 struct sigmatel_spec *spec = codec->spec;
3373 struct hda_input_mux *imux = &spec->private_imux;
3573 struct hda_input_mux *dimux = &spec->private_dimux; 3374 struct hda_input_mux *dimux = &spec->private_dimux;
3574 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; 3375 int err, i, active_mics;
3575 int err, i, j; 3376 unsigned int def_conf;
3576 char name[32];
3577 3377
3578 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0]; 3378 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
3579 dimux->items[dimux->num_items].index = 0; 3379 dimux->items[dimux->num_items].index = 0;
3580 dimux->num_items++; 3380 dimux->num_items++;
3581 3381
3382 active_mics = 0;
3383 for (i = 0; i < spec->num_dmics; i++) {
3384 /* check the validity: sometimes it's a dead vendor-spec node */
3385 if (get_wcaps_type(get_wcaps(codec, spec->dmic_nids[i]))
3386 != AC_WID_PIN)
3387 continue;
3388 def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]);
3389 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_NONE)
3390 active_mics++;
3391 }
3392
3582 for (i = 0; i < spec->num_dmics; i++) { 3393 for (i = 0; i < spec->num_dmics; i++) {
3583 hda_nid_t nid; 3394 hda_nid_t nid;
3584 int index; 3395 int index;
3585 int num_cons; 3396 const char *label;
3586 unsigned int wcaps;
3587 unsigned int def_conf;
3588 3397
3589 def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); 3398 nid = spec->dmic_nids[i];
3399 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
3400 continue;
3401 def_conf = snd_hda_codec_get_pincfg(codec, nid);
3590 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) 3402 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
3591 continue; 3403 continue;
3592 3404
3593 nid = spec->dmic_nids[i]; 3405 index = get_connection_index(codec, spec->dmux_nids[0], nid);
3594 num_cons = snd_hda_get_connections(codec, 3406 if (index < 0)
3595 spec->dmux_nids[0], 3407 continue;
3596 con_lst,
3597 HDA_MAX_NUM_INPUTS);
3598 for (j = 0; j < num_cons; j++)
3599 if (con_lst[j] == nid) {
3600 index = j;
3601 goto found;
3602 }
3603 continue;
3604found:
3605 wcaps = get_wcaps(codec, nid) &
3606 (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP);
3607 3408
3608 if (wcaps) { 3409 if (active_mics == 1)
3609 sprintf(name, "%s Capture Volume", 3410 label = "Digital Mic";
3610 stac92xx_dmic_labels[dimux->num_items]); 3411 else
3412 label = stac92xx_dmic_labels[dimux->num_items];
3611 3413
3612 err = stac92xx_add_control(spec, 3414 err = create_elem_capture_vol(codec, nid, label, HDA_INPUT);
3613 STAC_CTL_WIDGET_VOL, 3415 if (err < 0)
3614 name, 3416 return err;
3615 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 3417 if (!err) {
3616 (wcaps & AC_WCAP_OUT_AMP) ? 3418 err = create_elem_capture_vol(codec, nid, label,
3617 HDA_OUTPUT : HDA_INPUT)); 3419 HDA_OUTPUT);
3618 if (err < 0) 3420 if (err < 0)
3619 return err; 3421 return err;
3620 } 3422 }
3621 3423
3622 dimux->items[dimux->num_items].label = 3424 dimux->items[dimux->num_items].label = label;
3623 stac92xx_dmic_labels[dimux->num_items];
3624 dimux->items[dimux->num_items].index = index; 3425 dimux->items[dimux->num_items].index = index;
3625 dimux->num_items++; 3426 dimux->num_items++;
3427 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) {
3428 imux->items[imux->num_items].label = label;
3429 imux->items[imux->num_items].index = index;
3430 imux->num_items++;
3431 }
3626 } 3432 }
3627 3433
3628 return 0; 3434 return 0;
3629} 3435}
3630 3436
3437static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid,
3438 hda_nid_t *fixed, hda_nid_t *ext)
3439{
3440 unsigned int cfg;
3441
3442 if (!nid)
3443 return 0;
3444 cfg = snd_hda_codec_get_pincfg(codec, nid);
3445 switch (get_defcfg_connect(cfg)) {
3446 case AC_JACK_PORT_FIXED:
3447 if (*fixed)
3448 return 1; /* already occupied */
3449 *fixed = nid;
3450 break;
3451 case AC_JACK_PORT_COMPLEX:
3452 if (*ext)
3453 return 1; /* already occupied */
3454 *ext = nid;
3455 break;
3456 }
3457 return 0;
3458}
3459
3460static int set_mic_route(struct hda_codec *codec,
3461 struct sigmatel_mic_route *mic,
3462 hda_nid_t pin)
3463{
3464 struct sigmatel_spec *spec = codec->spec;
3465 struct auto_pin_cfg *cfg = &spec->autocfg;
3466 int i;
3467
3468 mic->pin = pin;
3469 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++)
3470 if (pin == cfg->input_pins[i])
3471 break;
3472 if (i <= AUTO_PIN_FRONT_MIC) {
3473 /* analog pin */
3474 mic->dmux_idx = 0;
3475 i = get_connection_index(codec, spec->mux_nids[0], pin);
3476 if (i < 0)
3477 return -1;
3478 mic->mux_idx = i;
3479 } else if (spec->dmux_nids) {
3480 /* digital pin */
3481 mic->mux_idx = 0;
3482 i = get_connection_index(codec, spec->dmux_nids[0], pin);
3483 if (i < 0)
3484 return -1;
3485 mic->dmux_idx = i;
3486 }
3487 return 0;
3488}
3489
3490/* return non-zero if the device is for automatic mic switch */
3491static int stac_check_auto_mic(struct hda_codec *codec)
3492{
3493 struct sigmatel_spec *spec = codec->spec;
3494 struct auto_pin_cfg *cfg = &spec->autocfg;
3495 hda_nid_t fixed, ext;
3496 int i;
3497
3498 for (i = AUTO_PIN_LINE; i < AUTO_PIN_LAST; i++) {
3499 if (cfg->input_pins[i])
3500 return 0; /* must be exclusively mics */
3501 }
3502 fixed = ext = 0;
3503 for (i = AUTO_PIN_MIC; i <= AUTO_PIN_FRONT_MIC; i++)
3504 if (check_mic_pin(codec, cfg->input_pins[i], &fixed, &ext))
3505 return 0;
3506 for (i = 0; i < spec->num_dmics; i++)
3507 if (check_mic_pin(codec, spec->dmic_nids[i], &fixed, &ext))
3508 return 0;
3509 if (!fixed || !ext)
3510 return 0;
3511 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
3512 return 0; /* no unsol support */
3513 if (set_mic_route(codec, &spec->ext_mic, ext) ||
3514 set_mic_route(codec, &spec->int_mic, fixed))
3515 return 0; /* something is wrong */
3516 return 1;
3517}
3518
3631/* create playback/capture controls for input pins */ 3519/* create playback/capture controls for input pins */
3632static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) 3520static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
3633{ 3521{
3634 struct sigmatel_spec *spec = codec->spec; 3522 struct sigmatel_spec *spec = codec->spec;
3635 struct hda_input_mux *imux = &spec->private_imux; 3523 struct hda_input_mux *imux = &spec->private_imux;
3636 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; 3524 int i, j;
3637 int i, j, k;
3638 3525
3639 for (i = 0; i < AUTO_PIN_LAST; i++) { 3526 for (i = 0; i < AUTO_PIN_LAST; i++) {
3640 int index; 3527 hda_nid_t nid = cfg->input_pins[i];
3528 int index, err;
3641 3529
3642 if (!cfg->input_pins[i]) 3530 if (!nid)
3643 continue; 3531 continue;
3644 index = -1; 3532 index = -1;
3645 for (j = 0; j < spec->num_muxes; j++) { 3533 for (j = 0; j < spec->num_muxes; j++) {
3646 int num_cons; 3534 index = get_connection_index(codec, spec->mux_nids[j],
3647 num_cons = snd_hda_get_connections(codec, 3535 nid);
3648 spec->mux_nids[j], 3536 if (index >= 0)
3649 con_lst, 3537 break;
3650 HDA_MAX_NUM_INPUTS);
3651 for (k = 0; k < num_cons; k++)
3652 if (con_lst[k] == cfg->input_pins[i]) {
3653 index = k;
3654 goto found;
3655 }
3656 } 3538 }
3657 continue; 3539 if (index < 0)
3658 found: 3540 continue;
3541
3542 err = create_elem_capture_vol(codec, nid,
3543 auto_pin_cfg_labels[i],
3544 HDA_INPUT);
3545 if (err < 0)
3546 return err;
3547
3659 imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; 3548 imux->items[imux->num_items].label = auto_pin_cfg_labels[i];
3660 imux->items[imux->num_items].index = index; 3549 imux->items[imux->num_items].index = index;
3661 imux->num_items++; 3550 imux->num_items++;
3662 } 3551 }
3552 spec->num_analog_muxes = imux->num_items;
3663 3553
3664 if (imux->num_items) { 3554 if (imux->num_items) {
3665 /* 3555 /*
@@ -3711,7 +3601,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3711{ 3601{
3712 struct sigmatel_spec *spec = codec->spec; 3602 struct sigmatel_spec *spec = codec->spec;
3713 int hp_swap = 0; 3603 int hp_swap = 0;
3714 int err; 3604 int i, err;
3715 3605
3716 if ((err = snd_hda_parse_pin_def_config(codec, 3606 if ((err = snd_hda_parse_pin_def_config(codec,
3717 &spec->autocfg, 3607 &spec->autocfg,
@@ -3751,11 +3641,10 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3751 if (snd_hda_get_connections(codec, 3641 if (snd_hda_get_connections(codec,
3752 spec->autocfg.mono_out_pin, conn_list, 1) && 3642 spec->autocfg.mono_out_pin, conn_list, 1) &&
3753 snd_hda_get_connections(codec, conn_list[0], 3643 snd_hda_get_connections(codec, conn_list[0],
3754 conn_list, 1)) { 3644 conn_list, 1) > 0) {
3755 3645
3756 int wcaps = get_wcaps(codec, conn_list[0]); 3646 int wcaps = get_wcaps(codec, conn_list[0]);
3757 int wid_type = (wcaps & AC_WCAP_TYPE) 3647 int wid_type = get_wcaps_type(wcaps);
3758 >> AC_WCAP_TYPE_SHIFT;
3759 /* LR swap check, some stac925x have a mux that 3648 /* LR swap check, some stac925x have a mux that
3760 * changes the DACs output path instead of the 3649 * changes the DACs output path instead of the
3761 * mono-mux path. 3650 * mono-mux path.
@@ -3846,6 +3735,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3846 spec->autocfg.line_outs = 0; 3735 spec->autocfg.line_outs = 0;
3847 } 3736 }
3848 3737
3738 if (stac_check_auto_mic(codec)) {
3739 spec->auto_mic = 1;
3740 /* only one capture for auto-mic */
3741 spec->num_adcs = 1;
3742 spec->num_caps = 1;
3743 spec->num_muxes = 1;
3744 }
3745
3746 for (i = 0; i < spec->num_caps; i++) {
3747 err = stac92xx_add_capvol_ctls(codec, spec->capvols[i],
3748 spec->capsws[i], i);
3749 if (err < 0)
3750 return err;
3751 }
3752
3849 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); 3753 err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg);
3850 if (err < 0) 3754 if (err < 0)
3851 return err; 3755 return err;
@@ -3855,11 +3759,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3855 if (err < 0) 3759 if (err < 0)
3856 return err; 3760 return err;
3857 } 3761 }
3858 if (spec->num_amps > 0) {
3859 err = stac92xx_auto_create_amp_output_ctls(codec);
3860 if (err < 0)
3861 return err;
3862 }
3863 if (spec->num_dmics > 0 && !spec->dinput_mux) 3762 if (spec->num_dmics > 0 && !spec->dinput_mux)
3864 if ((err = stac92xx_auto_create_dmic_input_ctls(codec, 3763 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
3865 &spec->autocfg)) < 0) 3764 &spec->autocfg)) < 0)
@@ -3896,7 +3795,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3896 spec->dinput_mux = &spec->private_dimux; 3795 spec->dinput_mux = &spec->private_dimux;
3897 spec->sinput_mux = &spec->private_smux; 3796 spec->sinput_mux = &spec->private_smux;
3898 spec->mono_mux = &spec->private_mono_mux; 3797 spec->mono_mux = &spec->private_mono_mux;
3899 spec->amp_mux = &spec->private_amp_mux;
3900 return 1; 3798 return 1;
3901} 3799}
3902 3800
@@ -4108,14 +4006,14 @@ static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
4108} 4006}
4109 4007
4110static struct sigmatel_event *stac_get_event(struct hda_codec *codec, 4008static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
4111 hda_nid_t nid, unsigned char type) 4009 hda_nid_t nid)
4112{ 4010{
4113 struct sigmatel_spec *spec = codec->spec; 4011 struct sigmatel_spec *spec = codec->spec;
4114 struct sigmatel_event *event = spec->events.list; 4012 struct sigmatel_event *event = spec->events.list;
4115 int i; 4013 int i;
4116 4014
4117 for (i = 0; i < spec->events.used; i++, event++) { 4015 for (i = 0; i < spec->events.used; i++, event++) {
4118 if (event->nid == nid && event->type == type) 4016 if (event->nid == nid)
4119 return event; 4017 return event;
4120 } 4018 }
4121 return NULL; 4019 return NULL;
@@ -4135,24 +4033,32 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
4135 return NULL; 4033 return NULL;
4136} 4034}
4137 4035
4138static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, 4036/* check if given nid is a valid pin and no other events are assigned
4139 unsigned int type) 4037 * to it. If OK, assign the event, set the unsol flag, and returns 1.
4038 * Otherwise, returns zero.
4039 */
4040static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
4041 unsigned int type)
4140{ 4042{
4141 struct sigmatel_event *event; 4043 struct sigmatel_event *event;
4142 int tag; 4044 int tag;
4143 4045
4144 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) 4046 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
4145 return; 4047 return 0;
4146 event = stac_get_event(codec, nid, type); 4048 event = stac_get_event(codec, nid);
4147 if (event) 4049 if (event) {
4050 if (event->type != type)
4051 return 0;
4148 tag = event->tag; 4052 tag = event->tag;
4149 else 4053 } else {
4150 tag = stac_add_event(codec->spec, nid, type, 0); 4054 tag = stac_add_event(codec->spec, nid, type, 0);
4151 if (tag < 0) 4055 if (tag < 0)
4152 return; 4056 return 0;
4057 }
4153 snd_hda_codec_write_cache(codec, nid, 0, 4058 snd_hda_codec_write_cache(codec, nid, 0,
4154 AC_VERB_SET_UNSOLICITED_ENABLE, 4059 AC_VERB_SET_UNSOLICITED_ENABLE,
4155 AC_USRSP_EN | tag); 4060 AC_USRSP_EN | tag);
4061 return 1;
4156} 4062}
4157 4063
4158static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 4064static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
@@ -4245,20 +4151,36 @@ static int stac92xx_init(struct hda_codec *codec)
4245 hda_nid_t nid = cfg->hp_pins[i]; 4151 hda_nid_t nid = cfg->hp_pins[i];
4246 enable_pin_detect(codec, nid, STAC_HP_EVENT); 4152 enable_pin_detect(codec, nid, STAC_HP_EVENT);
4247 } 4153 }
4154 if (cfg->line_out_type == AUTO_PIN_LINE_OUT &&
4155 cfg->speaker_outs > 0) {
4156 /* enable pin-detect for line-outs as well */
4157 for (i = 0; i < cfg->line_outs; i++) {
4158 hda_nid_t nid = cfg->line_out_pins[i];
4159 enable_pin_detect(codec, nid, STAC_LO_EVENT);
4160 }
4161 }
4162
4248 /* force to enable the first line-out; the others are set up 4163 /* force to enable the first line-out; the others are set up
4249 * in unsol_event 4164 * in unsol_event
4250 */ 4165 */
4251 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 4166 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
4252 AC_PINCTL_OUT_EN); 4167 AC_PINCTL_OUT_EN);
4253 /* fake event to set up pins */ 4168 /* fake event to set up pins */
4254 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4169 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4255 STAC_HP_EVENT);
4256 } else { 4170 } else {
4257 stac92xx_auto_init_multi_out(codec); 4171 stac92xx_auto_init_multi_out(codec);
4258 stac92xx_auto_init_hp_out(codec); 4172 stac92xx_auto_init_hp_out(codec);
4259 for (i = 0; i < cfg->hp_outs; i++) 4173 for (i = 0; i < cfg->hp_outs; i++)
4260 stac_toggle_power_map(codec, cfg->hp_pins[i], 1); 4174 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
4261 } 4175 }
4176 if (spec->auto_mic) {
4177 /* initialize connection to analog input */
4178 if (spec->dmux_nids)
4179 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4180 AC_VERB_SET_CONNECT_SEL, 0);
4181 if (enable_pin_detect(codec, spec->ext_mic.pin, STAC_MIC_EVENT))
4182 stac_issue_unsol_event(codec, spec->ext_mic.pin);
4183 }
4262 for (i = 0; i < AUTO_PIN_LAST; i++) { 4184 for (i = 0; i < AUTO_PIN_LAST; i++) {
4263 hda_nid_t nid = cfg->input_pins[i]; 4185 hda_nid_t nid = cfg->input_pins[i];
4264 if (nid) { 4186 if (nid) {
@@ -4285,10 +4207,9 @@ static int stac92xx_init(struct hda_codec *codec)
4285 } 4207 }
4286 conf = snd_hda_codec_get_pincfg(codec, nid); 4208 conf = snd_hda_codec_get_pincfg(codec, nid);
4287 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { 4209 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
4288 enable_pin_detect(codec, nid, 4210 if (enable_pin_detect(codec, nid,
4289 STAC_INSERT_EVENT); 4211 STAC_INSERT_EVENT))
4290 stac_issue_unsol_event(codec, nid, 4212 stac_issue_unsol_event(codec, nid);
4291 STAC_INSERT_EVENT);
4292 } 4213 }
4293 } 4214 }
4294 } 4215 }
@@ -4333,10 +4254,8 @@ static int stac92xx_init(struct hda_codec *codec)
4333 stac_toggle_power_map(codec, nid, 1); 4254 stac_toggle_power_map(codec, nid, 1);
4334 continue; 4255 continue;
4335 } 4256 }
4336 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { 4257 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4337 enable_pin_detect(codec, nid, STAC_PWR_EVENT); 4258 stac_issue_unsol_event(codec, nid);
4338 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
4339 }
4340 } 4259 }
4341 if (spec->dac_list) 4260 if (spec->dac_list)
4342 stac92xx_power_down(codec); 4261 stac92xx_power_down(codec);
@@ -4440,6 +4359,48 @@ static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
4440 return 0; 4359 return 0;
4441} 4360}
4442 4361
4362static void stac92xx_line_out_detect(struct hda_codec *codec,
4363 int presence)
4364{
4365 struct sigmatel_spec *spec = codec->spec;
4366 struct auto_pin_cfg *cfg = &spec->autocfg;
4367 int i;
4368
4369 for (i = 0; i < cfg->line_outs; i++) {
4370 if (presence)
4371 break;
4372 presence = get_pin_presence(codec, cfg->line_out_pins[i]);
4373 if (presence) {
4374 unsigned int pinctl;
4375 pinctl = snd_hda_codec_read(codec,
4376 cfg->line_out_pins[i], 0,
4377 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4378 if (pinctl & AC_PINCTL_IN_EN)
4379 presence = 0; /* mic- or line-input */
4380 }
4381 }
4382
4383 if (presence) {
4384 /* disable speakers */
4385 for (i = 0; i < cfg->speaker_outs; i++)
4386 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
4387 AC_PINCTL_OUT_EN);
4388 if (spec->eapd_mask && spec->eapd_switch)
4389 stac_gpio_set(codec, spec->gpio_mask,
4390 spec->gpio_dir, spec->gpio_data &
4391 ~spec->eapd_mask);
4392 } else {
4393 /* enable speakers */
4394 for (i = 0; i < cfg->speaker_outs; i++)
4395 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
4396 AC_PINCTL_OUT_EN);
4397 if (spec->eapd_mask && spec->eapd_switch)
4398 stac_gpio_set(codec, spec->gpio_mask,
4399 spec->gpio_dir, spec->gpio_data |
4400 spec->eapd_mask);
4401 }
4402}
4403
4443/* return non-zero if the hp-pin of the given array index isn't 4404/* return non-zero if the hp-pin of the given array index isn't
4444 * a jack-detection target 4405 * a jack-detection target
4445 */ 4406 */
@@ -4492,13 +4453,6 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4492 for (i = 0; i < cfg->line_outs; i++) 4453 for (i = 0; i < cfg->line_outs; i++)
4493 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], 4454 stac92xx_reset_pinctl(codec, cfg->line_out_pins[i],
4494 AC_PINCTL_OUT_EN); 4455 AC_PINCTL_OUT_EN);
4495 for (i = 0; i < cfg->speaker_outs; i++)
4496 stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
4497 AC_PINCTL_OUT_EN);
4498 if (spec->eapd_mask && spec->eapd_switch)
4499 stac_gpio_set(codec, spec->gpio_mask,
4500 spec->gpio_dir, spec->gpio_data &
4501 ~spec->eapd_mask);
4502 } else { 4456 } else {
4503 /* enable lineouts */ 4457 /* enable lineouts */
4504 if (spec->hp_switch) 4458 if (spec->hp_switch)
@@ -4507,14 +4461,8 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
4507 for (i = 0; i < cfg->line_outs; i++) 4461 for (i = 0; i < cfg->line_outs; i++)
4508 stac92xx_set_pinctl(codec, cfg->line_out_pins[i], 4462 stac92xx_set_pinctl(codec, cfg->line_out_pins[i],
4509 AC_PINCTL_OUT_EN); 4463 AC_PINCTL_OUT_EN);
4510 for (i = 0; i < cfg->speaker_outs; i++)
4511 stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
4512 AC_PINCTL_OUT_EN);
4513 if (spec->eapd_mask && spec->eapd_switch)
4514 stac_gpio_set(codec, spec->gpio_mask,
4515 spec->gpio_dir, spec->gpio_data |
4516 spec->eapd_mask);
4517 } 4464 }
4465 stac92xx_line_out_detect(codec, presence);
4518 /* toggle hp outs */ 4466 /* toggle hp outs */
4519 for (i = 0; i < cfg->hp_outs; i++) { 4467 for (i = 0; i < cfg->hp_outs; i++) {
4520 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN; 4468 unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
@@ -4599,10 +4547,28 @@ static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4599 } 4547 }
4600} 4548}
4601 4549
4602static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, 4550static void stac92xx_mic_detect(struct hda_codec *codec)
4603 unsigned char type)
4604{ 4551{
4605 struct sigmatel_event *event = stac_get_event(codec, nid, type); 4552 struct sigmatel_spec *spec = codec->spec;
4553 struct sigmatel_mic_route *mic;
4554
4555 if (get_pin_presence(codec, spec->ext_mic.pin))
4556 mic = &spec->ext_mic;
4557 else
4558 mic = &spec->int_mic;
4559 if (mic->dmux_idx)
4560 snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0,
4561 AC_VERB_SET_CONNECT_SEL,
4562 mic->dmux_idx);
4563 else
4564 snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0,
4565 AC_VERB_SET_CONNECT_SEL,
4566 mic->mux_idx);
4567}
4568
4569static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid)
4570{
4571 struct sigmatel_event *event = stac_get_event(codec, nid);
4606 if (!event) 4572 if (!event)
4607 return; 4573 return;
4608 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); 4574 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
@@ -4621,8 +4587,18 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4621 4587
4622 switch (event->type) { 4588 switch (event->type) {
4623 case STAC_HP_EVENT: 4589 case STAC_HP_EVENT:
4590 case STAC_LO_EVENT:
4624 stac92xx_hp_detect(codec); 4591 stac92xx_hp_detect(codec);
4625 /* fallthru */ 4592 break;
4593 case STAC_MIC_EVENT:
4594 stac92xx_mic_detect(codec);
4595 break;
4596 }
4597
4598 switch (event->type) {
4599 case STAC_HP_EVENT:
4600 case STAC_LO_EVENT:
4601 case STAC_MIC_EVENT:
4626 case STAC_INSERT_EVENT: 4602 case STAC_INSERT_EVENT:
4627 case STAC_PWR_EVENT: 4603 case STAC_PWR_EVENT:
4628 if (spec->num_pwrs > 0) 4604 if (spec->num_pwrs > 0)
@@ -4713,8 +4689,7 @@ static int stac92xx_resume(struct hda_codec *codec)
4713 snd_hda_codec_resume_cache(codec); 4689 snd_hda_codec_resume_cache(codec);
4714 /* fake event to set up pins again to override cached values */ 4690 /* fake event to set up pins again to override cached values */
4715 if (spec->hp_detect) 4691 if (spec->hp_detect)
4716 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], 4692 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0]);
4717 STAC_HP_EVENT);
4718 return 0; 4693 return 0;
4719} 4694}
4720 4695
@@ -4754,6 +4729,19 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4754static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4729static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4755{ 4730{
4756 struct sigmatel_spec *spec = codec->spec; 4731 struct sigmatel_spec *spec = codec->spec;
4732 int i;
4733 hda_nid_t nid;
4734
4735 /* reset each pin before powering down DAC/ADC to avoid click noise */
4736 nid = codec->start_nid;
4737 for (i = 0; i < codec->num_nodes; i++, nid++) {
4738 unsigned int wcaps = get_wcaps(codec, nid);
4739 unsigned int wid_type = get_wcaps_type(wcaps);
4740 if (wid_type == AC_WID_PIN)
4741 snd_hda_codec_read(codec, nid, 0,
4742 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
4743 }
4744
4757 if (spec->eapd_mask) 4745 if (spec->eapd_mask)
4758 stac_gpio_set(codec, spec->gpio_mask, 4746 stac_gpio_set(codec, spec->gpio_mask,
4759 spec->gpio_dir, spec->gpio_data & 4747 spec->gpio_dir, spec->gpio_data &
@@ -4790,7 +4778,8 @@ static int patch_stac9200(struct hda_codec *codec)
4790 stac9200_models, 4778 stac9200_models,
4791 stac9200_cfg_tbl); 4779 stac9200_cfg_tbl);
4792 if (spec->board_config < 0) 4780 if (spec->board_config < 0)
4793 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 4781 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4782 codec->chip_name);
4794 else 4783 else
4795 stac92xx_set_config_regs(codec, 4784 stac92xx_set_config_regs(codec,
4796 stac9200_brd_tbl[spec->board_config]); 4785 stac9200_brd_tbl[spec->board_config]);
@@ -4862,8 +4851,8 @@ static int patch_stac925x(struct hda_codec *codec)
4862 stac925x_cfg_tbl); 4851 stac925x_cfg_tbl);
4863 again: 4852 again:
4864 if (spec->board_config < 0) 4853 if (spec->board_config < 0)
4865 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 4854 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4866 "using BIOS defaults\n"); 4855 codec->chip_name);
4867 else 4856 else
4868 stac92xx_set_config_regs(codec, 4857 stac92xx_set_config_regs(codec,
4869 stac925x_brd_tbl[spec->board_config]); 4858 stac925x_brd_tbl[spec->board_config]);
@@ -4893,6 +4882,9 @@ static int patch_stac925x(struct hda_codec *codec)
4893 4882
4894 spec->init = stac925x_core_init; 4883 spec->init = stac925x_core_init;
4895 spec->mixer = stac925x_mixer; 4884 spec->mixer = stac925x_mixer;
4885 spec->num_caps = 1;
4886 spec->capvols = stac925x_capvols;
4887 spec->capsws = stac925x_capsws;
4896 4888
4897 err = stac92xx_parse_auto_config(codec, 0x8, 0x7); 4889 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
4898 if (!err) { 4890 if (!err) {
@@ -4914,16 +4906,6 @@ static int patch_stac925x(struct hda_codec *codec)
4914 return 0; 4906 return 0;
4915} 4907}
4916 4908
4917static struct hda_input_mux stac92hd73xx_dmux = {
4918 .num_items = 4,
4919 .items = {
4920 { "Analog Inputs", 0x0b },
4921 { "Digital Mic 1", 0x09 },
4922 { "Digital Mic 2", 0x0a },
4923 { "CD", 0x08 },
4924 }
4925};
4926
4927static int patch_stac92hd73xx(struct hda_codec *codec) 4909static int patch_stac92hd73xx(struct hda_codec *codec)
4928{ 4910{
4929 struct sigmatel_spec *spec; 4911 struct sigmatel_spec *spec;
@@ -4943,10 +4925,16 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4943 STAC_92HD73XX_MODELS, 4925 STAC_92HD73XX_MODELS,
4944 stac92hd73xx_models, 4926 stac92hd73xx_models,
4945 stac92hd73xx_cfg_tbl); 4927 stac92hd73xx_cfg_tbl);
4928 /* check codec subsystem id if not found */
4929 if (spec->board_config < 0)
4930 spec->board_config =
4931 snd_hda_check_board_codec_sid_config(codec,
4932 STAC_92HD73XX_MODELS, stac92hd73xx_models,
4933 stac92hd73xx_codec_id_cfg_tbl);
4946again: 4934again:
4947 if (spec->board_config < 0) 4935 if (spec->board_config < 0)
4948 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4936 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4949 " STAC92HD73XX, using BIOS defaults\n"); 4937 codec->chip_name);
4950 else 4938 else
4951 stac92xx_set_config_regs(codec, 4939 stac92xx_set_config_regs(codec,
4952 stac92hd73xx_brd_tbl[spec->board_config]); 4940 stac92hd73xx_brd_tbl[spec->board_config]);
@@ -4959,20 +4947,15 @@ again:
4959 "number of channels defaulting to DAC count\n"); 4947 "number of channels defaulting to DAC count\n");
4960 num_dacs = STAC92HD73_DAC_COUNT; 4948 num_dacs = STAC92HD73_DAC_COUNT;
4961 } 4949 }
4950 spec->init = stac92hd73xx_core_init;
4962 switch (num_dacs) { 4951 switch (num_dacs) {
4963 case 0x3: /* 6 Channel */ 4952 case 0x3: /* 6 Channel */
4964 spec->mixer = stac92hd73xx_6ch_mixer;
4965 spec->init = stac92hd73xx_6ch_core_init;
4966 spec->aloopback_ctl = stac92hd73xx_6ch_loopback; 4953 spec->aloopback_ctl = stac92hd73xx_6ch_loopback;
4967 break; 4954 break;
4968 case 0x4: /* 8 Channel */ 4955 case 0x4: /* 8 Channel */
4969 spec->mixer = stac92hd73xx_8ch_mixer;
4970 spec->init = stac92hd73xx_8ch_core_init;
4971 spec->aloopback_ctl = stac92hd73xx_8ch_loopback; 4956 spec->aloopback_ctl = stac92hd73xx_8ch_loopback;
4972 break; 4957 break;
4973 case 0x5: /* 10 Channel */ 4958 case 0x5: /* 10 Channel */
4974 spec->mixer = stac92hd73xx_10ch_mixer;
4975 spec->init = stac92hd73xx_10ch_core_init;
4976 spec->aloopback_ctl = stac92hd73xx_10ch_loopback; 4959 spec->aloopback_ctl = stac92hd73xx_10ch_loopback;
4977 break; 4960 break;
4978 } 4961 }
@@ -4987,14 +4970,14 @@ again:
4987 spec->dmic_nids = stac92hd73xx_dmic_nids; 4970 spec->dmic_nids = stac92hd73xx_dmic_nids;
4988 spec->dmux_nids = stac92hd73xx_dmux_nids; 4971 spec->dmux_nids = stac92hd73xx_dmux_nids;
4989 spec->smux_nids = stac92hd73xx_smux_nids; 4972 spec->smux_nids = stac92hd73xx_smux_nids;
4990 spec->amp_nids = stac92hd73xx_amp_nids;
4991 spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids);
4992 4973
4993 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); 4974 spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids);
4994 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); 4975 spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids);
4995 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); 4976 spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids);
4996 memcpy(&spec->private_dimux, &stac92hd73xx_dmux, 4977
4997 sizeof(stac92hd73xx_dmux)); 4978 spec->num_caps = STAC92HD73XX_NUM_CAPS;
4979 spec->capvols = stac92hd73xx_capvols;
4980 spec->capsws = stac92hd73xx_capsws;
4998 4981
4999 switch (spec->board_config) { 4982 switch (spec->board_config) {
5000 case STAC_DELL_EQ: 4983 case STAC_DELL_EQ:
@@ -5004,43 +4987,40 @@ again:
5004 case STAC_DELL_M6_DMIC: 4987 case STAC_DELL_M6_DMIC:
5005 case STAC_DELL_M6_BOTH: 4988 case STAC_DELL_M6_BOTH:
5006 spec->num_smuxes = 0; 4989 spec->num_smuxes = 0;
5007 spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
5008 spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
5009 spec->eapd_switch = 0; 4990 spec->eapd_switch = 0;
5010 spec->num_amps = 1;
5011 4991
5012 if (spec->board_config != STAC_DELL_EQ)
5013 spec->init = dell_m6_core_init;
5014 switch (spec->board_config) { 4992 switch (spec->board_config) {
5015 case STAC_DELL_M6_AMIC: /* Analog Mics */ 4993 case STAC_DELL_M6_AMIC: /* Analog Mics */
5016 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); 4994 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
5017 spec->num_dmics = 0; 4995 spec->num_dmics = 0;
5018 spec->private_dimux.num_items = 1;
5019 break; 4996 break;
5020 case STAC_DELL_M6_DMIC: /* Digital Mics */ 4997 case STAC_DELL_M6_DMIC: /* Digital Mics */
5021 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); 4998 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
5022 spec->num_dmics = 1; 4999 spec->num_dmics = 1;
5023 spec->private_dimux.num_items = 2;
5024 break; 5000 break;
5025 case STAC_DELL_M6_BOTH: /* Both */ 5001 case STAC_DELL_M6_BOTH: /* Both */
5026 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); 5002 snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170);
5027 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); 5003 snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160);
5028 spec->num_dmics = 1; 5004 spec->num_dmics = 1;
5029 spec->private_dimux.num_items = 2;
5030 break; 5005 break;
5031 } 5006 }
5032 break; 5007 break;
5008 case STAC_ALIENWARE_M17X:
5009 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
5010 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
5011 spec->eapd_switch = 0;
5012 break;
5033 default: 5013 default:
5034 spec->num_dmics = STAC92HD73XX_NUM_DMICS; 5014 spec->num_dmics = STAC92HD73XX_NUM_DMICS;
5035 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); 5015 spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
5036 spec->eapd_switch = 1; 5016 spec->eapd_switch = 1;
5017 break;
5037 } 5018 }
5038 if (spec->board_config > STAC_92HD73XX_REF) { 5019 if (spec->board_config > STAC_92HD73XX_REF) {
5039 /* GPIO0 High = Enable EAPD */ 5020 /* GPIO0 High = Enable EAPD */
5040 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; 5021 spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1;
5041 spec->gpio_data = 0x01; 5022 spec->gpio_data = 0x01;
5042 } 5023 }
5043 spec->dinput_mux = &spec->private_dimux;
5044 5024
5045 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); 5025 spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids);
5046 spec->pwr_nids = stac92hd73xx_pwr_nids; 5026 spec->pwr_nids = stac92hd73xx_pwr_nids;
@@ -5072,15 +5052,6 @@ again:
5072 return 0; 5052 return 0;
5073} 5053}
5074 5054
5075static struct hda_input_mux stac92hd83xxx_dmux = {
5076 .num_items = 3,
5077 .items = {
5078 { "Analog Inputs", 0x03 },
5079 { "Digital Mic 1", 0x04 },
5080 { "Digital Mic 2", 0x05 },
5081 }
5082};
5083
5084static int patch_stac92hd83xxx(struct hda_codec *codec) 5055static int patch_stac92hd83xxx(struct hda_codec *codec)
5085{ 5056{
5086 struct sigmatel_spec *spec; 5057 struct sigmatel_spec *spec;
@@ -5097,32 +5068,30 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5097 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5068 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5098 spec->mono_nid = 0x19; 5069 spec->mono_nid = 0x19;
5099 spec->digbeep_nid = 0x21; 5070 spec->digbeep_nid = 0x21;
5100 spec->dmic_nids = stac92hd83xxx_dmic_nids; 5071 spec->mux_nids = stac92hd83xxx_mux_nids;
5101 spec->dmux_nids = stac92hd83xxx_dmux_nids; 5072 spec->num_muxes = ARRAY_SIZE(stac92hd83xxx_mux_nids);
5102 spec->adc_nids = stac92hd83xxx_adc_nids; 5073 spec->adc_nids = stac92hd83xxx_adc_nids;
5074 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
5103 spec->pwr_nids = stac92hd83xxx_pwr_nids; 5075 spec->pwr_nids = stac92hd83xxx_pwr_nids;
5104 spec->amp_nids = stac92hd83xxx_amp_nids;
5105 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 5076 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
5106 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 5077 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
5107 spec->multiout.dac_nids = spec->dac_nids; 5078 spec->multiout.dac_nids = spec->dac_nids;
5108 5079
5109 spec->init = stac92hd83xxx_core_init; 5080 spec->init = stac92hd83xxx_core_init;
5110 spec->mixer = stac92hd83xxx_mixer;
5111 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); 5081 spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids);
5112 spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids);
5113 spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids);
5114 spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids);
5115 spec->num_dmics = STAC92HD83XXX_NUM_DMICS;
5116 spec->dinput_mux = &stac92hd83xxx_dmux;
5117 spec->pin_nids = stac92hd83xxx_pin_nids; 5082 spec->pin_nids = stac92hd83xxx_pin_nids;
5083 spec->num_caps = STAC92HD83XXX_NUM_CAPS;
5084 spec->capvols = stac92hd83xxx_capvols;
5085 spec->capsws = stac92hd83xxx_capsws;
5086
5118 spec->board_config = snd_hda_check_board_config(codec, 5087 spec->board_config = snd_hda_check_board_config(codec,
5119 STAC_92HD83XXX_MODELS, 5088 STAC_92HD83XXX_MODELS,
5120 stac92hd83xxx_models, 5089 stac92hd83xxx_models,
5121 stac92hd83xxx_cfg_tbl); 5090 stac92hd83xxx_cfg_tbl);
5122again: 5091again:
5123 if (spec->board_config < 0) 5092 if (spec->board_config < 0)
5124 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5093 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5125 " STAC92HD83XXX, using BIOS defaults\n"); 5094 codec->chip_name);
5126 else 5095 else
5127 stac92xx_set_config_regs(codec, 5096 stac92xx_set_config_regs(codec,
5128 stac92hd83xxx_brd_tbl[spec->board_config]); 5097 stac92hd83xxx_brd_tbl[spec->board_config]);
@@ -5164,6 +5133,8 @@ again:
5164 5133
5165 num_dacs = snd_hda_get_connections(codec, nid, 5134 num_dacs = snd_hda_get_connections(codec, nid,
5166 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5135 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5136 if (num_dacs < 0)
5137 num_dacs = STAC92HD83_DAC_COUNT;
5167 5138
5168 /* set port X to select the last DAC 5139 /* set port X to select the last DAC
5169 */ 5140 */
@@ -5177,25 +5148,6 @@ again:
5177 return 0; 5148 return 0;
5178} 5149}
5179 5150
5180static struct hda_input_mux stac92hd71bxx_dmux_nomixer = {
5181 .num_items = 3,
5182 .items = {
5183 { "Analog Inputs", 0x00 },
5184 { "Digital Mic 1", 0x02 },
5185 { "Digital Mic 2", 0x03 },
5186 }
5187};
5188
5189static struct hda_input_mux stac92hd71bxx_dmux_amixer = {
5190 .num_items = 4,
5191 .items = {
5192 { "Analog Inputs", 0x00 },
5193 { "Mixer", 0x01 },
5194 { "Digital Mic 1", 0x02 },
5195 { "Digital Mic 2", 0x03 },
5196 }
5197};
5198
5199/* get the pin connection (fixed, none, etc) */ 5151/* get the pin connection (fixed, none, etc) */
5200static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) 5152static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx)
5201{ 5153{
@@ -5256,7 +5208,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
5256 struct sigmatel_spec *spec; 5208 struct sigmatel_spec *spec;
5257 struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; 5209 struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
5258 int err = 0; 5210 int err = 0;
5259 unsigned int ndmic_nids = 0;
5260 5211
5261 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5212 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5262 if (spec == NULL) 5213 if (spec == NULL)
@@ -5285,8 +5236,8 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
5285 stac92hd71bxx_cfg_tbl); 5236 stac92hd71bxx_cfg_tbl);
5286again: 5237again:
5287 if (spec->board_config < 0) 5238 if (spec->board_config < 0)
5288 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5239 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5289 " STAC92HD71BXX, using BIOS defaults\n"); 5240 codec->chip_name);
5290 else 5241 else
5291 stac92xx_set_config_regs(codec, 5242 stac92xx_set_config_regs(codec,
5292 stac92hd71bxx_brd_tbl[spec->board_config]); 5243 stac92hd71bxx_brd_tbl[spec->board_config]);
@@ -5301,6 +5252,10 @@ again:
5301 spec->dmic_nids = stac92hd71bxx_dmic_nids; 5252 spec->dmic_nids = stac92hd71bxx_dmic_nids;
5302 spec->dmux_nids = stac92hd71bxx_dmux_nids; 5253 spec->dmux_nids = stac92hd71bxx_dmux_nids;
5303 5254
5255 spec->num_caps = STAC92HD71BXX_NUM_CAPS;
5256 spec->capvols = stac92hd71bxx_capvols;
5257 spec->capsws = stac92hd71bxx_capsws;
5258
5304 switch (codec->vendor_id) { 5259 switch (codec->vendor_id) {
5305 case 0x111d76b6: /* 4 Port without Analog Mixer */ 5260 case 0x111d76b6: /* 4 Port without Analog Mixer */
5306 case 0x111d76b7: 5261 case 0x111d76b7:
@@ -5308,24 +5263,13 @@ again:
5308 /* fallthru */ 5263 /* fallthru */
5309 case 0x111d76b4: /* 6 Port without Analog Mixer */ 5264 case 0x111d76b4: /* 6 Port without Analog Mixer */
5310 case 0x111d76b5: 5265 case 0x111d76b5:
5311 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer,
5312 sizeof(stac92hd71bxx_dmux_nomixer));
5313 spec->mixer = stac92hd71bxx_mixer;
5314 spec->init = stac92hd71bxx_core_init; 5266 spec->init = stac92hd71bxx_core_init;
5315 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5267 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5316 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5268 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
5317 stac92hd71bxx_dmic_nids, 5269 stac92hd71bxx_dmic_nids,
5318 STAC92HD71BXX_NUM_DMICS); 5270 STAC92HD71BXX_NUM_DMICS);
5319 if (spec->num_dmics) {
5320 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5321 spec->dinput_mux = &spec->private_dimux;
5322 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1;
5323 }
5324 break; 5271 break;
5325 case 0x111d7608: /* 5 Port with Analog Mixer */ 5272 case 0x111d7608: /* 5 Port with Analog Mixer */
5326 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer,
5327 sizeof(stac92hd71bxx_dmux_amixer));
5328 spec->private_dimux.num_items--;
5329 switch (spec->board_config) { 5273 switch (spec->board_config) {
5330 case STAC_HP_M4: 5274 case STAC_HP_M4:
5331 /* Enable VREF power saving on GPIO1 detect */ 5275 /* Enable VREF power saving on GPIO1 detect */
@@ -5347,11 +5291,8 @@ again:
5347 5291
5348 /* no output amps */ 5292 /* no output amps */
5349 spec->num_pwrs = 0; 5293 spec->num_pwrs = 0;
5350 spec->mixer = stac92hd71bxx_analog_mixer;
5351 spec->dinput_mux = &spec->private_dimux;
5352
5353 /* disable VSW */ 5294 /* disable VSW */
5354 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 5295 spec->init = stac92hd71bxx_core_init;
5355 unmute_init++; 5296 unmute_init++;
5356 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 5297 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
5357 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 5298 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
@@ -5359,8 +5300,6 @@ again:
5359 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5300 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
5360 stac92hd71bxx_dmic_nids, 5301 stac92hd71bxx_dmic_nids,
5361 STAC92HD71BXX_NUM_DMICS - 1); 5302 STAC92HD71BXX_NUM_DMICS - 1);
5362 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5363 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2;
5364 break; 5303 break;
5365 case 0x111d7603: /* 6 Port with Analog Mixer */ 5304 case 0x111d7603: /* 6 Port with Analog Mixer */
5366 if ((codec->revision_id & 0xf) == 1) 5305 if ((codec->revision_id & 0xf) == 1)
@@ -5370,17 +5309,12 @@ again:
5370 spec->num_pwrs = 0; 5309 spec->num_pwrs = 0;
5371 /* fallthru */ 5310 /* fallthru */
5372 default: 5311 default:
5373 memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, 5312 spec->init = stac92hd71bxx_core_init;
5374 sizeof(stac92hd71bxx_dmux_amixer));
5375 spec->dinput_mux = &spec->private_dimux;
5376 spec->mixer = stac92hd71bxx_analog_mixer;
5377 spec->init = stac92hd71bxx_analog_core_init;
5378 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; 5313 codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs;
5379 spec->num_dmics = stac92hd71bxx_connected_ports(codec, 5314 spec->num_dmics = stac92hd71bxx_connected_ports(codec,
5380 stac92hd71bxx_dmic_nids, 5315 stac92hd71bxx_dmic_nids,
5381 STAC92HD71BXX_NUM_DMICS); 5316 STAC92HD71BXX_NUM_DMICS);
5382 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 5317 break;
5383 ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1;
5384 } 5318 }
5385 5319
5386 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 5320 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
@@ -5408,6 +5342,7 @@ again:
5408 5342
5409 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); 5343 spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids);
5410 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); 5344 spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids);
5345 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
5411 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); 5346 spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e);
5412 5347
5413 switch (spec->board_config) { 5348 switch (spec->board_config) {
@@ -5462,8 +5397,6 @@ again:
5462#endif 5397#endif
5463 5398
5464 spec->multiout.dac_nids = spec->dac_nids; 5399 spec->multiout.dac_nids = spec->dac_nids;
5465 if (spec->dinput_mux)
5466 spec->private_dimux.num_items += spec->num_dmics - ndmic_nids;
5467 5400
5468 err = stac92xx_parse_auto_config(codec, 0x21, 0); 5401 err = stac92xx_parse_auto_config(codec, 0x21, 0);
5469 if (!err) { 5402 if (!err) {
@@ -5541,8 +5474,8 @@ static int patch_stac922x(struct hda_codec *codec)
5541 5474
5542 again: 5475 again:
5543 if (spec->board_config < 0) 5476 if (spec->board_config < 0)
5544 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 5477 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5545 "using BIOS defaults\n"); 5478 codec->chip_name);
5546 else 5479 else
5547 stac92xx_set_config_regs(codec, 5480 stac92xx_set_config_regs(codec,
5548 stac922x_brd_tbl[spec->board_config]); 5481 stac922x_brd_tbl[spec->board_config]);
@@ -5555,7 +5488,10 @@ static int patch_stac922x(struct hda_codec *codec)
5555 spec->num_pwrs = 0; 5488 spec->num_pwrs = 0;
5556 5489
5557 spec->init = stac922x_core_init; 5490 spec->init = stac922x_core_init;
5558 spec->mixer = stac922x_mixer; 5491
5492 spec->num_caps = STAC922X_NUM_CAPS;
5493 spec->capvols = stac922x_capvols;
5494 spec->capsws = stac922x_capsws;
5559 5495
5560 spec->multiout.dac_nids = spec->dac_nids; 5496 spec->multiout.dac_nids = spec->dac_nids;
5561 5497
@@ -5604,8 +5540,8 @@ static int patch_stac927x(struct hda_codec *codec)
5604 stac927x_cfg_tbl); 5540 stac927x_cfg_tbl);
5605 again: 5541 again:
5606 if (spec->board_config < 0) 5542 if (spec->board_config < 0)
5607 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5543 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5608 "STAC927x, using BIOS defaults\n"); 5544 codec->chip_name);
5609 else 5545 else
5610 stac92xx_set_config_regs(codec, 5546 stac92xx_set_config_regs(codec,
5611 stac927x_brd_tbl[spec->board_config]); 5547 stac927x_brd_tbl[spec->board_config]);
@@ -5630,7 +5566,6 @@ static int patch_stac927x(struct hda_codec *codec)
5630 spec->num_dmics = 0; 5566 spec->num_dmics = 0;
5631 5567
5632 spec->init = d965_core_init; 5568 spec->init = d965_core_init;
5633 spec->mixer = stac927x_mixer;
5634 break; 5569 break;
5635 case STAC_DELL_BIOS: 5570 case STAC_DELL_BIOS:
5636 switch (codec->subsystem_id) { 5571 switch (codec->subsystem_id) {
@@ -5662,7 +5597,6 @@ static int patch_stac927x(struct hda_codec *codec)
5662 spec->num_dmics = STAC927X_NUM_DMICS; 5597 spec->num_dmics = STAC927X_NUM_DMICS;
5663 5598
5664 spec->init = d965_core_init; 5599 spec->init = d965_core_init;
5665 spec->mixer = stac927x_mixer;
5666 spec->dmux_nids = stac927x_dmux_nids; 5600 spec->dmux_nids = stac927x_dmux_nids;
5667 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); 5601 spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids);
5668 break; 5602 break;
@@ -5675,9 +5609,12 @@ static int patch_stac927x(struct hda_codec *codec)
5675 spec->num_dmics = 0; 5609 spec->num_dmics = 0;
5676 5610
5677 spec->init = stac927x_core_init; 5611 spec->init = stac927x_core_init;
5678 spec->mixer = stac927x_mixer;
5679 } 5612 }
5680 5613
5614 spec->num_caps = STAC927X_NUM_CAPS;
5615 spec->capvols = stac927x_capvols;
5616 spec->capsws = stac927x_capsws;
5617
5681 spec->num_pwrs = 0; 5618 spec->num_pwrs = 0;
5682 spec->aloopback_ctl = stac927x_loopback; 5619 spec->aloopback_ctl = stac927x_loopback;
5683 spec->aloopback_mask = 0x40; 5620 spec->aloopback_mask = 0x40;
@@ -5739,7 +5676,8 @@ static int patch_stac9205(struct hda_codec *codec)
5739 stac9205_cfg_tbl); 5676 stac9205_cfg_tbl);
5740 again: 5677 again:
5741 if (spec->board_config < 0) 5678 if (spec->board_config < 0)
5742 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 5679 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5680 codec->chip_name);
5743 else 5681 else
5744 stac92xx_set_config_regs(codec, 5682 stac92xx_set_config_regs(codec,
5745 stac9205_brd_tbl[spec->board_config]); 5683 stac9205_brd_tbl[spec->board_config]);
@@ -5758,9 +5696,12 @@ static int patch_stac9205(struct hda_codec *codec)
5758 spec->num_pwrs = 0; 5696 spec->num_pwrs = 0;
5759 5697
5760 spec->init = stac9205_core_init; 5698 spec->init = stac9205_core_init;
5761 spec->mixer = stac9205_mixer;
5762 spec->aloopback_ctl = stac9205_loopback; 5699 spec->aloopback_ctl = stac9205_loopback;
5763 5700
5701 spec->num_caps = STAC9205_NUM_CAPS;
5702 spec->capvols = stac9205_capvols;
5703 spec->capsws = stac9205_capsws;
5704
5764 spec->aloopback_mask = 0x40; 5705 spec->aloopback_mask = 0x40;
5765 spec->aloopback_shift = 0; 5706 spec->aloopback_shift = 0;
5766 /* Turn on/off EAPD per HP plugging */ 5707 /* Turn on/off EAPD per HP plugging */
@@ -5835,12 +5776,6 @@ static struct hda_verb stac9872_core_init[] = {
5835 {} 5776 {}
5836}; 5777};
5837 5778
5838static struct snd_kcontrol_new stac9872_mixer[] = {
5839 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5840 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
5841 { } /* end */
5842};
5843
5844static hda_nid_t stac9872_pin_nids[] = { 5779static hda_nid_t stac9872_pin_nids[] = {
5845 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 5780 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
5846 0x11, 0x13, 0x14, 5781 0x11, 0x13, 0x14,
@@ -5854,6 +5789,11 @@ static hda_nid_t stac9872_mux_nids[] = {
5854 0x15 5789 0x15
5855}; 5790};
5856 5791
5792static unsigned long stac9872_capvols[] = {
5793 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
5794};
5795#define stac9872_capsws stac9872_capvols
5796
5857static unsigned int stac9872_vaio_pin_configs[9] = { 5797static unsigned int stac9872_vaio_pin_configs[9] = {
5858 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, 5798 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030,
5859 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, 5799 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0,
@@ -5891,8 +5831,8 @@ static int patch_stac9872(struct hda_codec *codec)
5891 stac9872_models, 5831 stac9872_models,
5892 stac9872_cfg_tbl); 5832 stac9872_cfg_tbl);
5893 if (spec->board_config < 0) 5833 if (spec->board_config < 0)
5894 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " 5834 snd_printdd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5895 "using BIOS defaults\n"); 5835 codec->chip_name);
5896 else 5836 else
5897 stac92xx_set_config_regs(codec, 5837 stac92xx_set_config_regs(codec,
5898 stac9872_brd_tbl[spec->board_config]); 5838 stac9872_brd_tbl[spec->board_config]);
@@ -5902,8 +5842,10 @@ static int patch_stac9872(struct hda_codec *codec)
5902 spec->adc_nids = stac9872_adc_nids; 5842 spec->adc_nids = stac9872_adc_nids;
5903 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); 5843 spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids);
5904 spec->mux_nids = stac9872_mux_nids; 5844 spec->mux_nids = stac9872_mux_nids;
5905 spec->mixer = stac9872_mixer;
5906 spec->init = stac9872_core_init; 5845 spec->init = stac9872_core_init;
5846 spec->num_caps = 1;
5847 spec->capvols = stac9872_capvols;
5848 spec->capsws = stac9872_capsws;
5907 5849
5908 err = stac92xx_parse_auto_config(codec, 0x10, 0x12); 5850 err = stac92xx_parse_auto_config(codec, 0x10, 0x12);
5909 if (err < 0) { 5851 if (err < 0) {
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 9008b4b013aa..ee89db90c9b6 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1339,8 +1339,7 @@ static int get_mux_nids(struct hda_codec *codec)
1339 for (i = 0; i < spec->num_adc_nids; i++) { 1339 for (i = 0; i < spec->num_adc_nids; i++) {
1340 nid = spec->adc_nids[i]; 1340 nid = spec->adc_nids[i];
1341 while (nid) { 1341 while (nid) {
1342 type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) 1342 type = get_wcaps_type(get_wcaps(codec, nid));
1343 >> AC_WCAP_TYPE_SHIFT;
1344 if (type == AC_WID_PIN) 1343 if (type == AC_WID_PIN)
1345 break; 1344 break;
1346 n = snd_hda_get_connections(codec, nid, conn, 1345 n = snd_hda_get_connections(codec, nid, conn,
@@ -1395,6 +1394,7 @@ static int patch_vt1708(struct hda_codec *codec)
1395 if (!spec->adc_nids && spec->input_mux) { 1394 if (!spec->adc_nids && spec->input_mux) {
1396 spec->adc_nids = vt1708_adc_nids; 1395 spec->adc_nids = vt1708_adc_nids;
1397 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids); 1396 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
1397 get_mux_nids(codec);
1398 spec->mixers[spec->num_mixers] = vt1708_capture_mixer; 1398 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
1399 spec->num_mixers++; 1399 spec->num_mixers++;
1400 } 1400 }
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index adc909ec125c..9da2dae64c5b 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -379,6 +379,15 @@ struct snd_ice1712 {
379 unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate); 379 unsigned char (*set_mclk)(struct snd_ice1712 *ice, unsigned int rate);
380 void (*set_spdif_clock)(struct snd_ice1712 *ice); 380 void (*set_spdif_clock)(struct snd_ice1712 *ice);
381 381
382#ifdef CONFIG_PM
383 int (*pm_suspend)(struct snd_ice1712 *);
384 int (*pm_resume)(struct snd_ice1712 *);
385 int pm_suspend_enabled:1;
386 int pm_saved_is_spdif_master:1;
387 unsigned int pm_saved_spdif_ctrl;
388 unsigned char pm_saved_spdif_cfg;
389 unsigned int pm_saved_route;
390#endif
382}; 391};
383 392
384 393
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index cc84a831eb21..af6e00148621 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -560,6 +560,7 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
560 560
561 case SNDRV_PCM_TRIGGER_START: 561 case SNDRV_PCM_TRIGGER_START:
562 case SNDRV_PCM_TRIGGER_STOP: 562 case SNDRV_PCM_TRIGGER_STOP:
563 case SNDRV_PCM_TRIGGER_SUSPEND:
563 spin_lock(&ice->reg_lock); 564 spin_lock(&ice->reg_lock);
564 old = inb(ICEMT1724(ice, DMA_CONTROL)); 565 old = inb(ICEMT1724(ice, DMA_CONTROL));
565 if (cmd == SNDRV_PCM_TRIGGER_START) 566 if (cmd == SNDRV_PCM_TRIGGER_START)
@@ -570,6 +571,10 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
570 spin_unlock(&ice->reg_lock); 571 spin_unlock(&ice->reg_lock);
571 break; 572 break;
572 573
574 case SNDRV_PCM_TRIGGER_RESUME:
575 /* apps will have to restart stream */
576 break;
577
573 default: 578 default:
574 return -EINVAL; 579 return -EINVAL;
575 } 580 }
@@ -2262,7 +2267,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
2262 2267
2263 2268
2264 2269
2265static void __devinit snd_vt1724_chip_reset(struct snd_ice1712 *ice) 2270static void snd_vt1724_chip_reset(struct snd_ice1712 *ice)
2266{ 2271{
2267 outb(VT1724_RESET , ICEREG1724(ice, CONTROL)); 2272 outb(VT1724_RESET , ICEREG1724(ice, CONTROL));
2268 inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */ 2273 inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */
@@ -2272,7 +2277,7 @@ static void __devinit snd_vt1724_chip_reset(struct snd_ice1712 *ice)
2272 msleep(10); 2277 msleep(10);
2273} 2278}
2274 2279
2275static int __devinit snd_vt1724_chip_init(struct snd_ice1712 *ice) 2280static int snd_vt1724_chip_init(struct snd_ice1712 *ice)
2276{ 2281{
2277 outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG)); 2282 outb(ice->eeprom.data[ICE_EEP2_SYSCONF], ICEREG1724(ice, SYS_CFG));
2278 outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG)); 2283 outb(ice->eeprom.data[ICE_EEP2_ACLINK], ICEREG1724(ice, AC97_CFG));
@@ -2287,6 +2292,14 @@ static int __devinit snd_vt1724_chip_init(struct snd_ice1712 *ice)
2287 2292
2288 outb(0, ICEREG1724(ice, POWERDOWN)); 2293 outb(0, ICEREG1724(ice, POWERDOWN));
2289 2294
2295 /* MPU_RX and TX irq masks are cleared later dynamically */
2296 outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
2297
2298 /* don't handle FIFO overrun/underruns (just yet),
2299 * since they cause machine lockups
2300 */
2301 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
2302
2290 return 0; 2303 return 0;
2291} 2304}
2292 2305
@@ -2431,6 +2444,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2431 snd_vt1724_proc_init(ice); 2444 snd_vt1724_proc_init(ice);
2432 synchronize_irq(pci->irq); 2445 synchronize_irq(pci->irq);
2433 2446
2447 card->private_data = ice;
2448
2434 err = pci_request_regions(pci, "ICE1724"); 2449 err = pci_request_regions(pci, "ICE1724");
2435 if (err < 0) { 2450 if (err < 0) {
2436 kfree(ice); 2451 kfree(ice);
@@ -2459,14 +2474,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2459 return -EIO; 2474 return -EIO;
2460 } 2475 }
2461 2476
2462 /* MPU_RX and TX irq masks are cleared later dynamically */
2463 outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
2464
2465 /* don't handle FIFO overrun/underruns (just yet),
2466 * since they cause machine lockups
2467 */
2468 outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK));
2469
2470 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); 2477 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops);
2471 if (err < 0) { 2478 if (err < 0) {
2472 snd_vt1724_free(ice); 2479 snd_vt1724_free(ice);
@@ -2650,11 +2657,96 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2650 pci_set_drvdata(pci, NULL); 2657 pci_set_drvdata(pci, NULL);
2651} 2658}
2652 2659
2660#ifdef CONFIG_PM
2661static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
2662{
2663 struct snd_card *card = pci_get_drvdata(pci);
2664 struct snd_ice1712 *ice = card->private_data;
2665
2666 if (!ice->pm_suspend_enabled)
2667 return 0;
2668
2669 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2670
2671 snd_pcm_suspend_all(ice->pcm);
2672 snd_pcm_suspend_all(ice->pcm_pro);
2673 snd_pcm_suspend_all(ice->pcm_ds);
2674 snd_ac97_suspend(ice->ac97);
2675
2676 spin_lock_irq(&ice->reg_lock);
2677 ice->pm_saved_is_spdif_master = ice->is_spdif_master(ice);
2678 ice->pm_saved_spdif_ctrl = inw(ICEMT1724(ice, SPDIF_CTRL));
2679 ice->pm_saved_spdif_cfg = inb(ICEREG1724(ice, SPDIF_CFG));
2680 ice->pm_saved_route = inl(ICEMT1724(ice, ROUTE_PLAYBACK));
2681 spin_unlock_irq(&ice->reg_lock);
2682
2683 if (ice->pm_suspend)
2684 ice->pm_suspend(ice);
2685
2686 pci_disable_device(pci);
2687 pci_save_state(pci);
2688 pci_set_power_state(pci, pci_choose_state(pci, state));
2689 return 0;
2690}
2691
2692static int snd_vt1724_resume(struct pci_dev *pci)
2693{
2694 struct snd_card *card = pci_get_drvdata(pci);
2695 struct snd_ice1712 *ice = card->private_data;
2696
2697 if (!ice->pm_suspend_enabled)
2698 return 0;
2699
2700 pci_set_power_state(pci, PCI_D0);
2701 pci_restore_state(pci);
2702
2703 if (pci_enable_device(pci) < 0) {
2704 snd_card_disconnect(card);
2705 return -EIO;
2706 }
2707
2708 pci_set_master(pci);
2709
2710 snd_vt1724_chip_reset(ice);
2711
2712 if (snd_vt1724_chip_init(ice) < 0) {
2713 snd_card_disconnect(card);
2714 return -EIO;
2715 }
2716
2717 if (ice->pm_resume)
2718 ice->pm_resume(ice);
2719
2720 if (ice->pm_saved_is_spdif_master) {
2721 /* switching to external clock via SPDIF */
2722 ice->set_spdif_clock(ice);
2723 } else {
2724 /* internal on-card clock */
2725 snd_vt1724_set_pro_rate(ice, ice->pro_rate_default, 1);
2726 }
2727
2728 update_spdif_bits(ice, ice->pm_saved_spdif_ctrl);
2729
2730 outb(ice->pm_saved_spdif_cfg, ICEREG1724(ice, SPDIF_CFG));
2731 outl(ice->pm_saved_route, ICEMT1724(ice, ROUTE_PLAYBACK));
2732
2733 if (ice->ac97)
2734 snd_ac97_resume(ice->ac97);
2735
2736 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2737 return 0;
2738}
2739#endif
2740
2653static struct pci_driver driver = { 2741static struct pci_driver driver = {
2654 .name = "ICE1724", 2742 .name = "ICE1724",
2655 .id_table = snd_vt1724_ids, 2743 .id_table = snd_vt1724_ids,
2656 .probe = snd_vt1724_probe, 2744 .probe = snd_vt1724_probe,
2657 .remove = __devexit_p(snd_vt1724_remove), 2745 .remove = __devexit_p(snd_vt1724_remove),
2746#ifdef CONFIG_PM
2747 .suspend = snd_vt1724_suspend,
2748 .resume = snd_vt1724_resume,
2749#endif
2658}; 2750};
2659 2751
2660static int __init alsa_card_ice1724_init(void) 2752static int __init alsa_card_ice1724_init(void)
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index 043a93879bd5..c75515f5be6f 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1077,7 +1077,7 @@ static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
1077/* 1077/*
1078 * initialize the chip 1078 * initialize the chip
1079 */ 1079 */
1080static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice) 1080static void ak4396_init(struct snd_ice1712 *ice)
1081{ 1081{
1082 static unsigned short ak4396_inits[] = { 1082 static unsigned short ak4396_inits[] = {
1083 AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */ 1083 AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */
@@ -1087,9 +1087,37 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1087 AK4396_RCH_ATT, 0x00, 1087 AK4396_RCH_ATT, 0x00,
1088 }; 1088 };
1089 1089
1090 struct prodigy_hifi_spec *spec;
1091 unsigned int i; 1090 unsigned int i;
1092 1091
1092 /* initialize ak4396 codec */
1093 /* reset codec */
1094 ak4396_write(ice, AK4396_CTRL1, 0x86);
1095 msleep(100);
1096 ak4396_write(ice, AK4396_CTRL1, 0x87);
1097
1098 for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1099 ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1100}
1101
1102#ifdef CONFIG_PM
1103static int __devinit prodigy_hd2_resume(struct snd_ice1712 *ice)
1104{
1105 /* initialize ak4396 codec and restore previous mixer volumes */
1106 struct prodigy_hifi_spec *spec = ice->spec;
1107 int i;
1108 mutex_lock(&ice->gpio_mutex);
1109 ak4396_init(ice);
1110 for (i = 0; i < 2; i++)
1111 ak4396_write(ice, AK4396_LCH_ATT + i, spec->vol[i] & 0xff);
1112 mutex_unlock(&ice->gpio_mutex);
1113 return 0;
1114}
1115#endif
1116
1117static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1118{
1119 struct prodigy_hifi_spec *spec;
1120
1093 ice->vt1720 = 0; 1121 ice->vt1720 = 0;
1094 ice->vt1724 = 1; 1122 ice->vt1724 = 1;
1095 1123
@@ -1112,14 +1140,12 @@ static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1112 return -ENOMEM; 1140 return -ENOMEM;
1113 ice->spec = spec; 1141 ice->spec = spec;
1114 1142
1115 /* initialize ak4396 codec */ 1143#ifdef CONFIG_PM
1116 /* reset codec */ 1144 ice->pm_resume = &prodigy_hd2_resume;
1117 ak4396_write(ice, AK4396_CTRL1, 0x86); 1145 ice->pm_suspend_enabled = 1;
1118 msleep(100); 1146#endif
1119 ak4396_write(ice, AK4396_CTRL1, 0x87); 1147
1120 1148 ak4396_init(ice);
1121 for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1122 ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1123 1149
1124 return 0; 1150 return 0;
1125} 1151}
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 3da5c029f93b..7bb827c7d806 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3294,15 +3294,33 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3294 char *clock_source; 3294 char *clock_source;
3295 int x; 3295 int x;
3296 3296
3297 if (hdsp_check_for_iobox (hdsp)) { 3297 status = hdsp_read(hdsp, HDSP_statusRegister);
3298 snd_iprintf(buffer, "No I/O box connected.\nPlease connect one and upload firmware.\n"); 3298 status2 = hdsp_read(hdsp, HDSP_status2Register);
3299
3300 snd_iprintf(buffer, "%s (Card #%d)\n", hdsp->card_name,
3301 hdsp->card->number + 1);
3302 snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
3303 hdsp->capture_buffer, hdsp->playback_buffer);
3304 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3305 hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
3306 snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
3307 snd_iprintf(buffer, "Control2 register: 0x%x\n",
3308 hdsp->control2_register);
3309 snd_iprintf(buffer, "Status register: 0x%x\n", status);
3310 snd_iprintf(buffer, "Status2 register: 0x%x\n", status2);
3311
3312 if (hdsp_check_for_iobox(hdsp)) {
3313 snd_iprintf(buffer, "No I/O box connected.\n"
3314 "Please connect one and upload firmware.\n");
3299 return; 3315 return;
3300 } 3316 }
3301 3317
3302 if (hdsp_check_for_firmware(hdsp, 0)) { 3318 if (hdsp_check_for_firmware(hdsp, 0)) {
3303 if (hdsp->state & HDSP_FirmwareCached) { 3319 if (hdsp->state & HDSP_FirmwareCached) {
3304 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) { 3320 if (snd_hdsp_load_firmware_from_cache(hdsp) != 0) {
3305 snd_iprintf(buffer, "Firmware loading from cache failed, please upload manually.\n"); 3321 snd_iprintf(buffer, "Firmware loading from "
3322 "cache failed, "
3323 "please upload manually.\n");
3306 return; 3324 return;
3307 } 3325 }
3308 } else { 3326 } else {
@@ -3319,18 +3337,6 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3319 } 3337 }
3320 } 3338 }
3321 3339
3322 status = hdsp_read(hdsp, HDSP_statusRegister);
3323 status2 = hdsp_read(hdsp, HDSP_status2Register);
3324
3325 snd_iprintf(buffer, "%s (Card #%d)\n", hdsp->card_name, hdsp->card->number + 1);
3326 snd_iprintf(buffer, "Buffers: capture %p playback %p\n",
3327 hdsp->capture_buffer, hdsp->playback_buffer);
3328 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3329 hdsp->irq, hdsp->port, (unsigned long)hdsp->iobase);
3330 snd_iprintf(buffer, "Control register: 0x%x\n", hdsp->control_register);
3331 snd_iprintf(buffer, "Control2 register: 0x%x\n", hdsp->control2_register);
3332 snd_iprintf(buffer, "Status register: 0x%x\n", status);
3333 snd_iprintf(buffer, "Status2 register: 0x%x\n", status2);
3334 snd_iprintf(buffer, "FIFO status: %d\n", hdsp_read(hdsp, HDSP_fifoStatus) & 0xff); 3340 snd_iprintf(buffer, "FIFO status: %d\n", hdsp_read(hdsp, HDSP_fifoStatus) & 0xff);
3335 snd_iprintf(buffer, "MIDI1 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut0)); 3341 snd_iprintf(buffer, "MIDI1 Output status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusOut0));
3336 snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0)); 3342 snd_iprintf(buffer, "MIDI1 Input status: 0x%x\n", hdsp_read(hdsp, HDSP_midiStatusIn0));
@@ -3351,7 +3357,6 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3351 3357
3352 snd_iprintf(buffer, "\n"); 3358 snd_iprintf(buffer, "\n");
3353 3359
3354
3355 switch (hdsp_clock_source(hdsp)) { 3360 switch (hdsp_clock_source(hdsp)) {
3356 case HDSP_CLOCK_SOURCE_AUTOSYNC: 3361 case HDSP_CLOCK_SOURCE_AUTOSYNC:
3357 clock_source = "AutoSync"; 3362 clock_source = "AutoSync";
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index d3e786a9a0a7..b1749bc67979 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -29,6 +29,7 @@ source "sound/soc/au1x/Kconfig"
29source "sound/soc/blackfin/Kconfig" 29source "sound/soc/blackfin/Kconfig"
30source "sound/soc/davinci/Kconfig" 30source "sound/soc/davinci/Kconfig"
31source "sound/soc/fsl/Kconfig" 31source "sound/soc/fsl/Kconfig"
32source "sound/soc/imx/Kconfig"
32source "sound/soc/omap/Kconfig" 33source "sound/soc/omap/Kconfig"
33source "sound/soc/pxa/Kconfig" 34source "sound/soc/pxa/Kconfig"
34source "sound/soc/s3c24xx/Kconfig" 35source "sound/soc/s3c24xx/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 6f1e28de23cf..0c5eac01bf2e 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,4 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ 4obj-$(CONFIG_SND_SOC) += codecs/
@@ -7,6 +7,7 @@ obj-$(CONFIG_SND_SOC) += au1x/
7obj-$(CONFIG_SND_SOC) += blackfin/ 7obj-$(CONFIG_SND_SOC) += blackfin/
8obj-$(CONFIG_SND_SOC) += davinci/ 8obj-$(CONFIG_SND_SOC) += davinci/
9obj-$(CONFIG_SND_SOC) += fsl/ 9obj-$(CONFIG_SND_SOC) += fsl/
10obj-$(CONFIG_SND_SOC) += imx/
10obj-$(CONFIG_SND_SOC) += omap/ 11obj-$(CONFIG_SND_SOC) += omap/
11obj-$(CONFIG_SND_SOC) += pxa/ 12obj-$(CONFIG_SND_SOC) += pxa/
12obj-$(CONFIG_SND_SOC) += s3c24xx/ 13obj-$(CONFIG_SND_SOC) += s3c24xx/
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 173a239a541c..130b12118d4f 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -56,30 +56,14 @@
56 56
57#define MCLK_RATE 12000000 57#define MCLK_RATE 12000000
58 58
59static struct clk *mclk; 59/*
60 60 * As shipped the board does not have inputs. However, it is relatively
61static int at91sam9g20ek_startup(struct snd_pcm_substream *substream) 61 * straightforward to modify the board to hook them up so support is left
62{ 62 * in the driver.
63 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); 63 */
64 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 64#undef ENABLE_MIC_INPUT
65 int ret;
66
67 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
68 MCLK_RATE, SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 clk_disable(mclk);
71 return ret;
72 }
73
74 return 0;
75}
76
77static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
78{
79 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
80 65
81 dev_dbg(rtd->socdev->dev, "shutdown"); 66static struct clk *mclk;
82}
83 67
84static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream, 68static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
85 struct snd_pcm_hw_params *params) 69 struct snd_pcm_hw_params *params)
@@ -87,102 +71,17 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
87 struct snd_soc_pcm_runtime *rtd = substream->private_data; 71 struct snd_soc_pcm_runtime *rtd = substream->private_data;
88 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
89 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 73 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
90 struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
91 struct ssc_device *ssc = ssc_p->ssc;
92 int ret; 74 int ret;
93 75
94 unsigned int rate;
95 int cmr_div, period;
96
97 if (ssc == NULL) {
98 printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
99 return -EINVAL;
100 }
101
102 /* set codec DAI configuration */ 76 /* set codec DAI configuration */
103 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 77 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
104 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 78 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
105 if (ret < 0) 79 if (ret < 0)
106 return ret; 80 return ret;
107 81
108 /* set cpu DAI configuration */ 82 /* set cpu DAI configuration */
109 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 83 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
110 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); 84 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
111 if (ret < 0)
112 return ret;
113
114 /*
115 * The SSC clock dividers depend on the sample rate. The CMR.DIV
116 * field divides the system master clock MCK to drive the SSC TK
117 * signal which provides the codec BCLK. The TCMR.PERIOD and
118 * RCMR.PERIOD fields further divide the BCLK signal to drive
119 * the SSC TF and RF signals which provide the codec DACLRC and
120 * ADCLRC clocks.
121 *
122 * The dividers were determined through trial and error, where a
123 * CMR.DIV value is chosen such that the resulting BCLK value is
124 * divisible, or almost divisible, by (2 * sample rate), and then
125 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
126 */
127 rate = params_rate(params);
128
129 switch (rate) {
130 case 8000:
131 cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */
132 period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
133 break;
134 case 11025:
135 cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */
136 period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
137 break;
138 case 16000:
139 cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */
140 period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
141 break;
142 case 22050:
143 cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */
144 period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */
145 break;
146 case 32000:
147 cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */
148 period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
149 break;
150 case 44100:
151 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
152 period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */
153 break;
154 case 48000:
155 cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */
156 period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
157 break;
158 case 88200:
159 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
160 period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */
161 break;
162 case 96000:
163 cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */
164 period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */
165 break;
166 default:
167 printk(KERN_WARNING "unsupported rate %d"
168 " on at91sam9g20ek board\n", rate);
169 return -EINVAL;
170 }
171
172 /* set the MCK divider for BCLK */
173 ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
174 if (ret < 0)
175 return ret;
176
177 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 /* set the BCLK divider for DACLRC */
179 ret = snd_soc_dai_set_clkdiv(cpu_dai,
180 ATMEL_SSC_TCMR_PERIOD, period);
181 } else {
182 /* set the BCLK divider for ADCLRC */
183 ret = snd_soc_dai_set_clkdiv(cpu_dai,
184 ATMEL_SSC_RCMR_PERIOD, period);
185 }
186 if (ret < 0) 85 if (ret < 0)
187 return ret; 86 return ret;
188 87
@@ -190,9 +89,7 @@ static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
190} 89}
191 90
192static struct snd_soc_ops at91sam9g20ek_ops = { 91static struct snd_soc_ops at91sam9g20ek_ops = {
193 .startup = at91sam9g20ek_startup,
194 .hw_params = at91sam9g20ek_hw_params, 92 .hw_params = at91sam9g20ek_hw_params,
195 .shutdown = at91sam9g20ek_shutdown,
196}; 93};
197 94
198static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card, 95static int at91sam9g20ek_set_bias_level(struct snd_soc_card *card,
@@ -241,10 +138,20 @@ static const struct snd_soc_dapm_route intercon[] = {
241 */ 138 */
242static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec) 139static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
243{ 140{
141 struct snd_soc_dai *codec_dai = &codec->dai[0];
142 int ret;
143
244 printk(KERN_DEBUG 144 printk(KERN_DEBUG
245 "at91sam9g20ek_wm8731 " 145 "at91sam9g20ek_wm8731 "
246 ": at91sam9g20ek_wm8731_init() called\n"); 146 ": at91sam9g20ek_wm8731_init() called\n");
247 147
148 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
149 MCLK_RATE, SND_SOC_CLOCK_IN);
150 if (ret < 0) {
151 printk(KERN_ERR "Failed to set WM8731 SYSCLK: %d\n", ret);
152 return ret;
153 }
154
248 /* Add specific widgets */ 155 /* Add specific widgets */
249 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets, 156 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
250 ARRAY_SIZE(at91sam9g20ek_dapm_widgets)); 157 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
@@ -255,8 +162,13 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
255 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 162 snd_soc_dapm_nc_pin(codec, "RLINEIN");
256 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 163 snd_soc_dapm_nc_pin(codec, "LLINEIN");
257 164
258 /* always connected */ 165#ifdef ENABLE_MIC_INPUT
259 snd_soc_dapm_enable_pin(codec, "Int Mic"); 166 snd_soc_dapm_enable_pin(codec, "Int Mic");
167#else
168 snd_soc_dapm_nc_pin(codec, "Int Mic");
169#endif
170
171 /* always connected */
260 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 172 snd_soc_dapm_enable_pin(codec, "Ext Spk");
261 173
262 snd_soc_dapm_sync(codec); 174 snd_soc_dapm_sync(codec);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 479d7bdf1865..a521aa90ddee 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2009 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License version 2 as
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/mutex.h>
22#include <linux/suspend.h> 23#include <linux/suspend.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -29,6 +30,9 @@
29 30
30#include "psc.h" 31#include "psc.h"
31 32
33/* how often to retry failed codec register reads/writes */
34#define AC97_RW_RETRIES 5
35
32#define AC97_DIR \ 36#define AC97_DIR \
33 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) 37 (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE)
34 38
@@ -45,6 +49,9 @@
45#define AC97PCR_CLRFIFO(stype) \ 49#define AC97PCR_CLRFIFO(stype) \
46 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) 50 ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC)
47 51
52#define AC97STAT_BUSY(stype) \
53 ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB)
54
48/* instance data. There can be only one, MacLeod!!!! */ 55/* instance data. There can be only one, MacLeod!!!! */
49static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; 56static struct au1xpsc_audio_data *au1xpsc_ac97_workdata;
50 57
@@ -54,24 +61,33 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
54{ 61{
55 /* FIXME */ 62 /* FIXME */
56 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
57 unsigned short data, tmo; 64 unsigned short data, retry, tmo;
58 65
59 au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg), AC97_CDC(pscdata)); 66 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
60 au_sync(); 67 au_sync();
61 68
62 tmo = 1000; 69 retry = AC97_RW_RETRIES;
63 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) 70 do {
64 udelay(2); 71 mutex_lock(&pscdata->lock);
72
73 au_writel(PSC_AC97CDC_RD | PSC_AC97CDC_INDX(reg),
74 AC97_CDC(pscdata));
75 au_sync();
76
77 tmo = 2000;
78 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD))
79 && --tmo)
80 udelay(2);
65 81
66 if (!tmo)
67 data = 0xffff;
68 else
69 data = au_readl(AC97_CDC(pscdata)) & 0xffff; 82 data = au_readl(AC97_CDC(pscdata)) & 0xffff;
70 83
71 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 84 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
72 au_sync(); 85 au_sync();
86
87 mutex_unlock(&pscdata->lock);
88 } while (--retry && !tmo);
73 89
74 return data; 90 return retry ? data : 0xffff;
75} 91}
76 92
77/* AC97 controller writes to codec register */ 93/* AC97 controller writes to codec register */
@@ -80,16 +96,29 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
80{ 96{
81 /* FIXME */ 97 /* FIXME */
82 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 98 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
83 unsigned int tmo; 99 unsigned int tmo, retry;
84 100
85 au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff), AC97_CDC(pscdata)); 101 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
86 au_sync(); 102 au_sync();
87 tmo = 1000; 103
88 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) && --tmo) 104 retry = AC97_RW_RETRIES;
105 do {
106 mutex_lock(&pscdata->lock);
107
108 au_writel(PSC_AC97CDC_INDX(reg) | (val & 0xffff),
109 AC97_CDC(pscdata));
89 au_sync(); 110 au_sync();
90 111
91 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 112 tmo = 2000;
92 au_sync(); 113 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD))
114 && --tmo)
115 udelay(2);
116
117 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
118 au_sync();
119
120 mutex_unlock(&pscdata->lock);
121 } while (--retry && !tmo);
93} 122}
94 123
95/* AC97 controller asserts a warm reset */ 124/* AC97 controller asserts a warm reset */
@@ -129,9 +158,9 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
129 au_sync(); 158 au_sync();
130 159
131 /* wait for PSC to indicate it's ready */ 160 /* wait for PSC to indicate it's ready */
132 i = 100000; 161 i = 1000;
133 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i)) 162 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_SR)) && (--i))
134 au_sync(); 163 msleep(1);
135 164
136 if (i == 0) { 165 if (i == 0) {
137 printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n"); 166 printk(KERN_ERR "au1xpsc-ac97: PSC not ready!\n");
@@ -143,9 +172,9 @@ static void au1xpsc_ac97_cold_reset(struct snd_ac97 *ac97)
143 au_sync(); 172 au_sync();
144 173
145 /* wait for AC97 core to become ready */ 174 /* wait for AC97 core to become ready */
146 i = 100000; 175 i = 1000;
147 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i)) 176 while (!((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && (--i))
148 au_sync(); 177 msleep(1);
149 if (i == 0) 178 if (i == 0)
150 printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n"); 179 printk(KERN_ERR "au1xpsc-ac97: AC97 ctrl not ready\n");
151} 180}
@@ -165,12 +194,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
165{ 194{
166 /* FIXME */ 195 /* FIXME */
167 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 196 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
168 unsigned long r, stat; 197 unsigned long r, ro, stat;
169 int chans, stype = SUBSTREAM_TYPE(substream); 198 int chans, stype = SUBSTREAM_TYPE(substream);
170 199
171 chans = params_channels(params); 200 chans = params_channels(params);
172 201
173 r = au_readl(AC97_CFG(pscdata)); 202 r = ro = au_readl(AC97_CFG(pscdata));
174 stat = au_readl(AC97_STAT(pscdata)); 203 stat = au_readl(AC97_STAT(pscdata));
175 204
176 /* already active? */ 205 /* already active? */
@@ -180,9 +209,6 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
180 (pscdata->rate != params_rate(params))) 209 (pscdata->rate != params_rate(params)))
181 return -EINVAL; 210 return -EINVAL;
182 } else { 211 } else {
183 /* disable AC97 device controller first */
184 au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
185 au_sync();
186 212
187 /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */ 213 /* set sample bitdepth: REG[24:21]=(BITS-2)/2 */
188 r &= ~PSC_AC97CFG_LEN_MASK; 214 r &= ~PSC_AC97CFG_LEN_MASK;
@@ -199,14 +225,40 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
199 r |= PSC_AC97CFG_RXSLOT_ENA(4); 225 r |= PSC_AC97CFG_RXSLOT_ENA(4);
200 } 226 }
201 227
202 /* finally enable the AC97 controller again */ 228 /* do we need to poke the hardware? */
229 if (!(r ^ ro))
230 goto out;
231
232 /* ac97 engine is about to be disabled */
233 mutex_lock(&pscdata->lock);
234
235 /* disable AC97 device controller first... */
236 au_writel(r & ~PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
237 au_sync();
238
239 /* ...wait for it... */
240 while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)
241 asm volatile ("nop");
242
243 /* ...write config... */
244 au_writel(r, AC97_CFG(pscdata));
245 au_sync();
246
247 /* ...enable the AC97 controller again... */
203 au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata)); 248 au_writel(r | PSC_AC97CFG_DE_ENABLE, AC97_CFG(pscdata));
204 au_sync(); 249 au_sync();
205 250
251 /* ...and wait for ready bit */
252 while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR))
253 asm volatile ("nop");
254
255 mutex_unlock(&pscdata->lock);
256
206 pscdata->cfg = r; 257 pscdata->cfg = r;
207 pscdata->rate = params_rate(params); 258 pscdata->rate = params_rate(params);
208 } 259 }
209 260
261out:
210 return 0; 262 return 0;
211} 263}
212 264
@@ -222,6 +274,8 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
222 switch (cmd) { 274 switch (cmd) {
223 case SNDRV_PCM_TRIGGER_START: 275 case SNDRV_PCM_TRIGGER_START:
224 case SNDRV_PCM_TRIGGER_RESUME: 276 case SNDRV_PCM_TRIGGER_RESUME:
277 au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
278 au_sync();
225 au_writel(AC97PCR_START(stype), AC97_PCR(pscdata)); 279 au_writel(AC97PCR_START(stype), AC97_PCR(pscdata));
226 au_sync(); 280 au_sync();
227 break; 281 break;
@@ -229,6 +283,13 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
229 case SNDRV_PCM_TRIGGER_SUSPEND: 283 case SNDRV_PCM_TRIGGER_SUSPEND:
230 au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata)); 284 au_writel(AC97PCR_STOP(stype), AC97_PCR(pscdata));
231 au_sync(); 285 au_sync();
286
287 while (au_readl(AC97_STAT(pscdata)) & AC97STAT_BUSY(stype))
288 asm volatile ("nop");
289
290 au_writel(AC97PCR_CLRFIFO(stype), AC97_PCR(pscdata));
291 au_sync();
292
232 break; 293 break;
233 default: 294 default:
234 ret = -EINVAL; 295 ret = -EINVAL;
@@ -251,6 +312,8 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev,
251 if (!au1xpsc_ac97_workdata) 312 if (!au1xpsc_ac97_workdata)
252 return -ENOMEM; 313 return -ENOMEM;
253 314
315 mutex_init(&au1xpsc_ac97_workdata->lock);
316
254 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 317 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
255 if (!r) { 318 if (!r) {
256 ret = -ENODEV; 319 ret = -ENODEV;
@@ -269,9 +332,9 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev,
269 goto out1; 332 goto out1;
270 333
271 /* configuration: max dma trigger threshold, enable ac97 */ 334 /* configuration: max dma trigger threshold, enable ac97 */
272 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | 335 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 |
273 PSC_AC97CFG_TT_FIFO8 | 336 PSC_AC97CFG_TT_FIFO8 |
274 PSC_AC97CFG_DE_ENABLE; 337 PSC_AC97CFG_DE_ENABLE;
275 338
276 /* preserve PSC clock source set up by platform (dev.platform_data 339 /* preserve PSC clock source set up by platform (dev.platform_data
277 * is already occupied by soc layer) 340 * is already occupied by soc layer)
@@ -386,4 +449,4 @@ module_exit(au1xpsc_ac97_exit);
386 449
387MODULE_LICENSE("GPL"); 450MODULE_LICENSE("GPL");
388MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 451MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
389MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 452MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>");
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 8fdb1a04a07b..3f474e8ed4f6 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -29,6 +29,7 @@ struct au1xpsc_audio_data {
29 29
30 unsigned long pm[2]; 30 unsigned long pm[2];
31 struct resource *ioarea; 31 struct resource *ioarea;
32 struct mutex lock;
32}; 33};
33 34
34#define PCM_TX 0 35#define PCM_TX 0
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 811596f4c092..ac927ffdc961 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -7,6 +7,15 @@ config SND_BF5XX_I2S
7 mode (supports single stereo In/Out). 7 mode (supports single stereo In/Out).
8 You will also need to select the audio interfaces to support below. 8 You will also need to select the audio interfaces to support below.
9 9
10config SND_BF5XX_TDM
11 tristate "SoC I2S(TDM mode) Audio for the ADI BF5xx chip"
12 depends on (BLACKFIN && SND_SOC)
13 help
14 Say Y or M if you want to add support for codecs attached to
15 the Blackfin SPORT (synchronous serial ports) interface in TDM
16 mode.
17 You will also need to select the audio interfaces to support below.
18
10config SND_BF5XX_SOC_SSM2602 19config SND_BF5XX_SOC_SSM2602
11 tristate "SoC SSM2602 Audio support for BF52x ezkit" 20 tristate "SoC SSM2602 Audio support for BF52x ezkit"
12 depends on SND_BF5XX_I2S 21 depends on SND_BF5XX_I2S
@@ -69,12 +78,24 @@ config SND_BF5XX_SOC_I2S
69 tristate 78 tristate
70 select SND_BF5XX_SOC_SPORT 79 select SND_BF5XX_SOC_SPORT
71 80
81config SND_BF5XX_SOC_TDM
82 tristate
83 select SND_BF5XX_SOC_SPORT
84
72config SND_BF5XX_SOC_AC97 85config SND_BF5XX_SOC_AC97
73 tristate 86 tristate
74 select AC97_BUS 87 select AC97_BUS
75 select SND_SOC_AC97_BUS 88 select SND_SOC_AC97_BUS
76 select SND_BF5XX_SOC_SPORT 89 select SND_BF5XX_SOC_SPORT
77 90
91config SND_BF5XX_SOC_AD1836
92 tristate "SoC AD1836 Audio support for BF5xx"
93 depends on SND_BF5XX_TDM
94 select SND_BF5XX_SOC_TDM
95 select SND_SOC_AD1836
96 help
97 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
98
78config SND_BF5XX_SOC_AD1980 99config SND_BF5XX_SOC_AD1980
79 tristate "SoC AD1980/1 Audio support for BF5xx" 100 tristate "SoC AD1980/1 Audio support for BF5xx"
80 depends on SND_BF5XX_AC97 101 depends on SND_BF5XX_AC97
@@ -83,9 +104,17 @@ config SND_BF5XX_SOC_AD1980
83 help 104 help
84 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT. 105 Say Y if you want to add support for SoC audio on BF5xx STAMP/EZKIT.
85 106
107config SND_BF5XX_SOC_AD1938
108 tristate "SoC AD1938 Audio support for Blackfin"
109 depends on SND_BF5XX_TDM
110 select SND_BF5XX_SOC_TDM
111 select SND_SOC_AD1938
112 help
113 Say Y if you want to add support for AD1938 codec on Blackfin.
114
86config SND_BF5XX_SPORT_NUM 115config SND_BF5XX_SPORT_NUM
87 int "Set a SPORT for Sound chip" 116 int "Set a SPORT for Sound chip"
88 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97) 117 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM)
89 range 0 3 if BF54x 118 range 0 3 if BF54x
90 range 0 1 if !BF54x 119 range 0 1 if !BF54x
91 default 0 120 default 0
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 97bb37a6359c..87e30423912f 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -1,21 +1,29 @@
1# Blackfin Platform Support 1# Blackfin Platform Support
2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o 2snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o 3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o
4snd-soc-bf5xx-sport-objs := bf5xx-sport.o 5snd-soc-bf5xx-sport-objs := bf5xx-sport.o
5snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o 6snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
6snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o 7snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
8snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
7 9
8obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o 10obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
9obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o 11obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
12obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o
10obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o 13obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
11obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o 14obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
12obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o 15obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
16obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
13 17
14# Blackfin Machine Support 18# Blackfin Machine Support
19snd-ad1836-objs := bf5xx-ad1836.o
15snd-ad1980-objs := bf5xx-ad1980.o 20snd-ad1980-objs := bf5xx-ad1980.o
16snd-ssm2602-objs := bf5xx-ssm2602.o 21snd-ssm2602-objs := bf5xx-ssm2602.o
17snd-ad73311-objs := bf5xx-ad73311.o 22snd-ad73311-objs := bf5xx-ad73311.o
23snd-ad1938-objs := bf5xx-ad1938.o
18 24
25obj-$(CONFIG_SND_BF5XX_SOC_AD1836) += snd-ad1836.o
19obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o 26obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o
20obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o 27obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o
21obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o 28obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o
29obj-$(CONFIG_SND_BF5XX_SOC_AD1938) += snd-ad1938.o
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index b1ed423fabd5..2758b9017a7f 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -277,28 +277,24 @@ static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
277 if (!dai->active) 277 if (!dai->active)
278 return 0; 278 return 0;
279 279
280 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); 280 ret = sport_set_multichannel(sport, 16, 0x1F, 1);
281 if (ret) { 281 if (ret) {
282 pr_err("SPORT is busy!\n"); 282 pr_err("SPORT is busy!\n");
283 return -EBUSY; 283 return -EBUSY;
284 } 284 }
285 285
286 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1)); 286 ret = sport_config_rx(sport, IRFS, 0xF, 0, (16*16-1));
287 if (ret) { 287 if (ret) {
288 pr_err("SPORT is busy!\n"); 288 pr_err("SPORT is busy!\n");
289 return -EBUSY; 289 return -EBUSY;
290 } 290 }
291 291
292 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1)); 292 ret = sport_config_tx(sport, ITFS, 0xF, 0, (16*16-1));
293 if (ret) { 293 if (ret) {
294 pr_err("SPORT is busy!\n"); 294 pr_err("SPORT is busy!\n");
295 return -EBUSY; 295 return -EBUSY;
296 } 296 }
297 297
298 if (dai->capture.active)
299 sport_rx_start(sport);
300 if (dai->playback.active)
301 sport_tx_start(sport);
302 return 0; 298 return 0;
303} 299}
304 300
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
new file mode 100644
index 000000000000..cd361e304b0f
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -0,0 +1,128 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad1836.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Aug 4 2009
6 * Description: Board driver for ad1836 sound chip
7 *
8 * Bugs: Enter bugs at http://blackfin.uclinux.org/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/moduleparam.h>
19#include <linux/device.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm_params.h>
25
26#include <asm/blackfin.h>
27#include <asm/cacheflush.h>
28#include <asm/irq.h>
29#include <asm/dma.h>
30#include <asm/portmux.h>
31
32#include "../codecs/ad1836.h"
33#include "bf5xx-sport.h"
34
35#include "bf5xx-tdm-pcm.h"
36#include "bf5xx-tdm.h"
37
38static struct snd_soc_card bf5xx_ad1836;
39
40static int bf5xx_ad1836_startup(struct snd_pcm_substream *substream)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44
45 cpu_dai->private_data = sport_handle;
46 return 0;
47}
48
49static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
50 struct snd_pcm_hw_params *params)
51{
52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
55 int ret = 0;
56 /* set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
58 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
59 if (ret < 0)
60 return ret;
61
62 /* set codec DAI configuration */
63 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
64 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
65 if (ret < 0)
66 return ret;
67
68 return 0;
69}
70
71static struct snd_soc_ops bf5xx_ad1836_ops = {
72 .startup = bf5xx_ad1836_startup,
73 .hw_params = bf5xx_ad1836_hw_params,
74};
75
76static struct snd_soc_dai_link bf5xx_ad1836_dai = {
77 .name = "ad1836",
78 .stream_name = "AD1836",
79 .cpu_dai = &bf5xx_tdm_dai,
80 .codec_dai = &ad1836_dai,
81 .ops = &bf5xx_ad1836_ops,
82};
83
84static struct snd_soc_card bf5xx_ad1836 = {
85 .name = "bf5xx_ad1836",
86 .platform = &bf5xx_tdm_soc_platform,
87 .dai_link = &bf5xx_ad1836_dai,
88 .num_links = 1,
89};
90
91static struct snd_soc_device bf5xx_ad1836_snd_devdata = {
92 .card = &bf5xx_ad1836,
93 .codec_dev = &soc_codec_dev_ad1836,
94};
95
96static struct platform_device *bfxx_ad1836_snd_device;
97
98static int __init bf5xx_ad1836_init(void)
99{
100 int ret;
101
102 bfxx_ad1836_snd_device = platform_device_alloc("soc-audio", -1);
103 if (!bfxx_ad1836_snd_device)
104 return -ENOMEM;
105
106 platform_set_drvdata(bfxx_ad1836_snd_device, &bf5xx_ad1836_snd_devdata);
107 bf5xx_ad1836_snd_devdata.dev = &bfxx_ad1836_snd_device->dev;
108 ret = platform_device_add(bfxx_ad1836_snd_device);
109
110 if (ret)
111 platform_device_put(bfxx_ad1836_snd_device);
112
113 return ret;
114}
115
116static void __exit bf5xx_ad1836_exit(void)
117{
118 platform_device_unregister(bfxx_ad1836_snd_device);
119}
120
121module_init(bf5xx_ad1836_init);
122module_exit(bf5xx_ad1836_exit);
123
124/* Module information */
125MODULE_AUTHOR("Barry Song");
126MODULE_DESCRIPTION("ALSA SoC AD1836 board driver");
127MODULE_LICENSE("GPL");
128
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad1938.c
new file mode 100644
index 000000000000..08269e91810c
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-ad1938.c
@@ -0,0 +1,142 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-ad1938.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Thur June 4 2009
6 * Description: Board driver for ad1938 sound chip
7 *
8 * Bugs: Enter bugs at http://blackfin.uclinux.org/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see the file COPYING, or write
22 * to the Free Software Foundation, Inc.,
23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26#include <linux/module.h>
27#include <linux/moduleparam.h>
28#include <linux/device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/pcm_params.h>
34
35#include <asm/blackfin.h>
36#include <asm/cacheflush.h>
37#include <asm/irq.h>
38#include <asm/dma.h>
39#include <asm/portmux.h>
40
41#include "../codecs/ad1938.h"
42#include "bf5xx-sport.h"
43
44#include "bf5xx-tdm-pcm.h"
45#include "bf5xx-tdm.h"
46
47static struct snd_soc_card bf5xx_ad1938;
48
49static int bf5xx_ad1938_startup(struct snd_pcm_substream *substream)
50{
51 struct snd_soc_pcm_runtime *rtd = substream->private_data;
52 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
53
54 cpu_dai->private_data = sport_handle;
55 return 0;
56}
57
58static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
59 struct snd_pcm_hw_params *params)
60{
61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 int ret = 0;
65 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
67 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
68 if (ret < 0)
69 return ret;
70
71 /* set codec DAI configuration */
72 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |
73 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
74 if (ret < 0)
75 return ret;
76
77 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 8);
79 if (ret < 0)
80 return ret;
81
82 return 0;
83}
84
85static struct snd_soc_ops bf5xx_ad1938_ops = {
86 .startup = bf5xx_ad1938_startup,
87 .hw_params = bf5xx_ad1938_hw_params,
88};
89
90static struct snd_soc_dai_link bf5xx_ad1938_dai = {
91 .name = "ad1938",
92 .stream_name = "AD1938",
93 .cpu_dai = &bf5xx_tdm_dai,
94 .codec_dai = &ad1938_dai,
95 .ops = &bf5xx_ad1938_ops,
96};
97
98static struct snd_soc_card bf5xx_ad1938 = {
99 .name = "bf5xx_ad1938",
100 .platform = &bf5xx_tdm_soc_platform,
101 .dai_link = &bf5xx_ad1938_dai,
102 .num_links = 1,
103};
104
105static struct snd_soc_device bf5xx_ad1938_snd_devdata = {
106 .card = &bf5xx_ad1938,
107 .codec_dev = &soc_codec_dev_ad1938,
108};
109
110static struct platform_device *bfxx_ad1938_snd_device;
111
112static int __init bf5xx_ad1938_init(void)
113{
114 int ret;
115
116 bfxx_ad1938_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!bfxx_ad1938_snd_device)
118 return -ENOMEM;
119
120 platform_set_drvdata(bfxx_ad1938_snd_device, &bf5xx_ad1938_snd_devdata);
121 bf5xx_ad1938_snd_devdata.dev = &bfxx_ad1938_snd_device->dev;
122 ret = platform_device_add(bfxx_ad1938_snd_device);
123
124 if (ret)
125 platform_device_put(bfxx_ad1938_snd_device);
126
127 return ret;
128}
129
130static void __exit bf5xx_ad1938_exit(void)
131{
132 platform_device_unregister(bfxx_ad1938_snd_device);
133}
134
135module_init(bf5xx_ad1938_init);
136module_exit(bf5xx_ad1938_exit);
137
138/* Module information */
139MODULE_AUTHOR("Barry Song");
140MODULE_DESCRIPTION("ALSA SoC AD1938 board driver");
141MODULE_LICENSE("GPL");
142
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index edfbdc024e66..9825b71d0e28 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -203,23 +203,23 @@ static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
203 .codec_dev = &soc_codec_dev_ad73311, 203 .codec_dev = &soc_codec_dev_ad73311,
204}; 204};
205 205
206static struct platform_device *bf52x_ad73311_snd_device; 206static struct platform_device *bf5xx_ad73311_snd_device;
207 207
208static int __init bf5xx_ad73311_init(void) 208static int __init bf5xx_ad73311_init(void)
209{ 209{
210 int ret; 210 int ret;
211 211
212 pr_debug("%s enter\n", __func__); 212 pr_debug("%s enter\n", __func__);
213 bf52x_ad73311_snd_device = platform_device_alloc("soc-audio", -1); 213 bf5xx_ad73311_snd_device = platform_device_alloc("soc-audio", -1);
214 if (!bf52x_ad73311_snd_device) 214 if (!bf5xx_ad73311_snd_device)
215 return -ENOMEM; 215 return -ENOMEM;
216 216
217 platform_set_drvdata(bf52x_ad73311_snd_device, &bf5xx_ad73311_snd_devdata); 217 platform_set_drvdata(bf5xx_ad73311_snd_device, &bf5xx_ad73311_snd_devdata);
218 bf5xx_ad73311_snd_devdata.dev = &bf52x_ad73311_snd_device->dev; 218 bf5xx_ad73311_snd_devdata.dev = &bf5xx_ad73311_snd_device->dev;
219 ret = platform_device_add(bf52x_ad73311_snd_device); 219 ret = platform_device_add(bf5xx_ad73311_snd_device);
220 220
221 if (ret) 221 if (ret)
222 platform_device_put(bf52x_ad73311_snd_device); 222 platform_device_put(bf5xx_ad73311_snd_device);
223 223
224 return ret; 224 return ret;
225} 225}
@@ -227,7 +227,7 @@ static int __init bf5xx_ad73311_init(void)
227static void __exit bf5xx_ad73311_exit(void) 227static void __exit bf5xx_ad73311_exit(void)
228{ 228{
229 pr_debug("%s enter\n", __func__); 229 pr_debug("%s enter\n", __func__);
230 platform_device_unregister(bf52x_ad73311_snd_device); 230 platform_device_unregister(bf5xx_ad73311_snd_device);
231} 231}
232 232
233module_init(bf5xx_ad73311_init); 233module_init(bf5xx_ad73311_init);
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index af06904bab0f..876abade27e1 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -259,22 +259,18 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
259 if (!dai->active) 259 if (!dai->active)
260 return 0; 260 return 0;
261 261
262 ret = sport_config_rx(sport_handle, RFSR | RCKFE, RSFSE|0x1f, 0, 0); 262 ret = sport_config_rx(sport, RFSR | RCKFE, RSFSE|0x1f, 0, 0);
263 if (ret) { 263 if (ret) {
264 pr_err("SPORT is busy!\n"); 264 pr_err("SPORT is busy!\n");
265 return -EBUSY; 265 return -EBUSY;
266 } 266 }
267 267
268 ret = sport_config_tx(sport_handle, TFSR | TCKFE, TSFSE|0x1f, 0, 0); 268 ret = sport_config_tx(sport, TFSR | TCKFE, TSFSE|0x1f, 0, 0);
269 if (ret) { 269 if (ret) {
270 pr_err("SPORT is busy!\n"); 270 pr_err("SPORT is busy!\n");
271 return -EBUSY; 271 return -EBUSY;
272 } 272 }
273 273
274 if (dai->capture.active)
275 sport_rx_start(sport);
276 if (dai->playback.active)
277 sport_tx_start(sport);
278 return 0; 274 return 0;
279} 275}
280 276
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index bc0cdded7116..3a00fa4dbe6d 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -148,24 +148,24 @@ static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
148 .codec_data = &bf5xx_ssm2602_setup, 148 .codec_data = &bf5xx_ssm2602_setup,
149}; 149};
150 150
151static struct platform_device *bf52x_ssm2602_snd_device; 151static struct platform_device *bf5xx_ssm2602_snd_device;
152 152
153static int __init bf5xx_ssm2602_init(void) 153static int __init bf5xx_ssm2602_init(void)
154{ 154{
155 int ret; 155 int ret;
156 156
157 pr_debug("%s enter\n", __func__); 157 pr_debug("%s enter\n", __func__);
158 bf52x_ssm2602_snd_device = platform_device_alloc("soc-audio", -1); 158 bf5xx_ssm2602_snd_device = platform_device_alloc("soc-audio", -1);
159 if (!bf52x_ssm2602_snd_device) 159 if (!bf5xx_ssm2602_snd_device)
160 return -ENOMEM; 160 return -ENOMEM;
161 161
162 platform_set_drvdata(bf52x_ssm2602_snd_device, 162 platform_set_drvdata(bf5xx_ssm2602_snd_device,
163 &bf5xx_ssm2602_snd_devdata); 163 &bf5xx_ssm2602_snd_devdata);
164 bf5xx_ssm2602_snd_devdata.dev = &bf52x_ssm2602_snd_device->dev; 164 bf5xx_ssm2602_snd_devdata.dev = &bf5xx_ssm2602_snd_device->dev;
165 ret = platform_device_add(bf52x_ssm2602_snd_device); 165 ret = platform_device_add(bf5xx_ssm2602_snd_device);
166 166
167 if (ret) 167 if (ret)
168 platform_device_put(bf52x_ssm2602_snd_device); 168 platform_device_put(bf5xx_ssm2602_snd_device);
169 169
170 return ret; 170 return ret;
171} 171}
@@ -173,7 +173,7 @@ static int __init bf5xx_ssm2602_init(void)
173static void __exit bf5xx_ssm2602_exit(void) 173static void __exit bf5xx_ssm2602_exit(void)
174{ 174{
175 pr_debug("%s enter\n", __func__); 175 pr_debug("%s enter\n", __func__);
176 platform_device_unregister(bf52x_ssm2602_snd_device); 176 platform_device_unregister(bf5xx_ssm2602_snd_device);
177} 177}
178 178
179module_init(bf5xx_ssm2602_init); 179module_init(bf5xx_ssm2602_init);
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
new file mode 100644
index 000000000000..ccb5e823bd18
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -0,0 +1,330 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-tdm-pcm.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Tue June 06 2009
6 * Description: DMA driver for tdm codec
7 *
8 * Modified:
9 * Copyright 2009 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/init.h>
31#include <linux/platform_device.h>
32#include <linux/slab.h>
33#include <linux/dma-mapping.h>
34
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39
40#include <asm/dma.h>
41
42#include "bf5xx-tdm-pcm.h"
43#include "bf5xx-tdm.h"
44#include "bf5xx-sport.h"
45
46#define PCM_BUFFER_MAX 0x10000
47#define FRAGMENT_SIZE_MIN (4*1024)
48#define FRAGMENTS_MIN 2
49#define FRAGMENTS_MAX 32
50
51static void bf5xx_dma_irq(void *data)
52{
53 struct snd_pcm_substream *pcm = data;
54 snd_pcm_period_elapsed(pcm);
55}
56
57static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
58 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
59 SNDRV_PCM_INFO_RESUME),
60 .formats = SNDRV_PCM_FMTBIT_S32_LE,
61 .rates = SNDRV_PCM_RATE_48000,
62 .channels_min = 2,
63 .channels_max = 8,
64 .buffer_bytes_max = PCM_BUFFER_MAX,
65 .period_bytes_min = FRAGMENT_SIZE_MIN,
66 .period_bytes_max = PCM_BUFFER_MAX/2,
67 .periods_min = FRAGMENTS_MIN,
68 .periods_max = FRAGMENTS_MAX,
69};
70
71static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
72 struct snd_pcm_hw_params *params)
73{
74 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
75 snd_pcm_lib_malloc_pages(substream, size * 4);
76
77 return 0;
78}
79
80static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
81{
82 snd_pcm_lib_free_pages(substream);
83
84 return 0;
85}
86
87static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
88{
89 struct snd_pcm_runtime *runtime = substream->runtime;
90 struct sport_device *sport = runtime->private_data;
91 int fragsize_bytes = frames_to_bytes(runtime, runtime->period_size);
92
93 fragsize_bytes /= runtime->channels;
94 /* inflate the fragsize to match the dma width of SPORT */
95 fragsize_bytes *= 8;
96
97 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
98 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
99 sport_config_tx_dma(sport, runtime->dma_area,
100 runtime->periods, fragsize_bytes);
101 } else {
102 sport_set_rx_callback(sport, bf5xx_dma_irq, substream);
103 sport_config_rx_dma(sport, runtime->dma_area,
104 runtime->periods, fragsize_bytes);
105 }
106
107 return 0;
108}
109
110static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
111{
112 struct snd_pcm_runtime *runtime = substream->runtime;
113 struct sport_device *sport = runtime->private_data;
114 int ret = 0;
115
116 switch (cmd) {
117 case SNDRV_PCM_TRIGGER_START:
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
119 sport_tx_start(sport);
120 else
121 sport_rx_start(sport);
122 break;
123 case SNDRV_PCM_TRIGGER_STOP:
124 case SNDRV_PCM_TRIGGER_SUSPEND:
125 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
126 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
127 sport_tx_stop(sport);
128 else
129 sport_rx_stop(sport);
130 break;
131 default:
132 ret = -EINVAL;
133 }
134
135 return ret;
136}
137
138static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
139{
140 struct snd_pcm_runtime *runtime = substream->runtime;
141 struct sport_device *sport = runtime->private_data;
142 unsigned int diff;
143 snd_pcm_uframes_t frames;
144
145 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
146 diff = sport_curr_offset_tx(sport);
147 frames = diff / (8*4); /* 32 bytes per frame */
148 } else {
149 diff = sport_curr_offset_rx(sport);
150 frames = diff / (8*4);
151 }
152 return frames;
153}
154
155static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
156{
157 struct snd_pcm_runtime *runtime = substream->runtime;
158 int ret = 0;
159
160 snd_soc_set_runtime_hwparams(substream, &bf5xx_pcm_hardware);
161
162 ret = snd_pcm_hw_constraint_integer(runtime,
163 SNDRV_PCM_HW_PARAM_PERIODS);
164 if (ret < 0)
165 goto out;
166
167 if (sport_handle != NULL)
168 runtime->private_data = sport_handle;
169 else {
170 pr_err("sport_handle is NULL\n");
171 ret = -ENODEV;
172 }
173out:
174 return ret;
175}
176
177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
179{
180 unsigned int *src;
181 unsigned int *dst;
182 int i;
183
184 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
185 src = buf;
186 dst = (unsigned int *)substream->runtime->dma_area;
187
188 dst += pos * 8;
189 while (count--) {
190 for (i = 0; i < substream->runtime->channels; i++)
191 *(dst + i) = *src++;
192 dst += 8;
193 }
194 } else {
195 src = (unsigned int *)substream->runtime->dma_area;
196 dst = buf;
197
198 src += pos * 8;
199 while (count--) {
200 for (i = 0; i < substream->runtime->channels; i++)
201 *dst++ = *(src+i);
202 src += 8;
203 }
204 }
205
206 return 0;
207}
208
209static int bf5xx_pcm_silence(struct snd_pcm_substream *substream,
210 int channel, snd_pcm_uframes_t pos, snd_pcm_uframes_t count)
211{
212 unsigned char *buf = substream->runtime->dma_area;
213 buf += pos * 8 * 4;
214 memset(buf, '\0', count * 8 * 4);
215
216 return 0;
217}
218
219
220struct snd_pcm_ops bf5xx_pcm_tdm_ops = {
221 .open = bf5xx_pcm_open,
222 .ioctl = snd_pcm_lib_ioctl,
223 .hw_params = bf5xx_pcm_hw_params,
224 .hw_free = bf5xx_pcm_hw_free,
225 .prepare = bf5xx_pcm_prepare,
226 .trigger = bf5xx_pcm_trigger,
227 .pointer = bf5xx_pcm_pointer,
228 .copy = bf5xx_pcm_copy,
229 .silence = bf5xx_pcm_silence,
230};
231
232static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
233{
234 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
235 struct snd_dma_buffer *buf = &substream->dma_buffer;
236 size_t size = bf5xx_pcm_hardware.buffer_bytes_max;
237
238 buf->dev.type = SNDRV_DMA_TYPE_DEV;
239 buf->dev.dev = pcm->card->dev;
240 buf->private_data = NULL;
241 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
242 &buf->addr, GFP_KERNEL);
243 if (!buf->area) {
244 pr_err("Failed to allocate dma memory \
245 Please increase uncached DMA memory region\n");
246 return -ENOMEM;
247 }
248 buf->bytes = size;
249
250 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
251 sport_handle->tx_buf = buf->area;
252 else
253 sport_handle->rx_buf = buf->area;
254
255 return 0;
256}
257
258static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
259{
260 struct snd_pcm_substream *substream;
261 struct snd_dma_buffer *buf;
262 int stream;
263
264 for (stream = 0; stream < 2; stream++) {
265 substream = pcm->streams[stream].substream;
266 if (!substream)
267 continue;
268
269 buf = &substream->dma_buffer;
270 if (!buf->area)
271 continue;
272 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
273 buf->area = NULL;
274 }
275 if (sport_handle)
276 sport_done(sport_handle);
277}
278
279static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32);
280
281static int bf5xx_pcm_tdm_new(struct snd_card *card, struct snd_soc_dai *dai,
282 struct snd_pcm *pcm)
283{
284 int ret = 0;
285
286 if (!card->dev->dma_mask)
287 card->dev->dma_mask = &bf5xx_pcm_dmamask;
288 if (!card->dev->coherent_dma_mask)
289 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
290
291 if (dai->playback.channels_min) {
292 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
293 SNDRV_PCM_STREAM_PLAYBACK);
294 if (ret)
295 goto out;
296 }
297
298 if (dai->capture.channels_min) {
299 ret = bf5xx_pcm_preallocate_dma_buffer(pcm,
300 SNDRV_PCM_STREAM_CAPTURE);
301 if (ret)
302 goto out;
303 }
304out:
305 return ret;
306}
307
308struct snd_soc_platform bf5xx_tdm_soc_platform = {
309 .name = "bf5xx-audio",
310 .pcm_ops = &bf5xx_pcm_tdm_ops,
311 .pcm_new = bf5xx_pcm_tdm_new,
312 .pcm_free = bf5xx_pcm_free_dma_buffers,
313};
314EXPORT_SYMBOL_GPL(bf5xx_tdm_soc_platform);
315
316static int __init bfin_pcm_tdm_init(void)
317{
318 return snd_soc_register_platform(&bf5xx_tdm_soc_platform);
319}
320module_init(bfin_pcm_tdm_init);
321
322static void __exit bfin_pcm_tdm_exit(void)
323{
324 snd_soc_unregister_platform(&bf5xx_tdm_soc_platform);
325}
326module_exit(bfin_pcm_tdm_exit);
327
328MODULE_AUTHOR("Barry Song");
329MODULE_DESCRIPTION("ADI Blackfin TDM PCM DMA module");
330MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.h b/sound/soc/blackfin/bf5xx-tdm-pcm.h
new file mode 100644
index 000000000000..ddc5047df88c
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.h
@@ -0,0 +1,21 @@
1/*
2 * sound/soc/blackfin/bf5xx-tdm-pcm.h -- ALSA PCM interface for the Blackfin
3 *
4 * Copyright 2009 Analog Device Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef _BF5XX_TDM_PCM_H
12#define _BF5XX_TDM_PCM_H
13
14struct bf5xx_pcm_dma_params {
15 char *name; /* stream identifier */
16};
17
18/* platform data */
19extern struct snd_soc_platform bf5xx_tdm_soc_platform;
20
21#endif
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
new file mode 100644
index 000000000000..3096badf09a5
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -0,0 +1,343 @@
1/*
2 * File: sound/soc/blackfin/bf5xx-tdm.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Thurs June 04 2009
6 * Description: Blackfin I2S(TDM) CPU DAI driver
7 * Even though TDM mode can be as part of I2S DAI, but there
8 * are so much difference in configuration and data flow,
9 * it's very ugly to integrate I2S and TDM into a module
10 *
11 * Modified:
12 * Copyright 2009 Analog Devices Inc.
13 *
14 * Bugs: Enter bugs at http://blackfin.uclinux.org/
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, see the file COPYING, or write
28 * to the Free Software Foundation, Inc.,
29 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 */
31
32#include <linux/init.h>
33#include <linux/module.h>
34#include <linux/device.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/initval.h>
39#include <sound/soc.h>
40
41#include <asm/irq.h>
42#include <asm/portmux.h>
43#include <linux/mutex.h>
44#include <linux/gpio.h>
45
46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h"
48
49struct bf5xx_tdm_port {
50 u16 tcr1;
51 u16 rcr1;
52 u16 tcr2;
53 u16 rcr2;
54 int configured;
55};
56
57static struct bf5xx_tdm_port bf5xx_tdm;
58static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
59
60static struct sport_param sport_params[2] = {
61 {
62 .dma_rx_chan = CH_SPORT0_RX,
63 .dma_tx_chan = CH_SPORT0_TX,
64 .err_irq = IRQ_SPORT0_ERROR,
65 .regs = (struct sport_register *)SPORT0_TCR1,
66 },
67 {
68 .dma_rx_chan = CH_SPORT1_RX,
69 .dma_tx_chan = CH_SPORT1_TX,
70 .err_irq = IRQ_SPORT1_ERROR,
71 .regs = (struct sport_register *)SPORT1_TCR1,
72 }
73};
74
75/*
76 * Setting the TFS pin selector for SPORT 0 based on whether the selected
77 * port id F or G. If the port is F then no conflict should exist for the
78 * TFS. When Port G is selected and EMAC then there is a conflict between
79 * the PHY interrupt line and TFS. Current settings prevent the conflict
80 * by ignoring the TFS pin when Port G is selected. This allows both
81 * ssm2602 using Port G and EMAC concurrently.
82 */
83#ifdef CONFIG_BF527_SPORT0_PORTF
84#define LOCAL_SPORT0_TFS (P_SPORT0_TFS)
85#else
86#define LOCAL_SPORT0_TFS (0)
87#endif
88
89static u16 sport_req[][7] = { {P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
90 P_SPORT0_DRPRI, P_SPORT0_RSCLK, LOCAL_SPORT0_TFS, 0},
91 {P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS, P_SPORT1_DRPRI,
92 P_SPORT1_RSCLK, P_SPORT1_TFS, 0} };
93
94static int bf5xx_tdm_set_dai_fmt(struct snd_soc_dai *cpu_dai,
95 unsigned int fmt)
96{
97 int ret = 0;
98
99 /* interface format:support TDM,slave mode */
100 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
101 case SND_SOC_DAIFMT_DSP_A:
102 break;
103 default:
104 printk(KERN_ERR "%s: Unknown DAI format type\n", __func__);
105 ret = -EINVAL;
106 break;
107 }
108
109 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
110 case SND_SOC_DAIFMT_CBM_CFM:
111 break;
112 case SND_SOC_DAIFMT_CBS_CFS:
113 case SND_SOC_DAIFMT_CBM_CFS:
114 case SND_SOC_DAIFMT_CBS_CFM:
115 ret = -EINVAL;
116 break;
117 default:
118 printk(KERN_ERR "%s: Unknown DAI master type\n", __func__);
119 ret = -EINVAL;
120 break;
121 }
122
123 return ret;
124}
125
126static int bf5xx_tdm_hw_params(struct snd_pcm_substream *substream,
127 struct snd_pcm_hw_params *params,
128 struct snd_soc_dai *dai)
129{
130 int ret = 0;
131
132 bf5xx_tdm.tcr2 &= ~0x1f;
133 bf5xx_tdm.rcr2 &= ~0x1f;
134 switch (params_format(params)) {
135 case SNDRV_PCM_FORMAT_S32_LE:
136 bf5xx_tdm.tcr2 |= 31;
137 bf5xx_tdm.rcr2 |= 31;
138 sport_handle->wdsize = 4;
139 break;
140 /* at present, we only support 32bit transfer */
141 default:
142 pr_err("not supported PCM format yet\n");
143 return -EINVAL;
144 break;
145 }
146
147 if (!bf5xx_tdm.configured) {
148 /*
149 * TX and RX are not independent,they are enabled at the
150 * same time, even if only one side is running. So, we
151 * need to configure both of them at the time when the first
152 * stream is opened.
153 *
154 * CPU DAI:slave mode.
155 */
156 ret = sport_config_rx(sport_handle, bf5xx_tdm.rcr1,
157 bf5xx_tdm.rcr2, 0, 0);
158 if (ret) {
159 pr_err("SPORT is busy!\n");
160 return -EBUSY;
161 }
162
163 ret = sport_config_tx(sport_handle, bf5xx_tdm.tcr1,
164 bf5xx_tdm.tcr2, 0, 0);
165 if (ret) {
166 pr_err("SPORT is busy!\n");
167 return -EBUSY;
168 }
169
170 bf5xx_tdm.configured = 1;
171 }
172
173 return 0;
174}
175
176static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
177 struct snd_soc_dai *dai)
178{
179 /* No active stream, SPORT is allowed to be configured again. */
180 if (!dai->active)
181 bf5xx_tdm.configured = 0;
182}
183
184#ifdef CONFIG_PM
185static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
186{
187 struct sport_device *sport =
188 (struct sport_device *)dai->private_data;
189
190 if (!dai->active)
191 return 0;
192 if (dai->capture.active)
193 sport_rx_stop(sport);
194 if (dai->playback.active)
195 sport_tx_stop(sport);
196 return 0;
197}
198
199static int bf5xx_tdm_resume(struct snd_soc_dai *dai)
200{
201 int ret;
202 struct sport_device *sport =
203 (struct sport_device *)dai->private_data;
204
205 if (!dai->active)
206 return 0;
207
208 ret = sport_set_multichannel(sport, 8, 0xFF, 1);
209 if (ret) {
210 pr_err("SPORT is busy!\n");
211 ret = -EBUSY;
212 }
213
214 ret = sport_config_rx(sport, IRFS, 0x1F, 0, 0);
215 if (ret) {
216 pr_err("SPORT is busy!\n");
217 ret = -EBUSY;
218 }
219
220 ret = sport_config_tx(sport, ITFS, 0x1F, 0, 0);
221 if (ret) {
222 pr_err("SPORT is busy!\n");
223 ret = -EBUSY;
224 }
225
226 return 0;
227}
228
229#else
230#define bf5xx_tdm_suspend NULL
231#define bf5xx_tdm_resume NULL
232#endif
233
234static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
235 .hw_params = bf5xx_tdm_hw_params,
236 .set_fmt = bf5xx_tdm_set_dai_fmt,
237 .shutdown = bf5xx_tdm_shutdown,
238};
239
240struct snd_soc_dai bf5xx_tdm_dai = {
241 .name = "bf5xx-tdm",
242 .id = 0,
243 .suspend = bf5xx_tdm_suspend,
244 .resume = bf5xx_tdm_resume,
245 .playback = {
246 .channels_min = 2,
247 .channels_max = 8,
248 .rates = SNDRV_PCM_RATE_48000,
249 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
250 .capture = {
251 .channels_min = 2,
252 .channels_max = 8,
253 .rates = SNDRV_PCM_RATE_48000,
254 .formats = SNDRV_PCM_FMTBIT_S32_LE,},
255 .ops = &bf5xx_tdm_dai_ops,
256};
257EXPORT_SYMBOL_GPL(bf5xx_tdm_dai);
258
259static int __devinit bfin_tdm_probe(struct platform_device *pdev)
260{
261 int ret = 0;
262
263 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
264 pr_err("Requesting Peripherals failed\n");
265 return -EFAULT;
266 }
267
268 /* request DMA for SPORT */
269 sport_handle = sport_init(&sport_params[sport_num], 4, \
270 8 * sizeof(u32), NULL);
271 if (!sport_handle) {
272 peripheral_free_list(&sport_req[sport_num][0]);
273 return -ENODEV;
274 }
275
276 /* SPORT works in TDM mode */
277 ret = sport_set_multichannel(sport_handle, 8, 0xFF, 1);
278 if (ret) {
279 pr_err("SPORT is busy!\n");
280 ret = -EBUSY;
281 goto sport_config_err;
282 }
283
284 ret = sport_config_rx(sport_handle, IRFS, 0x1F, 0, 0);
285 if (ret) {
286 pr_err("SPORT is busy!\n");
287 ret = -EBUSY;
288 goto sport_config_err;
289 }
290
291 ret = sport_config_tx(sport_handle, ITFS, 0x1F, 0, 0);
292 if (ret) {
293 pr_err("SPORT is busy!\n");
294 ret = -EBUSY;
295 goto sport_config_err;
296 }
297
298 ret = snd_soc_register_dai(&bf5xx_tdm_dai);
299 if (ret) {
300 pr_err("Failed to register DAI: %d\n", ret);
301 goto sport_config_err;
302 }
303 return 0;
304
305sport_config_err:
306 peripheral_free_list(&sport_req[sport_num][0]);
307 return ret;
308}
309
310static int __devexit bfin_tdm_remove(struct platform_device *pdev)
311{
312 peripheral_free_list(&sport_req[sport_num][0]);
313 snd_soc_unregister_dai(&bf5xx_tdm_dai);
314
315 return 0;
316}
317
318static struct platform_driver bfin_tdm_driver = {
319 .probe = bfin_tdm_probe,
320 .remove = __devexit_p(bfin_tdm_remove),
321 .driver = {
322 .name = "bfin-tdm",
323 .owner = THIS_MODULE,
324 },
325};
326
327static int __init bfin_tdm_init(void)
328{
329 return platform_driver_register(&bfin_tdm_driver);
330}
331module_init(bfin_tdm_init);
332
333static void __exit bfin_tdm_exit(void)
334{
335 platform_driver_unregister(&bfin_tdm_driver);
336}
337module_exit(bfin_tdm_exit);
338
339/* Module information */
340MODULE_AUTHOR("Barry Song");
341MODULE_DESCRIPTION("TDM driver for ADI Blackfin");
342MODULE_LICENSE("GPL");
343
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
new file mode 100644
index 000000000000..618ec3d90cd4
--- /dev/null
+++ b/sound/soc/blackfin/bf5xx-tdm.h
@@ -0,0 +1,14 @@
1/*
2 * sound/soc/blackfin/bf5xx-tdm.h
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 _BF5XX_TDM_H
10#define _BF5XX_TDM_H
11
12extern struct snd_soc_dai bf5xx_tdm_dai;
13
14#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index bbc97fd76648..0edca93af3b0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -12,11 +12,15 @@ config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_L3 13 select SND_SOC_L3
14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 14 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER
15 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
16 select SND_SOC_AD73311 if I2C 18 select SND_SOC_AD73311 if I2C
17 select SND_SOC_AK4104 if SPI_MASTER 19 select SND_SOC_AK4104 if SPI_MASTER
18 select SND_SOC_AK4535 if I2C 20 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C
19 select SND_SOC_CS4270 if I2C 22 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C
20 select SND_SOC_PCM3008 24 select SND_SOC_PCM3008
21 select SND_SOC_SPDIF 25 select SND_SOC_SPDIF
22 select SND_SOC_SSM2602 if I2C 26 select SND_SOC_SSM2602 if I2C
@@ -30,18 +34,23 @@ config SND_SOC_ALL_CODECS
30 select SND_SOC_WM8350 if MFD_WM8350 34 select SND_SOC_WM8350 if MFD_WM8350
31 select SND_SOC_WM8400 if MFD_WM8400 35 select SND_SOC_WM8400 if MFD_WM8400
32 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C
33 select SND_SOC_WM8580 if I2C 38 select SND_SOC_WM8580 if I2C
34 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
35 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
36 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
43 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
38 select SND_SOC_WM8900 if I2C 44 select SND_SOC_WM8900 if I2C
39 select SND_SOC_WM8903 if I2C 45 select SND_SOC_WM8903 if I2C
40 select SND_SOC_WM8940 if I2C 46 select SND_SOC_WM8940 if I2C
41 select SND_SOC_WM8960 if I2C 47 select SND_SOC_WM8960 if I2C
48 select SND_SOC_WM8961 if I2C
42 select SND_SOC_WM8971 if I2C 49 select SND_SOC_WM8971 if I2C
50 select SND_SOC_WM8974 if I2C
43 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
44 select SND_SOC_WM8990 if I2C 52 select SND_SOC_WM8990 if I2C
53 select SND_SOC_WM8993 if I2C
45 select SND_SOC_WM9081 if I2C 54 select SND_SOC_WM9081 if I2C
46 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 55 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
47 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 56 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -57,11 +66,21 @@ config SND_SOC_ALL_CODECS
57 66
58 If unsure select "N". 67 If unsure select "N".
59 68
69config SND_SOC_WM_HUBS
70 tristate
71 default y if SND_SOC_WM8993=y
72 default m if SND_SOC_WM8993=m
60 73
61config SND_SOC_AC97_CODEC 74config SND_SOC_AC97_CODEC
62 tristate 75 tristate
63 select SND_AC97_CODEC 76 select SND_AC97_CODEC
64 77
78config SND_SOC_AD1836
79 tristate
80
81config SND_SOC_AD1938
82 tristate
83
65config SND_SOC_AD1980 84config SND_SOC_AD1980
66 tristate 85 tristate
67 86
@@ -74,6 +93,9 @@ config SND_SOC_AK4104
74config SND_SOC_AK4535 93config SND_SOC_AK4535
75 tristate 94 tristate
76 95
96config SND_SOC_AK4642
97 tristate
98
77# Cirrus Logic CS4270 Codec 99# Cirrus Logic CS4270 Codec
78config SND_SOC_CS4270 100config SND_SOC_CS4270
79 tristate 101 tristate
@@ -86,6 +108,9 @@ config SND_SOC_CS4270_VD33_ERRATA
86 bool 108 bool
87 depends on SND_SOC_CS4270 109 depends on SND_SOC_CS4270
88 110
111config SND_SOC_CX20442
112 tristate
113
89config SND_SOC_L3 114config SND_SOC_L3
90 tristate 115 tristate
91 116
@@ -129,6 +154,9 @@ config SND_SOC_WM8400
129config SND_SOC_WM8510 154config SND_SOC_WM8510
130 tristate 155 tristate
131 156
157config SND_SOC_WM8523
158 tristate
159
132config SND_SOC_WM8580 160config SND_SOC_WM8580
133 tristate 161 tristate
134 162
@@ -144,6 +172,9 @@ config SND_SOC_WM8750
144config SND_SOC_WM8753 172config SND_SOC_WM8753
145 tristate 173 tristate
146 174
175config SND_SOC_WM8776
176 tristate
177
147config SND_SOC_WM8900 178config SND_SOC_WM8900
148 tristate 179 tristate
149 180
@@ -156,15 +187,24 @@ config SND_SOC_WM8940
156config SND_SOC_WM8960 187config SND_SOC_WM8960
157 tristate 188 tristate
158 189
190config SND_SOC_WM8961
191 tristate
192
159config SND_SOC_WM8971 193config SND_SOC_WM8971
160 tristate 194 tristate
161 195
196config SND_SOC_WM8974
197 tristate
198
162config SND_SOC_WM8988 199config SND_SOC_WM8988
163 tristate 200 tristate
164 201
165config SND_SOC_WM8990 202config SND_SOC_WM8990
166 tristate 203 tristate
167 204
205config SND_SOC_WM8993
206 tristate
207
168config SND_SOC_WM9081 208config SND_SOC_WM9081
169 tristate 209 tristate
170 210
@@ -176,3 +216,7 @@ config SND_SOC_WM9712
176 216
177config SND_SOC_WM9713 217config SND_SOC_WM9713
178 tristate 218 tristate
219
220# Amp
221config SND_SOC_MAX9877
222 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 8b7530546f4d..fb4af28486ba 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,9 +1,13 @@
1snd-soc-ac97-objs := ac97.o 1snd-soc-ac97-objs := ac97.o
2snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o
2snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
4snd-soc-ak4104-objs := ak4104.o 6snd-soc-ak4104-objs := ak4104.o
5snd-soc-ak4535-objs := ak4535.o 7snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o
6snd-soc-cs4270-objs := cs4270.o 9snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o
7snd-soc-l3-objs := l3.o 11snd-soc-l3-objs := l3.o
8snd-soc-pcm3008-objs := pcm3008.o 12snd-soc-pcm3008-objs := pcm3008.o
9snd-soc-spdif-objs := spdif_transciever.o 13snd-soc-spdif-objs := spdif_transciever.o
@@ -18,29 +22,42 @@ snd-soc-uda1380-objs := uda1380.o
18snd-soc-wm8350-objs := wm8350.o 22snd-soc-wm8350-objs := wm8350.o
19snd-soc-wm8400-objs := wm8400.o 23snd-soc-wm8400-objs := wm8400.o
20snd-soc-wm8510-objs := wm8510.o 24snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o
21snd-soc-wm8580-objs := wm8580.o 26snd-soc-wm8580-objs := wm8580.o
22snd-soc-wm8728-objs := wm8728.o 27snd-soc-wm8728-objs := wm8728.o
23snd-soc-wm8731-objs := wm8731.o 28snd-soc-wm8731-objs := wm8731.o
24snd-soc-wm8750-objs := wm8750.o 29snd-soc-wm8750-objs := wm8750.o
25snd-soc-wm8753-objs := wm8753.o 30snd-soc-wm8753-objs := wm8753.o
31snd-soc-wm8776-objs := wm8776.o
26snd-soc-wm8900-objs := wm8900.o 32snd-soc-wm8900-objs := wm8900.o
27snd-soc-wm8903-objs := wm8903.o 33snd-soc-wm8903-objs := wm8903.o
28snd-soc-wm8940-objs := wm8940.o 34snd-soc-wm8940-objs := wm8940.o
29snd-soc-wm8960-objs := wm8960.o 35snd-soc-wm8960-objs := wm8960.o
36snd-soc-wm8961-objs := wm8961.o
30snd-soc-wm8971-objs := wm8971.o 37snd-soc-wm8971-objs := wm8971.o
38snd-soc-wm8974-objs := wm8974.o
31snd-soc-wm8988-objs := wm8988.o 39snd-soc-wm8988-objs := wm8988.o
32snd-soc-wm8990-objs := wm8990.o 40snd-soc-wm8990-objs := wm8990.o
41snd-soc-wm8993-objs := wm8993.o
33snd-soc-wm9081-objs := wm9081.o 42snd-soc-wm9081-objs := wm9081.o
34snd-soc-wm9705-objs := wm9705.o 43snd-soc-wm9705-objs := wm9705.o
35snd-soc-wm9712-objs := wm9712.o 44snd-soc-wm9712-objs := wm9712.o
36snd-soc-wm9713-objs := wm9713.o 45snd-soc-wm9713-objs := wm9713.o
46snd-soc-wm-hubs-objs := wm_hubs.o
47
48# Amp
49snd-soc-max9877-objs := max9877.o
37 50
38obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
53obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
39obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 54obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
40obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 55obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
41obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
42obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
43obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
44obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
45obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 62obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
46obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 63obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -55,19 +72,28 @@ obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
55obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 72obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
56obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 73obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
57obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
58obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
59obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
60obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
61obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
62obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 80obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
81obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
63obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 82obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
64obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 83obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
65obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 84obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
85obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
66obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 86obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
67obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 87obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
88obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
68obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 89obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
69obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 90obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
91obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
70obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 92obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
71obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 93obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
72obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 94obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
73obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o 95obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
96obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97
98# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
new file mode 100644
index 000000000000..3612bb92df90
--- /dev/null
+++ b/sound/soc/codecs/ad1836.c
@@ -0,0 +1,446 @@
1/*
2 * File: sound/soc/codecs/ad1836.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: Aug 04 2009
6 * Description: Driver for AD1836 sound chip
7 *
8 * Modified:
9 * Copyright 2009 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
19#include <linux/init.h>
20#include <linux/module.h>
21#include <linux/version.h>
22#include <linux/kernel.h>
23#include <linux/device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/initval.h>
28#include <sound/soc.h>
29#include <sound/tlv.h>
30#include <sound/soc-dapm.h>
31#include <linux/spi/spi.h>
32#include "ad1836.h"
33
34/* codec private data */
35struct ad1836_priv {
36 struct snd_soc_codec codec;
37 u16 reg_cache[AD1836_NUM_REGS];
38};
39
40static struct snd_soc_codec *ad1836_codec;
41struct snd_soc_codec_device soc_codec_dev_ad1836;
42static int ad1836_register(struct ad1836_priv *ad1836);
43static void ad1836_unregister(struct ad1836_priv *ad1836);
44
45/*
46 * AD1836 volume/mute/de-emphasis etc. controls
47 */
48static const char *ad1836_deemp[] = {"None", "44.1kHz", "32kHz", "48kHz"};
49
50static const struct soc_enum ad1836_deemp_enum =
51 SOC_ENUM_SINGLE(AD1836_DAC_CTRL1, 8, 4, ad1836_deemp);
52
53static const struct snd_kcontrol_new ad1836_snd_controls[] = {
54 /* DAC volume control */
55 SOC_DOUBLE_R("DAC1 Volume", AD1836_DAC_L1_VOL,
56 AD1836_DAC_R1_VOL, 0, 0x3FF, 0),
57 SOC_DOUBLE_R("DAC2 Volume", AD1836_DAC_L2_VOL,
58 AD1836_DAC_R2_VOL, 0, 0x3FF, 0),
59 SOC_DOUBLE_R("DAC3 Volume", AD1836_DAC_L3_VOL,
60 AD1836_DAC_R3_VOL, 0, 0x3FF, 0),
61
62 /* ADC switch control */
63 SOC_DOUBLE("ADC1 Switch", AD1836_ADC_CTRL2, AD1836_ADCL1_MUTE,
64 AD1836_ADCR1_MUTE, 1, 1),
65 SOC_DOUBLE("ADC2 Switch", AD1836_ADC_CTRL2, AD1836_ADCL2_MUTE,
66 AD1836_ADCR2_MUTE, 1, 1),
67
68 /* DAC switch control */
69 SOC_DOUBLE("DAC1 Switch", AD1836_DAC_CTRL2, AD1836_DACL1_MUTE,
70 AD1836_DACR1_MUTE, 1, 1),
71 SOC_DOUBLE("DAC2 Switch", AD1836_DAC_CTRL2, AD1836_DACL2_MUTE,
72 AD1836_DACR2_MUTE, 1, 1),
73 SOC_DOUBLE("DAC3 Switch", AD1836_DAC_CTRL2, AD1836_DACL3_MUTE,
74 AD1836_DACR3_MUTE, 1, 1),
75
76 /* ADC high-pass filter */
77 SOC_SINGLE("ADC High Pass Filter Switch", AD1836_ADC_CTRL1,
78 AD1836_ADC_HIGHPASS_FILTER, 1, 0),
79
80 /* DAC de-emphasis */
81 SOC_ENUM("Playback Deemphasis", ad1836_deemp_enum),
82};
83
84static const struct snd_soc_dapm_widget ad1836_dapm_widgets[] = {
85 SND_SOC_DAPM_DAC("DAC", "Playback", AD1836_DAC_CTRL1,
86 AD1836_DAC_POWERDOWN, 1),
87 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
88 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1836_ADC_CTRL1,
89 AD1836_ADC_POWERDOWN, 1, NULL, 0),
90 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
91 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
92 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
93 SND_SOC_DAPM_INPUT("ADC1IN"),
94 SND_SOC_DAPM_INPUT("ADC2IN"),
95};
96
97static const struct snd_soc_dapm_route audio_paths[] = {
98 { "DAC", NULL, "ADC_PWR" },
99 { "ADC", NULL, "ADC_PWR" },
100 { "DAC1OUT", "DAC1 Switch", "DAC" },
101 { "DAC2OUT", "DAC2 Switch", "DAC" },
102 { "DAC3OUT", "DAC3 Switch", "DAC" },
103 { "ADC", "ADC1 Switch", "ADC1IN" },
104 { "ADC", "ADC2 Switch", "ADC2IN" },
105};
106
107/*
108 * DAI ops entries
109 */
110
111static int ad1836_set_dai_fmt(struct snd_soc_dai *codec_dai,
112 unsigned int fmt)
113{
114 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
115 /* at present, we support adc aux mode to interface with
116 * blackfin sport tdm mode
117 */
118 case SND_SOC_DAIFMT_DSP_A:
119 break;
120 default:
121 return -EINVAL;
122 }
123
124 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
125 case SND_SOC_DAIFMT_IB_IF:
126 break;
127 default:
128 return -EINVAL;
129 }
130
131 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
132 /* ALCLK,ABCLK are both output, AD1836 can only be master */
133 case SND_SOC_DAIFMT_CBM_CFM:
134 break;
135 default:
136 return -EINVAL;
137 }
138
139 return 0;
140}
141
142static int ad1836_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai)
145{
146 int word_len = 0;
147
148 struct snd_soc_pcm_runtime *rtd = substream->private_data;
149 struct snd_soc_device *socdev = rtd->socdev;
150 struct snd_soc_codec *codec = socdev->card->codec;
151
152 /* bit size */
153 switch (params_format(params)) {
154 case SNDRV_PCM_FORMAT_S16_LE:
155 word_len = 3;
156 break;
157 case SNDRV_PCM_FORMAT_S20_3LE:
158 word_len = 1;
159 break;
160 case SNDRV_PCM_FORMAT_S24_LE:
161 case SNDRV_PCM_FORMAT_S32_LE:
162 word_len = 0;
163 break;
164 }
165
166 snd_soc_update_bits(codec, AD1836_DAC_CTRL1,
167 AD1836_DAC_WORD_LEN_MASK, word_len);
168
169 snd_soc_update_bits(codec, AD1836_ADC_CTRL2,
170 AD1836_ADC_WORD_LEN_MASK, word_len);
171
172 return 0;
173}
174
175
176/*
177 * interface to read/write ad1836 register
178 */
179#define AD1836_SPI_REG_SHFT 12
180#define AD1836_SPI_READ (1 << 11)
181#define AD1836_SPI_VAL_MSK 0x3FF
182
183/*
184 * write to the ad1836 register space
185 */
186
187static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
188 unsigned int value)
189{
190 u16 *reg_cache = codec->reg_cache;
191 int ret = 0;
192
193 if (value != reg_cache[reg]) {
194 unsigned short buf;
195 struct spi_transfer t = {
196 .tx_buf = &buf,
197 .len = 2,
198 };
199 struct spi_message m;
200
201 buf = (reg << AD1836_SPI_REG_SHFT) |
202 (value & AD1836_SPI_VAL_MSK);
203 spi_message_init(&m);
204 spi_message_add_tail(&t, &m);
205 ret = spi_sync(codec->control_data, &m);
206 if (ret == 0)
207 reg_cache[reg] = value;
208 }
209
210 return ret;
211}
212
213/*
214 * read from the ad1836 register space cache
215 */
216static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
217 unsigned int reg)
218{
219 u16 *reg_cache = codec->reg_cache;
220
221 if (reg >= codec->reg_cache_size)
222 return -EINVAL;
223
224 return reg_cache[reg];
225}
226
227static int __devinit ad1836_spi_probe(struct spi_device *spi)
228{
229 struct snd_soc_codec *codec;
230 struct ad1836_priv *ad1836;
231
232 ad1836 = kzalloc(sizeof(struct ad1836_priv), GFP_KERNEL);
233 if (ad1836 == NULL)
234 return -ENOMEM;
235
236 codec = &ad1836->codec;
237 codec->control_data = spi;
238 codec->dev = &spi->dev;
239
240 dev_set_drvdata(&spi->dev, ad1836);
241
242 return ad1836_register(ad1836);
243}
244
245static int __devexit ad1836_spi_remove(struct spi_device *spi)
246{
247 struct ad1836_priv *ad1836 = dev_get_drvdata(&spi->dev);
248
249 ad1836_unregister(ad1836);
250 return 0;
251}
252
253static struct spi_driver ad1836_spi_driver = {
254 .driver = {
255 .name = "ad1836-spi",
256 .bus = &spi_bus_type,
257 .owner = THIS_MODULE,
258 },
259 .probe = ad1836_spi_probe,
260 .remove = __devexit_p(ad1836_spi_remove),
261};
262
263static struct snd_soc_dai_ops ad1836_dai_ops = {
264 .hw_params = ad1836_hw_params,
265 .set_fmt = ad1836_set_dai_fmt,
266};
267
268/* codec DAI instance */
269struct snd_soc_dai ad1836_dai = {
270 .name = "AD1836",
271 .playback = {
272 .stream_name = "Playback",
273 .channels_min = 2,
274 .channels_max = 6,
275 .rates = SNDRV_PCM_RATE_48000,
276 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
277 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
278 },
279 .capture = {
280 .stream_name = "Capture",
281 .channels_min = 2,
282 .channels_max = 4,
283 .rates = SNDRV_PCM_RATE_48000,
284 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
285 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
286 },
287 .ops = &ad1836_dai_ops,
288};
289EXPORT_SYMBOL_GPL(ad1836_dai);
290
291static int ad1836_register(struct ad1836_priv *ad1836)
292{
293 int ret;
294 struct snd_soc_codec *codec = &ad1836->codec;
295
296 if (ad1836_codec) {
297 dev_err(codec->dev, "Another ad1836 is registered\n");
298 return -EINVAL;
299 }
300
301 mutex_init(&codec->mutex);
302 INIT_LIST_HEAD(&codec->dapm_widgets);
303 INIT_LIST_HEAD(&codec->dapm_paths);
304 codec->private_data = ad1836;
305 codec->reg_cache = ad1836->reg_cache;
306 codec->reg_cache_size = AD1836_NUM_REGS;
307 codec->name = "AD1836";
308 codec->owner = THIS_MODULE;
309 codec->dai = &ad1836_dai;
310 codec->num_dai = 1;
311 codec->write = ad1836_write_reg;
312 codec->read = ad1836_read_reg_cache;
313 INIT_LIST_HEAD(&codec->dapm_widgets);
314 INIT_LIST_HEAD(&codec->dapm_paths);
315
316 ad1836_dai.dev = codec->dev;
317 ad1836_codec = codec;
318
319 /* default setting for ad1836 */
320 /* de-emphasis: 48kHz, power-on dac */
321 codec->write(codec, AD1836_DAC_CTRL1, 0x300);
322 /* unmute dac channels */
323 codec->write(codec, AD1836_DAC_CTRL2, 0x0);
324 /* high-pass filter enable, power-on adc */
325 codec->write(codec, AD1836_ADC_CTRL1, 0x100);
326 /* unmute adc channles, adc aux mode */
327 codec->write(codec, AD1836_ADC_CTRL2, 0x180);
328 /* left/right diff:PGA/MUX */
329 codec->write(codec, AD1836_ADC_CTRL3, 0x3A);
330 /* volume */
331 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF);
335 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF);
336 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF);
337
338 ret = snd_soc_register_codec(codec);
339 if (ret != 0) {
340 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
341 kfree(ad1836);
342 return ret;
343 }
344
345 ret = snd_soc_register_dai(&ad1836_dai);
346 if (ret != 0) {
347 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
348 snd_soc_unregister_codec(codec);
349 kfree(ad1836);
350 return ret;
351 }
352
353 return 0;
354}
355
356static void ad1836_unregister(struct ad1836_priv *ad1836)
357{
358 snd_soc_unregister_dai(&ad1836_dai);
359 snd_soc_unregister_codec(&ad1836->codec);
360 kfree(ad1836);
361 ad1836_codec = NULL;
362}
363
364static int ad1836_probe(struct platform_device *pdev)
365{
366 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
367 struct snd_soc_codec *codec;
368 int ret = 0;
369
370 if (ad1836_codec == NULL) {
371 dev_err(&pdev->dev, "Codec device not registered\n");
372 return -ENODEV;
373 }
374
375 socdev->card->codec = ad1836_codec;
376 codec = ad1836_codec;
377
378 /* register pcms */
379 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
380 if (ret < 0) {
381 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
382 goto pcm_err;
383 }
384
385 snd_soc_add_controls(codec, ad1836_snd_controls,
386 ARRAY_SIZE(ad1836_snd_controls));
387 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
388 ARRAY_SIZE(ad1836_dapm_widgets));
389 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
390 snd_soc_dapm_new_widgets(codec);
391
392 ret = snd_soc_init_card(socdev);
393 if (ret < 0) {
394 dev_err(codec->dev, "failed to register card: %d\n", ret);
395 goto card_err;
396 }
397
398 return ret;
399
400card_err:
401 snd_soc_free_pcms(socdev);
402 snd_soc_dapm_free(socdev);
403pcm_err:
404 return ret;
405}
406
407/* power down chip */
408static int ad1836_remove(struct platform_device *pdev)
409{
410 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
411
412 snd_soc_free_pcms(socdev);
413 snd_soc_dapm_free(socdev);
414
415 return 0;
416}
417
418struct snd_soc_codec_device soc_codec_dev_ad1836 = {
419 .probe = ad1836_probe,
420 .remove = ad1836_remove,
421};
422EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
423
424static int __init ad1836_init(void)
425{
426 int ret;
427
428 ret = spi_register_driver(&ad1836_spi_driver);
429 if (ret != 0) {
430 printk(KERN_ERR "Failed to register ad1836 SPI driver: %d\n",
431 ret);
432 }
433
434 return ret;
435}
436module_init(ad1836_init);
437
438static void __exit ad1836_exit(void)
439{
440 spi_unregister_driver(&ad1836_spi_driver);
441}
442module_exit(ad1836_exit);
443
444MODULE_DESCRIPTION("ASoC ad1836 driver");
445MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
446MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
new file mode 100644
index 000000000000..7660ee6973c0
--- /dev/null
+++ b/sound/soc/codecs/ad1836.h
@@ -0,0 +1,64 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: Aug 04, 2009
7 * Description: definitions for AD1836 registers
8 *
9 * Modified:
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
19#ifndef __AD1836_H__
20#define __AD1836_H__
21
22#define AD1836_DAC_CTRL1 0
23#define AD1836_DAC_POWERDOWN 2
24#define AD1836_DAC_SERFMT_MASK 0xE0
25#define AD1836_DAC_SERFMT_PCK256 (0x4 << 5)
26#define AD1836_DAC_SERFMT_PCK128 (0x5 << 5)
27#define AD1836_DAC_WORD_LEN_MASK 0x18
28
29#define AD1836_DAC_CTRL2 1
30#define AD1836_DACL1_MUTE 0
31#define AD1836_DACR1_MUTE 1
32#define AD1836_DACL2_MUTE 2
33#define AD1836_DACR2_MUTE 3
34#define AD1836_DACL3_MUTE 4
35#define AD1836_DACR3_MUTE 5
36
37#define AD1836_DAC_L1_VOL 2
38#define AD1836_DAC_R1_VOL 3
39#define AD1836_DAC_L2_VOL 4
40#define AD1836_DAC_R2_VOL 5
41#define AD1836_DAC_L3_VOL 6
42#define AD1836_DAC_R3_VOL 7
43
44#define AD1836_ADC_CTRL1 12
45#define AD1836_ADC_POWERDOWN 7
46#define AD1836_ADC_HIGHPASS_FILTER 8
47
48#define AD1836_ADC_CTRL2 13
49#define AD1836_ADCL1_MUTE 0
50#define AD1836_ADCR1_MUTE 1
51#define AD1836_ADCL2_MUTE 2
52#define AD1836_ADCR2_MUTE 3
53#define AD1836_ADC_WORD_LEN_MASK 0x30
54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57
58#define AD1836_ADC_CTRL3 14
59
60#define AD1836_NUM_REGS 16
61
62extern struct snd_soc_dai ad1836_dai;
63extern struct snd_soc_codec_device soc_codec_dev_ad1836;
64#endif
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
new file mode 100644
index 000000000000..e62b27701a49
--- /dev/null
+++ b/sound/soc/codecs/ad1938.c
@@ -0,0 +1,682 @@
1/*
2 * File: sound/soc/codecs/ad1938.c
3 * Author: Barry Song <Barry.Song@analog.com>
4 *
5 * Created: June 04 2009
6 * Description: Driver for AD1938 sound chip
7 *
8 * Modified:
9 * Copyright 2009 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/init.h>
30#include <linux/module.h>
31#include <linux/version.h>
32#include <linux/kernel.h>
33#include <linux/device.h>
34#include <sound/core.h>
35#include <sound/pcm.h>
36#include <sound/pcm_params.h>
37#include <sound/initval.h>
38#include <sound/soc.h>
39#include <sound/tlv.h>
40#include <sound/soc-dapm.h>
41#include <linux/spi/spi.h>
42#include "ad1938.h"
43
44/* codec private data */
45struct ad1938_priv {
46 struct snd_soc_codec codec;
47 u8 reg_cache[AD1938_NUM_REGS];
48};
49
50static struct snd_soc_codec *ad1938_codec;
51struct snd_soc_codec_device soc_codec_dev_ad1938;
52static int ad1938_register(struct ad1938_priv *ad1938);
53static void ad1938_unregister(struct ad1938_priv *ad1938);
54
55/*
56 * AD1938 volume/mute/de-emphasis etc. controls
57 */
58static const char *ad1938_deemp[] = {"None", "48kHz", "44.1kHz", "32kHz"};
59
60static const struct soc_enum ad1938_deemp_enum =
61 SOC_ENUM_SINGLE(AD1938_DAC_CTRL2, 1, 4, ad1938_deemp);
62
63static const struct snd_kcontrol_new ad1938_snd_controls[] = {
64 /* DAC volume control */
65 SOC_DOUBLE_R("DAC1 Volume", AD1938_DAC_L1_VOL,
66 AD1938_DAC_R1_VOL, 0, 0xFF, 1),
67 SOC_DOUBLE_R("DAC2 Volume", AD1938_DAC_L2_VOL,
68 AD1938_DAC_R2_VOL, 0, 0xFF, 1),
69 SOC_DOUBLE_R("DAC3 Volume", AD1938_DAC_L3_VOL,
70 AD1938_DAC_R3_VOL, 0, 0xFF, 1),
71 SOC_DOUBLE_R("DAC4 Volume", AD1938_DAC_L4_VOL,
72 AD1938_DAC_R4_VOL, 0, 0xFF, 1),
73
74 /* ADC switch control */
75 SOC_DOUBLE("ADC1 Switch", AD1938_ADC_CTRL0, AD1938_ADCL1_MUTE,
76 AD1938_ADCR1_MUTE, 1, 1),
77 SOC_DOUBLE("ADC2 Switch", AD1938_ADC_CTRL0, AD1938_ADCL2_MUTE,
78 AD1938_ADCR2_MUTE, 1, 1),
79
80 /* DAC switch control */
81 SOC_DOUBLE("DAC1 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL1_MUTE,
82 AD1938_DACR1_MUTE, 1, 1),
83 SOC_DOUBLE("DAC2 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL2_MUTE,
84 AD1938_DACR2_MUTE, 1, 1),
85 SOC_DOUBLE("DAC3 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL3_MUTE,
86 AD1938_DACR3_MUTE, 1, 1),
87 SOC_DOUBLE("DAC4 Switch", AD1938_DAC_CHNL_MUTE, AD1938_DACL4_MUTE,
88 AD1938_DACR4_MUTE, 1, 1),
89
90 /* ADC high-pass filter */
91 SOC_SINGLE("ADC High Pass Filter Switch", AD1938_ADC_CTRL0,
92 AD1938_ADC_HIGHPASS_FILTER, 1, 0),
93
94 /* DAC de-emphasis */
95 SOC_ENUM("Playback Deemphasis", ad1938_deemp_enum),
96};
97
98static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
99 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
100 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
101 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
102 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
103 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
104 SND_SOC_DAPM_OUTPUT("DAC3OUT"),
105 SND_SOC_DAPM_OUTPUT("DAC4OUT"),
106 SND_SOC_DAPM_INPUT("ADC1IN"),
107 SND_SOC_DAPM_INPUT("ADC2IN"),
108};
109
110static const struct snd_soc_dapm_route audio_paths[] = {
111 { "DAC", NULL, "ADC_PWR" },
112 { "ADC", NULL, "ADC_PWR" },
113 { "DAC1OUT", "DAC1 Switch", "DAC" },
114 { "DAC2OUT", "DAC2 Switch", "DAC" },
115 { "DAC3OUT", "DAC3 Switch", "DAC" },
116 { "DAC4OUT", "DAC4 Switch", "DAC" },
117 { "ADC", "ADC1 Switch", "ADC1IN" },
118 { "ADC", "ADC2 Switch", "ADC2IN" },
119};
120
121/*
122 * DAI ops entries
123 */
124
125static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126{
127 struct snd_soc_codec *codec = dai->codec;
128 int reg;
129
130 reg = codec->read(codec, AD1938_DAC_CTRL2);
131 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
132 (~AD1938_DAC_MASTER_MUTE);
133 codec->write(codec, AD1938_DAC_CTRL2, reg);
134
135 return 0;
136}
137
138static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
139{
140 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
141 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
142 AD1938_PLL_POWERDOWN;
143 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
144
145 return 0;
146}
147
148static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
149 unsigned int mask, int slots, int width)
150{
151 struct snd_soc_codec *codec = dai->codec;
152 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1);
153 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2);
154
155 dac_reg &= ~AD1938_DAC_CHAN_MASK;
156 adc_reg &= ~AD1938_ADC_CHAN_MASK;
157
158 switch (slots) {
159 case 2:
160 dac_reg |= AD1938_DAC_2_CHANNELS << AD1938_DAC_CHAN_SHFT;
161 adc_reg |= AD1938_ADC_2_CHANNELS << AD1938_ADC_CHAN_SHFT;
162 break;
163 case 4:
164 dac_reg |= AD1938_DAC_4_CHANNELS << AD1938_DAC_CHAN_SHFT;
165 adc_reg |= AD1938_ADC_4_CHANNELS << AD1938_ADC_CHAN_SHFT;
166 break;
167 case 8:
168 dac_reg |= AD1938_DAC_8_CHANNELS << AD1938_DAC_CHAN_SHFT;
169 adc_reg |= AD1938_ADC_8_CHANNELS << AD1938_ADC_CHAN_SHFT;
170 break;
171 case 16:
172 dac_reg |= AD1938_DAC_16_CHANNELS << AD1938_DAC_CHAN_SHFT;
173 adc_reg |= AD1938_ADC_16_CHANNELS << AD1938_ADC_CHAN_SHFT;
174 break;
175 default:
176 return -EINVAL;
177 }
178
179 codec->write(codec, AD1938_DAC_CTRL1, dac_reg);
180 codec->write(codec, AD1938_ADC_CTRL2, adc_reg);
181
182 return 0;
183}
184
185static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
186 unsigned int fmt)
187{
188 struct snd_soc_codec *codec = codec_dai->codec;
189 int adc_reg, dac_reg;
190
191 adc_reg = codec->read(codec, AD1938_ADC_CTRL2);
192 dac_reg = codec->read(codec, AD1938_DAC_CTRL1);
193
194 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
195 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
196 */
197 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
198 case SND_SOC_DAIFMT_I2S:
199 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
200 adc_reg |= AD1938_ADC_SERFMT_TDM;
201 break;
202 case SND_SOC_DAIFMT_DSP_A:
203 adc_reg &= ~AD1938_ADC_SERFMT_MASK;
204 adc_reg |= AD1938_ADC_SERFMT_AUX;
205 break;
206 default:
207 return -EINVAL;
208 }
209
210 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
211 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
212 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
213 adc_reg &= ~AD1938_ADC_BCLK_INV;
214 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
215 dac_reg &= ~AD1938_DAC_BCLK_INV;
216 break;
217 case SND_SOC_DAIFMT_NB_IF: /* normal bclk + invert frm */
218 adc_reg |= AD1938_ADC_LEFT_HIGH;
219 adc_reg &= ~AD1938_ADC_BCLK_INV;
220 dac_reg |= AD1938_DAC_LEFT_HIGH;
221 dac_reg &= ~AD1938_DAC_BCLK_INV;
222 break;
223 case SND_SOC_DAIFMT_IB_NF: /* invert bclk + normal frm */
224 adc_reg &= ~AD1938_ADC_LEFT_HIGH;
225 adc_reg |= AD1938_ADC_BCLK_INV;
226 dac_reg &= ~AD1938_DAC_LEFT_HIGH;
227 dac_reg |= AD1938_DAC_BCLK_INV;
228 break;
229
230 case SND_SOC_DAIFMT_IB_IF: /* invert bclk + frm */
231 adc_reg |= AD1938_ADC_LEFT_HIGH;
232 adc_reg |= AD1938_ADC_BCLK_INV;
233 dac_reg |= AD1938_DAC_LEFT_HIGH;
234 dac_reg |= AD1938_DAC_BCLK_INV;
235 break;
236 default:
237 return -EINVAL;
238 }
239
240 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
241 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & frm master */
242 adc_reg |= AD1938_ADC_LCR_MASTER;
243 adc_reg |= AD1938_ADC_BCLK_MASTER;
244 dac_reg |= AD1938_DAC_LCR_MASTER;
245 dac_reg |= AD1938_DAC_BCLK_MASTER;
246 break;
247 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & frm master */
248 adc_reg |= AD1938_ADC_LCR_MASTER;
249 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
250 dac_reg |= AD1938_DAC_LCR_MASTER;
251 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
252 break;
253 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
254 adc_reg &= ~AD1938_ADC_LCR_MASTER;
255 adc_reg |= AD1938_ADC_BCLK_MASTER;
256 dac_reg &= ~AD1938_DAC_LCR_MASTER;
257 dac_reg |= AD1938_DAC_BCLK_MASTER;
258 break;
259 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & frm slave */
260 adc_reg &= ~AD1938_ADC_LCR_MASTER;
261 adc_reg &= ~AD1938_ADC_BCLK_MASTER;
262 dac_reg &= ~AD1938_DAC_LCR_MASTER;
263 dac_reg &= ~AD1938_DAC_BCLK_MASTER;
264 break;
265 default:
266 return -EINVAL;
267 }
268
269 codec->write(codec, AD1938_ADC_CTRL2, adc_reg);
270 codec->write(codec, AD1938_DAC_CTRL1, dac_reg);
271
272 return 0;
273}
274
275static int ad1938_hw_params(struct snd_pcm_substream *substream,
276 struct snd_pcm_hw_params *params,
277 struct snd_soc_dai *dai)
278{
279 int word_len = 0, reg = 0;
280
281 struct snd_soc_pcm_runtime *rtd = substream->private_data;
282 struct snd_soc_device *socdev = rtd->socdev;
283 struct snd_soc_codec *codec = socdev->card->codec;
284
285 /* bit size */
286 switch (params_format(params)) {
287 case SNDRV_PCM_FORMAT_S16_LE:
288 word_len = 3;
289 break;
290 case SNDRV_PCM_FORMAT_S20_3LE:
291 word_len = 1;
292 break;
293 case SNDRV_PCM_FORMAT_S24_LE:
294 case SNDRV_PCM_FORMAT_S32_LE:
295 word_len = 0;
296 break;
297 }
298
299 reg = codec->read(codec, AD1938_DAC_CTRL2);
300 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
301 codec->write(codec, AD1938_DAC_CTRL2, reg);
302
303 reg = codec->read(codec, AD1938_ADC_CTRL1);
304 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
305 codec->write(codec, AD1938_ADC_CTRL1, reg);
306
307 return 0;
308}
309
310static int ad1938_set_bias_level(struct snd_soc_codec *codec,
311 enum snd_soc_bias_level level)
312{
313 switch (level) {
314 case SND_SOC_BIAS_ON:
315 ad1938_pll_powerctrl(codec, 1);
316 break;
317 case SND_SOC_BIAS_PREPARE:
318 break;
319 case SND_SOC_BIAS_STANDBY:
320 case SND_SOC_BIAS_OFF:
321 ad1938_pll_powerctrl(codec, 0);
322 break;
323 }
324 codec->bias_level = level;
325 return 0;
326}
327
328/*
329 * interface to read/write ad1938 register
330 */
331
332#define AD1938_SPI_ADDR 0x4
333#define AD1938_SPI_READ 0x1
334#define AD1938_SPI_BUFLEN 3
335
336/*
337 * write to the ad1938 register space
338 */
339
340static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
341 unsigned int value)
342{
343 u8 *reg_cache = codec->reg_cache;
344 int ret = 0;
345
346 if (value != reg_cache[reg]) {
347 uint8_t buf[AD1938_SPI_BUFLEN];
348 struct spi_transfer t = {
349 .tx_buf = buf,
350 .len = AD1938_SPI_BUFLEN,
351 };
352 struct spi_message m;
353
354 buf[0] = AD1938_SPI_ADDR << 1;
355 buf[1] = reg;
356 buf[2] = value;
357 spi_message_init(&m);
358 spi_message_add_tail(&t, &m);
359 ret = spi_sync(codec->control_data, &m);
360 if (ret == 0)
361 reg_cache[reg] = value;
362 }
363
364 return ret;
365}
366
367/*
368 * read from the ad1938 register space cache
369 */
370
371static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
372 unsigned int reg)
373{
374 u8 *reg_cache = codec->reg_cache;
375
376 if (reg >= codec->reg_cache_size)
377 return -EINVAL;
378
379 return reg_cache[reg];
380}
381
382/*
383 * read from the ad1938 register space
384 */
385
386static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
387 unsigned int reg)
388{
389 char w_buf[AD1938_SPI_BUFLEN];
390 char r_buf[AD1938_SPI_BUFLEN];
391 int ret;
392
393 struct spi_transfer t = {
394 .tx_buf = w_buf,
395 .rx_buf = r_buf,
396 .len = AD1938_SPI_BUFLEN,
397 };
398 struct spi_message m;
399
400 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
401 w_buf[1] = reg;
402 w_buf[2] = 0;
403
404 spi_message_init(&m);
405 spi_message_add_tail(&t, &m);
406 ret = spi_sync(codec->control_data, &m);
407 if (ret == 0)
408 return r_buf[2];
409 else
410 return -EIO;
411}
412
413static int ad1938_fill_cache(struct snd_soc_codec *codec)
414{
415 int i;
416 u8 *reg_cache = codec->reg_cache;
417 struct spi_device *spi = codec->control_data;
418
419 for (i = 0; i < codec->reg_cache_size; i++) {
420 int ret = ad1938_read_reg(codec, i);
421 if (ret == -EIO) {
422 dev_err(&spi->dev, "AD1938 SPI read failure\n");
423 return ret;
424 }
425 reg_cache[i] = ret;
426 }
427
428 return 0;
429}
430
431static int __devinit ad1938_spi_probe(struct spi_device *spi)
432{
433 struct snd_soc_codec *codec;
434 struct ad1938_priv *ad1938;
435
436 ad1938 = kzalloc(sizeof(struct ad1938_priv), GFP_KERNEL);
437 if (ad1938 == NULL)
438 return -ENOMEM;
439
440 codec = &ad1938->codec;
441 codec->control_data = spi;
442 codec->dev = &spi->dev;
443
444 dev_set_drvdata(&spi->dev, ad1938);
445
446 return ad1938_register(ad1938);
447}
448
449static int __devexit ad1938_spi_remove(struct spi_device *spi)
450{
451 struct ad1938_priv *ad1938 = dev_get_drvdata(&spi->dev);
452
453 ad1938_unregister(ad1938);
454 return 0;
455}
456
457static struct spi_driver ad1938_spi_driver = {
458 .driver = {
459 .name = "ad1938",
460 .bus = &spi_bus_type,
461 .owner = THIS_MODULE,
462 },
463 .probe = ad1938_spi_probe,
464 .remove = __devexit_p(ad1938_spi_remove),
465};
466
467static struct snd_soc_dai_ops ad1938_dai_ops = {
468 .hw_params = ad1938_hw_params,
469 .digital_mute = ad1938_mute,
470 .set_tdm_slot = ad1938_set_tdm_slot,
471 .set_fmt = ad1938_set_dai_fmt,
472};
473
474/* codec DAI instance */
475struct snd_soc_dai ad1938_dai = {
476 .name = "AD1938",
477 .playback = {
478 .stream_name = "Playback",
479 .channels_min = 2,
480 .channels_max = 8,
481 .rates = SNDRV_PCM_RATE_48000,
482 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
483 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
484 },
485 .capture = {
486 .stream_name = "Capture",
487 .channels_min = 2,
488 .channels_max = 4,
489 .rates = SNDRV_PCM_RATE_48000,
490 .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE |
491 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE,
492 },
493 .ops = &ad1938_dai_ops,
494};
495EXPORT_SYMBOL_GPL(ad1938_dai);
496
497static int ad1938_register(struct ad1938_priv *ad1938)
498{
499 int ret;
500 struct snd_soc_codec *codec = &ad1938->codec;
501
502 if (ad1938_codec) {
503 dev_err(codec->dev, "Another ad1938 is registered\n");
504 return -EINVAL;
505 }
506
507 mutex_init(&codec->mutex);
508 INIT_LIST_HEAD(&codec->dapm_widgets);
509 INIT_LIST_HEAD(&codec->dapm_paths);
510 codec->private_data = ad1938;
511 codec->reg_cache = ad1938->reg_cache;
512 codec->reg_cache_size = AD1938_NUM_REGS;
513 codec->name = "AD1938";
514 codec->owner = THIS_MODULE;
515 codec->dai = &ad1938_dai;
516 codec->num_dai = 1;
517 codec->write = ad1938_write_reg;
518 codec->read = ad1938_read_reg_cache;
519 INIT_LIST_HEAD(&codec->dapm_widgets);
520 INIT_LIST_HEAD(&codec->dapm_paths);
521
522 ad1938_dai.dev = codec->dev;
523 ad1938_codec = codec;
524
525 /* default setting for ad1938 */
526
527 /* unmute dac channels */
528 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
529 /* de-emphasis: 48kHz, powedown dac */
530 codec->write(codec, AD1938_DAC_CTRL2, 0x1A);
531 /* powerdown dac, dac in tdm mode */
532 codec->write(codec, AD1938_DAC_CTRL0, 0x41);
533 /* high-pass filter enable */
534 codec->write(codec, AD1938_ADC_CTRL0, 0x3);
535 /* sata delay=1, adc aux mode */
536 codec->write(codec, AD1938_ADC_CTRL1, 0x43);
537 /* pll input: mclki/xi */
538 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
539 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
540
541 ad1938_fill_cache(codec);
542
543 ret = snd_soc_register_codec(codec);
544 if (ret != 0) {
545 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
546 kfree(ad1938);
547 return ret;
548 }
549
550 ret = snd_soc_register_dai(&ad1938_dai);
551 if (ret != 0) {
552 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
553 snd_soc_unregister_codec(codec);
554 kfree(ad1938);
555 return ret;
556 }
557
558 return 0;
559}
560
561static void ad1938_unregister(struct ad1938_priv *ad1938)
562{
563 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
564 snd_soc_unregister_dai(&ad1938_dai);
565 snd_soc_unregister_codec(&ad1938->codec);
566 kfree(ad1938);
567 ad1938_codec = NULL;
568}
569
570static int ad1938_probe(struct platform_device *pdev)
571{
572 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
573 struct snd_soc_codec *codec;
574 int ret = 0;
575
576 if (ad1938_codec == NULL) {
577 dev_err(&pdev->dev, "Codec device not registered\n");
578 return -ENODEV;
579 }
580
581 socdev->card->codec = ad1938_codec;
582 codec = ad1938_codec;
583
584 /* register pcms */
585 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
586 if (ret < 0) {
587 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
588 goto pcm_err;
589 }
590
591 snd_soc_add_controls(codec, ad1938_snd_controls,
592 ARRAY_SIZE(ad1938_snd_controls));
593 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
594 ARRAY_SIZE(ad1938_dapm_widgets));
595 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
596 snd_soc_dapm_new_widgets(codec);
597
598 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
599
600 ret = snd_soc_init_card(socdev);
601 if (ret < 0) {
602 dev_err(codec->dev, "failed to register card: %d\n", ret);
603 goto card_err;
604 }
605
606 return ret;
607
608card_err:
609 snd_soc_free_pcms(socdev);
610 snd_soc_dapm_free(socdev);
611pcm_err:
612 return ret;
613}
614
615/* power down chip */
616static int ad1938_remove(struct platform_device *pdev)
617{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
619
620 snd_soc_free_pcms(socdev);
621 snd_soc_dapm_free(socdev);
622
623 return 0;
624}
625
626#ifdef CONFIG_PM
627static int ad1938_suspend(struct platform_device *pdev,
628 pm_message_t state)
629{
630 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
631 struct snd_soc_codec *codec = socdev->card->codec;
632
633 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
634 return 0;
635}
636
637static int ad1938_resume(struct platform_device *pdev)
638{
639 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
640 struct snd_soc_codec *codec = socdev->card->codec;
641
642 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
643 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
644
645 return 0;
646}
647#else
648#define ad1938_suspend NULL
649#define ad1938_resume NULL
650#endif
651
652struct snd_soc_codec_device soc_codec_dev_ad1938 = {
653 .probe = ad1938_probe,
654 .remove = ad1938_remove,
655 .suspend = ad1938_suspend,
656 .resume = ad1938_resume,
657};
658EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
659
660static int __init ad1938_init(void)
661{
662 int ret;
663
664 ret = spi_register_driver(&ad1938_spi_driver);
665 if (ret != 0) {
666 printk(KERN_ERR "Failed to register ad1938 SPI driver: %d\n",
667 ret);
668 }
669
670 return ret;
671}
672module_init(ad1938_init);
673
674static void __exit ad1938_exit(void)
675{
676 spi_unregister_driver(&ad1938_spi_driver);
677}
678module_exit(ad1938_exit);
679
680MODULE_DESCRIPTION("ASoC ad1938 driver");
681MODULE_AUTHOR("Barry Song ");
682MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ad1938.h b/sound/soc/codecs/ad1938.h
new file mode 100644
index 000000000000..fe3c48cd2d5b
--- /dev/null
+++ b/sound/soc/codecs/ad1938.h
@@ -0,0 +1,100 @@
1/*
2 * File: sound/soc/codecs/ad1836.h
3 * Based on:
4 * Author: Barry Song <Barry.Song@analog.com>
5 *
6 * Created: May 25, 2009
7 * Description: definitions for AD1938 registers
8 *
9 * Modified:
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#ifndef __AD1938_H__
30#define __AD1938_H__
31
32#define AD1938_PLL_CLK_CTRL0 0
33#define AD1938_PLL_POWERDOWN 0x01
34#define AD1938_PLL_CLK_CTRL1 1
35#define AD1938_DAC_CTRL0 2
36#define AD1938_DAC_POWERDOWN 0x01
37#define AD1938_DAC_SERFMT_MASK 0xC0
38#define AD1938_DAC_SERFMT_STEREO (0 << 6)
39#define AD1938_DAC_SERFMT_TDM (1 << 6)
40#define AD1938_DAC_CTRL1 3
41#define AD1938_DAC_2_CHANNELS 0
42#define AD1938_DAC_4_CHANNELS 1
43#define AD1938_DAC_8_CHANNELS 2
44#define AD1938_DAC_16_CHANNELS 3
45#define AD1938_DAC_CHAN_SHFT 1
46#define AD1938_DAC_CHAN_MASK (3 << AD1938_DAC_CHAN_SHFT)
47#define AD1938_DAC_LCR_MASTER (1 << 4)
48#define AD1938_DAC_BCLK_MASTER (1 << 5)
49#define AD1938_DAC_LEFT_HIGH (1 << 3)
50#define AD1938_DAC_BCLK_INV (1 << 7)
51#define AD1938_DAC_CTRL2 4
52#define AD1938_DAC_WORD_LEN_MASK 0xC
53#define AD1938_DAC_MASTER_MUTE 1
54#define AD1938_DAC_CHNL_MUTE 5
55#define AD1938_DACL1_MUTE 0
56#define AD1938_DACR1_MUTE 1
57#define AD1938_DACL2_MUTE 2
58#define AD1938_DACR2_MUTE 3
59#define AD1938_DACL3_MUTE 4
60#define AD1938_DACR3_MUTE 5
61#define AD1938_DACL4_MUTE 6
62#define AD1938_DACR4_MUTE 7
63#define AD1938_DAC_L1_VOL 6
64#define AD1938_DAC_R1_VOL 7
65#define AD1938_DAC_L2_VOL 8
66#define AD1938_DAC_R2_VOL 9
67#define AD1938_DAC_L3_VOL 10
68#define AD1938_DAC_R3_VOL 11
69#define AD1938_DAC_L4_VOL 12
70#define AD1938_DAC_R4_VOL 13
71#define AD1938_ADC_CTRL0 14
72#define AD1938_ADC_POWERDOWN 0x01
73#define AD1938_ADC_HIGHPASS_FILTER 1
74#define AD1938_ADCL1_MUTE 2
75#define AD1938_ADCR1_MUTE 3
76#define AD1938_ADCL2_MUTE 4
77#define AD1938_ADCR2_MUTE 5
78#define AD1938_ADC_CTRL1 15
79#define AD1938_ADC_SERFMT_MASK 0x60
80#define AD1938_ADC_SERFMT_STEREO (0 << 5)
81#define AD1938_ADC_SERFMT_TDM (1 << 2)
82#define AD1938_ADC_SERFMT_AUX (2 << 5)
83#define AD1938_ADC_WORD_LEN_MASK 0x3
84#define AD1938_ADC_CTRL2 16
85#define AD1938_ADC_2_CHANNELS 0
86#define AD1938_ADC_4_CHANNELS 1
87#define AD1938_ADC_8_CHANNELS 2
88#define AD1938_ADC_16_CHANNELS 3
89#define AD1938_ADC_CHAN_SHFT 4
90#define AD1938_ADC_CHAN_MASK (3 << AD1938_ADC_CHAN_SHFT)
91#define AD1938_ADC_LCR_MASTER (1 << 3)
92#define AD1938_ADC_BCLK_MASTER (1 << 6)
93#define AD1938_ADC_LEFT_HIGH (1 << 2)
94#define AD1938_ADC_BCLK_INV (1 << 1)
95
96#define AD1938_NUM_REGS 17
97
98extern struct snd_soc_dai ad1938_dai;
99extern struct snd_soc_codec_device soc_codec_dev_ad1938;
100#endif
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index dd3380202766..0abec0d29a96 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -59,21 +59,6 @@ static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec,
59 return cache[reg]; 59 return cache[reg];
60} 60}
61 61
62static inline unsigned int ak4535_read(struct snd_soc_codec *codec,
63 unsigned int reg)
64{
65 u8 data;
66 data = reg;
67
68 if (codec->hw_write(codec->control_data, &data, 1) != 1)
69 return -EIO;
70
71 if (codec->hw_read(codec->control_data, &data, 1) != 1)
72 return -EIO;
73
74 return data;
75};
76
77/* 62/*
78 * write ak4535 register cache 63 * write ak4535 register cache
79 */ 64 */
@@ -635,7 +620,6 @@ static int ak4535_probe(struct platform_device *pdev)
635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 620#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
636 if (setup->i2c_address) { 621 if (setup->i2c_address) {
637 codec->hw_write = (hw_write_t)i2c_master_send; 622 codec->hw_write = (hw_write_t)i2c_master_send;
638 codec->hw_read = (hw_read_t)i2c_master_recv;
639 ret = ak4535_add_i2c_device(pdev, setup); 623 ret = ak4535_add_i2c_device(pdev, setup);
640 } 624 }
641#endif 625#endif
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
new file mode 100644
index 000000000000..e057c7b578df
--- /dev/null
+++ b/sound/soc/codecs/ak4642.c
@@ -0,0 +1,502 @@
1/*
2 * ak4642.c -- AK4642/AK4643 ALSA Soc Audio driver
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on wm8731.c by Richard Purdie
8 * Based on ak4535.c by Richard Purdie
9 * Based on wm8753.c by Liam Girdwood
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/* ** CAUTION **
17 *
18 * This is very simple driver.
19 * It can use headphone output / stereo input only
20 *
21 * AK4642 is not tested.
22 * AK4643 is tested.
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/i2c.h>
31#include <linux/platform_device.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/initval.h>
38
39#include "ak4642.h"
40
41#define AK4642_VERSION "0.0.1"
42
43#define PW_MGMT1 0x00
44#define PW_MGMT2 0x01
45#define SG_SL1 0x02
46#define SG_SL2 0x03
47#define MD_CTL1 0x04
48#define MD_CTL2 0x05
49#define TIMER 0x06
50#define ALC_CTL1 0x07
51#define ALC_CTL2 0x08
52#define L_IVC 0x09
53#define L_DVC 0x0a
54#define ALC_CTL3 0x0b
55#define R_IVC 0x0c
56#define R_DVC 0x0d
57#define MD_CTL3 0x0e
58#define MD_CTL4 0x0f
59#define PW_MGMT3 0x10
60#define DF_S 0x11
61#define FIL3_0 0x12
62#define FIL3_1 0x13
63#define FIL3_2 0x14
64#define FIL3_3 0x15
65#define EQ_0 0x16
66#define EQ_1 0x17
67#define EQ_2 0x18
68#define EQ_3 0x19
69#define EQ_4 0x1a
70#define EQ_5 0x1b
71#define FIL1_0 0x1c
72#define FIL1_1 0x1d
73#define FIL1_2 0x1e
74#define FIL1_3 0x1f
75#define PW_MGMT4 0x20
76#define MD_CTL5 0x21
77#define LO_MS 0x22
78#define HP_MS 0x23
79#define SPK_MS 0x24
80
81#define AK4642_CACHEREGNUM 0x25
82
83struct snd_soc_codec_device soc_codec_dev_ak4642;
84
85/* codec private data */
86struct ak4642_priv {
87 struct snd_soc_codec codec;
88 unsigned int sysclk;
89};
90
91static struct snd_soc_codec *ak4642_codec;
92
93/*
94 * ak4642 register cache
95 */
96static const u16 ak4642_reg[AK4642_CACHEREGNUM] = {
97 0x0000, 0x0000, 0x0001, 0x0000,
98 0x0002, 0x0000, 0x0000, 0x0000,
99 0x00e1, 0x00e1, 0x0018, 0x0000,
100 0x00e1, 0x0018, 0x0011, 0x0008,
101 0x0000, 0x0000, 0x0000, 0x0000,
102 0x0000, 0x0000, 0x0000, 0x0000,
103 0x0000, 0x0000, 0x0000, 0x0000,
104 0x0000, 0x0000, 0x0000, 0x0000,
105 0x0000, 0x0000, 0x0000, 0x0000,
106 0x0000,
107};
108
109/*
110 * read ak4642 register cache
111 */
112static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec,
113 unsigned int reg)
114{
115 u16 *cache = codec->reg_cache;
116 if (reg >= AK4642_CACHEREGNUM)
117 return -1;
118 return cache[reg];
119}
120
121/*
122 * write ak4642 register cache
123 */
124static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec,
125 u16 reg, unsigned int value)
126{
127 u16 *cache = codec->reg_cache;
128 if (reg >= AK4642_CACHEREGNUM)
129 return;
130
131 cache[reg] = value;
132}
133
134/*
135 * write to the AK4642 register space
136 */
137static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg,
138 unsigned int value)
139{
140 u8 data[2];
141
142 /* data is
143 * D15..D8 AK4642 register offset
144 * D7...D0 register data
145 */
146 data[0] = reg & 0xff;
147 data[1] = value & 0xff;
148
149 if (codec->hw_write(codec->control_data, data, 2) == 2) {
150 ak4642_write_reg_cache(codec, reg, value);
151 return 0;
152 } else
153 return -EIO;
154}
155
156static int ak4642_sync(struct snd_soc_codec *codec)
157{
158 u16 *cache = codec->reg_cache;
159 int i, r = 0;
160
161 for (i = 0; i < AK4642_CACHEREGNUM; i++)
162 r |= ak4642_write(codec, i, cache[i]);
163
164 return r;
165};
166
167static int ak4642_dai_startup(struct snd_pcm_substream *substream,
168 struct snd_soc_dai *dai)
169{
170 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
171 struct snd_soc_codec *codec = dai->codec;
172
173 if (is_play) {
174 /*
175 * start headphone output
176 *
177 * PLL, Master Mode
178 * Audio I/F Format :MSB justified (ADC & DAC)
179 * Sampling Frequency: 44.1kHz
180 * Digital Volume: −8dB
181 * Bass Boost Level : Middle
182 *
183 * This operation came from example code of
184 * "ASAHI KASEI AK4642" (japanese) manual p97.
185 *
186 * Example code use 0x39, 0x79 value for 0x01 address,
187 * But we need MCKO (0x02) bit now
188 */
189 ak4642_write(codec, 0x05, 0x27);
190 ak4642_write(codec, 0x0f, 0x09);
191 ak4642_write(codec, 0x0e, 0x19);
192 ak4642_write(codec, 0x09, 0x91);
193 ak4642_write(codec, 0x0c, 0x91);
194 ak4642_write(codec, 0x0a, 0x28);
195 ak4642_write(codec, 0x0d, 0x28);
196 ak4642_write(codec, 0x00, 0x64);
197 ak4642_write(codec, 0x01, 0x3b); /* + MCKO bit */
198 ak4642_write(codec, 0x01, 0x7b); /* + MCKO bit */
199 } else {
200 /*
201 * start stereo input
202 *
203 * PLL Master Mode
204 * Audio I/F Format:MSB justified (ADC & DAC)
205 * Sampling Frequency:44.1kHz
206 * Pre MIC AMP:+20dB
207 * MIC Power On
208 * ALC setting:Refer to Table 35
209 * ALC bit=“1”
210 *
211 * This operation came from example code of
212 * "ASAHI KASEI AK4642" (japanese) manual p94.
213 */
214 ak4642_write(codec, 0x05, 0x27);
215 ak4642_write(codec, 0x02, 0x05);
216 ak4642_write(codec, 0x06, 0x3c);
217 ak4642_write(codec, 0x08, 0xe1);
218 ak4642_write(codec, 0x0b, 0x00);
219 ak4642_write(codec, 0x07, 0x21);
220 ak4642_write(codec, 0x00, 0x41);
221 ak4642_write(codec, 0x10, 0x01);
222 }
223
224 return 0;
225}
226
227static void ak4642_dai_shutdown(struct snd_pcm_substream *substream,
228 struct snd_soc_dai *dai)
229{
230 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
231 struct snd_soc_codec *codec = dai->codec;
232
233 if (is_play) {
234 /* stop headphone output */
235 ak4642_write(codec, 0x01, 0x3b);
236 ak4642_write(codec, 0x01, 0x0b);
237 ak4642_write(codec, 0x00, 0x40);
238 ak4642_write(codec, 0x0e, 0x11);
239 ak4642_write(codec, 0x0f, 0x08);
240 } else {
241 /* stop stereo input */
242 ak4642_write(codec, 0x00, 0x40);
243 ak4642_write(codec, 0x10, 0x00);
244 ak4642_write(codec, 0x07, 0x01);
245 }
246}
247
248static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai,
249 int clk_id, unsigned int freq, int dir)
250{
251 struct snd_soc_codec *codec = codec_dai->codec;
252 struct ak4642_priv *ak4642 = codec->private_data;
253
254 ak4642->sysclk = freq;
255 return 0;
256}
257
258static struct snd_soc_dai_ops ak4642_dai_ops = {
259 .startup = ak4642_dai_startup,
260 .shutdown = ak4642_dai_shutdown,
261 .set_sysclk = ak4642_dai_set_sysclk,
262};
263
264struct snd_soc_dai ak4642_dai = {
265 .name = "AK4642",
266 .playback = {
267 .stream_name = "Playback",
268 .channels_min = 1,
269 .channels_max = 2,
270 .rates = SNDRV_PCM_RATE_8000_48000,
271 .formats = SNDRV_PCM_FMTBIT_S16_LE },
272 .capture = {
273 .stream_name = "Capture",
274 .channels_min = 1,
275 .channels_max = 2,
276 .rates = SNDRV_PCM_RATE_8000_48000,
277 .formats = SNDRV_PCM_FMTBIT_S16_LE },
278 .ops = &ak4642_dai_ops,
279};
280EXPORT_SYMBOL_GPL(ak4642_dai);
281
282static int ak4642_resume(struct platform_device *pdev)
283{
284 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
285 struct snd_soc_codec *codec = socdev->card->codec;
286
287 ak4642_sync(codec);
288 return 0;
289}
290
291/*
292 * initialise the AK4642 driver
293 * register the mixer and dsp interfaces with the kernel
294 */
295static int ak4642_init(struct ak4642_priv *ak4642)
296{
297 struct snd_soc_codec *codec = &ak4642->codec;
298 int ret = 0;
299
300 if (ak4642_codec) {
301 dev_err(codec->dev, "Another ak4642 is registered\n");
302 return -EINVAL;
303 }
304
305 mutex_init(&codec->mutex);
306 INIT_LIST_HEAD(&codec->dapm_widgets);
307 INIT_LIST_HEAD(&codec->dapm_paths);
308
309 codec->private_data = ak4642;
310 codec->name = "AK4642";
311 codec->owner = THIS_MODULE;
312 codec->read = ak4642_read_reg_cache;
313 codec->write = ak4642_write;
314 codec->dai = &ak4642_dai;
315 codec->num_dai = 1;
316 codec->hw_write = (hw_write_t)i2c_master_send;
317 codec->reg_cache_size = ARRAY_SIZE(ak4642_reg);
318 codec->reg_cache = kmemdup(ak4642_reg,
319 sizeof(ak4642_reg), GFP_KERNEL);
320
321 if (!codec->reg_cache)
322 return -ENOMEM;
323
324 ak4642_dai.dev = codec->dev;
325 ak4642_codec = codec;
326
327 ret = snd_soc_register_codec(codec);
328 if (ret) {
329 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
330 goto reg_cache_err;
331 }
332
333 ret = snd_soc_register_dai(&ak4642_dai);
334 if (ret) {
335 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
336 snd_soc_unregister_codec(codec);
337 goto reg_cache_err;
338 }
339
340 /*
341 * clock setting
342 *
343 * Audio I/F Format: MSB justified (ADC & DAC)
344 * BICK frequency at Master Mode: 64fs
345 * Input Master Clock Select at PLL Mode: 11.2896MHz
346 * MCKO: Enable
347 * Sampling Frequency: 44.1kHz
348 *
349 * This operation came from example code of
350 * "ASAHI KASEI AK4642" (japanese) manual p89.
351 *
352 * please fix-me
353 */
354 ak4642_write(codec, 0x01, 0x08);
355 ak4642_write(codec, 0x04, 0x4a);
356 ak4642_write(codec, 0x05, 0x27);
357 ak4642_write(codec, 0x00, 0x40);
358 ak4642_write(codec, 0x01, 0x0b);
359
360 return ret;
361
362reg_cache_err:
363 kfree(codec->reg_cache);
364 codec->reg_cache = NULL;
365
366 return ret;
367}
368
369#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
370static int ak4642_i2c_probe(struct i2c_client *i2c,
371 const struct i2c_device_id *id)
372{
373 struct ak4642_priv *ak4642;
374 struct snd_soc_codec *codec;
375 int ret;
376
377 ak4642 = kzalloc(sizeof(struct ak4642_priv), GFP_KERNEL);
378 if (!ak4642)
379 return -ENOMEM;
380
381 codec = &ak4642->codec;
382 codec->dev = &i2c->dev;
383
384 i2c_set_clientdata(i2c, ak4642);
385 codec->control_data = i2c;
386
387 ret = ak4642_init(ak4642);
388 if (ret < 0)
389 printk(KERN_ERR "failed to initialise AK4642\n");
390
391 return ret;
392}
393
394static int ak4642_i2c_remove(struct i2c_client *client)
395{
396 struct ak4642_priv *ak4642 = i2c_get_clientdata(client);
397
398 snd_soc_unregister_dai(&ak4642_dai);
399 snd_soc_unregister_codec(&ak4642->codec);
400 kfree(ak4642->codec.reg_cache);
401 kfree(ak4642);
402 ak4642_codec = NULL;
403
404 return 0;
405}
406
407static const struct i2c_device_id ak4642_i2c_id[] = {
408 { "ak4642", 0 },
409 { "ak4643", 0 },
410 { }
411};
412MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id);
413
414static struct i2c_driver ak4642_i2c_driver = {
415 .driver = {
416 .name = "AK4642 I2C Codec",
417 .owner = THIS_MODULE,
418 },
419 .probe = ak4642_i2c_probe,
420 .remove = ak4642_i2c_remove,
421 .id_table = ak4642_i2c_id,
422};
423
424#endif
425
426static int ak4642_probe(struct platform_device *pdev)
427{
428 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
429 int ret;
430
431 if (!ak4642_codec) {
432 dev_err(&pdev->dev, "Codec device not registered\n");
433 return -ENODEV;
434 }
435
436 socdev->card->codec = ak4642_codec;
437
438 /* register pcms */
439 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
440 if (ret < 0) {
441 printk(KERN_ERR "ak4642: failed to create pcms\n");
442 goto pcm_err;
443 }
444
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret;
453
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err:
458 return ret;
459
460}
461
462/* power down chip */
463static int ak4642_remove(struct platform_device *pdev)
464{
465 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
466
467 snd_soc_free_pcms(socdev);
468 snd_soc_dapm_free(socdev);
469
470 return 0;
471}
472
473struct snd_soc_codec_device soc_codec_dev_ak4642 = {
474 .probe = ak4642_probe,
475 .remove = ak4642_remove,
476 .resume = ak4642_resume,
477};
478EXPORT_SYMBOL_GPL(soc_codec_dev_ak4642);
479
480static int __init ak4642_modinit(void)
481{
482 int ret;
483#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
484 ret = i2c_add_driver(&ak4642_i2c_driver);
485#endif
486 return ret;
487
488}
489module_init(ak4642_modinit);
490
491static void __exit ak4642_exit(void)
492{
493#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
494 i2c_del_driver(&ak4642_i2c_driver);
495#endif
496
497}
498module_exit(ak4642_exit);
499
500MODULE_DESCRIPTION("Soc AK4642 driver");
501MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
502MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4642.h b/sound/soc/codecs/ak4642.h
new file mode 100644
index 000000000000..e476833d314e
--- /dev/null
+++ b/sound/soc/codecs/ak4642.h
@@ -0,0 +1,20 @@
1/*
2 * ak4642.h -- AK4642 Soc Audio driver
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ak4535.c
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#ifndef _AK4642_H
15#define _AK4642_H
16
17extern struct snd_soc_dai ak4642_dai;
18extern struct snd_soc_codec_device soc_codec_dev_ak4642;
19
20#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index a32b8226c8a4..ca1e24a8f12a 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -806,15 +806,30 @@ static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{ 806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec; 808 struct snd_soc_codec *codec = &cs4270->codec;
809 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
810 809
811 return snd_soc_write(codec, CS4270_PWRCTL, reg); 810 return snd_soc_suspend_device(codec->dev);
812} 811}
813 812
814static int cs4270_i2c_resume(struct i2c_client *client) 813static int cs4270_i2c_resume(struct i2c_client *client)
815{ 814{
816 struct cs4270_private *cs4270 = i2c_get_clientdata(client); 815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
817 struct snd_soc_codec *codec = &cs4270->codec; 816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{
823 struct snd_soc_codec *codec = cs4270_codec;
824 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
825
826 return snd_soc_write(codec, CS4270_PWRCTL, reg);
827}
828
829static int cs4270_soc_resume(struct platform_device *pdev)
830{
831 struct snd_soc_codec *codec = cs4270_codec;
832 struct i2c_client *i2c_client = codec->control_data;
818 int reg; 833 int reg;
819 834
820 /* In case the device was put to hard reset during sleep, we need to 835 /* In case the device was put to hard reset during sleep, we need to
@@ -825,7 +840,7 @@ static int cs4270_i2c_resume(struct i2c_client *client)
825 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { 840 for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) {
826 u8 val = snd_soc_read(codec, reg); 841 u8 val = snd_soc_read(codec, reg);
827 842
828 if (i2c_smbus_write_byte_data(client, reg, val)) { 843 if (i2c_smbus_write_byte_data(i2c_client, reg, val)) {
829 dev_err(codec->dev, "i2c write failed\n"); 844 dev_err(codec->dev, "i2c write failed\n");
830 return -EIO; 845 return -EIO;
831 } 846 }
@@ -840,6 +855,8 @@ static int cs4270_i2c_resume(struct i2c_client *client)
840#else 855#else
841#define cs4270_i2c_suspend NULL 856#define cs4270_i2c_suspend NULL
842#define cs4270_i2c_resume NULL 857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL
843#endif /* CONFIG_PM */ 860#endif /* CONFIG_PM */
844 861
845/* 862/*
@@ -868,7 +885,9 @@ static struct i2c_driver cs4270_i2c_driver = {
868 */ 885 */
869struct snd_soc_codec_device soc_codec_device_cs4270 = { 886struct snd_soc_codec_device soc_codec_device_cs4270 = {
870 .probe = cs4270_probe, 887 .probe = cs4270_probe,
871 .remove = cs4270_remove 888 .remove = cs4270_remove,
889 .suspend = cs4270_soc_suspend,
890 .resume = cs4270_soc_resume,
872}; 891};
873EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); 892EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
874 893
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
new file mode 100644
index 000000000000..38eac9c866e1
--- /dev/null
+++ b/sound/soc/codecs/cx20442.c
@@ -0,0 +1,501 @@
1/*
2 * cx20442.c -- CX20442 ALSA Soc Audio driver
3 *
4 * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * Initially based on sound/soc/codecs/wm8400.c
7 * Copyright 2008, 2009 Wolfson Microelectronics PLC.
8 * Author: Mark Brown <broonie@opensource.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#include <linux/tty.h>
17
18#include <sound/core.h>
19#include <sound/initval.h>
20#include <sound/soc-dapm.h>
21
22#include "cx20442.h"
23
24
25struct cx20442_priv {
26 struct snd_soc_codec codec;
27 u8 reg_cache[1];
28};
29
30#define CX20442_PM 0x0
31
32#define CX20442_TELIN 0
33#define CX20442_TELOUT 1
34#define CX20442_MIC 2
35#define CX20442_SPKOUT 3
36#define CX20442_AGC 4
37
38static const struct snd_soc_dapm_widget cx20442_dapm_widgets[] = {
39 SND_SOC_DAPM_OUTPUT("TELOUT"),
40 SND_SOC_DAPM_OUTPUT("SPKOUT"),
41 SND_SOC_DAPM_OUTPUT("AGCOUT"),
42
43 SND_SOC_DAPM_MIXER("SPKOUT Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
44
45 SND_SOC_DAPM_PGA("TELOUT Amp", CX20442_PM, CX20442_TELOUT, 0, NULL, 0),
46 SND_SOC_DAPM_PGA("SPKOUT Amp", CX20442_PM, CX20442_SPKOUT, 0, NULL, 0),
47 SND_SOC_DAPM_PGA("SPKOUT AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
48
49 SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
50 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
51
52 SND_SOC_DAPM_MIXER("Input Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
53
54 SND_SOC_DAPM_MICBIAS("TELIN Bias", CX20442_PM, CX20442_TELIN, 0),
55 SND_SOC_DAPM_MICBIAS("MIC Bias", CX20442_PM, CX20442_MIC, 0),
56
57 SND_SOC_DAPM_PGA("MIC AGC", CX20442_PM, CX20442_AGC, 0, NULL, 0),
58
59 SND_SOC_DAPM_INPUT("TELIN"),
60 SND_SOC_DAPM_INPUT("MIC"),
61 SND_SOC_DAPM_INPUT("AGCIN"),
62};
63
64static const struct snd_soc_dapm_route cx20442_audio_map[] = {
65 {"TELOUT", NULL, "TELOUT Amp"},
66
67 {"SPKOUT", NULL, "SPKOUT Mixer"},
68 {"SPKOUT Mixer", NULL, "SPKOUT Amp"},
69
70 {"TELOUT Amp", NULL, "DAC"},
71 {"SPKOUT Amp", NULL, "DAC"},
72
73 {"SPKOUT Mixer", NULL, "SPKOUT AGC"},
74 {"SPKOUT AGC", NULL, "AGCIN"},
75
76 {"AGCOUT", NULL, "MIC AGC"},
77 {"MIC AGC", NULL, "MIC"},
78
79 {"MIC Bias", NULL, "MIC"},
80 {"Input Mixer", NULL, "MIC Bias"},
81
82 {"TELIN Bias", NULL, "TELIN"},
83 {"Input Mixer", NULL, "TELIN Bias"},
84
85 {"ADC", NULL, "Input Mixer"},
86};
87
88static int cx20442_add_widgets(struct snd_soc_codec *codec)
89{
90 snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets,
91 ARRAY_SIZE(cx20442_dapm_widgets));
92
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map));
95
96 snd_soc_dapm_new_widgets(codec);
97 return 0;
98}
99
100static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 u8 *reg_cache = codec->reg_cache;
104
105 if (reg >= codec->reg_cache_size)
106 return -EINVAL;
107
108 return reg_cache[reg];
109}
110
111enum v253_vls {
112 V253_VLS_NONE = 0,
113 V253_VLS_T,
114 V253_VLS_L,
115 V253_VLS_LT,
116 V253_VLS_S,
117 V253_VLS_ST,
118 V253_VLS_M,
119 V253_VLS_MST,
120 V253_VLS_S1,
121 V253_VLS_S1T,
122 V253_VLS_MS1T,
123 V253_VLS_M1,
124 V253_VLS_M1ST,
125 V253_VLS_M1S1T,
126 V253_VLS_H,
127 V253_VLS_HT,
128 V253_VLS_MS,
129 V253_VLS_MS1,
130 V253_VLS_M1S,
131 V253_VLS_M1S1,
132 V253_VLS_TEST,
133};
134
135static int cx20442_pm_to_v253_vls(u8 value)
136{
137 switch (value & ~(1 << CX20442_AGC)) {
138 case 0:
139 return V253_VLS_T;
140 case (1 << CX20442_SPKOUT):
141 case (1 << CX20442_MIC):
142 case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
143 return V253_VLS_M1S1;
144 case (1 << CX20442_TELOUT):
145 case (1 << CX20442_TELIN):
146 case (1 << CX20442_TELOUT) | (1 << CX20442_TELIN):
147 return V253_VLS_L;
148 case (1 << CX20442_TELOUT) | (1 << CX20442_MIC):
149 return V253_VLS_NONE;
150 }
151 return -EINVAL;
152}
153static int cx20442_pm_to_v253_vsp(u8 value)
154{
155 switch (value & ~(1 << CX20442_AGC)) {
156 case (1 << CX20442_SPKOUT):
157 case (1 << CX20442_MIC):
158 case (1 << CX20442_SPKOUT) | (1 << CX20442_MIC):
159 return (bool)(value & (1 << CX20442_AGC));
160 }
161 return (value & (1 << CX20442_AGC)) ? -EINVAL : 0;
162}
163
164static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg,
165 unsigned int value)
166{
167 u8 *reg_cache = codec->reg_cache;
168 int vls, vsp, old, len;
169 char buf[18];
170
171 if (reg >= codec->reg_cache_size)
172 return -EINVAL;
173
174 /* hw_write and control_data pointers required for talking to the modem
175 * are expected to be set by the line discipline initialization code */
176 if (!codec->hw_write || !codec->control_data)
177 return -EIO;
178
179 old = reg_cache[reg];
180 reg_cache[reg] = value;
181
182 vls = cx20442_pm_to_v253_vls(value);
183 if (vls < 0)
184 return vls;
185
186 vsp = cx20442_pm_to_v253_vsp(value);
187 if (vsp < 0)
188 return vsp;
189
190 if ((vls == V253_VLS_T) ||
191 (vls == cx20442_pm_to_v253_vls(old))) {
192 if (vsp == cx20442_pm_to_v253_vsp(old))
193 return 0;
194 len = snprintf(buf, ARRAY_SIZE(buf), "at+vsp=%d\r", vsp);
195 } else if (vsp == cx20442_pm_to_v253_vsp(old))
196 len = snprintf(buf, ARRAY_SIZE(buf), "at+vls=%d\r", vls);
197 else
198 len = snprintf(buf, ARRAY_SIZE(buf),
199 "at+vls=%d;+vsp=%d\r", vls, vsp);
200
201 if (unlikely(len > (ARRAY_SIZE(buf) - 1)))
202 return -ENOMEM;
203
204 dev_dbg(codec->dev, "%s: %s\n", __func__, buf);
205 if (codec->hw_write(codec->control_data, buf, len) != len)
206 return -EIO;
207
208 return 0;
209}
210
211
212/* Moved up here as line discipline referres it during initialization */
213static struct snd_soc_codec *cx20442_codec;
214
215
216/*
217 * Line discpline related code
218 *
219 * Any of the callback functions below can be used in two ways:
220 * 1) registerd by a machine driver as one of line discipline operations,
221 * 2) called from a machine's provided line discipline callback function
222 * in case when extra machine specific code must be run as well.
223 */
224
225/* Modem init: echo off, digital speaker off, quiet off, voice mode */
226static const char *v253_init = "ate0m0q0+fclass=8\r";
227
228/* Line discipline .open() */
229static int v253_open(struct tty_struct *tty)
230{
231 struct snd_soc_codec *codec = cx20442_codec;
232 int ret, len = strlen(v253_init);
233
234 /* Doesn't make sense without write callback */
235 if (!tty->ops->write)
236 return -EINVAL;
237
238 /* Pass the codec structure address for use by other ldisc callbacks */
239 tty->disc_data = codec;
240
241 if (tty->ops->write(tty, v253_init, len) != len) {
242 ret = -EIO;
243 goto err;
244 }
245 /* Actual setup will be performed after the modem responds. */
246 return 0;
247err:
248 tty->disc_data = NULL;
249 return ret;
250}
251
252/* Line discipline .close() */
253static void v253_close(struct tty_struct *tty)
254{
255 struct snd_soc_codec *codec = tty->disc_data;
256
257 tty->disc_data = NULL;
258
259 if (!codec)
260 return;
261
262 /* Prevent the codec driver from further accessing the modem */
263 codec->hw_write = NULL;
264 codec->control_data = NULL;
265 codec->pop_time = 0;
266}
267
268/* Line discipline .hangup() */
269static int v253_hangup(struct tty_struct *tty)
270{
271 v253_close(tty);
272 return 0;
273}
274
275/* Line discipline .receive_buf() */
276static void v253_receive(struct tty_struct *tty,
277 const unsigned char *cp, char *fp, int count)
278{
279 struct snd_soc_codec *codec = tty->disc_data;
280
281 if (!codec)
282 return;
283
284 if (!codec->control_data) {
285 /* First modem response, complete setup procedure */
286
287 /* Set up codec driver access to modem controls */
288 codec->control_data = tty;
289 codec->hw_write = (hw_write_t)tty->ops->write;
290 codec->pop_time = 1;
291 }
292}
293
294/* Line discipline .write_wakeup() */
295static void v253_wakeup(struct tty_struct *tty)
296{
297}
298
299struct tty_ldisc_ops v253_ops = {
300 .magic = TTY_LDISC_MAGIC,
301 .name = "cx20442",
302 .owner = THIS_MODULE,
303 .open = v253_open,
304 .close = v253_close,
305 .hangup = v253_hangup,
306 .receive_buf = v253_receive,
307 .write_wakeup = v253_wakeup,
308};
309EXPORT_SYMBOL_GPL(v253_ops);
310
311
312/*
313 * Codec DAI
314 */
315
316struct snd_soc_dai cx20442_dai = {
317 .name = "CX20442",
318 .playback = {
319 .stream_name = "Playback",
320 .channels_min = 1,
321 .channels_max = 1,
322 .rates = SNDRV_PCM_RATE_8000,
323 .formats = SNDRV_PCM_FMTBIT_S16_LE,
324 },
325 .capture = {
326 .stream_name = "Capture",
327 .channels_min = 1,
328 .channels_max = 1,
329 .rates = SNDRV_PCM_RATE_8000,
330 .formats = SNDRV_PCM_FMTBIT_S16_LE,
331 },
332};
333EXPORT_SYMBOL_GPL(cx20442_dai);
334
335static int cx20442_codec_probe(struct platform_device *pdev)
336{
337 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
338 struct snd_soc_codec *codec;
339 int ret;
340
341 if (!cx20442_codec) {
342 dev_err(&pdev->dev, "cx20442 not yet discovered\n");
343 return -ENODEV;
344 }
345 codec = cx20442_codec;
346
347 socdev->card->codec = codec;
348
349 /* register pcms */
350 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
351 if (ret < 0) {
352 dev_err(&pdev->dev, "failed to create pcms\n");
353 goto pcm_err;
354 }
355
356 cx20442_add_widgets(codec);
357
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret;
365
366card_err:
367 snd_soc_free_pcms(socdev);
368 snd_soc_dapm_free(socdev);
369pcm_err:
370 return ret;
371}
372
373/* power down chip */
374static int cx20442_codec_remove(struct platform_device *pdev)
375{
376 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
377
378 snd_soc_free_pcms(socdev);
379 snd_soc_dapm_free(socdev);
380
381 return 0;
382}
383
384struct snd_soc_codec_device cx20442_codec_dev = {
385 .probe = cx20442_codec_probe,
386 .remove = cx20442_codec_remove,
387};
388EXPORT_SYMBOL_GPL(cx20442_codec_dev);
389
390static int cx20442_register(struct cx20442_priv *cx20442)
391{
392 struct snd_soc_codec *codec = &cx20442->codec;
393 int ret;
394
395 mutex_init(&codec->mutex);
396 INIT_LIST_HEAD(&codec->dapm_widgets);
397 INIT_LIST_HEAD(&codec->dapm_paths);
398
399 codec->name = "CX20442";
400 codec->owner = THIS_MODULE;
401 codec->private_data = cx20442;
402
403 codec->dai = &cx20442_dai;
404 codec->num_dai = 1;
405
406 codec->reg_cache = &cx20442->reg_cache;
407 codec->reg_cache_size = ARRAY_SIZE(cx20442->reg_cache);
408 codec->read = cx20442_read_reg_cache;
409 codec->write = cx20442_write;
410
411 codec->bias_level = SND_SOC_BIAS_OFF;
412
413 cx20442_dai.dev = codec->dev;
414
415 cx20442_codec = codec;
416
417 ret = snd_soc_register_codec(codec);
418 if (ret != 0) {
419 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
420 goto err;
421 }
422
423 ret = snd_soc_register_dai(&cx20442_dai);
424 if (ret != 0) {
425 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
426 goto err_codec;
427 }
428
429 return 0;
430
431err_codec:
432 snd_soc_unregister_codec(codec);
433err:
434 cx20442_codec = NULL;
435 kfree(cx20442);
436 return ret;
437}
438
439static void cx20442_unregister(struct cx20442_priv *cx20442)
440{
441 snd_soc_unregister_dai(&cx20442_dai);
442 snd_soc_unregister_codec(&cx20442->codec);
443
444 cx20442_codec = NULL;
445 kfree(cx20442);
446}
447
448static int cx20442_platform_probe(struct platform_device *pdev)
449{
450 struct cx20442_priv *cx20442;
451 struct snd_soc_codec *codec;
452
453 cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
454 if (cx20442 == NULL)
455 return -ENOMEM;
456
457 codec = &cx20442->codec;
458
459 codec->control_data = NULL;
460 codec->hw_write = NULL;
461 codec->pop_time = 0;
462
463 codec->dev = &pdev->dev;
464 platform_set_drvdata(pdev, cx20442);
465
466 return cx20442_register(cx20442);
467}
468
469static int __exit cx20442_platform_remove(struct platform_device *pdev)
470{
471 struct cx20442_priv *cx20442 = platform_get_drvdata(pdev);
472
473 cx20442_unregister(cx20442);
474 return 0;
475}
476
477static struct platform_driver cx20442_platform_driver = {
478 .driver = {
479 .name = "cx20442",
480 .owner = THIS_MODULE,
481 },
482 .probe = cx20442_platform_probe,
483 .remove = __exit_p(cx20442_platform_remove),
484};
485
486static int __init cx20442_init(void)
487{
488 return platform_driver_register(&cx20442_platform_driver);
489}
490module_init(cx20442_init);
491
492static void __exit cx20442_exit(void)
493{
494 platform_driver_unregister(&cx20442_platform_driver);
495}
496module_exit(cx20442_exit);
497
498MODULE_DESCRIPTION("ASoC CX20442-11 voice modem codec driver");
499MODULE_AUTHOR("Janusz Krzysztofik");
500MODULE_LICENSE("GPL");
501MODULE_ALIAS("platform:cx20442");
diff --git a/sound/soc/codecs/cx20442.h b/sound/soc/codecs/cx20442.h
new file mode 100644
index 000000000000..688a5eb62e17
--- /dev/null
+++ b/sound/soc/codecs/cx20442.h
@@ -0,0 +1,20 @@
1/*
2 * cx20442.h -- audio driver for CX20442
3 *
4 * Copyright 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#ifndef _CX20442_CODEC_H
14#define _CX20442_CODEC_H
15
16extern struct snd_soc_dai cx20442_dai;
17extern struct snd_soc_codec_device cx20442_codec_dev;
18extern struct tty_ldisc_ops v253_ops;
19
20#endif
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c
new file mode 100644
index 000000000000..9e7e964a5fa3
--- /dev/null
+++ b/sound/soc/codecs/max9877.c
@@ -0,0 +1,308 @@
1/*
2 * max9877.c -- amp driver for max9877
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.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
14#include <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <sound/soc.h>
18#include <sound/tlv.h>
19
20#include "max9877.h"
21
22static struct i2c_client *i2c;
23
24static u8 max9877_regs[5] = { 0x40, 0x00, 0x00, 0x00, 0x49 };
25
26static void max9877_write_regs(void)
27{
28 unsigned int i;
29 u8 data[6];
30
31 data[0] = MAX9877_INPUT_MODE;
32 for (i = 0; i < ARRAY_SIZE(max9877_regs); i++)
33 data[i + 1] = max9877_regs[i];
34
35 if (i2c_master_send(i2c, data, 6) != 6)
36 dev_err(&i2c->dev, "i2c write failed\n");
37}
38
39static int max9877_get_reg(struct snd_kcontrol *kcontrol,
40 struct snd_ctl_elem_value *ucontrol)
41{
42 struct soc_mixer_control *mc =
43 (struct soc_mixer_control *)kcontrol->private_value;
44 unsigned int reg = mc->reg;
45 unsigned int shift = mc->shift;
46 unsigned int mask = mc->max;
47 unsigned int invert = mc->invert;
48
49 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
50
51 if (invert)
52 ucontrol->value.integer.value[0] =
53 mask - ucontrol->value.integer.value[0];
54
55 return 0;
56}
57
58static int max9877_set_reg(struct snd_kcontrol *kcontrol,
59 struct snd_ctl_elem_value *ucontrol)
60{
61 struct soc_mixer_control *mc =
62 (struct soc_mixer_control *)kcontrol->private_value;
63 unsigned int reg = mc->reg;
64 unsigned int shift = mc->shift;
65 unsigned int mask = mc->max;
66 unsigned int invert = mc->invert;
67 unsigned int val = (ucontrol->value.integer.value[0] & mask);
68
69 if (invert)
70 val = mask - val;
71
72 if (((max9877_regs[reg] >> shift) & mask) == val)
73 return 0;
74
75 max9877_regs[reg] &= ~(mask << shift);
76 max9877_regs[reg] |= val << shift;
77 max9877_write_regs();
78
79 return 1;
80}
81
82static int max9877_get_2reg(struct snd_kcontrol *kcontrol,
83 struct snd_ctl_elem_value *ucontrol)
84{
85 struct soc_mixer_control *mc =
86 (struct soc_mixer_control *)kcontrol->private_value;
87 unsigned int reg = mc->reg;
88 unsigned int reg2 = mc->rreg;
89 unsigned int shift = mc->shift;
90 unsigned int mask = mc->max;
91
92 ucontrol->value.integer.value[0] = (max9877_regs[reg] >> shift) & mask;
93 ucontrol->value.integer.value[1] = (max9877_regs[reg2] >> shift) & mask;
94
95 return 0;
96}
97
98static int max9877_set_2reg(struct snd_kcontrol *kcontrol,
99 struct snd_ctl_elem_value *ucontrol)
100{
101 struct soc_mixer_control *mc =
102 (struct soc_mixer_control *)kcontrol->private_value;
103 unsigned int reg = mc->reg;
104 unsigned int reg2 = mc->rreg;
105 unsigned int shift = mc->shift;
106 unsigned int mask = mc->max;
107 unsigned int val = (ucontrol->value.integer.value[0] & mask);
108 unsigned int val2 = (ucontrol->value.integer.value[1] & mask);
109 unsigned int change = 1;
110
111 if (((max9877_regs[reg] >> shift) & mask) == val)
112 change = 0;
113
114 if (((max9877_regs[reg2] >> shift) & mask) == val2)
115 change = 0;
116
117 if (change) {
118 max9877_regs[reg] &= ~(mask << shift);
119 max9877_regs[reg] |= val << shift;
120 max9877_regs[reg2] &= ~(mask << shift);
121 max9877_regs[reg2] |= val2 << shift;
122 max9877_write_regs();
123 }
124
125 return change;
126}
127
128static int max9877_get_out_mode(struct snd_kcontrol *kcontrol,
129 struct snd_ctl_elem_value *ucontrol)
130{
131 u8 value = max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK;
132
133 if (value)
134 value -= 1;
135
136 ucontrol->value.integer.value[0] = value;
137 return 0;
138}
139
140static int max9877_set_out_mode(struct snd_kcontrol *kcontrol,
141 struct snd_ctl_elem_value *ucontrol)
142{
143 u8 value = ucontrol->value.integer.value[0];
144
145 value += 1;
146
147 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OUTMODE_MASK) == value)
148 return 0;
149
150 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OUTMODE_MASK;
151 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
152 max9877_write_regs();
153 return 1;
154}
155
156static int max9877_get_osc_mode(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol)
158{
159 u8 value = (max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK);
160
161 value = value >> MAX9877_OSC_OFFSET;
162
163 ucontrol->value.integer.value[0] = value;
164 return 0;
165}
166
167static int max9877_set_osc_mode(struct snd_kcontrol *kcontrol,
168 struct snd_ctl_elem_value *ucontrol)
169{
170 u8 value = ucontrol->value.integer.value[0];
171
172 value = value << MAX9877_OSC_OFFSET;
173 if ((max9877_regs[MAX9877_OUTPUT_MODE] & MAX9877_OSC_MASK) == value)
174 return 0;
175
176 max9877_regs[MAX9877_OUTPUT_MODE] &= ~MAX9877_OSC_MASK;
177 max9877_regs[MAX9877_OUTPUT_MODE] |= value;
178 max9877_write_regs();
179 return 1;
180}
181
182static const unsigned int max9877_pgain_tlv[] = {
183 TLV_DB_RANGE_HEAD(2),
184 0, 1, TLV_DB_SCALE_ITEM(0, 900, 0),
185 2, 2, TLV_DB_SCALE_ITEM(2000, 0, 0),
186};
187
188static const unsigned int max9877_output_tlv[] = {
189 TLV_DB_RANGE_HEAD(4),
190 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1),
191 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0),
192 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0),
193 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0),
194};
195
196static const char *max9877_out_mode[] = {
197 "INA -> SPK",
198 "INA -> HP",
199 "INA -> SPK and HP",
200 "INB -> SPK",
201 "INB -> HP",
202 "INB -> SPK and HP",
203 "INA + INB -> SPK",
204 "INA + INB -> HP",
205 "INA + INB -> SPK and HP",
206};
207
208static const char *max9877_osc_mode[] = {
209 "1176KHz",
210 "1100KHz",
211 "700KHz",
212};
213
214static const struct soc_enum max9877_enum[] = {
215 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_out_mode), max9877_out_mode),
216 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max9877_osc_mode), max9877_osc_mode),
217};
218
219static const struct snd_kcontrol_new max9877_controls[] = {
220 SOC_SINGLE_EXT_TLV("MAX9877 PGAINA Playback Volume",
221 MAX9877_INPUT_MODE, 0, 2, 0,
222 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
223 SOC_SINGLE_EXT_TLV("MAX9877 PGAINB Playback Volume",
224 MAX9877_INPUT_MODE, 2, 2, 0,
225 max9877_get_reg, max9877_set_reg, max9877_pgain_tlv),
226 SOC_SINGLE_EXT_TLV("MAX9877 Amp Speaker Playback Volume",
227 MAX9877_SPK_VOLUME, 0, 31, 0,
228 max9877_get_reg, max9877_set_reg, max9877_output_tlv),
229 SOC_DOUBLE_R_EXT_TLV("MAX9877 Amp HP Playback Volume",
230 MAX9877_HPL_VOLUME, MAX9877_HPR_VOLUME, 0, 31, 0,
231 max9877_get_2reg, max9877_set_2reg, max9877_output_tlv),
232 SOC_SINGLE_EXT("MAX9877 INB Stereo Switch",
233 MAX9877_INPUT_MODE, 4, 1, 1,
234 max9877_get_reg, max9877_set_reg),
235 SOC_SINGLE_EXT("MAX9877 INA Stereo Switch",
236 MAX9877_INPUT_MODE, 5, 1, 1,
237 max9877_get_reg, max9877_set_reg),
238 SOC_SINGLE_EXT("MAX9877 Zero-crossing detection Switch",
239 MAX9877_INPUT_MODE, 6, 1, 0,
240 max9877_get_reg, max9877_set_reg),
241 SOC_SINGLE_EXT("MAX9877 Bypass Mode Switch",
242 MAX9877_OUTPUT_MODE, 6, 1, 0,
243 max9877_get_reg, max9877_set_reg),
244 SOC_SINGLE_EXT("MAX9877 Shutdown Mode Switch",
245 MAX9877_OUTPUT_MODE, 7, 1, 1,
246 max9877_get_reg, max9877_set_reg),
247 SOC_ENUM_EXT("MAX9877 Output Mode", max9877_enum[0],
248 max9877_get_out_mode, max9877_set_out_mode),
249 SOC_ENUM_EXT("MAX9877 Oscillator Mode", max9877_enum[1],
250 max9877_get_osc_mode, max9877_set_osc_mode),
251};
252
253/* This function is called from ASoC machine driver */
254int max9877_add_controls(struct snd_soc_codec *codec)
255{
256 return snd_soc_add_controls(codec, max9877_controls,
257 ARRAY_SIZE(max9877_controls));
258}
259EXPORT_SYMBOL_GPL(max9877_add_controls);
260
261static int __devinit max9877_i2c_probe(struct i2c_client *client,
262 const struct i2c_device_id *id)
263{
264 i2c = client;
265
266 max9877_write_regs();
267
268 return 0;
269}
270
271static __devexit int max9877_i2c_remove(struct i2c_client *client)
272{
273 i2c = NULL;
274
275 return 0;
276}
277
278static const struct i2c_device_id max9877_i2c_id[] = {
279 { "max9877", 0 },
280 { }
281};
282MODULE_DEVICE_TABLE(i2c, max9877_i2c_id);
283
284static struct i2c_driver max9877_i2c_driver = {
285 .driver = {
286 .name = "max9877",
287 .owner = THIS_MODULE,
288 },
289 .probe = max9877_i2c_probe,
290 .remove = __devexit_p(max9877_i2c_remove),
291 .id_table = max9877_i2c_id,
292};
293
294static int __init max9877_init(void)
295{
296 return i2c_add_driver(&max9877_i2c_driver);
297}
298module_init(max9877_init);
299
300static void __exit max9877_exit(void)
301{
302 i2c_del_driver(&max9877_i2c_driver);
303}
304module_exit(max9877_exit);
305
306MODULE_DESCRIPTION("ASoC MAX9877 amp driver");
307MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
308MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/max9877.h b/sound/soc/codecs/max9877.h
new file mode 100644
index 000000000000..6da72290ac58
--- /dev/null
+++ b/sound/soc/codecs/max9877.h
@@ -0,0 +1,37 @@
1/*
2 * max9877.h -- amp driver for max9877
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.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
14#ifndef _MAX9877_H
15#define _MAX9877_H
16
17#define MAX9877_INPUT_MODE 0x00
18#define MAX9877_SPK_VOLUME 0x01
19#define MAX9877_HPL_VOLUME 0x02
20#define MAX9877_HPR_VOLUME 0x03
21#define MAX9877_OUTPUT_MODE 0x04
22
23/* MAX9877_INPUT_MODE */
24#define MAX9877_INB (1 << 4)
25#define MAX9877_INA (1 << 5)
26#define MAX9877_ZCD (1 << 6)
27
28/* MAX9877_OUTPUT_MODE */
29#define MAX9877_OUTMODE_MASK (15 << 0)
30#define MAX9877_OSC_MASK (3 << 4)
31#define MAX9877_OSC_OFFSET 4
32#define MAX9877_BYPASS (1 << 6)
33#define MAX9877_SHDN (1 << 7)
34
35extern int max9877_add_controls(struct snd_soc_codec *codec);
36
37#endif
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c
index 218b33adad90..a63191141052 100644
--- a/sound/soc/codecs/spdif_transciever.c
+++ b/sound/soc/codecs/spdif_transciever.c
@@ -21,6 +21,8 @@
21 21
22#include "spdif_transciever.h" 22#include "spdif_transciever.h"
23 23
24MODULE_LICENSE("GPL");
25
24#define STUB_RATES SNDRV_PCM_RATE_8000_96000 26#define STUB_RATES SNDRV_PCM_RATE_8000_96000
25#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE 27#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE
26 28
@@ -34,6 +36,7 @@ struct snd_soc_dai dit_stub_dai = {
34 .formats = STUB_FORMATS, 36 .formats = STUB_FORMATS,
35 }, 37 },
36}; 38};
39EXPORT_SYMBOL_GPL(dit_stub_dai);
37 40
38static int spdif_dit_probe(struct platform_device *pdev) 41static int spdif_dit_probe(struct platform_device *pdev)
39{ 42{
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 8ad4b7b3e3ba..befc6488c39a 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -149,7 +149,7 @@ static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg,
149 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 149 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
150 return 0; 150 return 0;
151 } 151 }
152 if (reg / 2 > ARRAY_SIZE(stac9766_reg)) 152 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
153 return -EIO; 153 return -EIO;
154 154
155 soc_ac97_ops.write(codec->ac97, reg, val); 155 soc_ac97_ops.write(codec->ac97, reg, val);
@@ -168,7 +168,7 @@ static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec,
168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1); 168 stac9766_ac97_write(codec, AC97_INT_PAGING, 1);
169 return val; 169 return val;
170 } 170 }
171 if (reg / 2 > ARRAY_SIZE(stac9766_reg)) 171 if (reg / 2 >= ARRAY_SIZE(stac9766_reg))
172 return -EIO; 172 return -EIO;
173 173
174 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || 174 if (reg == AC97_RESET || reg == AC97_GPIO_STATUS ||
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index cb0d1bf34b57..3395cf945d56 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -53,6 +53,7 @@
53 53
54/* codec private data */ 54/* codec private data */
55struct aic3x_priv { 55struct aic3x_priv {
56 struct snd_soc_codec codec;
56 unsigned int sysclk; 57 unsigned int sysclk;
57 int master; 58 int master;
58}; 59};
@@ -145,8 +146,8 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg,
145 u8 *value) 146 u8 *value)
146{ 147{
147 *value = reg & 0xff; 148 *value = reg & 0xff;
148 if (codec->hw_read(codec->control_data, value, 1) != 1) 149
149 return -EIO; 150 value[0] = i2c_smbus_read_byte_data(codec->control_data, value[0]);
150 151
151 aic3x_write_reg_cache(codec, reg, *value); 152 aic3x_write_reg_cache(codec, reg, *value);
152 return 0; 153 return 0;
@@ -1156,11 +1157,13 @@ static int aic3x_resume(struct platform_device *pdev)
1156 * initialise the AIC3X driver 1157 * initialise the AIC3X driver
1157 * register the mixer and dsp interfaces with the kernel 1158 * register the mixer and dsp interfaces with the kernel
1158 */ 1159 */
1159static int aic3x_init(struct snd_soc_device *socdev) 1160static int aic3x_init(struct snd_soc_codec *codec)
1160{ 1161{
1161 struct snd_soc_codec *codec = socdev->card->codec; 1162 int reg;
1162 struct aic3x_setup_data *setup = socdev->codec_data; 1163
1163 int reg, ret = 0; 1164 mutex_init(&codec->mutex);
1165 INIT_LIST_HEAD(&codec->dapm_widgets);
1166 INIT_LIST_HEAD(&codec->dapm_paths);
1164 1167
1165 codec->name = "tlv320aic3x"; 1168 codec->name = "tlv320aic3x";
1166 codec->owner = THIS_MODULE; 1169 codec->owner = THIS_MODULE;
@@ -1177,13 +1180,6 @@ static int aic3x_init(struct snd_soc_device *socdev)
1177 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT); 1180 aic3x_write(codec, AIC3X_PAGE_SELECT, PAGE0_SELECT);
1178 aic3x_write(codec, AIC3X_RESET, SOFT_RESET); 1181 aic3x_write(codec, AIC3X_RESET, SOFT_RESET);
1179 1182
1180 /* register pcms */
1181 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1182 if (ret < 0) {
1183 printk(KERN_ERR "aic3x: failed to create pcms\n");
1184 goto pcm_err;
1185 }
1186
1187 /* DAC default volume and mute */ 1183 /* DAC default volume and mute */
1188 aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON); 1184 aic3x_write(codec, LDAC_VOL, DEFAULT_VOL | MUTE_ON);
1189 aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON); 1185 aic3x_write(codec, RDAC_VOL, DEFAULT_VOL | MUTE_ON);
@@ -1250,30 +1246,51 @@ static int aic3x_init(struct snd_soc_device *socdev)
1250 /* off, with power on */ 1246 /* off, with power on */
1251 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1247 aic3x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1252 1248
1253 /* setup GPIO functions */ 1249 return 0;
1254 aic3x_write(codec, AIC3X_GPIO1_REG, (setup->gpio_func[0] & 0xf) << 4); 1250}
1255 aic3x_write(codec, AIC3X_GPIO2_REG, (setup->gpio_func[1] & 0xf) << 4);
1256 1251
1257 snd_soc_add_controls(codec, aic3x_snd_controls, 1252static struct snd_soc_codec *aic3x_codec;
1258 ARRAY_SIZE(aic3x_snd_controls)); 1253
1259 aic3x_add_widgets(codec); 1254static int aic3x_register(struct snd_soc_codec *codec)
1260 ret = snd_soc_init_card(socdev); 1255{
1256 int ret;
1257
1258 ret = aic3x_init(codec);
1261 if (ret < 0) { 1259 if (ret < 0) {
1262 printk(KERN_ERR "aic3x: failed to register card\n"); 1260 dev_err(codec->dev, "Failed to initialise device\n");
1263 goto card_err; 1261 return ret;
1264 } 1262 }
1265 1263
1266 return ret; 1264 aic3x_codec = codec;
1267 1265
1268card_err: 1266 ret = snd_soc_register_codec(codec);
1269 snd_soc_free_pcms(socdev); 1267 if (ret) {
1270 snd_soc_dapm_free(socdev); 1268 dev_err(codec->dev, "Failed to register codec\n");
1271pcm_err: 1269 return ret;
1272 kfree(codec->reg_cache); 1270 }
1273 return ret; 1271
1272 ret = snd_soc_register_dai(&aic3x_dai);
1273 if (ret) {
1274 dev_err(codec->dev, "Failed to register dai\n");
1275 snd_soc_unregister_codec(codec);
1276 return ret;
1277 }
1278
1279 return 0;
1274} 1280}
1275 1281
1276static struct snd_soc_device *aic3x_socdev; 1282static int aic3x_unregister(struct aic3x_priv *aic3x)
1283{
1284 aic3x_set_bias_level(&aic3x->codec, SND_SOC_BIAS_OFF);
1285
1286 snd_soc_unregister_dai(&aic3x_dai);
1287 snd_soc_unregister_codec(&aic3x->codec);
1288
1289 kfree(aic3x);
1290 aic3x_codec = NULL;
1291
1292 return 0;
1293}
1277 1294
1278#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1295#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1279/* 1296/*
@@ -1288,28 +1305,36 @@ static struct snd_soc_device *aic3x_socdev;
1288static int aic3x_i2c_probe(struct i2c_client *i2c, 1305static int aic3x_i2c_probe(struct i2c_client *i2c,
1289 const struct i2c_device_id *id) 1306 const struct i2c_device_id *id)
1290{ 1307{
1291 struct snd_soc_device *socdev = aic3x_socdev; 1308 struct snd_soc_codec *codec;
1292 struct snd_soc_codec *codec = socdev->card->codec; 1309 struct aic3x_priv *aic3x;
1293 int ret;
1294 1310
1295 i2c_set_clientdata(i2c, codec); 1311 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL);
1312 if (aic3x == NULL) {
1313 dev_err(&i2c->dev, "failed to create private data\n");
1314 return -ENOMEM;
1315 }
1316
1317 codec = &aic3x->codec;
1318 codec->dev = &i2c->dev;
1319 codec->private_data = aic3x;
1296 codec->control_data = i2c; 1320 codec->control_data = i2c;
1321 codec->hw_write = (hw_write_t) i2c_master_send;
1297 1322
1298 ret = aic3x_init(socdev); 1323 i2c_set_clientdata(i2c, aic3x);
1299 if (ret < 0) 1324
1300 printk(KERN_ERR "aic3x: failed to initialise AIC3X\n"); 1325 return aic3x_register(codec);
1301 return ret;
1302} 1326}
1303 1327
1304static int aic3x_i2c_remove(struct i2c_client *client) 1328static int aic3x_i2c_remove(struct i2c_client *client)
1305{ 1329{
1306 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1330 struct aic3x_priv *aic3x = i2c_get_clientdata(client);
1307 kfree(codec->reg_cache); 1331
1308 return 0; 1332 return aic3x_unregister(aic3x);
1309} 1333}
1310 1334
1311static const struct i2c_device_id aic3x_i2c_id[] = { 1335static const struct i2c_device_id aic3x_i2c_id[] = {
1312 { "tlv320aic3x", 0 }, 1336 { "tlv320aic3x", 0 },
1337 { "tlv320aic33", 0 },
1313 { } 1338 { }
1314}; 1339};
1315MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); 1340MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
@@ -1320,56 +1345,28 @@ static struct i2c_driver aic3x_i2c_driver = {
1320 .name = "aic3x I2C Codec", 1345 .name = "aic3x I2C Codec",
1321 .owner = THIS_MODULE, 1346 .owner = THIS_MODULE,
1322 }, 1347 },
1323 .probe = aic3x_i2c_probe, 1348 .probe = aic3x_i2c_probe,
1324 .remove = aic3x_i2c_remove, 1349 .remove = aic3x_i2c_remove,
1325 .id_table = aic3x_i2c_id, 1350 .id_table = aic3x_i2c_id,
1326}; 1351};
1327 1352
1328static int aic3x_i2c_read(struct i2c_client *client, u8 *value, int len) 1353static inline void aic3x_i2c_init(void)
1329{ 1354{
1330 value[0] = i2c_smbus_read_byte_data(client, value[0]);
1331 return (len == 1);
1332}
1333
1334static int aic3x_add_i2c_device(struct platform_device *pdev,
1335 const struct aic3x_setup_data *setup)
1336{
1337 struct i2c_board_info info;
1338 struct i2c_adapter *adapter;
1339 struct i2c_client *client;
1340 int ret; 1355 int ret;
1341 1356
1342 ret = i2c_add_driver(&aic3x_i2c_driver); 1357 ret = i2c_add_driver(&aic3x_i2c_driver);
1343 if (ret != 0) { 1358 if (ret)
1344 dev_err(&pdev->dev, "can't add i2c driver\n"); 1359 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1345 return ret; 1360 __func__, ret);
1346 } 1361}
1347
1348 memset(&info, 0, sizeof(struct i2c_board_info));
1349 info.addr = setup->i2c_address;
1350 strlcpy(info.type, "tlv320aic3x", I2C_NAME_SIZE);
1351
1352 adapter = i2c_get_adapter(setup->i2c_bus);
1353 if (!adapter) {
1354 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
1355 setup->i2c_bus);
1356 goto err_driver;
1357 }
1358
1359 client = i2c_new_device(adapter, &info);
1360 i2c_put_adapter(adapter);
1361 if (!client) {
1362 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
1363 (unsigned int)info.addr);
1364 goto err_driver;
1365 }
1366
1367 return 0;
1368 1362
1369err_driver: 1363static inline void aic3x_i2c_exit(void)
1364{
1370 i2c_del_driver(&aic3x_i2c_driver); 1365 i2c_del_driver(&aic3x_i2c_driver);
1371 return -ENODEV;
1372} 1366}
1367#else
1368static inline void aic3x_i2c_init(void) { }
1369static inline void aic3x_i2c_exit(void) { }
1373#endif 1370#endif
1374 1371
1375static int aic3x_probe(struct platform_device *pdev) 1372static int aic3x_probe(struct platform_device *pdev)
@@ -1377,43 +1374,51 @@ static int aic3x_probe(struct platform_device *pdev)
1377 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1374 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1378 struct aic3x_setup_data *setup; 1375 struct aic3x_setup_data *setup;
1379 struct snd_soc_codec *codec; 1376 struct snd_soc_codec *codec;
1380 struct aic3x_priv *aic3x;
1381 int ret = 0; 1377 int ret = 0;
1382 1378
1383 printk(KERN_INFO "AIC3X Audio Codec %s\n", AIC3X_VERSION); 1379 codec = aic3x_codec;
1380 if (!codec) {
1381 dev_err(&pdev->dev, "Codec not registered\n");
1382 return -ENODEV;
1383 }
1384 1384
1385 socdev->card->codec = codec;
1385 setup = socdev->codec_data; 1386 setup = socdev->codec_data;
1386 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1387 if (codec == NULL)
1388 return -ENOMEM;
1389 1387
1390 aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); 1388 if (setup) {
1391 if (aic3x == NULL) { 1389 /* setup GPIO functions */
1392 kfree(codec); 1390 aic3x_write(codec, AIC3X_GPIO1_REG,
1393 return -ENOMEM; 1391 (setup->gpio_func[0] & 0xf) << 4);
1392 aic3x_write(codec, AIC3X_GPIO2_REG,
1393 (setup->gpio_func[1] & 0xf) << 4);
1394 } 1394 }
1395 1395
1396 codec->private_data = aic3x; 1396 /* register pcms */
1397 socdev->card->codec = codec; 1397 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1398 mutex_init(&codec->mutex); 1398 if (ret < 0) {
1399 INIT_LIST_HEAD(&codec->dapm_widgets); 1399 printk(KERN_ERR "aic3x: failed to create pcms\n");
1400 INIT_LIST_HEAD(&codec->dapm_paths); 1400 goto pcm_err;
1401
1402 aic3x_socdev = socdev;
1403#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1404 if (setup->i2c_address) {
1405 codec->hw_write = (hw_write_t) i2c_master_send;
1406 codec->hw_read = (hw_read_t) aic3x_i2c_read;
1407 ret = aic3x_add_i2c_device(pdev, setup);
1408 } 1401 }
1409#else
1410 /* Add other interfaces here */
1411#endif
1412 1402
1413 if (ret != 0) { 1403 snd_soc_add_controls(codec, aic3x_snd_controls,
1414 kfree(codec->private_data); 1404 ARRAY_SIZE(aic3x_snd_controls));
1415 kfree(codec); 1405
1406 aic3x_add_widgets(codec);
1407
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1416 } 1412 }
1413
1414 return ret;
1415
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err:
1421 kfree(codec->reg_cache);
1417 return ret; 1422 return ret;
1418} 1423}
1419 1424
@@ -1428,12 +1433,8 @@ static int aic3x_remove(struct platform_device *pdev)
1428 1433
1429 snd_soc_free_pcms(socdev); 1434 snd_soc_free_pcms(socdev);
1430 snd_soc_dapm_free(socdev); 1435 snd_soc_dapm_free(socdev);
1431#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1436
1432 i2c_unregister_device(codec->control_data); 1437 kfree(codec->reg_cache);
1433 i2c_del_driver(&aic3x_i2c_driver);
1434#endif
1435 kfree(codec->private_data);
1436 kfree(codec);
1437 1438
1438 return 0; 1439 return 0;
1439} 1440}
@@ -1448,13 +1449,15 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1448 1449
1449static int __init aic3x_modinit(void) 1450static int __init aic3x_modinit(void)
1450{ 1451{
1451 return snd_soc_register_dai(&aic3x_dai); 1452 aic3x_i2c_init();
1453
1454 return 0;
1452} 1455}
1453module_init(aic3x_modinit); 1456module_init(aic3x_modinit);
1454 1457
1455static void __exit aic3x_exit(void) 1458static void __exit aic3x_exit(void)
1456{ 1459{
1457 snd_soc_unregister_dai(&aic3x_dai); 1460 aic3x_i2c_exit();
1458} 1461}
1459module_exit(aic3x_exit); 1462module_exit(aic3x_exit);
1460 1463
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index ac827e578c4d..9af1c886213c 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -282,8 +282,6 @@ int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec); 282int aic3x_button_pressed(struct snd_soc_codec *codec);
283 283
284struct aic3x_setup_data { 284struct aic3x_setup_data {
285 int i2c_bus;
286 unsigned short i2c_address;
287 unsigned int gpio_func[2]; 285 unsigned int gpio_func[2];
288}; 286};
289 287
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4dbb853eef5a..4df7c6c61c76 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -225,55 +225,11 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute)
225 return; 225 return;
226 226
227 if (mute) { 227 if (mute) {
228 /* Bypass the reg_cache and mute the volumes
229 * Headset mute is done in it's own event handler
230 * Things to mute: Earpiece, PreDrivL/R, CarkitL/R
231 */
232 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL);
233 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
234 reg_val & (~TWL4030_EAR_GAIN),
235 TWL4030_REG_EAR_CTL);
236
237 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL);
238 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
239 reg_val & (~TWL4030_PREDL_GAIN),
240 TWL4030_REG_PREDL_CTL);
241 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL);
242 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
243 reg_val & (~TWL4030_PREDR_GAIN),
244 TWL4030_REG_PREDL_CTL);
245
246 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL);
247 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
248 reg_val & (~TWL4030_PRECKL_GAIN),
249 TWL4030_REG_PRECKL_CTL);
250 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL);
251 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
252 reg_val & (~TWL4030_PRECKR_GAIN),
253 TWL4030_REG_PRECKR_CTL);
254
255 /* Disable PLL */ 228 /* Disable PLL */
256 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
257 reg_val &= ~TWL4030_APLL_EN; 230 reg_val &= ~TWL4030_APLL_EN;
258 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
259 } else { 232 } else {
260 /* Restore the volumes
261 * Headset mute is done in it's own event handler
262 * Things to restore: Earpiece, PreDrivL/R, CarkitL/R
263 */
264 twl4030_write(codec, TWL4030_REG_EAR_CTL,
265 twl4030_read_reg_cache(codec, TWL4030_REG_EAR_CTL));
266
267 twl4030_write(codec, TWL4030_REG_PREDL_CTL,
268 twl4030_read_reg_cache(codec, TWL4030_REG_PREDL_CTL));
269 twl4030_write(codec, TWL4030_REG_PREDR_CTL,
270 twl4030_read_reg_cache(codec, TWL4030_REG_PREDR_CTL));
271
272 twl4030_write(codec, TWL4030_REG_PRECKL_CTL,
273 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKL_CTL));
274 twl4030_write(codec, TWL4030_REG_PRECKR_CTL,
275 twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL));
276
277 /* Enable PLL */ 233 /* Enable PLL */
278 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
279 reg_val |= TWL4030_APLL_EN; 235 reg_val |= TWL4030_APLL_EN;
@@ -443,16 +399,20 @@ SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum);
443 399
444/* Left analog microphone selection */ 400/* Left analog microphone selection */
445static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = { 401static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = {
446 SOC_DAPM_SINGLE("Main mic", TWL4030_REG_ANAMICL, 0, 1, 0), 402 SOC_DAPM_SINGLE("Main Mic Capture Switch",
447 SOC_DAPM_SINGLE("Headset mic", TWL4030_REG_ANAMICL, 1, 1, 0), 403 TWL4030_REG_ANAMICL, 0, 1, 0),
448 SOC_DAPM_SINGLE("AUXL", TWL4030_REG_ANAMICL, 2, 1, 0), 404 SOC_DAPM_SINGLE("Headset Mic Capture Switch",
449 SOC_DAPM_SINGLE("Carkit mic", TWL4030_REG_ANAMICL, 3, 1, 0), 405 TWL4030_REG_ANAMICL, 1, 1, 0),
406 SOC_DAPM_SINGLE("AUXL Capture Switch",
407 TWL4030_REG_ANAMICL, 2, 1, 0),
408 SOC_DAPM_SINGLE("Carkit Mic Capture Switch",
409 TWL4030_REG_ANAMICL, 3, 1, 0),
450}; 410};
451 411
452/* Right analog microphone selection */ 412/* Right analog microphone selection */
453static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = { 413static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = {
454 SOC_DAPM_SINGLE("Sub mic", TWL4030_REG_ANAMICR, 0, 1, 0), 414 SOC_DAPM_SINGLE("Sub Mic Capture Switch", TWL4030_REG_ANAMICR, 0, 1, 0),
455 SOC_DAPM_SINGLE("AUXR", TWL4030_REG_ANAMICR, 2, 1, 0), 415 SOC_DAPM_SINGLE("AUXR Capture Switch", TWL4030_REG_ANAMICR, 2, 1, 0),
456}; 416};
457 417
458/* TX1 L/R Analog/Digital microphone selection */ 418/* TX1 L/R Analog/Digital microphone selection */
@@ -560,6 +520,41 @@ static int micpath_event(struct snd_soc_dapm_widget *w,
560 return 0; 520 return 0;
561} 521}
562 522
523/*
524 * Output PGA builder:
525 * Handle the muting and unmuting of the given output (turning off the
526 * amplifier associated with the output pin)
527 * On mute bypass the reg_cache and mute the volume
528 * On unmute: restore the register content
529 * Outputs handled in this way: Earpiece, PreDrivL/R, CarkitL/R
530 */
531#define TWL4030_OUTPUT_PGA(pin_name, reg, mask) \
532static int pin_name##pga_event(struct snd_soc_dapm_widget *w, \
533 struct snd_kcontrol *kcontrol, int event) \
534{ \
535 u8 reg_val; \
536 \
537 switch (event) { \
538 case SND_SOC_DAPM_POST_PMU: \
539 twl4030_write(w->codec, reg, \
540 twl4030_read_reg_cache(w->codec, reg)); \
541 break; \
542 case SND_SOC_DAPM_POST_PMD: \
543 reg_val = twl4030_read_reg_cache(w->codec, reg); \
544 twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, \
545 reg_val & (~mask), \
546 reg); \
547 break; \
548 } \
549 return 0; \
550}
551
552TWL4030_OUTPUT_PGA(earpiece, TWL4030_REG_EAR_CTL, TWL4030_EAR_GAIN);
553TWL4030_OUTPUT_PGA(predrivel, TWL4030_REG_PREDL_CTL, TWL4030_PREDL_GAIN);
554TWL4030_OUTPUT_PGA(predriver, TWL4030_REG_PREDR_CTL, TWL4030_PREDR_GAIN);
555TWL4030_OUTPUT_PGA(carkitl, TWL4030_REG_PRECKL_CTL, TWL4030_PRECKL_GAIN);
556TWL4030_OUTPUT_PGA(carkitr, TWL4030_REG_PRECKR_CTL, TWL4030_PRECKR_GAIN);
557
563static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) 558static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp)
564{ 559{
565 unsigned char hs_ctl; 560 unsigned char hs_ctl;
@@ -620,6 +615,9 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
620 615
621static void headset_ramp(struct snd_soc_codec *codec, int ramp) 616static void headset_ramp(struct snd_soc_codec *codec, int ramp)
622{ 617{
618 struct snd_soc_device *socdev = codec->socdev;
619 struct twl4030_setup_data *setup = socdev->codec_data;
620
623 unsigned char hs_gain, hs_pop; 621 unsigned char hs_gain, hs_pop;
624 struct twl4030_priv *twl4030 = codec->private_data; 622 struct twl4030_priv *twl4030 = codec->private_data;
625 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 623 /* Base values for ramp delay calculation: 2^19 - 2^26 */
@@ -629,6 +627,17 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
629 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 627 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
630 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 628 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
631 629
630 /* Enable external mute control, this dramatically reduces
631 * the pop-noise */
632 if (setup && setup->hs_extmute) {
633 if (setup->set_hs_extmute) {
634 setup->set_hs_extmute(1);
635 } else {
636 hs_pop |= TWL4030_EXTMUTE;
637 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
638 }
639 }
640
632 if (ramp) { 641 if (ramp) {
633 /* Headset ramp-up according to the TRM */ 642 /* Headset ramp-up according to the TRM */
634 hs_pop |= TWL4030_VMID_EN; 643 hs_pop |= TWL4030_VMID_EN;
@@ -636,6 +645,9 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
636 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); 645 twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain);
637 hs_pop |= TWL4030_RAMP_EN; 646 hs_pop |= TWL4030_RAMP_EN;
638 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 647 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
648 /* Wait ramp delay time + 1, so the VMID can settle */
649 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
650 twl4030->sysclk) + 1);
639 } else { 651 } else {
640 /* Headset ramp-down _not_ according to 652 /* Headset ramp-down _not_ according to
641 * the TRM, but in a way that it is working */ 653 * the TRM, but in a way that it is working */
@@ -652,6 +664,16 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
652 hs_pop &= ~TWL4030_VMID_EN; 664 hs_pop &= ~TWL4030_VMID_EN;
653 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 665 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
654 } 666 }
667
668 /* Disable external mute */
669 if (setup && setup->hs_extmute) {
670 if (setup->set_hs_extmute) {
671 setup->set_hs_extmute(0);
672 } else {
673 hs_pop &= ~TWL4030_EXTMUTE;
674 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
675 }
676 }
655} 677}
656 678
657static int headsetlpga_event(struct snd_soc_dapm_widget *w, 679static int headsetlpga_event(struct snd_soc_dapm_widget *w,
@@ -712,7 +734,19 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
712 734
713 reg = twl4030_read_reg_cache(w->codec, m->reg); 735 reg = twl4030_read_reg_cache(w->codec, m->reg);
714 736
715 if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) { 737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
716 /* Analog bypass */ 750 /* Analog bypass */
717 if (reg & (1 << m->shift)) 751 if (reg & (1 << m->shift))
718 twl4030->bypass_state |= 752 twl4030->bypass_state |=
@@ -726,12 +760,6 @@ static int bypass_event(struct snd_soc_dapm_widget *w,
726 twl4030->bypass_state |= (1 << 4); 760 twl4030->bypass_state |= (1 << 4);
727 else 761 else
728 twl4030->bypass_state &= ~(1 << 4); 762 twl4030->bypass_state &= ~(1 << 4);
729 } else if (m->reg == TWL4030_REG_VSTPGA) {
730 /* Voice digital bypass */
731 if (reg)
732 twl4030->bypass_state |= (1 << 5);
733 else
734 twl4030->bypass_state &= ~(1 << 5);
735 } else { 763 } else {
736 /* Digital bypass */ 764 /* Digital bypass */
737 if (reg & (0x7 << m->shift)) 765 if (reg & (0x7 << m->shift))
@@ -924,7 +952,7 @@ static const struct soc_enum twl4030_op_modes_enum =
924 ARRAY_SIZE(twl4030_op_modes_texts), 952 ARRAY_SIZE(twl4030_op_modes_texts),
925 twl4030_op_modes_texts); 953 twl4030_op_modes_texts);
926 954
927int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, 955static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol,
928 struct snd_ctl_elem_value *ucontrol) 956 struct snd_ctl_elem_value *ucontrol)
929{ 957{
930 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 958 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -1005,6 +1033,16 @@ static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
1005 */ 1033 */
1006static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0); 1034static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
1007 1035
1036/* AVADC clock priority */
1037static const char *twl4030_avadc_clk_priority_texts[] = {
1038 "Voice high priority", "HiFi high priority"
1039};
1040
1041static const struct soc_enum twl4030_avadc_clk_priority_enum =
1042 SOC_ENUM_SINGLE(TWL4030_REG_AVADC_CTL, 2,
1043 ARRAY_SIZE(twl4030_avadc_clk_priority_texts),
1044 twl4030_avadc_clk_priority_texts);
1045
1008static const char *twl4030_rampdelay_texts[] = { 1046static const char *twl4030_rampdelay_texts[] = {
1009 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms", 1047 "27/20/14 ms", "55/40/27 ms", "109/81/55 ms", "218/161/109 ms",
1010 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms", 1048 "437/323/218 ms", "874/645/437 ms", "1748/1291/874 ms",
@@ -1106,6 +1144,8 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = {
1106 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN, 1144 SOC_DOUBLE_TLV("Analog Capture Volume", TWL4030_REG_ANAMIC_GAIN,
1107 0, 3, 5, 0, input_gain_tlv), 1145 0, 3, 5, 0, input_gain_tlv),
1108 1146
1147 SOC_ENUM("AVADC Clock Priority", twl4030_avadc_clk_priority_enum),
1148
1109 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), 1149 SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum),
1110 1150
1111 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), 1151 SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum),
@@ -1208,13 +1248,22 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
1209 &twl4030_dapm_earpiece_controls[0], 1249 &twl4030_dapm_earpiece_controls[0],
1210 ARRAY_SIZE(twl4030_dapm_earpiece_controls)), 1250 ARRAY_SIZE(twl4030_dapm_earpiece_controls)),
1251 SND_SOC_DAPM_PGA_E("Earpiece PGA", SND_SOC_NOPM,
1252 0, 0, NULL, 0, earpiecepga_event,
1253 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1211 /* PreDrivL/R */ 1254 /* PreDrivL/R */
1212 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, 1255 SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_predrivel_controls[0], 1256 &twl4030_dapm_predrivel_controls[0],
1214 ARRAY_SIZE(twl4030_dapm_predrivel_controls)), 1257 ARRAY_SIZE(twl4030_dapm_predrivel_controls)),
1258 SND_SOC_DAPM_PGA_E("PredriveL PGA", SND_SOC_NOPM,
1259 0, 0, NULL, 0, predrivelpga_event,
1260 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1215 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, 1261 SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0,
1216 &twl4030_dapm_predriver_controls[0], 1262 &twl4030_dapm_predriver_controls[0],
1217 ARRAY_SIZE(twl4030_dapm_predriver_controls)), 1263 ARRAY_SIZE(twl4030_dapm_predriver_controls)),
1264 SND_SOC_DAPM_PGA_E("PredriveR PGA", SND_SOC_NOPM,
1265 0, 0, NULL, 0, predriverpga_event,
1266 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1218 /* HeadsetL/R */ 1267 /* HeadsetL/R */
1219 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, 1268 SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0,
1220 &twl4030_dapm_hsol_controls[0], 1269 &twl4030_dapm_hsol_controls[0],
@@ -1232,22 +1281,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1232 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, 1281 SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0,
1233 &twl4030_dapm_carkitl_controls[0], 1282 &twl4030_dapm_carkitl_controls[0],
1234 ARRAY_SIZE(twl4030_dapm_carkitl_controls)), 1283 ARRAY_SIZE(twl4030_dapm_carkitl_controls)),
1284 SND_SOC_DAPM_PGA_E("CarkitL PGA", SND_SOC_NOPM,
1285 0, 0, NULL, 0, carkitlpga_event,
1286 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1235 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, 1287 SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0,
1236 &twl4030_dapm_carkitr_controls[0], 1288 &twl4030_dapm_carkitr_controls[0],
1237 ARRAY_SIZE(twl4030_dapm_carkitr_controls)), 1289 ARRAY_SIZE(twl4030_dapm_carkitr_controls)),
1290 SND_SOC_DAPM_PGA_E("CarkitR PGA", SND_SOC_NOPM,
1291 0, 0, NULL, 0, carkitrpga_event,
1292 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1238 1293
1239 /* Output MUX controls */ 1294 /* Output MUX controls */
1240 /* HandsfreeL/R */ 1295 /* HandsfreeL/R */
1241 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0, 1296 SND_SOC_DAPM_MUX("HandsfreeL Mux", SND_SOC_NOPM, 0, 0,
1242 &twl4030_dapm_handsfreel_control), 1297 &twl4030_dapm_handsfreel_control),
1243 SND_SOC_DAPM_SWITCH("HandsfreeL Switch", SND_SOC_NOPM, 0, 0, 1298 SND_SOC_DAPM_SWITCH("HandsfreeL", SND_SOC_NOPM, 0, 0,
1244 &twl4030_dapm_handsfreelmute_control), 1299 &twl4030_dapm_handsfreelmute_control),
1245 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM, 1300 SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM,
1246 0, 0, NULL, 0, handsfreelpga_event, 1301 0, 0, NULL, 0, handsfreelpga_event,
1247 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1302 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1248 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0, 1303 SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0,
1249 &twl4030_dapm_handsfreer_control), 1304 &twl4030_dapm_handsfreer_control),
1250 SND_SOC_DAPM_SWITCH("HandsfreeR Switch", SND_SOC_NOPM, 0, 0, 1305 SND_SOC_DAPM_SWITCH("HandsfreeR", SND_SOC_NOPM, 0, 0,
1251 &twl4030_dapm_handsfreermute_control), 1306 &twl4030_dapm_handsfreermute_control),
1252 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM, 1307 SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM,
1253 0, 0, NULL, 0, handsfreerpga_event, 1308 0, 0, NULL, 0, handsfreerpga_event,
@@ -1282,11 +1337,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1282 SND_SOC_DAPM_POST_REG), 1337 SND_SOC_DAPM_POST_REG),
1283 1338
1284 /* Analog input mixers for the capture amplifiers */ 1339 /* Analog input mixers for the capture amplifiers */
1285 SND_SOC_DAPM_MIXER("Analog Left Capture Route", 1340 SND_SOC_DAPM_MIXER("Analog Left",
1286 TWL4030_REG_ANAMICL, 4, 0, 1341 TWL4030_REG_ANAMICL, 4, 0,
1287 &twl4030_dapm_analoglmic_controls[0], 1342 &twl4030_dapm_analoglmic_controls[0],
1288 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)), 1343 ARRAY_SIZE(twl4030_dapm_analoglmic_controls)),
1289 SND_SOC_DAPM_MIXER("Analog Right Capture Route", 1344 SND_SOC_DAPM_MIXER("Analog Right",
1290 TWL4030_REG_ANAMICR, 4, 0, 1345 TWL4030_REG_ANAMICR, 4, 0,
1291 &twl4030_dapm_analogrmic_controls[0], 1346 &twl4030_dapm_analogrmic_controls[0],
1292 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)), 1347 ARRAY_SIZE(twl4030_dapm_analogrmic_controls)),
@@ -1326,16 +1381,19 @@ static const struct snd_soc_dapm_route intercon[] = {
1326 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1381 {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1327 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1382 {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1328 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1383 {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1384 {"Earpiece PGA", NULL, "Earpiece Mixer"},
1329 /* PreDrivL */ 1385 /* PreDrivL */
1330 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1386 {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"},
1331 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1387 {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1332 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1388 {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1333 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1389 {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1390 {"PredriveL PGA", NULL, "PredriveL Mixer"},
1334 /* PreDrivR */ 1391 /* PreDrivR */
1335 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1392 {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"},
1336 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1393 {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1337 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1394 {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1338 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1395 {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1396 {"PredriveR PGA", NULL, "PredriveR Mixer"},
1339 /* HeadsetL */ 1397 /* HeadsetL */
1340 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1398 {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"},
1341 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1399 {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
@@ -1350,24 +1408,26 @@ static const struct snd_soc_dapm_route intercon[] = {
1350 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"}, 1408 {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"},
1351 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, 1409 {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"},
1352 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, 1410 {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"},
1411 {"CarkitL PGA", NULL, "CarkitL Mixer"},
1353 /* CarkitR */ 1412 /* CarkitR */
1354 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"}, 1413 {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"},
1355 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, 1414 {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"},
1356 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, 1415 {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"},
1416 {"CarkitR PGA", NULL, "CarkitR Mixer"},
1357 /* HandsfreeL */ 1417 /* HandsfreeL */
1358 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"}, 1418 {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"},
1359 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"}, 1419 {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"},
1360 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1420 {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"},
1361 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1421 {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"},
1362 {"HandsfreeL Switch", "Switch", "HandsfreeL Mux"}, 1422 {"HandsfreeL", "Switch", "HandsfreeL Mux"},
1363 {"HandsfreeL PGA", NULL, "HandsfreeL Switch"}, 1423 {"HandsfreeL PGA", NULL, "HandsfreeL"},
1364 /* HandsfreeR */ 1424 /* HandsfreeR */
1365 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"}, 1425 {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"},
1366 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"}, 1426 {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"},
1367 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"}, 1427 {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"},
1368 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"}, 1428 {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"},
1369 {"HandsfreeR Switch", "Switch", "HandsfreeR Mux"}, 1429 {"HandsfreeR", "Switch", "HandsfreeR Mux"},
1370 {"HandsfreeR PGA", NULL, "HandsfreeR Switch"}, 1430 {"HandsfreeR PGA", NULL, "HandsfreeR"},
1371 /* Vibra */ 1431 /* Vibra */
1372 {"Vibra Mux", "AudioL1", "DAC Left1"}, 1432 {"Vibra Mux", "AudioL1", "DAC Left1"},
1373 {"Vibra Mux", "AudioR1", "DAC Right1"}, 1433 {"Vibra Mux", "AudioR1", "DAC Right1"},
@@ -1377,29 +1437,29 @@ static const struct snd_soc_dapm_route intercon[] = {
1377 /* outputs */ 1437 /* outputs */
1378 {"OUTL", NULL, "Analog L2 Playback Mixer"}, 1438 {"OUTL", NULL, "Analog L2 Playback Mixer"},
1379 {"OUTR", NULL, "Analog R2 Playback Mixer"}, 1439 {"OUTR", NULL, "Analog R2 Playback Mixer"},
1380 {"EARPIECE", NULL, "Earpiece Mixer"}, 1440 {"EARPIECE", NULL, "Earpiece PGA"},
1381 {"PREDRIVEL", NULL, "PredriveL Mixer"}, 1441 {"PREDRIVEL", NULL, "PredriveL PGA"},
1382 {"PREDRIVER", NULL, "PredriveR Mixer"}, 1442 {"PREDRIVER", NULL, "PredriveR PGA"},
1383 {"HSOL", NULL, "HeadsetL PGA"}, 1443 {"HSOL", NULL, "HeadsetL PGA"},
1384 {"HSOR", NULL, "HeadsetR PGA"}, 1444 {"HSOR", NULL, "HeadsetR PGA"},
1385 {"CARKITL", NULL, "CarkitL Mixer"}, 1445 {"CARKITL", NULL, "CarkitL PGA"},
1386 {"CARKITR", NULL, "CarkitR Mixer"}, 1446 {"CARKITR", NULL, "CarkitR PGA"},
1387 {"HFL", NULL, "HandsfreeL PGA"}, 1447 {"HFL", NULL, "HandsfreeL PGA"},
1388 {"HFR", NULL, "HandsfreeR PGA"}, 1448 {"HFR", NULL, "HandsfreeR PGA"},
1389 {"Vibra Route", "Audio", "Vibra Mux"}, 1449 {"Vibra Route", "Audio", "Vibra Mux"},
1390 {"VIBRA", NULL, "Vibra Route"}, 1450 {"VIBRA", NULL, "Vibra Route"},
1391 1451
1392 /* Capture path */ 1452 /* Capture path */
1393 {"Analog Left Capture Route", "Main mic", "MAINMIC"}, 1453 {"Analog Left", "Main Mic Capture Switch", "MAINMIC"},
1394 {"Analog Left Capture Route", "Headset mic", "HSMIC"}, 1454 {"Analog Left", "Headset Mic Capture Switch", "HSMIC"},
1395 {"Analog Left Capture Route", "AUXL", "AUXL"}, 1455 {"Analog Left", "AUXL Capture Switch", "AUXL"},
1396 {"Analog Left Capture Route", "Carkit mic", "CARKITMIC"}, 1456 {"Analog Left", "Carkit Mic Capture Switch", "CARKITMIC"},
1397 1457
1398 {"Analog Right Capture Route", "Sub mic", "SUBMIC"}, 1458 {"Analog Right", "Sub Mic Capture Switch", "SUBMIC"},
1399 {"Analog Right Capture Route", "AUXR", "AUXR"}, 1459 {"Analog Right", "AUXR Capture Switch", "AUXR"},
1400 1460
1401 {"ADC Physical Left", NULL, "Analog Left Capture Route"}, 1461 {"ADC Physical Left", NULL, "Analog Left"},
1402 {"ADC Physical Right", NULL, "Analog Right Capture Route"}, 1462 {"ADC Physical Right", NULL, "Analog Right"},
1403 1463
1404 {"Digimic0 Enable", NULL, "DIGIMIC0"}, 1464 {"Digimic0 Enable", NULL, "DIGIMIC0"},
1405 {"Digimic1 Enable", NULL, "DIGIMIC1"}, 1465 {"Digimic1 Enable", NULL, "DIGIMIC1"},
@@ -1423,11 +1483,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1423 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1424 1484
1425 /* Analog bypass routes */ 1485 /* Analog bypass routes */
1426 {"Right1 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1486 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1427 {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1487 {"Left1 Analog Loopback", "Switch", "Analog Left"},
1428 {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, 1488 {"Right2 Analog Loopback", "Switch", "Analog Right"},
1429 {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, 1489 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1430 {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"}, 1490 {"Voice Analog Loopback", "Switch", "Analog Left"},
1431 1491
1432 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1433 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
@@ -1609,8 +1669,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1609 1669
1610 /* If the substream has 4 channel, do the necessary setup */ 1670 /* If the substream has 4 channel, do the necessary setup */
1611 if (params_channels(params) == 4) { 1671 if (params_channels(params) == 4) {
1612 u8 format, mode;
1613
1614 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); 1672 format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1615 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); 1673 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
1616 1674
@@ -1806,6 +1864,19 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1806 return 0; 1864 return 0;
1807} 1865}
1808 1866
1867static int twl4030_set_tristate(struct snd_soc_dai *dai, int tristate)
1868{
1869 struct snd_soc_codec *codec = dai->codec;
1870 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1871
1872 if (tristate)
1873 reg |= TWL4030_AIF_TRI_EN;
1874 else
1875 reg &= ~TWL4030_AIF_TRI_EN;
1876
1877 return twl4030_write(codec, TWL4030_REG_AUDIO_IF, reg);
1878}
1879
1809/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R 1880/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R
1810 * (VTXL, VTXR) for uplink has to be enabled/disabled. */ 1881 * (VTXL, VTXR) for uplink has to be enabled/disabled. */
1811static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, 1882static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction,
@@ -1948,7 +2019,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1948 2019
1949 /* set master/slave audio interface */ 2020 /* set master/slave audio interface */
1950 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 2021 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1951 case SND_SOC_DAIFMT_CBS_CFM: 2022 case SND_SOC_DAIFMT_CBM_CFM:
1952 format &= ~(TWL4030_VIF_SLAVE_EN); 2023 format &= ~(TWL4030_VIF_SLAVE_EN);
1953 break; 2024 break;
1954 case SND_SOC_DAIFMT_CBS_CFS: 2025 case SND_SOC_DAIFMT_CBS_CFS:
@@ -1980,6 +2051,19 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
1980 return 0; 2051 return 0;
1981} 2052}
1982 2053
2054static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2055{
2056 struct snd_soc_codec *codec = dai->codec;
2057 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_VOICE_IF);
2058
2059 if (tristate)
2060 reg |= TWL4030_VIF_TRI_EN;
2061 else
2062 reg &= ~TWL4030_VIF_TRI_EN;
2063
2064 return twl4030_write(codec, TWL4030_REG_VOICE_IF, reg);
2065}
2066
1983#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2067#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1984#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2068#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1985 2069
@@ -1989,6 +2073,7 @@ static struct snd_soc_dai_ops twl4030_dai_ops = {
1989 .hw_params = twl4030_hw_params, 2073 .hw_params = twl4030_hw_params,
1990 .set_sysclk = twl4030_set_dai_sysclk, 2074 .set_sysclk = twl4030_set_dai_sysclk,
1991 .set_fmt = twl4030_set_dai_fmt, 2075 .set_fmt = twl4030_set_dai_fmt,
2076 .set_tristate = twl4030_set_tristate,
1992}; 2077};
1993 2078
1994static struct snd_soc_dai_ops twl4030_dai_voice_ops = { 2079static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
@@ -1997,6 +2082,7 @@ static struct snd_soc_dai_ops twl4030_dai_voice_ops = {
1997 .hw_params = twl4030_voice_hw_params, 2082 .hw_params = twl4030_voice_hw_params,
1998 .set_sysclk = twl4030_voice_set_dai_sysclk, 2083 .set_sysclk = twl4030_voice_set_dai_sysclk,
1999 .set_fmt = twl4030_voice_set_dai_fmt, 2084 .set_fmt = twl4030_voice_set_dai_fmt,
2085 .set_tristate = twl4030_voice_set_tristate,
2000}; 2086};
2001 2087
2002struct snd_soc_dai twl4030_dai[] = { 2088struct snd_soc_dai twl4030_dai[] = {
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index fe5f395d9e4f..2b4bfa23f985 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -274,6 +274,8 @@ extern struct snd_soc_codec_device soc_codec_dev_twl4030;
274struct twl4030_setup_data { 274struct twl4030_setup_data {
275 unsigned int ramp_delay_value; 275 unsigned int ramp_delay_value;
276 unsigned int sysclk; 276 unsigned int sysclk;
277 unsigned int hs_extmute:1;
278 void (*set_hs_extmute)(int mute);
277}; 279};
278 280
279#endif /* End of __TWL4030_AUDIO_H__ */ 281#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 269b108e1de6..c33b92edbded 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -163,7 +163,7 @@ static int uda134x_mute(struct snd_soc_dai *dai, int mute)
163 else 163 else
164 mute_reg &= ~(1<<2); 164 mute_reg &= ~(1<<2);
165 165
166 uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2)); 166 uda134x_write(codec, UDA134X_DATA010, mute_reg);
167 167
168 return 0; 168 return 0;
169} 169}
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 5b21594e0e58..92ec03442154 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -5,9 +5,7 @@
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 * 7 *
8 * Copyright (c) 2007 Philipp Zabel <philipp.zabel@gmail.com> 8 * Copyright (c) 2007-2009 Philipp Zabel <philipp.zabel@gmail.com>
9 * Improved support for DAPM and audio routing/mixing capabilities,
10 * added TLV support.
11 * 9 *
12 * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC 10 * Modified by Richard Purdie <richard@openedhand.com> to fit into SoC
13 * codec model. 11 * codec model.
@@ -19,26 +17,32 @@
19#include <linux/module.h> 17#include <linux/module.h>
20#include <linux/init.h> 18#include <linux/init.h>
21#include <linux/types.h> 19#include <linux/types.h>
22#include <linux/string.h>
23#include <linux/slab.h> 20#include <linux/slab.h>
24#include <linux/errno.h> 21#include <linux/errno.h>
25#include <linux/ioctl.h> 22#include <linux/gpio.h>
26#include <linux/delay.h> 23#include <linux/delay.h>
27#include <linux/i2c.h> 24#include <linux/i2c.h>
28#include <linux/workqueue.h> 25#include <linux/workqueue.h>
29#include <sound/core.h> 26#include <sound/core.h>
30#include <sound/control.h> 27#include <sound/control.h>
31#include <sound/initval.h> 28#include <sound/initval.h>
32#include <sound/info.h>
33#include <sound/soc.h> 29#include <sound/soc.h>
34#include <sound/soc-dapm.h> 30#include <sound/soc-dapm.h>
35#include <sound/tlv.h> 31#include <sound/tlv.h>
32#include <sound/uda1380.h>
36 33
37#include "uda1380.h" 34#include "uda1380.h"
38 35
39static struct work_struct uda1380_work;
40static struct snd_soc_codec *uda1380_codec; 36static struct snd_soc_codec *uda1380_codec;
41 37
38/* codec private data */
39struct uda1380_priv {
40 struct snd_soc_codec codec;
41 u16 reg_cache[UDA1380_CACHEREGNUM];
42 unsigned int dac_clk;
43 struct work_struct work;
44};
45
42/* 46/*
43 * uda1380 register cache 47 * uda1380 register cache
44 */ 48 */
@@ -473,6 +477,7 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
473 struct snd_soc_pcm_runtime *rtd = substream->private_data; 477 struct snd_soc_pcm_runtime *rtd = substream->private_data;
474 struct snd_soc_device *socdev = rtd->socdev; 478 struct snd_soc_device *socdev = rtd->socdev;
475 struct snd_soc_codec *codec = socdev->card->codec; 479 struct snd_soc_codec *codec = socdev->card->codec;
480 struct uda1380_priv *uda1380 = codec->private_data;
476 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER); 481 int mixer = uda1380_read_reg_cache(codec, UDA1380_MIXER);
477 482
478 switch (cmd) { 483 switch (cmd) {
@@ -480,13 +485,13 @@ static int uda1380_trigger(struct snd_pcm_substream *substream, int cmd,
480 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 485 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
481 uda1380_write_reg_cache(codec, UDA1380_MIXER, 486 uda1380_write_reg_cache(codec, UDA1380_MIXER,
482 mixer & ~R14_SILENCE); 487 mixer & ~R14_SILENCE);
483 schedule_work(&uda1380_work); 488 schedule_work(&uda1380->work);
484 break; 489 break;
485 case SNDRV_PCM_TRIGGER_STOP: 490 case SNDRV_PCM_TRIGGER_STOP:
486 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 491 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
487 uda1380_write_reg_cache(codec, UDA1380_MIXER, 492 uda1380_write_reg_cache(codec, UDA1380_MIXER,
488 mixer | R14_SILENCE); 493 mixer | R14_SILENCE);
489 schedule_work(&uda1380_work); 494 schedule_work(&uda1380->work);
490 break; 495 break;
491 } 496 }
492 return 0; 497 return 0;
@@ -670,44 +675,33 @@ static int uda1380_resume(struct platform_device *pdev)
670 return 0; 675 return 0;
671} 676}
672 677
673/* 678static int uda1380_probe(struct platform_device *pdev)
674 * initialise the UDA1380 driver
675 * register mixer and dsp interfaces with the kernel
676 */
677static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
678{ 679{
679 struct snd_soc_codec *codec = socdev->card->codec; 680 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
681 struct snd_soc_codec *codec;
682 struct uda1380_platform_data *pdata;
680 int ret = 0; 683 int ret = 0;
681 684
682 codec->name = "UDA1380"; 685 if (uda1380_codec == NULL) {
683 codec->owner = THIS_MODULE; 686 dev_err(&pdev->dev, "Codec device not registered\n");
684 codec->read = uda1380_read_reg_cache; 687 return -ENODEV;
685 codec->write = uda1380_write; 688 }
686 codec->set_bias_level = uda1380_set_bias_level;
687 codec->dai = uda1380_dai;
688 codec->num_dai = ARRAY_SIZE(uda1380_dai);
689 codec->reg_cache = kmemdup(uda1380_reg, sizeof(uda1380_reg),
690 GFP_KERNEL);
691 if (codec->reg_cache == NULL)
692 return -ENOMEM;
693 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
694 codec->reg_cache_step = 1;
695 uda1380_reset(codec);
696 689
697 uda1380_codec = codec; 690 socdev->card->codec = uda1380_codec;
698 INIT_WORK(&uda1380_work, uda1380_flush_work); 691 codec = uda1380_codec;
692 pdata = codec->dev->platform_data;
699 693
700 /* register pcms */ 694 /* register pcms */
701 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 695 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
702 if (ret < 0) { 696 if (ret < 0) {
703 pr_err("uda1380: failed to create pcms\n"); 697 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
704 goto pcm_err; 698 goto pcm_err;
705 } 699 }
706 700
707 /* power on device */ 701 /* power on device */
708 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 702 uda1380_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
709 /* set clock input */ 703 /* set clock input */
710 switch (dac_clk) { 704 switch (pdata->dac_clk) {
711 case UDA1380_DAC_CLK_SYSCLK: 705 case UDA1380_DAC_CLK_SYSCLK:
712 uda1380_write(codec, UDA1380_CLK, 0); 706 uda1380_write(codec, UDA1380_CLK, 0);
713 break; 707 break;
@@ -716,13 +710,12 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
716 break; 710 break;
717 } 711 }
718 712
719 /* uda1380 init */
720 snd_soc_add_controls(codec, uda1380_snd_controls, 713 snd_soc_add_controls(codec, uda1380_snd_controls,
721 ARRAY_SIZE(uda1380_snd_controls)); 714 ARRAY_SIZE(uda1380_snd_controls));
722 uda1380_add_widgets(codec); 715 uda1380_add_widgets(codec);
723 ret = snd_soc_init_card(socdev); 716 ret = snd_soc_init_card(socdev);
724 if (ret < 0) { 717 if (ret < 0) {
725 pr_err("uda1380: failed to register card\n"); 718 dev_err(codec->dev, "failed to register card: %d\n", ret);
726 goto card_err; 719 goto card_err;
727 } 720 }
728 721
@@ -732,165 +725,201 @@ card_err:
732 snd_soc_free_pcms(socdev); 725 snd_soc_free_pcms(socdev);
733 snd_soc_dapm_free(socdev); 726 snd_soc_dapm_free(socdev);
734pcm_err: 727pcm_err:
735 kfree(codec->reg_cache);
736 return ret; 728 return ret;
737} 729}
738 730
739static struct snd_soc_device *uda1380_socdev; 731/* power down chip */
740 732static int uda1380_remove(struct platform_device *pdev)
741#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
742
743static int uda1380_i2c_probe(struct i2c_client *i2c,
744 const struct i2c_device_id *id)
745{ 733{
746 struct snd_soc_device *socdev = uda1380_socdev; 734 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
747 struct uda1380_setup_data *setup = socdev->codec_data;
748 struct snd_soc_codec *codec = socdev->card->codec; 735 struct snd_soc_codec *codec = socdev->card->codec;
749 int ret;
750
751 i2c_set_clientdata(i2c, codec);
752 codec->control_data = i2c;
753 736
754 ret = uda1380_init(socdev, setup->dac_clk); 737 if (codec->control_data)
755 if (ret < 0) 738 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
756 pr_err("uda1380: failed to initialise UDA1380\n");
757 739
758 return ret; 740 snd_soc_free_pcms(socdev);
759} 741 snd_soc_dapm_free(socdev);
760 742
761static int uda1380_i2c_remove(struct i2c_client *client)
762{
763 struct snd_soc_codec *codec = i2c_get_clientdata(client);
764 kfree(codec->reg_cache);
765 return 0; 743 return 0;
766} 744}
767 745
768static const struct i2c_device_id uda1380_i2c_id[] = { 746struct snd_soc_codec_device soc_codec_dev_uda1380 = {
769 { "uda1380", 0 }, 747 .probe = uda1380_probe,
770 { } 748 .remove = uda1380_remove,
771}; 749 .suspend = uda1380_suspend,
772MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id); 750 .resume = uda1380_resume,
773
774static struct i2c_driver uda1380_i2c_driver = {
775 .driver = {
776 .name = "UDA1380 I2C Codec",
777 .owner = THIS_MODULE,
778 },
779 .probe = uda1380_i2c_probe,
780 .remove = uda1380_i2c_remove,
781 .id_table = uda1380_i2c_id,
782}; 751};
752EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
783 753
784static int uda1380_add_i2c_device(struct platform_device *pdev, 754static int uda1380_register(struct uda1380_priv *uda1380)
785 const struct uda1380_setup_data *setup)
786{ 755{
787 struct i2c_board_info info; 756 int ret, i;
788 struct i2c_adapter *adapter; 757 struct snd_soc_codec *codec = &uda1380->codec;
789 struct i2c_client *client; 758 struct uda1380_platform_data *pdata = codec->dev->platform_data;
790 int ret;
791 759
792 ret = i2c_add_driver(&uda1380_i2c_driver); 760 if (uda1380_codec) {
793 if (ret != 0) { 761 dev_err(codec->dev, "Another UDA1380 is registered\n");
794 dev_err(&pdev->dev, "can't add i2c driver\n"); 762 return -EINVAL;
795 return ret; 763 }
764
765 if (!pdata || !pdata->gpio_power || !pdata->gpio_reset)
766 return -EINVAL;
767
768 ret = gpio_request(pdata->gpio_power, "uda1380 power");
769 if (ret)
770 goto err_out;
771 ret = gpio_request(pdata->gpio_reset, "uda1380 reset");
772 if (ret)
773 goto err_gpio;
774
775 gpio_direction_output(pdata->gpio_power, 1);
776
777 /* we may need to have the clock running here - pH5 */
778 gpio_direction_output(pdata->gpio_reset, 1);
779 udelay(5);
780 gpio_set_value(pdata->gpio_reset, 0);
781
782 mutex_init(&codec->mutex);
783 INIT_LIST_HEAD(&codec->dapm_widgets);
784 INIT_LIST_HEAD(&codec->dapm_paths);
785
786 codec->private_data = uda1380;
787 codec->name = "UDA1380";
788 codec->owner = THIS_MODULE;
789 codec->read = uda1380_read_reg_cache;
790 codec->write = uda1380_write;
791 codec->bias_level = SND_SOC_BIAS_OFF;
792 codec->set_bias_level = uda1380_set_bias_level;
793 codec->dai = uda1380_dai;
794 codec->num_dai = ARRAY_SIZE(uda1380_dai);
795 codec->reg_cache_size = ARRAY_SIZE(uda1380_reg);
796 codec->reg_cache = &uda1380->reg_cache;
797 codec->reg_cache_step = 1;
798
799 memcpy(codec->reg_cache, uda1380_reg, sizeof(uda1380_reg));
800
801 ret = uda1380_reset(codec);
802 if (ret < 0) {
803 dev_err(codec->dev, "Failed to issue reset\n");
804 goto err_reset;
796 } 805 }
797 806
798 memset(&info, 0, sizeof(struct i2c_board_info)); 807 INIT_WORK(&uda1380->work, uda1380_flush_work);
799 info.addr = setup->i2c_address; 808
800 strlcpy(info.type, "uda1380", I2C_NAME_SIZE); 809 for (i = 0; i < ARRAY_SIZE(uda1380_dai); i++)
810 uda1380_dai[i].dev = codec->dev;
801 811
802 adapter = i2c_get_adapter(setup->i2c_bus); 812 uda1380_codec = codec;
803 if (!adapter) { 813
804 dev_err(&pdev->dev, "can't get i2c adapter %d\n", 814 ret = snd_soc_register_codec(codec);
805 setup->i2c_bus); 815 if (ret != 0) {
806 goto err_driver; 816 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
817 goto err_reset;
807 } 818 }
808 819
809 client = i2c_new_device(adapter, &info); 820 ret = snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
810 i2c_put_adapter(adapter); 821 if (ret != 0) {
811 if (!client) { 822 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
812 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n", 823 goto err_dai;
813 (unsigned int)info.addr);
814 goto err_driver;
815 } 824 }
816 825
817 return 0; 826 return 0;
818 827
819err_driver: 828err_dai:
820 i2c_del_driver(&uda1380_i2c_driver); 829 snd_soc_unregister_codec(codec);
821 return -ENODEV; 830err_reset:
831 gpio_set_value(pdata->gpio_power, 0);
832 gpio_free(pdata->gpio_reset);
833err_gpio:
834 gpio_free(pdata->gpio_power);
835err_out:
836 return ret;
822} 837}
823#endif
824 838
825static int uda1380_probe(struct platform_device *pdev) 839static void uda1380_unregister(struct uda1380_priv *uda1380)
826{ 840{
827 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 841 struct snd_soc_codec *codec = &uda1380->codec;
828 struct uda1380_setup_data *setup; 842 struct uda1380_platform_data *pdata = codec->dev->platform_data;
843
844 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
845 snd_soc_unregister_codec(&uda1380->codec);
846
847 gpio_set_value(pdata->gpio_power, 0);
848 gpio_free(pdata->gpio_reset);
849 gpio_free(pdata->gpio_power);
850
851 kfree(uda1380);
852 uda1380_codec = NULL;
853}
854
855#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
856static __devinit int uda1380_i2c_probe(struct i2c_client *i2c,
857 const struct i2c_device_id *id)
858{
859 struct uda1380_priv *uda1380;
829 struct snd_soc_codec *codec; 860 struct snd_soc_codec *codec;
830 int ret; 861 int ret;
831 862
832 setup = socdev->codec_data; 863 uda1380 = kzalloc(sizeof(struct uda1380_priv), GFP_KERNEL);
833 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 864 if (uda1380 == NULL)
834 if (codec == NULL)
835 return -ENOMEM; 865 return -ENOMEM;
836 866
837 socdev->card->codec = codec; 867 codec = &uda1380->codec;
838 mutex_init(&codec->mutex); 868 codec->hw_write = (hw_write_t)i2c_master_send;
839 INIT_LIST_HEAD(&codec->dapm_widgets);
840 INIT_LIST_HEAD(&codec->dapm_paths);
841 869
842 uda1380_socdev = socdev; 870 i2c_set_clientdata(i2c, uda1380);
843 ret = -ENODEV; 871 codec->control_data = i2c;
844 872
845#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 873 codec->dev = &i2c->dev;
846 if (setup->i2c_address) {
847 codec->hw_write = (hw_write_t)i2c_master_send;
848 ret = uda1380_add_i2c_device(pdev, setup);
849 }
850#endif
851 874
875 ret = uda1380_register(uda1380);
852 if (ret != 0) 876 if (ret != 0)
853 kfree(codec); 877 kfree(uda1380);
878
854 return ret; 879 return ret;
855} 880}
856 881
857/* power down chip */ 882static int __devexit uda1380_i2c_remove(struct i2c_client *i2c)
858static int uda1380_remove(struct platform_device *pdev)
859{ 883{
860 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 884 struct uda1380_priv *uda1380 = i2c_get_clientdata(i2c);
861 struct snd_soc_codec *codec = socdev->card->codec; 885 uda1380_unregister(uda1380);
862
863 if (codec->control_data)
864 uda1380_set_bias_level(codec, SND_SOC_BIAS_OFF);
865
866 snd_soc_free_pcms(socdev);
867 snd_soc_dapm_free(socdev);
868#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
869 i2c_unregister_device(codec->control_data);
870 i2c_del_driver(&uda1380_i2c_driver);
871#endif
872 kfree(codec);
873
874 return 0; 886 return 0;
875} 887}
876 888
877struct snd_soc_codec_device soc_codec_dev_uda1380 = { 889static const struct i2c_device_id uda1380_i2c_id[] = {
878 .probe = uda1380_probe, 890 { "uda1380", 0 },
879 .remove = uda1380_remove, 891 { }
880 .suspend = uda1380_suspend,
881 .resume = uda1380_resume,
882}; 892};
883EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 893MODULE_DEVICE_TABLE(i2c, uda1380_i2c_id);
894
895static struct i2c_driver uda1380_i2c_driver = {
896 .driver = {
897 .name = "UDA1380 I2C Codec",
898 .owner = THIS_MODULE,
899 },
900 .probe = uda1380_i2c_probe,
901 .remove = __devexit_p(uda1380_i2c_remove),
902 .id_table = uda1380_i2c_id,
903};
904#endif
884 905
885static int __init uda1380_modinit(void) 906static int __init uda1380_modinit(void)
886{ 907{
887 return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 908 int ret;
909#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
910 ret = i2c_add_driver(&uda1380_i2c_driver);
911 if (ret != 0)
912 pr_err("Failed to register UDA1380 I2C driver: %d\n", ret);
913#endif
914 return 0;
888} 915}
889module_init(uda1380_modinit); 916module_init(uda1380_modinit);
890 917
891static void __exit uda1380_exit(void) 918static void __exit uda1380_exit(void)
892{ 919{
893 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai)); 920#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
921 i2c_del_driver(&uda1380_i2c_driver);
922#endif
894} 923}
895module_exit(uda1380_exit); 924module_exit(uda1380_exit);
896 925
diff --git a/sound/soc/codecs/uda1380.h b/sound/soc/codecs/uda1380.h
index c55c17a52a12..9cefa8a54770 100644
--- a/sound/soc/codecs/uda1380.h
+++ b/sound/soc/codecs/uda1380.h
@@ -72,14 +72,6 @@
72#define R22_SKIP_DCFIL 0x0002 72#define R22_SKIP_DCFIL 0x0002
73#define R23_AGC_EN 0x0001 73#define R23_AGC_EN 0x0001
74 74
75struct uda1380_setup_data {
76 int i2c_bus;
77 unsigned short i2c_address;
78 int dac_clk;
79#define UDA1380_DAC_CLK_SYSCLK 0
80#define UDA1380_DAC_CLK_WSPLL 1
81};
82
83#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */ 75#define UDA1380_DAI_DUPLEX 0 /* playback and capture on single DAI */
84#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */ 76#define UDA1380_DAI_PLAYBACK 1 /* playback DAI */
85#define UDA1380_DAI_CAPTURE 2 /* capture DAI */ 77#define UDA1380_DAI_CAPTURE 2 /* capture DAI */
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index e7348d341b76..3ff0373dff89 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -63,6 +63,8 @@ struct wm8350_data {
63 struct wm8350_jack_data hpl; 63 struct wm8350_jack_data hpl;
64 struct wm8350_jack_data hpr; 64 struct wm8350_jack_data hpr;
65 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; 65 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
66 int fll_freq_out;
67 int fll_freq_in;
66}; 68};
67 69
68static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec, 70static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
@@ -406,7 +408,6 @@ static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
406static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; 408static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
407static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; 409static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
408static const char *wm8350_dacmutes[] = { "Fast", "Slow" }; 410static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
409static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
410static const char *wm8350_adcfilter[] = { "None", "High Pass" }; 411static const char *wm8350_adcfilter[] = { "None", "High Pass" };
411static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" }; 412static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
412static const char *wm8350_lr[] = { "Left", "Right" }; 413static const char *wm8350_lr[] = { "Left", "Right" };
@@ -416,7 +417,6 @@ static const struct soc_enum wm8350_enum[] = {
416 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol), 417 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
417 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem), 418 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
418 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes), 419 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
419 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
420 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter), 420 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
421 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp), 421 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
422 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol), 422 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
@@ -444,10 +444,9 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = {
444 0, 255, 0, dac_pcm_tlv), 444 0, 255, 0, dac_pcm_tlv),
445 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), 445 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
446 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), 446 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
447 SOC_ENUM("Playback PCM Filter", wm8350_enum[4]), 447 SOC_ENUM("Capture PCM Filter", wm8350_enum[4]),
448 SOC_ENUM("Capture PCM Filter", wm8350_enum[5]), 448 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]),
449 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]), 449 SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]),
450 SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
451 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume", 450 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
452 WM8350_ADC_DIGITAL_VOLUME_L, 451 WM8350_ADC_DIGITAL_VOLUME_L,
453 WM8350_ADC_DIGITAL_VOLUME_R, 452 WM8350_ADC_DIGITAL_VOLUME_R,
@@ -613,7 +612,7 @@ SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
613 612
614/* Out4 Capture Mux */ 613/* Out4 Capture Mux */
615static const struct snd_kcontrol_new wm8350_out4_capture_controls = 614static const struct snd_kcontrol_new wm8350_out4_capture_controls =
616SOC_DAPM_ENUM("Route", wm8350_enum[8]); 615SOC_DAPM_ENUM("Route", wm8350_enum[7]);
617 616
618static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = { 617static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
619 618
@@ -993,6 +992,7 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
993 struct snd_soc_dai *codec_dai) 992 struct snd_soc_dai *codec_dai)
994{ 993{
995 struct snd_soc_codec *codec = codec_dai->codec; 994 struct snd_soc_codec *codec = codec_dai->codec;
995 struct wm8350 *wm8350 = codec->control_data;
996 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) & 996 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
997 ~WM8350_AIF_WL_MASK; 997 ~WM8350_AIF_WL_MASK;
998 998
@@ -1012,6 +1012,19 @@ static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1012 } 1012 }
1013 1013
1014 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface); 1014 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
1015
1016 /* The sloping stopband filter is recommended for use with
1017 * lower sample rates to improve performance.
1018 */
1019 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
1020 if (params_rate(params) < 24000)
1021 wm8350_set_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
1022 WM8350_DAC_SB_FILT);
1023 else
1024 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE_VOLUME,
1025 WM8350_DAC_SB_FILT);
1026 }
1027
1015 return 0; 1028 return 0;
1016} 1029}
1017 1030
@@ -1093,10 +1106,14 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1093{ 1106{
1094 struct snd_soc_codec *codec = codec_dai->codec; 1107 struct snd_soc_codec *codec = codec_dai->codec;
1095 struct wm8350 *wm8350 = codec->control_data; 1108 struct wm8350 *wm8350 = codec->control_data;
1109 struct wm8350_data *priv = codec->private_data;
1096 struct _fll_div fll_div; 1110 struct _fll_div fll_div;
1097 int ret = 0; 1111 int ret = 0;
1098 u16 fll_1, fll_4; 1112 u16 fll_1, fll_4;
1099 1113
1114 if (freq_in == priv->fll_freq_in && freq_out == priv->fll_freq_out)
1115 return 0;
1116
1100 /* power down FLL - we need to do this for reconfiguration */ 1117 /* power down FLL - we need to do this for reconfiguration */
1101 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, 1118 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1102 WM8350_FLL_ENA | WM8350_FLL_OSC_ENA); 1119 WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
@@ -1131,6 +1148,9 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1131 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA); 1148 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
1132 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA); 1149 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
1133 1150
1151 priv->fll_freq_out = freq_out;
1152 priv->fll_freq_in = freq_in;
1153
1134 return 0; 1154 return 0;
1135} 1155}
1136 1156
@@ -1660,6 +1680,21 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1660 return 0; 1680 return 0;
1661} 1681}
1662 1682
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1663static struct platform_driver wm8350_codec_driver = { 1698static struct platform_driver wm8350_codec_driver = {
1664 .driver = { 1699 .driver = {
1665 .name = "wm8350-codec", 1700 .name = "wm8350-codec",
@@ -1667,6 +1702,8 @@ static struct platform_driver wm8350_codec_driver = {
1667 }, 1702 },
1668 .probe = wm8350_codec_probe, 1703 .probe = wm8350_codec_probe,
1669 .remove = __devexit_p(wm8350_codec_remove), 1704 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1670}; 1707};
1671 1708
1672static __init int wm8350_init(void) 1709static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 502eefac1ecd..b9ef4d915221 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1022,10 +1022,15 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1022 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out) 1022 if (freq_in == wm8400->fll_in && freq_out == wm8400->fll_out)
1023 return 0; 1023 return 0;
1024 1024
1025 if (freq_out != 0) { 1025 if (freq_out) {
1026 ret = fll_factors(wm8400, &factors, freq_in, freq_out); 1026 ret = fll_factors(wm8400, &factors, freq_in, freq_out);
1027 if (ret != 0) 1027 if (ret != 0)
1028 return ret; 1028 return ret;
1029 } else {
1030 /* Bodge GCC 4.4.0 uninitialised variable warning - it
1031 * doesn't seem capable of working out that we exit if
1032 * freq_out is 0 before any of the uses. */
1033 memset(&factors, 0, sizeof(factors));
1029 } 1034 }
1030 1035
1031 wm8400->fll_out = freq_out; 1036 wm8400->fll_out = freq_out;
@@ -1040,7 +1045,7 @@ static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1040 reg &= ~WM8400_FLL_OSC_ENA; 1045 reg &= ~WM8400_FLL_OSC_ENA;
1041 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg); 1046 wm8400_write(codec, WM8400_FLL_CONTROL_1, reg);
1042 1047
1043 if (freq_out == 0) 1048 if (!freq_out)
1044 return 0; 1049 return 0;
1045 1050
1046 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK); 1051 reg &= ~(WM8400_FLL_REF_FREQ | WM8400_FLL_FRATIO_MASK);
@@ -1553,6 +1558,21 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1553 return 0; 1558 return 0;
1554} 1559}
1555 1560
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1556static struct platform_driver wm8400_codec_driver = { 1576static struct platform_driver wm8400_codec_driver = {
1557 .driver = { 1577 .driver = {
1558 .name = "wm8400-codec", 1578 .name = "wm8400-codec",
@@ -1560,6 +1580,8 @@ static struct platform_driver wm8400_codec_driver = {
1560 }, 1580 },
1561 .probe = wm8400_codec_probe, 1581 .probe = wm8400_codec_probe,
1562 .remove = __exit_p(wm8400_codec_remove), 1582 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1563}; 1585};
1564 1586
1565static int __init wm8400_codec_init(void) 1587static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index c8b8dba85890..060d5d06ba95 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -58,55 +58,7 @@ static const u16 wm8510_reg[WM8510_CACHEREGNUM] = {
58#define WM8510_POWER1_BIASEN 0x08 58#define WM8510_POWER1_BIASEN 0x08
59#define WM8510_POWER1_BUFIOEN 0x10 59#define WM8510_POWER1_BUFIOEN 0x10
60 60
61/* 61#define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
62 * read wm8510 register cache
63 */
64static inline unsigned int wm8510_read_reg_cache(struct snd_soc_codec *codec,
65 unsigned int reg)
66{
67 u16 *cache = codec->reg_cache;
68 if (reg == WM8510_RESET)
69 return 0;
70 if (reg >= WM8510_CACHEREGNUM)
71 return -1;
72 return cache[reg];
73}
74
75/*
76 * write wm8510 register cache
77 */
78static inline void wm8510_write_reg_cache(struct snd_soc_codec *codec,
79 u16 reg, unsigned int value)
80{
81 u16 *cache = codec->reg_cache;
82 if (reg >= WM8510_CACHEREGNUM)
83 return;
84 cache[reg] = value;
85}
86
87/*
88 * write to the WM8510 register space
89 */
90static int wm8510_write(struct snd_soc_codec *codec, unsigned int reg,
91 unsigned int value)
92{
93 u8 data[2];
94
95 /* data is
96 * D15..D9 WM8510 register offset
97 * D8...D0 register data
98 */
99 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
100 data[1] = value & 0x00ff;
101
102 wm8510_write_reg_cache(codec, reg, value);
103 if (codec->hw_write(codec->control_data, data, 2) == 2)
104 return 0;
105 else
106 return -EIO;
107}
108
109#define wm8510_reset(c) wm8510_write(c, WM8510_RESET, 0)
110 62
111static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" }; 63static const char *wm8510_companding[] = { "Off", "NC", "u-law", "A-law" };
112static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; 64static const char *wm8510_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
@@ -327,27 +279,27 @@ static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai,
327 279
328 if (freq_in == 0 || freq_out == 0) { 280 if (freq_in == 0 || freq_out == 0) {
329 /* Clock CODEC directly from MCLK */ 281 /* Clock CODEC directly from MCLK */
330 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK); 282 reg = snd_soc_read(codec, WM8510_CLOCK);
331 wm8510_write(codec, WM8510_CLOCK, reg & 0x0ff); 283 snd_soc_write(codec, WM8510_CLOCK, reg & 0x0ff);
332 284
333 /* Turn off PLL */ 285 /* Turn off PLL */
334 reg = wm8510_read_reg_cache(codec, WM8510_POWER1); 286 reg = snd_soc_read(codec, WM8510_POWER1);
335 wm8510_write(codec, WM8510_POWER1, reg & 0x1df); 287 snd_soc_write(codec, WM8510_POWER1, reg & 0x1df);
336 return 0; 288 return 0;
337 } 289 }
338 290
339 pll_factors(freq_out*4, freq_in); 291 pll_factors(freq_out*4, freq_in);
340 292
341 wm8510_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n); 293 snd_soc_write(codec, WM8510_PLLN, (pll_div.pre_div << 4) | pll_div.n);
342 wm8510_write(codec, WM8510_PLLK1, pll_div.k >> 18); 294 snd_soc_write(codec, WM8510_PLLK1, pll_div.k >> 18);
343 wm8510_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff); 295 snd_soc_write(codec, WM8510_PLLK2, (pll_div.k >> 9) & 0x1ff);
344 wm8510_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff); 296 snd_soc_write(codec, WM8510_PLLK3, pll_div.k & 0x1ff);
345 reg = wm8510_read_reg_cache(codec, WM8510_POWER1); 297 reg = snd_soc_read(codec, WM8510_POWER1);
346 wm8510_write(codec, WM8510_POWER1, reg | 0x020); 298 snd_soc_write(codec, WM8510_POWER1, reg | 0x020);
347 299
348 /* Run CODEC from PLL instead of MCLK */ 300 /* Run CODEC from PLL instead of MCLK */
349 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK); 301 reg = snd_soc_read(codec, WM8510_CLOCK);
350 wm8510_write(codec, WM8510_CLOCK, reg | 0x100); 302 snd_soc_write(codec, WM8510_CLOCK, reg | 0x100);
351 303
352 return 0; 304 return 0;
353} 305}
@@ -363,24 +315,24 @@ static int wm8510_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
363 315
364 switch (div_id) { 316 switch (div_id) {
365 case WM8510_OPCLKDIV: 317 case WM8510_OPCLKDIV:
366 reg = wm8510_read_reg_cache(codec, WM8510_GPIO) & 0x1cf; 318 reg = snd_soc_read(codec, WM8510_GPIO) & 0x1cf;
367 wm8510_write(codec, WM8510_GPIO, reg | div); 319 snd_soc_write(codec, WM8510_GPIO, reg | div);
368 break; 320 break;
369 case WM8510_MCLKDIV: 321 case WM8510_MCLKDIV:
370 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x11f; 322 reg = snd_soc_read(codec, WM8510_CLOCK) & 0x11f;
371 wm8510_write(codec, WM8510_CLOCK, reg | div); 323 snd_soc_write(codec, WM8510_CLOCK, reg | div);
372 break; 324 break;
373 case WM8510_ADCCLK: 325 case WM8510_ADCCLK:
374 reg = wm8510_read_reg_cache(codec, WM8510_ADC) & 0x1f7; 326 reg = snd_soc_read(codec, WM8510_ADC) & 0x1f7;
375 wm8510_write(codec, WM8510_ADC, reg | div); 327 snd_soc_write(codec, WM8510_ADC, reg | div);
376 break; 328 break;
377 case WM8510_DACCLK: 329 case WM8510_DACCLK:
378 reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0x1f7; 330 reg = snd_soc_read(codec, WM8510_DAC) & 0x1f7;
379 wm8510_write(codec, WM8510_DAC, reg | div); 331 snd_soc_write(codec, WM8510_DAC, reg | div);
380 break; 332 break;
381 case WM8510_BCLKDIV: 333 case WM8510_BCLKDIV:
382 reg = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1e3; 334 reg = snd_soc_read(codec, WM8510_CLOCK) & 0x1e3;
383 wm8510_write(codec, WM8510_CLOCK, reg | div); 335 snd_soc_write(codec, WM8510_CLOCK, reg | div);
384 break; 336 break;
385 default: 337 default:
386 return -EINVAL; 338 return -EINVAL;
@@ -394,7 +346,7 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
394{ 346{
395 struct snd_soc_codec *codec = codec_dai->codec; 347 struct snd_soc_codec *codec = codec_dai->codec;
396 u16 iface = 0; 348 u16 iface = 0;
397 u16 clk = wm8510_read_reg_cache(codec, WM8510_CLOCK) & 0x1fe; 349 u16 clk = snd_soc_read(codec, WM8510_CLOCK) & 0x1fe;
398 350
399 /* set master/slave audio interface */ 351 /* set master/slave audio interface */
400 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 352 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -441,8 +393,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
441 return -EINVAL; 393 return -EINVAL;
442 } 394 }
443 395
444 wm8510_write(codec, WM8510_IFACE, iface); 396 snd_soc_write(codec, WM8510_IFACE, iface);
445 wm8510_write(codec, WM8510_CLOCK, clk); 397 snd_soc_write(codec, WM8510_CLOCK, clk);
446 return 0; 398 return 0;
447} 399}
448 400
@@ -453,8 +405,8 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
453 struct snd_soc_pcm_runtime *rtd = substream->private_data; 405 struct snd_soc_pcm_runtime *rtd = substream->private_data;
454 struct snd_soc_device *socdev = rtd->socdev; 406 struct snd_soc_device *socdev = rtd->socdev;
455 struct snd_soc_codec *codec = socdev->card->codec; 407 struct snd_soc_codec *codec = socdev->card->codec;
456 u16 iface = wm8510_read_reg_cache(codec, WM8510_IFACE) & 0x19f; 408 u16 iface = snd_soc_read(codec, WM8510_IFACE) & 0x19f;
457 u16 adn = wm8510_read_reg_cache(codec, WM8510_ADD) & 0x1f1; 409 u16 adn = snd_soc_read(codec, WM8510_ADD) & 0x1f1;
458 410
459 /* bit size */ 411 /* bit size */
460 switch (params_format(params)) { 412 switch (params_format(params)) {
@@ -493,20 +445,20 @@ static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
493 break; 445 break;
494 } 446 }
495 447
496 wm8510_write(codec, WM8510_IFACE, iface); 448 snd_soc_write(codec, WM8510_IFACE, iface);
497 wm8510_write(codec, WM8510_ADD, adn); 449 snd_soc_write(codec, WM8510_ADD, adn);
498 return 0; 450 return 0;
499} 451}
500 452
501static int wm8510_mute(struct snd_soc_dai *dai, int mute) 453static int wm8510_mute(struct snd_soc_dai *dai, int mute)
502{ 454{
503 struct snd_soc_codec *codec = dai->codec; 455 struct snd_soc_codec *codec = dai->codec;
504 u16 mute_reg = wm8510_read_reg_cache(codec, WM8510_DAC) & 0xffbf; 456 u16 mute_reg = snd_soc_read(codec, WM8510_DAC) & 0xffbf;
505 457
506 if (mute) 458 if (mute)
507 wm8510_write(codec, WM8510_DAC, mute_reg | 0x40); 459 snd_soc_write(codec, WM8510_DAC, mute_reg | 0x40);
508 else 460 else
509 wm8510_write(codec, WM8510_DAC, mute_reg); 461 snd_soc_write(codec, WM8510_DAC, mute_reg);
510 return 0; 462 return 0;
511} 463}
512 464
@@ -514,13 +466,13 @@ static int wm8510_mute(struct snd_soc_dai *dai, int mute)
514static int wm8510_set_bias_level(struct snd_soc_codec *codec, 466static int wm8510_set_bias_level(struct snd_soc_codec *codec,
515 enum snd_soc_bias_level level) 467 enum snd_soc_bias_level level)
516{ 468{
517 u16 power1 = wm8510_read_reg_cache(codec, WM8510_POWER1) & ~0x3; 469 u16 power1 = snd_soc_read(codec, WM8510_POWER1) & ~0x3;
518 470
519 switch (level) { 471 switch (level) {
520 case SND_SOC_BIAS_ON: 472 case SND_SOC_BIAS_ON:
521 case SND_SOC_BIAS_PREPARE: 473 case SND_SOC_BIAS_PREPARE:
522 power1 |= 0x1; /* VMID 50k */ 474 power1 |= 0x1; /* VMID 50k */
523 wm8510_write(codec, WM8510_POWER1, power1); 475 snd_soc_write(codec, WM8510_POWER1, power1);
524 break; 476 break;
525 477
526 case SND_SOC_BIAS_STANDBY: 478 case SND_SOC_BIAS_STANDBY:
@@ -528,18 +480,18 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
528 480
529 if (codec->bias_level == SND_SOC_BIAS_OFF) { 481 if (codec->bias_level == SND_SOC_BIAS_OFF) {
530 /* Initial cap charge at VMID 5k */ 482 /* Initial cap charge at VMID 5k */
531 wm8510_write(codec, WM8510_POWER1, power1 | 0x3); 483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
532 mdelay(100); 484 mdelay(100);
533 } 485 }
534 486
535 power1 |= 0x2; /* VMID 500k */ 487 power1 |= 0x2; /* VMID 500k */
536 wm8510_write(codec, WM8510_POWER1, power1); 488 snd_soc_write(codec, WM8510_POWER1, power1);
537 break; 489 break;
538 490
539 case SND_SOC_BIAS_OFF: 491 case SND_SOC_BIAS_OFF:
540 wm8510_write(codec, WM8510_POWER1, 0); 492 snd_soc_write(codec, WM8510_POWER1, 0);
541 wm8510_write(codec, WM8510_POWER2, 0); 493 snd_soc_write(codec, WM8510_POWER2, 0);
542 wm8510_write(codec, WM8510_POWER3, 0); 494 snd_soc_write(codec, WM8510_POWER3, 0);
543 break; 495 break;
544 } 496 }
545 497
@@ -577,6 +529,7 @@ struct snd_soc_dai wm8510_dai = {
577 .rates = WM8510_RATES, 529 .rates = WM8510_RATES,
578 .formats = WM8510_FORMATS,}, 530 .formats = WM8510_FORMATS,},
579 .ops = &wm8510_dai_ops, 531 .ops = &wm8510_dai_ops,
532 .symmetric_rates = 1,
580}; 533};
581EXPORT_SYMBOL_GPL(wm8510_dai); 534EXPORT_SYMBOL_GPL(wm8510_dai);
582 535
@@ -612,15 +565,14 @@ static int wm8510_resume(struct platform_device *pdev)
612 * initialise the WM8510 driver 565 * initialise the WM8510 driver
613 * register the mixer and dsp interfaces with the kernel 566 * register the mixer and dsp interfaces with the kernel
614 */ 567 */
615static int wm8510_init(struct snd_soc_device *socdev) 568static int wm8510_init(struct snd_soc_device *socdev,
569 enum snd_soc_control_type control)
616{ 570{
617 struct snd_soc_codec *codec = socdev->card->codec; 571 struct snd_soc_codec *codec = socdev->card->codec;
618 int ret = 0; 572 int ret = 0;
619 573
620 codec->name = "WM8510"; 574 codec->name = "WM8510";
621 codec->owner = THIS_MODULE; 575 codec->owner = THIS_MODULE;
622 codec->read = wm8510_read_reg_cache;
623 codec->write = wm8510_write;
624 codec->set_bias_level = wm8510_set_bias_level; 576 codec->set_bias_level = wm8510_set_bias_level;
625 codec->dai = &wm8510_dai; 577 codec->dai = &wm8510_dai;
626 codec->num_dai = 1; 578 codec->num_dai = 1;
@@ -630,13 +582,20 @@ static int wm8510_init(struct snd_soc_device *socdev)
630 if (codec->reg_cache == NULL) 582 if (codec->reg_cache == NULL)
631 return -ENOMEM; 583 return -ENOMEM;
632 584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
586 if (ret < 0) {
587 printk(KERN_ERR "wm8510: failed to set cache I/O: %d\n",
588 ret);
589 goto err;
590 }
591
633 wm8510_reset(codec); 592 wm8510_reset(codec);
634 593
635 /* register pcms */ 594 /* register pcms */
636 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 595 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
637 if (ret < 0) { 596 if (ret < 0) {
638 printk(KERN_ERR "wm8510: failed to create pcms\n"); 597 printk(KERN_ERR "wm8510: failed to create pcms\n");
639 goto pcm_err; 598 goto err;
640 } 599 }
641 600
642 /* power on device */ 601 /* power on device */
@@ -655,7 +614,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
655card_err: 614card_err:
656 snd_soc_free_pcms(socdev); 615 snd_soc_free_pcms(socdev);
657 snd_soc_dapm_free(socdev); 616 snd_soc_dapm_free(socdev);
658pcm_err: 617err:
659 kfree(codec->reg_cache); 618 kfree(codec->reg_cache);
660 return ret; 619 return ret;
661} 620}
@@ -678,7 +637,7 @@ static int wm8510_i2c_probe(struct i2c_client *i2c,
678 i2c_set_clientdata(i2c, codec); 637 i2c_set_clientdata(i2c, codec);
679 codec->control_data = i2c; 638 codec->control_data = i2c;
680 639
681 ret = wm8510_init(socdev); 640 ret = wm8510_init(socdev, SND_SOC_I2C);
682 if (ret < 0) 641 if (ret < 0)
683 pr_err("failed to initialise WM8510\n"); 642 pr_err("failed to initialise WM8510\n");
684 643
@@ -758,7 +717,7 @@ static int __devinit wm8510_spi_probe(struct spi_device *spi)
758 717
759 codec->control_data = spi; 718 codec->control_data = spi;
760 719
761 ret = wm8510_init(socdev); 720 ret = wm8510_init(socdev, SND_SOC_SPI);
762 if (ret < 0) 721 if (ret < 0)
763 dev_err(&spi->dev, "failed to initialise WM8510\n"); 722 dev_err(&spi->dev, "failed to initialise WM8510\n");
764 723
@@ -779,30 +738,6 @@ static struct spi_driver wm8510_spi_driver = {
779 .probe = wm8510_spi_probe, 738 .probe = wm8510_spi_probe,
780 .remove = __devexit_p(wm8510_spi_remove), 739 .remove = __devexit_p(wm8510_spi_remove),
781}; 740};
782
783static int wm8510_spi_write(struct spi_device *spi, const char *data, int len)
784{
785 struct spi_transfer t;
786 struct spi_message m;
787 u8 msg[2];
788
789 if (len <= 0)
790 return 0;
791
792 msg[0] = data[0];
793 msg[1] = data[1];
794
795 spi_message_init(&m);
796 memset(&t, 0, (sizeof t));
797
798 t.tx_buf = &msg[0];
799 t.len = len;
800
801 spi_message_add_tail(&t, &m);
802 spi_sync(spi, &m);
803
804 return len;
805}
806#endif /* CONFIG_SPI_MASTER */ 741#endif /* CONFIG_SPI_MASTER */
807 742
808static int wm8510_probe(struct platform_device *pdev) 743static int wm8510_probe(struct platform_device *pdev)
@@ -827,13 +762,11 @@ static int wm8510_probe(struct platform_device *pdev)
827 wm8510_socdev = socdev; 762 wm8510_socdev = socdev;
828#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 763#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
829 if (setup->i2c_address) { 764 if (setup->i2c_address) {
830 codec->hw_write = (hw_write_t)i2c_master_send;
831 ret = wm8510_add_i2c_device(pdev, setup); 765 ret = wm8510_add_i2c_device(pdev, setup);
832 } 766 }
833#endif 767#endif
834#if defined(CONFIG_SPI_MASTER) 768#if defined(CONFIG_SPI_MASTER)
835 if (setup->spi) { 769 if (setup->spi) {
836 codec->hw_write = (hw_write_t)wm8510_spi_write;
837 ret = spi_register_driver(&wm8510_spi_driver); 770 ret = spi_register_driver(&wm8510_spi_driver);
838 if (ret != 0) 771 if (ret != 0)
839 printk(KERN_ERR "can't add spi driver"); 772 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
new file mode 100644
index 000000000000..25870a4652fb
--- /dev/null
+++ b/sound/soc/codecs/wm8523.c
@@ -0,0 +1,699 @@
1/*
2 * wm8523.c -- WM8523 ALSA SoC Audio driver
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <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 "wm8523.h"
31
32static struct snd_soc_codec *wm8523_codec;
33struct snd_soc_codec_device soc_codec_dev_wm8523;
34
35#define WM8523_NUM_SUPPLIES 2
36static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = {
37 "AVDD",
38 "LINEVDD",
39};
40
41#define WM8523_NUM_RATES 7
42
43/* codec private data */
44struct wm8523_priv {
45 struct snd_soc_codec codec;
46 u16 reg_cache[WM8523_REGISTER_COUNT];
47 struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES];
48 unsigned int sysclk;
49 unsigned int rate_constraint_list[WM8523_NUM_RATES];
50 struct snd_pcm_hw_constraint_list rate_constraint;
51};
52
53static const u16 wm8523_reg[WM8523_REGISTER_COUNT] = {
54 0x8523, /* R0 - DEVICE_ID */
55 0x0001, /* R1 - REVISION */
56 0x0000, /* R2 - PSCTRL1 */
57 0x1812, /* R3 - AIF_CTRL1 */
58 0x0000, /* R4 - AIF_CTRL2 */
59 0x0001, /* R5 - DAC_CTRL3 */
60 0x0190, /* R6 - DAC_GAINL */
61 0x0190, /* R7 - DAC_GAINR */
62 0x0000, /* R8 - ZERO_DETECT */
63};
64
65static int wm8523_volatile_register(unsigned int reg)
66{
67 switch (reg) {
68 case WM8523_DEVICE_ID:
69 case WM8523_REVISION:
70 return 1;
71 default:
72 return 0;
73 }
74}
75
76static int wm8523_reset(struct snd_soc_codec *codec)
77{
78 return snd_soc_write(codec, WM8523_DEVICE_ID, 0);
79}
80
81static const DECLARE_TLV_DB_SCALE(dac_tlv, -10000, 25, 0);
82
83static const char *wm8523_zd_count_text[] = {
84 "1024",
85 "2048",
86};
87
88static const struct soc_enum wm8523_zc_count =
89 SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text);
90
91static const struct snd_kcontrol_new wm8523_snd_controls[] = {
92SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR,
93 0, 448, 0, dac_tlv),
94SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0),
95SOC_SINGLE("Playback Deemphasis Switch", WM8523_AIF_CTRL1, 8, 1, 0),
96SOC_DOUBLE("Playback Switch", WM8523_DAC_CTRL3, 2, 3, 1, 1),
97SOC_SINGLE("Volume Ramp Up Switch", WM8523_DAC_CTRL3, 1, 1, 0),
98SOC_SINGLE("Volume Ramp Down Switch", WM8523_DAC_CTRL3, 0, 1, 0),
99SOC_ENUM("Zero Detect Count", wm8523_zc_count),
100};
101
102static const struct snd_soc_dapm_widget wm8523_dapm_widgets[] = {
103SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0),
104SND_SOC_DAPM_OUTPUT("LINEVOUTL"),
105SND_SOC_DAPM_OUTPUT("LINEVOUTR"),
106};
107
108static const struct snd_soc_dapm_route intercon[] = {
109 { "LINEVOUTL", NULL, "DAC" },
110 { "LINEVOUTR", NULL, "DAC" },
111};
112
113static int wm8523_add_widgets(struct snd_soc_codec *codec)
114{
115 snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets,
116 ARRAY_SIZE(wm8523_dapm_widgets));
117
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119
120 snd_soc_dapm_new_widgets(codec);
121 return 0;
122}
123
124static struct {
125 int value;
126 int ratio;
127} lrclk_ratios[WM8523_NUM_RATES] = {
128 { 1, 128 },
129 { 2, 192 },
130 { 3, 256 },
131 { 4, 384 },
132 { 5, 512 },
133 { 6, 768 },
134 { 7, 1152 },
135};
136
137static int wm8523_startup(struct snd_pcm_substream *substream,
138 struct snd_soc_dai *dai)
139{
140 struct snd_soc_codec *codec = dai->codec;
141 struct wm8523_priv *wm8523 = codec->private_data;
142
143 /* The set of sample rates that can be supported depends on the
144 * MCLK supplied to the CODEC - enforce this.
145 */
146 if (!wm8523->sysclk) {
147 dev_err(codec->dev,
148 "No MCLK configured, call set_sysclk() on init\n");
149 return -EINVAL;
150 }
151
152 return 0;
153 snd_pcm_hw_constraint_list(substream->runtime, 0,
154 SNDRV_PCM_HW_PARAM_RATE,
155 &wm8523->rate_constraint);
156
157 return 0;
158}
159
160static int wm8523_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params,
162 struct snd_soc_dai *dai)
163{
164 struct snd_soc_pcm_runtime *rtd = substream->private_data;
165 struct snd_soc_device *socdev = rtd->socdev;
166 struct snd_soc_codec *codec = socdev->card->codec;
167 struct wm8523_priv *wm8523 = codec->private_data;
168 int i;
169 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
170 u16 aifctrl2 = snd_soc_read(codec, WM8523_AIF_CTRL2);
171
172 /* Find a supported LRCLK ratio */
173 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
174 if (wm8523->sysclk / params_rate(params) ==
175 lrclk_ratios[i].ratio)
176 break;
177 }
178
179 /* Should never happen, should be handled by constraints */
180 if (i == ARRAY_SIZE(lrclk_ratios)) {
181 dev_err(codec->dev, "MCLK/fs ratio %d unsupported\n",
182 wm8523->sysclk / params_rate(params));
183 return -EINVAL;
184 }
185
186 aifctrl2 &= ~WM8523_SR_MASK;
187 aifctrl2 |= lrclk_ratios[i].value;
188
189 aifctrl1 &= ~WM8523_WL_MASK;
190 switch (params_format(params)) {
191 case SNDRV_PCM_FORMAT_S16_LE:
192 break;
193 case SNDRV_PCM_FORMAT_S20_3LE:
194 aifctrl1 |= 0x8;
195 break;
196 case SNDRV_PCM_FORMAT_S24_LE:
197 aifctrl1 |= 0x10;
198 break;
199 case SNDRV_PCM_FORMAT_S32_LE:
200 aifctrl1 |= 0x18;
201 break;
202 }
203
204 snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
205 snd_soc_write(codec, WM8523_AIF_CTRL2, aifctrl2);
206
207 return 0;
208}
209
210static int wm8523_set_dai_sysclk(struct snd_soc_dai *codec_dai,
211 int clk_id, unsigned int freq, int dir)
212{
213 struct snd_soc_codec *codec = codec_dai->codec;
214 struct wm8523_priv *wm8523 = codec->private_data;
215 unsigned int val;
216 int i;
217
218 wm8523->sysclk = freq;
219
220 wm8523->rate_constraint.count = 0;
221 for (i = 0; i < ARRAY_SIZE(lrclk_ratios); i++) {
222 val = freq / lrclk_ratios[i].ratio;
223 /* Check that it's a standard rate since core can't
224 * cope with others and having the odd rates confuses
225 * constraint matching.
226 */
227 switch (val) {
228 case 8000:
229 case 11025:
230 case 16000:
231 case 22050:
232 case 32000:
233 case 44100:
234 case 48000:
235 case 64000:
236 case 88200:
237 case 96000:
238 case 176400:
239 case 192000:
240 dev_dbg(codec->dev, "Supported sample rate: %dHz\n",
241 val);
242 wm8523->rate_constraint_list[i] = val;
243 wm8523->rate_constraint.count++;
244 break;
245 default:
246 dev_dbg(codec->dev, "Skipping sample rate: %dHz\n",
247 val);
248 }
249 }
250
251 /* Need at least one supported rate... */
252 if (wm8523->rate_constraint.count == 0)
253 return -EINVAL;
254
255 return 0;
256}
257
258
259static int wm8523_set_dai_fmt(struct snd_soc_dai *codec_dai,
260 unsigned int fmt)
261{
262 struct snd_soc_codec *codec = codec_dai->codec;
263 u16 aifctrl1 = snd_soc_read(codec, WM8523_AIF_CTRL1);
264
265 aifctrl1 &= ~(WM8523_BCLK_INV_MASK | WM8523_LRCLK_INV_MASK |
266 WM8523_FMT_MASK | WM8523_AIF_MSTR_MASK);
267
268 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
269 case SND_SOC_DAIFMT_CBM_CFM:
270 aifctrl1 |= WM8523_AIF_MSTR;
271 break;
272 case SND_SOC_DAIFMT_CBS_CFS:
273 break;
274 default:
275 return -EINVAL;
276 }
277
278 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
279 case SND_SOC_DAIFMT_I2S:
280 aifctrl1 |= 0x0002;
281 break;
282 case SND_SOC_DAIFMT_RIGHT_J:
283 break;
284 case SND_SOC_DAIFMT_LEFT_J:
285 aifctrl1 |= 0x0001;
286 break;
287 case SND_SOC_DAIFMT_DSP_A:
288 aifctrl1 |= 0x0003;
289 break;
290 case SND_SOC_DAIFMT_DSP_B:
291 aifctrl1 |= 0x0023;
292 break;
293 default:
294 return -EINVAL;
295 }
296
297 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
298 case SND_SOC_DAIFMT_NB_NF:
299 break;
300 case SND_SOC_DAIFMT_IB_IF:
301 aifctrl1 |= WM8523_BCLK_INV | WM8523_LRCLK_INV;
302 break;
303 case SND_SOC_DAIFMT_IB_NF:
304 aifctrl1 |= WM8523_BCLK_INV;
305 break;
306 case SND_SOC_DAIFMT_NB_IF:
307 aifctrl1 |= WM8523_LRCLK_INV;
308 break;
309 default:
310 return -EINVAL;
311 }
312
313 snd_soc_write(codec, WM8523_AIF_CTRL1, aifctrl1);
314
315 return 0;
316}
317
318static int wm8523_set_bias_level(struct snd_soc_codec *codec,
319 enum snd_soc_bias_level level)
320{
321 struct wm8523_priv *wm8523 = codec->private_data;
322 int ret, i;
323
324 switch (level) {
325 case SND_SOC_BIAS_ON:
326 break;
327
328 case SND_SOC_BIAS_PREPARE:
329 /* Full power on */
330 snd_soc_update_bits(codec, WM8523_PSCTRL1,
331 WM8523_SYS_ENA_MASK, 3);
332 break;
333
334 case SND_SOC_BIAS_STANDBY:
335 if (codec->bias_level == SND_SOC_BIAS_OFF) {
336 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
337 wm8523->supplies);
338 if (ret != 0) {
339 dev_err(codec->dev,
340 "Failed to enable supplies: %d\n",
341 ret);
342 return ret;
343 }
344
345 /* Initial power up */
346 snd_soc_update_bits(codec, WM8523_PSCTRL1,
347 WM8523_SYS_ENA_MASK, 1);
348
349 /* Sync back default/cached values */
350 for (i = WM8523_AIF_CTRL1;
351 i < WM8523_MAX_REGISTER; i++)
352 snd_soc_write(codec, i, wm8523->reg_cache[i]);
353
354
355 msleep(100);
356 }
357
358 /* Power up to mute */
359 snd_soc_update_bits(codec, WM8523_PSCTRL1,
360 WM8523_SYS_ENA_MASK, 2);
361
362 break;
363
364 case SND_SOC_BIAS_OFF:
365 /* The chip runs through the power down sequence for us. */
366 snd_soc_update_bits(codec, WM8523_PSCTRL1,
367 WM8523_SYS_ENA_MASK, 0);
368 msleep(100);
369
370 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies),
371 wm8523->supplies);
372 break;
373 }
374 codec->bias_level = level;
375 return 0;
376}
377
378#define WM8523_RATES SNDRV_PCM_RATE_8000_192000
379
380#define WM8523_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
381 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
382
383static struct snd_soc_dai_ops wm8523_dai_ops = {
384 .startup = wm8523_startup,
385 .hw_params = wm8523_hw_params,
386 .set_sysclk = wm8523_set_dai_sysclk,
387 .set_fmt = wm8523_set_dai_fmt,
388};
389
390struct snd_soc_dai wm8523_dai = {
391 .name = "WM8523",
392 .playback = {
393 .stream_name = "Playback",
394 .channels_min = 2, /* Mono modes not yet supported */
395 .channels_max = 2,
396 .rates = WM8523_RATES,
397 .formats = WM8523_FORMATS,
398 },
399 .ops = &wm8523_dai_ops,
400};
401EXPORT_SYMBOL_GPL(wm8523_dai);
402
403#ifdef CONFIG_PM
404static int wm8523_suspend(struct platform_device *pdev, pm_message_t state)
405{
406 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
407 struct snd_soc_codec *codec = socdev->card->codec;
408
409 wm8523_set_bias_level(codec, SND_SOC_BIAS_OFF);
410 return 0;
411}
412
413static int wm8523_resume(struct platform_device *pdev)
414{
415 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
416 struct snd_soc_codec *codec = socdev->card->codec;
417
418 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
419
420 return 0;
421}
422#else
423#define wm8523_suspend NULL
424#define wm8523_resume NULL
425#endif
426
427static int wm8523_probe(struct platform_device *pdev)
428{
429 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
430 struct snd_soc_codec *codec;
431 int ret = 0;
432
433 if (wm8523_codec == NULL) {
434 dev_err(&pdev->dev, "Codec device not registered\n");
435 return -ENODEV;
436 }
437
438 socdev->card->codec = wm8523_codec;
439 codec = wm8523_codec;
440
441 /* register pcms */
442 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
443 if (ret < 0) {
444 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
445 goto pcm_err;
446 }
447
448 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456
457 return ret;
458
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err:
463 return ret;
464}
465
466static int wm8523_remove(struct platform_device *pdev)
467{
468 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
469
470 snd_soc_free_pcms(socdev);
471 snd_soc_dapm_free(socdev);
472
473 return 0;
474}
475
476struct snd_soc_codec_device soc_codec_dev_wm8523 = {
477 .probe = wm8523_probe,
478 .remove = wm8523_remove,
479 .suspend = wm8523_suspend,
480 .resume = wm8523_resume,
481};
482EXPORT_SYMBOL_GPL(soc_codec_dev_wm8523);
483
484static int wm8523_register(struct wm8523_priv *wm8523,
485 enum snd_soc_control_type control)
486{
487 int ret;
488 struct snd_soc_codec *codec = &wm8523->codec;
489 int i;
490
491 if (wm8523_codec) {
492 dev_err(codec->dev, "Another WM8523 is registered\n");
493 return -EINVAL;
494 }
495
496 mutex_init(&codec->mutex);
497 INIT_LIST_HEAD(&codec->dapm_widgets);
498 INIT_LIST_HEAD(&codec->dapm_paths);
499
500 codec->private_data = wm8523;
501 codec->name = "WM8523";
502 codec->owner = THIS_MODULE;
503 codec->bias_level = SND_SOC_BIAS_OFF;
504 codec->set_bias_level = wm8523_set_bias_level;
505 codec->dai = &wm8523_dai;
506 codec->num_dai = 1;
507 codec->reg_cache_size = WM8523_REGISTER_COUNT;
508 codec->reg_cache = &wm8523->reg_cache;
509 codec->volatile_register = wm8523_volatile_register;
510
511 wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0];
512 wm8523->rate_constraint.count =
513 ARRAY_SIZE(wm8523->rate_constraint_list);
514
515 memcpy(codec->reg_cache, wm8523_reg, sizeof(wm8523_reg));
516
517 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
518 if (ret != 0) {
519 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
520 goto err;
521 }
522
523 for (i = 0; i < ARRAY_SIZE(wm8523->supplies); i++)
524 wm8523->supplies[i].supply = wm8523_supply_names[i];
525
526 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8523->supplies),
527 wm8523->supplies);
528 if (ret != 0) {
529 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
530 goto err;
531 }
532
533 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
534 wm8523->supplies);
535 if (ret != 0) {
536 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
537 goto err_get;
538 }
539
540 ret = snd_soc_read(codec, WM8523_DEVICE_ID);
541 if (ret < 0) {
542 dev_err(codec->dev, "Failed to read ID register\n");
543 goto err_enable;
544 }
545 if (ret != wm8523_reg[WM8523_DEVICE_ID]) {
546 dev_err(codec->dev, "Device is not a WM8523, ID is %x\n", ret);
547 ret = -EINVAL;
548 goto err_enable;
549 }
550
551 ret = snd_soc_read(codec, WM8523_REVISION);
552 if (ret < 0) {
553 dev_err(codec->dev, "Failed to read revision register\n");
554 goto err_enable;
555 }
556 dev_info(codec->dev, "revision %c\n",
557 (ret & WM8523_CHIP_REV_MASK) + 'A');
558
559 ret = wm8523_reset(codec);
560 if (ret < 0) {
561 dev_err(codec->dev, "Failed to issue reset\n");
562 goto err_enable;
563 }
564
565 wm8523_dai.dev = codec->dev;
566
567 /* Change some default settings - latch VU and enable ZC */
568 wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU;
569 wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC;
570
571 wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
572
573 /* Bias level configuration will have done an extra enable */
574 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
575
576 wm8523_codec = codec;
577
578 ret = snd_soc_register_codec(codec);
579 if (ret != 0) {
580 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
581 return ret;
582 }
583
584 ret = snd_soc_register_dai(&wm8523_dai);
585 if (ret != 0) {
586 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
587 snd_soc_unregister_codec(codec);
588 return ret;
589 }
590
591 return 0;
592
593err_enable:
594 regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
595err_get:
596 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
597err:
598 kfree(wm8523);
599 return ret;
600}
601
602static void wm8523_unregister(struct wm8523_priv *wm8523)
603{
604 wm8523_set_bias_level(&wm8523->codec, SND_SOC_BIAS_OFF);
605 regulator_bulk_free(ARRAY_SIZE(wm8523->supplies), wm8523->supplies);
606 snd_soc_unregister_dai(&wm8523_dai);
607 snd_soc_unregister_codec(&wm8523->codec);
608 kfree(wm8523);
609 wm8523_codec = NULL;
610}
611
612#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
613static __devinit int wm8523_i2c_probe(struct i2c_client *i2c,
614 const struct i2c_device_id *id)
615{
616 struct wm8523_priv *wm8523;
617 struct snd_soc_codec *codec;
618
619 wm8523 = kzalloc(sizeof(struct wm8523_priv), GFP_KERNEL);
620 if (wm8523 == NULL)
621 return -ENOMEM;
622
623 codec = &wm8523->codec;
624 codec->hw_write = (hw_write_t)i2c_master_send;
625
626 i2c_set_clientdata(i2c, wm8523);
627 codec->control_data = i2c;
628
629 codec->dev = &i2c->dev;
630
631 return wm8523_register(wm8523, SND_SOC_I2C);
632}
633
634static __devexit int wm8523_i2c_remove(struct i2c_client *client)
635{
636 struct wm8523_priv *wm8523 = i2c_get_clientdata(client);
637 wm8523_unregister(wm8523);
638 return 0;
639}
640
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 },
658 { }
659};
660MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id);
661
662static struct i2c_driver wm8523_i2c_driver = {
663 .driver = {
664 .name = "WM8523",
665 .owner = THIS_MODULE,
666 },
667 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id,
672};
673#endif
674
675static int __init wm8523_modinit(void)
676{
677 int ret;
678#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
679 ret = i2c_add_driver(&wm8523_i2c_driver);
680 if (ret != 0) {
681 printk(KERN_ERR "Failed to register WM8523 I2C driver: %d\n",
682 ret);
683 }
684#endif
685 return 0;
686}
687module_init(wm8523_modinit);
688
689static void __exit wm8523_exit(void)
690{
691#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
692 i2c_del_driver(&wm8523_i2c_driver);
693#endif
694}
695module_exit(wm8523_exit);
696
697MODULE_DESCRIPTION("ASoC WM8523 driver");
698MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
699MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8523.h b/sound/soc/codecs/wm8523.h
new file mode 100644
index 000000000000..1aa9ce3e1357
--- /dev/null
+++ b/sound/soc/codecs/wm8523.h
@@ -0,0 +1,160 @@
1/*
2 * wm8523.h -- WM8423 ASoC driver
3 *
4 * Copyright 2009 Wolfson Microelectronics, plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8753.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8523_H
16#define _WM8523_H
17
18/*
19 * Register values.
20 */
21#define WM8523_DEVICE_ID 0x00
22#define WM8523_REVISION 0x01
23#define WM8523_PSCTRL1 0x02
24#define WM8523_AIF_CTRL1 0x03
25#define WM8523_AIF_CTRL2 0x04
26#define WM8523_DAC_CTRL3 0x05
27#define WM8523_DAC_GAINL 0x06
28#define WM8523_DAC_GAINR 0x07
29#define WM8523_ZERO_DETECT 0x08
30
31#define WM8523_REGISTER_COUNT 9
32#define WM8523_MAX_REGISTER 0x08
33
34/*
35 * Field Definitions.
36 */
37
38/*
39 * R0 (0x00) - DEVICE_ID
40 */
41#define WM8523_CHIP_ID_MASK 0xFFFF /* CHIP_ID - [15:0] */
42#define WM8523_CHIP_ID_SHIFT 0 /* CHIP_ID - [15:0] */
43#define WM8523_CHIP_ID_WIDTH 16 /* CHIP_ID - [15:0] */
44
45/*
46 * R1 (0x01) - REVISION
47 */
48#define WM8523_CHIP_REV_MASK 0x0007 /* CHIP_REV - [2:0] */
49#define WM8523_CHIP_REV_SHIFT 0 /* CHIP_REV - [2:0] */
50#define WM8523_CHIP_REV_WIDTH 3 /* CHIP_REV - [2:0] */
51
52/*
53 * R2 (0x02) - PSCTRL1
54 */
55#define WM8523_SYS_ENA_MASK 0x0003 /* SYS_ENA - [1:0] */
56#define WM8523_SYS_ENA_SHIFT 0 /* SYS_ENA - [1:0] */
57#define WM8523_SYS_ENA_WIDTH 2 /* SYS_ENA - [1:0] */
58
59/*
60 * R3 (0x03) - AIF_CTRL1
61 */
62#define WM8523_TDM_MODE_MASK 0x1800 /* TDM_MODE - [12:11] */
63#define WM8523_TDM_MODE_SHIFT 11 /* TDM_MODE - [12:11] */
64#define WM8523_TDM_MODE_WIDTH 2 /* TDM_MODE - [12:11] */
65#define WM8523_TDM_SLOT_MASK 0x0600 /* TDM_SLOT - [10:9] */
66#define WM8523_TDM_SLOT_SHIFT 9 /* TDM_SLOT - [10:9] */
67#define WM8523_TDM_SLOT_WIDTH 2 /* TDM_SLOT - [10:9] */
68#define WM8523_DEEMPH 0x0100 /* DEEMPH */
69#define WM8523_DEEMPH_MASK 0x0100 /* DEEMPH */
70#define WM8523_DEEMPH_SHIFT 8 /* DEEMPH */
71#define WM8523_DEEMPH_WIDTH 1 /* DEEMPH */
72#define WM8523_AIF_MSTR 0x0080 /* AIF_MSTR */
73#define WM8523_AIF_MSTR_MASK 0x0080 /* AIF_MSTR */
74#define WM8523_AIF_MSTR_SHIFT 7 /* AIF_MSTR */
75#define WM8523_AIF_MSTR_WIDTH 1 /* AIF_MSTR */
76#define WM8523_LRCLK_INV 0x0040 /* LRCLK_INV */
77#define WM8523_LRCLK_INV_MASK 0x0040 /* LRCLK_INV */
78#define WM8523_LRCLK_INV_SHIFT 6 /* LRCLK_INV */
79#define WM8523_LRCLK_INV_WIDTH 1 /* LRCLK_INV */
80#define WM8523_BCLK_INV 0x0020 /* BCLK_INV */
81#define WM8523_BCLK_INV_MASK 0x0020 /* BCLK_INV */
82#define WM8523_BCLK_INV_SHIFT 5 /* BCLK_INV */
83#define WM8523_BCLK_INV_WIDTH 1 /* BCLK_INV */
84#define WM8523_WL_MASK 0x0018 /* WL - [4:3] */
85#define WM8523_WL_SHIFT 3 /* WL - [4:3] */
86#define WM8523_WL_WIDTH 2 /* WL - [4:3] */
87#define WM8523_FMT_MASK 0x0007 /* FMT - [2:0] */
88#define WM8523_FMT_SHIFT 0 /* FMT - [2:0] */
89#define WM8523_FMT_WIDTH 3 /* FMT - [2:0] */
90
91/*
92 * R4 (0x04) - AIF_CTRL2
93 */
94#define WM8523_DAC_OP_MUX_MASK 0x00C0 /* DAC_OP_MUX - [7:6] */
95#define WM8523_DAC_OP_MUX_SHIFT 6 /* DAC_OP_MUX - [7:6] */
96#define WM8523_DAC_OP_MUX_WIDTH 2 /* DAC_OP_MUX - [7:6] */
97#define WM8523_BCLKDIV_MASK 0x0038 /* BCLKDIV - [5:3] */
98#define WM8523_BCLKDIV_SHIFT 3 /* BCLKDIV - [5:3] */
99#define WM8523_BCLKDIV_WIDTH 3 /* BCLKDIV - [5:3] */
100#define WM8523_SR_MASK 0x0007 /* SR - [2:0] */
101#define WM8523_SR_SHIFT 0 /* SR - [2:0] */
102#define WM8523_SR_WIDTH 3 /* SR - [2:0] */
103
104/*
105 * R5 (0x05) - DAC_CTRL3
106 */
107#define WM8523_ZC 0x0010 /* ZC */
108#define WM8523_ZC_MASK 0x0010 /* ZC */
109#define WM8523_ZC_SHIFT 4 /* ZC */
110#define WM8523_ZC_WIDTH 1 /* ZC */
111#define WM8523_DACR 0x0008 /* DACR */
112#define WM8523_DACR_MASK 0x0008 /* DACR */
113#define WM8523_DACR_SHIFT 3 /* DACR */
114#define WM8523_DACR_WIDTH 1 /* DACR */
115#define WM8523_DACL 0x0004 /* DACL */
116#define WM8523_DACL_MASK 0x0004 /* DACL */
117#define WM8523_DACL_SHIFT 2 /* DACL */
118#define WM8523_DACL_WIDTH 1 /* DACL */
119#define WM8523_VOL_UP_RAMP 0x0002 /* VOL_UP_RAMP */
120#define WM8523_VOL_UP_RAMP_MASK 0x0002 /* VOL_UP_RAMP */
121#define WM8523_VOL_UP_RAMP_SHIFT 1 /* VOL_UP_RAMP */
122#define WM8523_VOL_UP_RAMP_WIDTH 1 /* VOL_UP_RAMP */
123#define WM8523_VOL_DOWN_RAMP 0x0001 /* VOL_DOWN_RAMP */
124#define WM8523_VOL_DOWN_RAMP_MASK 0x0001 /* VOL_DOWN_RAMP */
125#define WM8523_VOL_DOWN_RAMP_SHIFT 0 /* VOL_DOWN_RAMP */
126#define WM8523_VOL_DOWN_RAMP_WIDTH 1 /* VOL_DOWN_RAMP */
127
128/*
129 * R6 (0x06) - DAC_GAINL
130 */
131#define WM8523_DACL_VU 0x0200 /* DACL_VU */
132#define WM8523_DACL_VU_MASK 0x0200 /* DACL_VU */
133#define WM8523_DACL_VU_SHIFT 9 /* DACL_VU */
134#define WM8523_DACL_VU_WIDTH 1 /* DACL_VU */
135#define WM8523_DACL_VOL_MASK 0x01FF /* DACL_VOL - [8:0] */
136#define WM8523_DACL_VOL_SHIFT 0 /* DACL_VOL - [8:0] */
137#define WM8523_DACL_VOL_WIDTH 9 /* DACL_VOL - [8:0] */
138
139/*
140 * R7 (0x07) - DAC_GAINR
141 */
142#define WM8523_DACR_VU 0x0200 /* DACR_VU */
143#define WM8523_DACR_VU_MASK 0x0200 /* DACR_VU */
144#define WM8523_DACR_VU_SHIFT 9 /* DACR_VU */
145#define WM8523_DACR_VU_WIDTH 1 /* DACR_VU */
146#define WM8523_DACR_VOL_MASK 0x01FF /* DACR_VOL - [8:0] */
147#define WM8523_DACR_VOL_SHIFT 0 /* DACR_VOL - [8:0] */
148#define WM8523_DACR_VOL_WIDTH 9 /* DACR_VOL - [8:0] */
149
150/*
151 * R8 (0x08) - ZERO_DETECT
152 */
153#define WM8523_ZD_COUNT_MASK 0x0003 /* ZD_COUNT - [1:0] */
154#define WM8523_ZD_COUNT_SHIFT 0 /* ZD_COUNT - [1:0] */
155#define WM8523_ZD_COUNT_WIDTH 2 /* ZD_COUNT - [1:0] */
156
157extern struct snd_soc_dai wm8523_dai;
158extern struct snd_soc_codec_device soc_codec_dev_wm8523;
159
160#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 86c4b24db817..6bded8c78150 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -24,6 +24,8 @@
24#include <linux/pm.h> 24#include <linux/pm.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h>
28
27#include <sound/core.h> 29#include <sound/core.h>
28#include <sound/pcm.h> 30#include <sound/pcm.h>
29#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -187,82 +189,22 @@ struct pll_state {
187 unsigned int out; 189 unsigned int out;
188}; 190};
189 191
192#define WM8580_NUM_SUPPLIES 3
193static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
194 "AVDD",
195 "DVDD",
196 "PVDD",
197};
198
190/* codec private data */ 199/* codec private data */
191struct wm8580_priv { 200struct wm8580_priv {
192 struct snd_soc_codec codec; 201 struct snd_soc_codec codec;
202 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
193 u16 reg_cache[WM8580_MAX_REGISTER + 1]; 203 u16 reg_cache[WM8580_MAX_REGISTER + 1];
194 struct pll_state a; 204 struct pll_state a;
195 struct pll_state b; 205 struct pll_state b;
196}; 206};
197 207
198
199/*
200 * read wm8580 register cache
201 */
202static inline unsigned int wm8580_read_reg_cache(struct snd_soc_codec *codec,
203 unsigned int reg)
204{
205 u16 *cache = codec->reg_cache;
206 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
207 return cache[reg];
208}
209
210/*
211 * write wm8580 register cache
212 */
213static inline void wm8580_write_reg_cache(struct snd_soc_codec *codec,
214 unsigned int reg, unsigned int value)
215{
216 u16 *cache = codec->reg_cache;
217
218 cache[reg] = value;
219}
220
221/*
222 * write to the WM8580 register space
223 */
224static int wm8580_write(struct snd_soc_codec *codec, unsigned int reg,
225 unsigned int value)
226{
227 u8 data[2];
228
229 BUG_ON(reg >= ARRAY_SIZE(wm8580_reg));
230
231 /* Registers are 9 bits wide */
232 value &= 0x1ff;
233
234 switch (reg) {
235 case WM8580_RESET:
236 /* Uncached */
237 break;
238 default:
239 if (value == wm8580_read_reg_cache(codec, reg))
240 return 0;
241 }
242
243 /* data is
244 * D15..D9 WM8580 register offset
245 * D8...D0 register data
246 */
247 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
248 data[1] = value & 0x00ff;
249
250 wm8580_write_reg_cache(codec, reg, value);
251 if (codec->hw_write(codec->control_data, data, 2) == 2)
252 return 0;
253 else
254 return -EIO;
255}
256
257static inline unsigned int wm8580_read(struct snd_soc_codec *codec,
258 unsigned int reg)
259{
260 switch (reg) {
261 default:
262 return wm8580_read_reg_cache(codec, reg);
263 }
264}
265
266static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); 208static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
267 209
268static int wm8580_out_vu(struct snd_kcontrol *kcontrol, 210static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
@@ -271,25 +213,22 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
271 struct soc_mixer_control *mc = 213 struct soc_mixer_control *mc =
272 (struct soc_mixer_control *)kcontrol->private_value; 214 (struct soc_mixer_control *)kcontrol->private_value;
273 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 215 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
216 u16 *reg_cache = codec->reg_cache;
274 unsigned int reg = mc->reg; 217 unsigned int reg = mc->reg;
275 unsigned int reg2 = mc->rreg; 218 unsigned int reg2 = mc->rreg;
276 int ret; 219 int ret;
277 u16 val;
278 220
279 /* Clear the register cache so we write without VU set */ 221 /* Clear the register cache so we write without VU set */
280 wm8580_write_reg_cache(codec, reg, 0); 222 reg_cache[reg] = 0;
281 wm8580_write_reg_cache(codec, reg2, 0); 223 reg_cache[reg2] = 0;
282 224
283 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 225 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
284 if (ret < 0) 226 if (ret < 0)
285 return ret; 227 return ret;
286 228
287 /* Now write again with the volume update bit set */ 229 /* Now write again with the volume update bit set */
288 val = wm8580_read_reg_cache(codec, reg); 230 snd_soc_update_bits(codec, reg, 0x100, 0x100);
289 wm8580_write(codec, reg, val | 0x0100); 231 snd_soc_update_bits(codec, reg2, 0x100, 0x100);
290
291 val = wm8580_read_reg_cache(codec, reg2);
292 wm8580_write(codec, reg2, val | 0x0100);
293 232
294 return 0; 233 return 0;
295} 234}
@@ -512,27 +451,27 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
512 /* Always disable the PLL - it is not safe to leave it running 451 /* Always disable the PLL - it is not safe to leave it running
513 * while reprogramming it. 452 * while reprogramming it.
514 */ 453 */
515 reg = wm8580_read(codec, WM8580_PWRDN2); 454 reg = snd_soc_read(codec, WM8580_PWRDN2);
516 wm8580_write(codec, WM8580_PWRDN2, reg | pwr_mask); 455 snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
517 456
518 if (!freq_in || !freq_out) 457 if (!freq_in || !freq_out)
519 return 0; 458 return 0;
520 459
521 wm8580_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff); 460 snd_soc_write(codec, WM8580_PLLA1 + offset, pll_div.k & 0x1ff);
522 wm8580_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0xff); 461 snd_soc_write(codec, WM8580_PLLA2 + offset, (pll_div.k >> 9) & 0x1ff);
523 wm8580_write(codec, WM8580_PLLA3 + offset, 462 snd_soc_write(codec, WM8580_PLLA3 + offset,
524 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4)); 463 (pll_div.k >> 18 & 0xf) | (pll_div.n << 4));
525 464
526 reg = wm8580_read(codec, WM8580_PLLA4 + offset); 465 reg = snd_soc_read(codec, WM8580_PLLA4 + offset);
527 reg &= ~0x3f; 466 reg &= ~0x1b;
528 reg |= pll_div.prescale | pll_div.postscale << 1 | 467 reg |= pll_div.prescale | pll_div.postscale << 1 |
529 pll_div.freqmode << 3; 468 pll_div.freqmode << 3;
530 469
531 wm8580_write(codec, WM8580_PLLA4 + offset, reg); 470 snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
532 471
533 /* All done, turn it on */ 472 /* All done, turn it on */
534 reg = wm8580_read(codec, WM8580_PWRDN2); 473 reg = snd_soc_read(codec, WM8580_PWRDN2);
535 wm8580_write(codec, WM8580_PWRDN2, reg & ~pwr_mask); 474 snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
536 475
537 return 0; 476 return 0;
538} 477}
@@ -547,7 +486,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
547 struct snd_soc_pcm_runtime *rtd = substream->private_data; 486 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_device *socdev = rtd->socdev; 487 struct snd_soc_device *socdev = rtd->socdev;
549 struct snd_soc_codec *codec = socdev->card->codec; 488 struct snd_soc_codec *codec = socdev->card->codec;
550 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id); 489 u16 paifb = snd_soc_read(codec, WM8580_PAIF3 + dai->id);
551 490
552 paifb &= ~WM8580_AIF_LENGTH_MASK; 491 paifb &= ~WM8580_AIF_LENGTH_MASK;
553 /* bit size */ 492 /* bit size */
@@ -567,7 +506,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
567 return -EINVAL; 506 return -EINVAL;
568 } 507 }
569 508
570 wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb); 509 snd_soc_write(codec, WM8580_PAIF3 + dai->id, paifb);
571 return 0; 510 return 0;
572} 511}
573 512
@@ -579,8 +518,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
579 unsigned int aifb; 518 unsigned int aifb;
580 int can_invert_lrclk; 519 int can_invert_lrclk;
581 520
582 aifa = wm8580_read(codec, WM8580_PAIF1 + codec_dai->id); 521 aifa = snd_soc_read(codec, WM8580_PAIF1 + codec_dai->id);
583 aifb = wm8580_read(codec, WM8580_PAIF3 + codec_dai->id); 522 aifb = snd_soc_read(codec, WM8580_PAIF3 + codec_dai->id);
584 523
585 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP); 524 aifb &= ~(WM8580_AIF_FMT_MASK | WM8580_AIF_LRP | WM8580_AIF_BCP);
586 525
@@ -646,8 +585,8 @@ static int wm8580_set_paif_dai_fmt(struct snd_soc_dai *codec_dai,
646 return -EINVAL; 585 return -EINVAL;
647 } 586 }
648 587
649 wm8580_write(codec, WM8580_PAIF1 + codec_dai->id, aifa); 588 snd_soc_write(codec, WM8580_PAIF1 + codec_dai->id, aifa);
650 wm8580_write(codec, WM8580_PAIF3 + codec_dai->id, aifb); 589 snd_soc_write(codec, WM8580_PAIF3 + codec_dai->id, aifb);
651 590
652 return 0; 591 return 0;
653} 592}
@@ -660,7 +599,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
660 599
661 switch (div_id) { 600 switch (div_id) {
662 case WM8580_MCLK: 601 case WM8580_MCLK:
663 reg = wm8580_read(codec, WM8580_PLLB4); 602 reg = snd_soc_read(codec, WM8580_PLLB4);
664 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK; 603 reg &= ~WM8580_PLLB4_MCLKOUTSRC_MASK;
665 604
666 switch (div) { 605 switch (div) {
@@ -682,11 +621,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
682 default: 621 default:
683 return -EINVAL; 622 return -EINVAL;
684 } 623 }
685 wm8580_write(codec, WM8580_PLLB4, reg); 624 snd_soc_write(codec, WM8580_PLLB4, reg);
686 break; 625 break;
687 626
688 case WM8580_DAC_CLKSEL: 627 case WM8580_DAC_CLKSEL:
689 reg = wm8580_read(codec, WM8580_CLKSEL); 628 reg = snd_soc_read(codec, WM8580_CLKSEL);
690 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK; 629 reg &= ~WM8580_CLKSEL_DAC_CLKSEL_MASK;
691 630
692 switch (div) { 631 switch (div) {
@@ -704,11 +643,11 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
704 default: 643 default:
705 return -EINVAL; 644 return -EINVAL;
706 } 645 }
707 wm8580_write(codec, WM8580_CLKSEL, reg); 646 snd_soc_write(codec, WM8580_CLKSEL, reg);
708 break; 647 break;
709 648
710 case WM8580_CLKOUTSRC: 649 case WM8580_CLKOUTSRC:
711 reg = wm8580_read(codec, WM8580_PLLB4); 650 reg = snd_soc_read(codec, WM8580_PLLB4);
712 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK; 651 reg &= ~WM8580_PLLB4_CLKOUTSRC_MASK;
713 652
714 switch (div) { 653 switch (div) {
@@ -730,7 +669,7 @@ static int wm8580_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
730 default: 669 default:
731 return -EINVAL; 670 return -EINVAL;
732 } 671 }
733 wm8580_write(codec, WM8580_PLLB4, reg); 672 snd_soc_write(codec, WM8580_PLLB4, reg);
734 break; 673 break;
735 674
736 default: 675 default:
@@ -745,14 +684,14 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
745 struct snd_soc_codec *codec = codec_dai->codec; 684 struct snd_soc_codec *codec = codec_dai->codec;
746 unsigned int reg; 685 unsigned int reg;
747 686
748 reg = wm8580_read(codec, WM8580_DAC_CONTROL5); 687 reg = snd_soc_read(codec, WM8580_DAC_CONTROL5);
749 688
750 if (mute) 689 if (mute)
751 reg |= WM8580_DAC_CONTROL5_MUTEALL; 690 reg |= WM8580_DAC_CONTROL5_MUTEALL;
752 else 691 else
753 reg &= ~WM8580_DAC_CONTROL5_MUTEALL; 692 reg &= ~WM8580_DAC_CONTROL5_MUTEALL;
754 693
755 wm8580_write(codec, WM8580_DAC_CONTROL5, reg); 694 snd_soc_write(codec, WM8580_DAC_CONTROL5, reg);
756 695
757 return 0; 696 return 0;
758} 697}
@@ -769,20 +708,20 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
769 case SND_SOC_BIAS_STANDBY: 708 case SND_SOC_BIAS_STANDBY:
770 if (codec->bias_level == SND_SOC_BIAS_OFF) { 709 if (codec->bias_level == SND_SOC_BIAS_OFF) {
771 /* Power up and get individual control of the DACs */ 710 /* Power up and get individual control of the DACs */
772 reg = wm8580_read(codec, WM8580_PWRDN1); 711 reg = snd_soc_read(codec, WM8580_PWRDN1);
773 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 712 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
774 wm8580_write(codec, WM8580_PWRDN1, reg); 713 snd_soc_write(codec, WM8580_PWRDN1, reg);
775 714
776 /* Make VMID high impedence */ 715 /* Make VMID high impedence */
777 reg = wm8580_read(codec, WM8580_ADC_CONTROL1); 716 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1);
778 reg &= ~0x100; 717 reg &= ~0x100;
779 wm8580_write(codec, WM8580_ADC_CONTROL1, reg); 718 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
780 } 719 }
781 break; 720 break;
782 721
783 case SND_SOC_BIAS_OFF: 722 case SND_SOC_BIAS_OFF:
784 reg = wm8580_read(codec, WM8580_PWRDN1); 723 reg = snd_soc_read(codec, WM8580_PWRDN1);
785 wm8580_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 724 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
786 break; 725 break;
787 } 726 }
788 codec->bias_level = level; 727 codec->bias_level = level;
@@ -893,7 +832,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
893}; 832};
894EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); 833EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
895 834
896static int wm8580_register(struct wm8580_priv *wm8580) 835static int wm8580_register(struct wm8580_priv *wm8580,
836 enum snd_soc_control_type control)
897{ 837{
898 int ret, i; 838 int ret, i;
899 struct snd_soc_codec *codec = &wm8580->codec; 839 struct snd_soc_codec *codec = &wm8580->codec;
@@ -911,8 +851,6 @@ static int wm8580_register(struct wm8580_priv *wm8580)
911 codec->private_data = wm8580; 851 codec->private_data = wm8580;
912 codec->name = "WM8580"; 852 codec->name = "WM8580";
913 codec->owner = THIS_MODULE; 853 codec->owner = THIS_MODULE;
914 codec->read = wm8580_read_reg_cache;
915 codec->write = wm8580_write;
916 codec->bias_level = SND_SOC_BIAS_OFF; 854 codec->bias_level = SND_SOC_BIAS_OFF;
917 codec->set_bias_level = wm8580_set_bias_level; 855 codec->set_bias_level = wm8580_set_bias_level;
918 codec->dai = wm8580_dai; 856 codec->dai = wm8580_dai;
@@ -922,11 +860,34 @@ static int wm8580_register(struct wm8580_priv *wm8580)
922 860
923 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg)); 861 memcpy(codec->reg_cache, wm8580_reg, sizeof(wm8580_reg));
924 862
863 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
864 if (ret < 0) {
865 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
866 goto err;
867 }
868
869 for (i = 0; i < ARRAY_SIZE(wm8580->supplies); i++)
870 wm8580->supplies[i].supply = wm8580_supply_names[i];
871
872 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8580->supplies),
873 wm8580->supplies);
874 if (ret != 0) {
875 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
876 goto err;
877 }
878
879 ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies),
880 wm8580->supplies);
881 if (ret != 0) {
882 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
883 goto err_regulator_get;
884 }
885
925 /* Get the codec into a known state */ 886 /* Get the codec into a known state */
926 ret = wm8580_write(codec, WM8580_RESET, 0); 887 ret = snd_soc_write(codec, WM8580_RESET, 0);
927 if (ret != 0) { 888 if (ret != 0) {
928 dev_err(codec->dev, "Failed to reset codec: %d\n", ret); 889 dev_err(codec->dev, "Failed to reset codec: %d\n", ret);
929 goto err; 890 goto err_regulator_enable;
930 } 891 }
931 892
932 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++) 893 for (i = 0; i < ARRAY_SIZE(wm8580_dai); i++)
@@ -939,7 +900,7 @@ static int wm8580_register(struct wm8580_priv *wm8580)
939 ret = snd_soc_register_codec(codec); 900 ret = snd_soc_register_codec(codec);
940 if (ret != 0) { 901 if (ret != 0) {
941 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 902 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
942 goto err; 903 goto err_regulator_enable;
943 } 904 }
944 905
945 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 906 ret = snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
@@ -952,6 +913,10 @@ static int wm8580_register(struct wm8580_priv *wm8580)
952 913
953err_codec: 914err_codec:
954 snd_soc_unregister_codec(codec); 915 snd_soc_unregister_codec(codec);
916err_regulator_enable:
917 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
918err_regulator_get:
919 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
955err: 920err:
956 kfree(wm8580); 921 kfree(wm8580);
957 return ret; 922 return ret;
@@ -962,6 +927,8 @@ static void wm8580_unregister(struct wm8580_priv *wm8580)
962 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF); 927 wm8580_set_bias_level(&wm8580->codec, SND_SOC_BIAS_OFF);
963 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai)); 928 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
964 snd_soc_unregister_codec(&wm8580->codec); 929 snd_soc_unregister_codec(&wm8580->codec);
930 regulator_bulk_disable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
931 regulator_bulk_free(ARRAY_SIZE(wm8580->supplies), wm8580->supplies);
965 kfree(wm8580); 932 kfree(wm8580);
966 wm8580_codec = NULL; 933 wm8580_codec = NULL;
967} 934}
@@ -978,14 +945,13 @@ static int wm8580_i2c_probe(struct i2c_client *i2c,
978 return -ENOMEM; 945 return -ENOMEM;
979 946
980 codec = &wm8580->codec; 947 codec = &wm8580->codec;
981 codec->hw_write = (hw_write_t)i2c_master_send;
982 948
983 i2c_set_clientdata(i2c, wm8580); 949 i2c_set_clientdata(i2c, wm8580);
984 codec->control_data = i2c; 950 codec->control_data = i2c;
985 951
986 codec->dev = &i2c->dev; 952 codec->dev = &i2c->dev;
987 953
988 return wm8580_register(wm8580); 954 return wm8580_register(wm8580, SND_SOC_I2C);
989} 955}
990 956
991static int wm8580_i2c_remove(struct i2c_client *client) 957static int wm8580_i2c_remove(struct i2c_client *client)
@@ -995,6 +961,21 @@ static int wm8580_i2c_remove(struct i2c_client *client)
995 return 0; 961 return 0;
996} 962}
997 963
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
998static const struct i2c_device_id wm8580_i2c_id[] = { 979static const struct i2c_device_id wm8580_i2c_id[] = {
999 { "wm8580", 0 }, 980 { "wm8580", 0 },
1000 { } 981 { }
@@ -1008,6 +989,8 @@ static struct i2c_driver wm8580_i2c_driver = {
1008 }, 989 },
1009 .probe = wm8580_i2c_probe, 990 .probe = wm8580_i2c_probe,
1010 .remove = wm8580_i2c_remove, 991 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
1011 .id_table = wm8580_i2c_id, 994 .id_table = wm8580_i2c_id,
1012}; 995};
1013#endif 996#endif
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index e7ff2121ede9..16e969a762c3 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -43,45 +43,6 @@ static const u16 wm8728_reg_defaults[] = {
43 0x100, 43 0x100,
44}; 44};
45 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); 46static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
86 47
87static const struct snd_kcontrol_new wm8728_snd_controls[] = { 48static const struct snd_kcontrol_new wm8728_snd_controls[] = {
@@ -121,12 +82,12 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
121static int wm8728_mute(struct snd_soc_dai *dai, int mute) 82static int wm8728_mute(struct snd_soc_dai *dai, int mute)
122{ 83{
123 struct snd_soc_codec *codec = dai->codec; 84 struct snd_soc_codec *codec = dai->codec;
124 u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 85 u16 mute_reg = snd_soc_read(codec, WM8728_DACCTL);
125 86
126 if (mute) 87 if (mute)
127 wm8728_write(codec, WM8728_DACCTL, mute_reg | 1); 88 snd_soc_write(codec, WM8728_DACCTL, mute_reg | 1);
128 else 89 else
129 wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1); 90 snd_soc_write(codec, WM8728_DACCTL, mute_reg & ~1);
130 91
131 return 0; 92 return 0;
132} 93}
@@ -138,7 +99,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
138 struct snd_soc_pcm_runtime *rtd = substream->private_data; 99 struct snd_soc_pcm_runtime *rtd = substream->private_data;
139 struct snd_soc_device *socdev = rtd->socdev; 100 struct snd_soc_device *socdev = rtd->socdev;
140 struct snd_soc_codec *codec = socdev->card->codec; 101 struct snd_soc_codec *codec = socdev->card->codec;
141 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL); 102 u16 dac = snd_soc_read(codec, WM8728_DACCTL);
142 103
143 dac &= ~0x18; 104 dac &= ~0x18;
144 105
@@ -155,7 +116,7 @@ static int wm8728_hw_params(struct snd_pcm_substream *substream,
155 return -EINVAL; 116 return -EINVAL;
156 } 117 }
157 118
158 wm8728_write(codec, WM8728_DACCTL, dac); 119 snd_soc_write(codec, WM8728_DACCTL, dac);
159 120
160 return 0; 121 return 0;
161} 122}
@@ -164,7 +125,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
164 unsigned int fmt) 125 unsigned int fmt)
165{ 126{
166 struct snd_soc_codec *codec = codec_dai->codec; 127 struct snd_soc_codec *codec = codec_dai->codec;
167 u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL); 128 u16 iface = snd_soc_read(codec, WM8728_IFCTL);
168 129
169 /* Currently only I2S is supported by the driver, though the 130 /* Currently only I2S is supported by the driver, though the
170 * hardware is more flexible. 131 * hardware is more flexible.
@@ -204,7 +165,7 @@ static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
204 return -EINVAL; 165 return -EINVAL;
205 } 166 }
206 167
207 wm8728_write(codec, WM8728_IFCTL, iface); 168 snd_soc_write(codec, WM8728_IFCTL, iface);
208 return 0; 169 return 0;
209} 170}
210 171
@@ -220,19 +181,19 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
220 case SND_SOC_BIAS_STANDBY: 181 case SND_SOC_BIAS_STANDBY:
221 if (codec->bias_level == SND_SOC_BIAS_OFF) { 182 if (codec->bias_level == SND_SOC_BIAS_OFF) {
222 /* Power everything up... */ 183 /* Power everything up... */
223 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 184 reg = snd_soc_read(codec, WM8728_DACCTL);
224 wm8728_write(codec, WM8728_DACCTL, reg & ~0x4); 185 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
225 186
226 /* ..then sync in the register cache. */ 187 /* ..then sync in the register cache. */
227 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++) 188 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
228 wm8728_write(codec, i, 189 snd_soc_write(codec, i,
229 wm8728_read_reg_cache(codec, i)); 190 snd_soc_read(codec, i));
230 } 191 }
231 break; 192 break;
232 193
233 case SND_SOC_BIAS_OFF: 194 case SND_SOC_BIAS_OFF:
234 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL); 195 reg = snd_soc_read(codec, WM8728_DACCTL);
235 wm8728_write(codec, WM8728_DACCTL, reg | 0x4); 196 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
236 break; 197 break;
237 } 198 }
238 codec->bias_level = level; 199 codec->bias_level = level;
@@ -287,15 +248,14 @@ static int wm8728_resume(struct platform_device *pdev)
287 * initialise the WM8728 driver 248 * initialise the WM8728 driver
288 * register the mixer and dsp interfaces with the kernel 249 * register the mixer and dsp interfaces with the kernel
289 */ 250 */
290static int wm8728_init(struct snd_soc_device *socdev) 251static int wm8728_init(struct snd_soc_device *socdev,
252 enum snd_soc_control_type control)
291{ 253{
292 struct snd_soc_codec *codec = socdev->card->codec; 254 struct snd_soc_codec *codec = socdev->card->codec;
293 int ret = 0; 255 int ret = 0;
294 256
295 codec->name = "WM8728"; 257 codec->name = "WM8728";
296 codec->owner = THIS_MODULE; 258 codec->owner = THIS_MODULE;
297 codec->read = wm8728_read_reg_cache;
298 codec->write = wm8728_write;
299 codec->set_bias_level = wm8728_set_bias_level; 259 codec->set_bias_level = wm8728_set_bias_level;
300 codec->dai = &wm8728_dai; 260 codec->dai = &wm8728_dai;
301 codec->num_dai = 1; 261 codec->num_dai = 1;
@@ -307,11 +267,18 @@ static int wm8728_init(struct snd_soc_device *socdev)
307 if (codec->reg_cache == NULL) 267 if (codec->reg_cache == NULL)
308 return -ENOMEM; 268 return -ENOMEM;
309 269
270 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
271 if (ret < 0) {
272 printk(KERN_ERR "wm8728: failed to configure cache I/O: %d\n",
273 ret);
274 goto err;
275 }
276
310 /* register pcms */ 277 /* register pcms */
311 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 278 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
312 if (ret < 0) { 279 if (ret < 0) {
313 printk(KERN_ERR "wm8728: failed to create pcms\n"); 280 printk(KERN_ERR "wm8728: failed to create pcms\n");
314 goto pcm_err; 281 goto err;
315 } 282 }
316 283
317 /* power on device */ 284 /* power on device */
@@ -331,7 +298,7 @@ static int wm8728_init(struct snd_soc_device *socdev)
331card_err: 298card_err:
332 snd_soc_free_pcms(socdev); 299 snd_soc_free_pcms(socdev);
333 snd_soc_dapm_free(socdev); 300 snd_soc_dapm_free(socdev);
334pcm_err: 301err:
335 kfree(codec->reg_cache); 302 kfree(codec->reg_cache);
336 return ret; 303 return ret;
337} 304}
@@ -357,7 +324,7 @@ static int wm8728_i2c_probe(struct i2c_client *i2c,
357 i2c_set_clientdata(i2c, codec); 324 i2c_set_clientdata(i2c, codec);
358 codec->control_data = i2c; 325 codec->control_data = i2c;
359 326
360 ret = wm8728_init(socdev); 327 ret = wm8728_init(socdev, SND_SOC_I2C);
361 if (ret < 0) 328 if (ret < 0)
362 pr_err("failed to initialise WM8728\n"); 329 pr_err("failed to initialise WM8728\n");
363 330
@@ -437,7 +404,7 @@ static int __devinit wm8728_spi_probe(struct spi_device *spi)
437 404
438 codec->control_data = spi; 405 codec->control_data = spi;
439 406
440 ret = wm8728_init(socdev); 407 ret = wm8728_init(socdev, SND_SOC_SPI);
441 if (ret < 0) 408 if (ret < 0)
442 dev_err(&spi->dev, "failed to initialise WM8728\n"); 409 dev_err(&spi->dev, "failed to initialise WM8728\n");
443 410
@@ -458,30 +425,6 @@ static struct spi_driver wm8728_spi_driver = {
458 .probe = wm8728_spi_probe, 425 .probe = wm8728_spi_probe,
459 .remove = __devexit_p(wm8728_spi_remove), 426 .remove = __devexit_p(wm8728_spi_remove),
460}; 427};
461
462static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
463{
464 struct spi_transfer t;
465 struct spi_message m;
466 u8 msg[2];
467
468 if (len <= 0)
469 return 0;
470
471 msg[0] = data[0];
472 msg[1] = data[1];
473
474 spi_message_init(&m);
475 memset(&t, 0, (sizeof t));
476
477 t.tx_buf = &msg[0];
478 t.len = len;
479
480 spi_message_add_tail(&t, &m);
481 spi_sync(spi, &m);
482
483 return len;
484}
485#endif /* CONFIG_SPI_MASTER */ 428#endif /* CONFIG_SPI_MASTER */
486 429
487static int wm8728_probe(struct platform_device *pdev) 430static int wm8728_probe(struct platform_device *pdev)
@@ -506,13 +449,11 @@ static int wm8728_probe(struct platform_device *pdev)
506 449
507#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 450#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
508 if (setup->i2c_address) { 451 if (setup->i2c_address) {
509 codec->hw_write = (hw_write_t)i2c_master_send;
510 ret = wm8728_add_i2c_device(pdev, setup); 452 ret = wm8728_add_i2c_device(pdev, setup);
511 } 453 }
512#endif 454#endif
513#if defined(CONFIG_SPI_MASTER) 455#if defined(CONFIG_SPI_MASTER)
514 if (setup->spi) { 456 if (setup->spi) {
515 codec->hw_write = (hw_write_t)wm8728_spi_write;
516 ret = spi_register_driver(&wm8728_spi_driver); 457 ret = spi_register_driver(&wm8728_spi_driver);
517 if (ret != 0) 458 if (ret != 0)
518 printk(KERN_ERR "can't add spi driver"); 459 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7a205876ef4f..d3fd4f28d96e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,6 +26,7 @@
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h> 27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/tlv.h>
29 30
30#include "wm8731.h" 31#include "wm8731.h"
31 32
@@ -39,9 +40,6 @@ struct wm8731_priv {
39 unsigned int sysclk; 40 unsigned int sysclk;
40}; 41};
41 42
42#ifdef CONFIG_SPI_MASTER
43static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
44#endif
45 43
46/* 44/*
47 * wm8731 register cache 45 * wm8731 register cache
@@ -50,60 +48,12 @@ static int wm8731_spi_write(struct spi_device *spi, const char *data, int len);
50 * There is no point in caching the reset register 48 * There is no point in caching the reset register
51 */ 49 */
52static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 50static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
53 0x0097, 0x0097, 0x0079, 0x0079, 51 0x0097, 0x0097, 0x0079, 0x0079,
54 0x000a, 0x0008, 0x009f, 0x000a, 52 0x000a, 0x0008, 0x009f, 0x000a,
55 0x0000, 0x0000 53 0x0000, 0x0000
56}; 54};
57 55
58/* 56#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
59 * read wm8731 register cache
60 */
61static inline unsigned int wm8731_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg == WM8731_RESET)
66 return 0;
67 if (reg >= WM8731_CACHEREGNUM)
68 return -1;
69 return cache[reg];
70}
71
72/*
73 * write wm8731 register cache
74 */
75static inline void wm8731_write_reg_cache(struct snd_soc_codec *codec,
76 u16 reg, unsigned int value)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg >= WM8731_CACHEREGNUM)
80 return;
81 cache[reg] = value;
82}
83
84/*
85 * write to the WM8731 register space
86 */
87static int wm8731_write(struct snd_soc_codec *codec, unsigned int reg,
88 unsigned int value)
89{
90 u8 data[2];
91
92 /* data is
93 * D15..D9 WM8731 register offset
94 * D8...D0 register data
95 */
96 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
97 data[1] = value & 0x00ff;
98
99 wm8731_write_reg_cache(codec, reg, value);
100 if (codec->hw_write(codec->control_data, data, 2) == 2)
101 return 0;
102 else
103 return -EIO;
104}
105
106#define wm8731_reset(c) wm8731_write(c, WM8731_RESET, 0)
107 57
108static const char *wm8731_input_select[] = {"Line In", "Mic"}; 58static const char *wm8731_input_select[] = {"Line In", "Mic"};
109static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 59static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
@@ -113,20 +63,26 @@ static const struct soc_enum wm8731_enum[] = {
113 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), 63 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph),
114}; 64};
115 65
66static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
67static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
68static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
69
116static const struct snd_kcontrol_new wm8731_snd_controls[] = { 70static const struct snd_kcontrol_new wm8731_snd_controls[] = {
117 71
118SOC_DOUBLE_R("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, 72SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V,
119 0, 127, 0), 73 0, 127, 0, out_tlv),
120SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, 74SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V,
121 7, 1, 0), 75 7, 1, 0),
122 76
123SOC_DOUBLE_R("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0), 77SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
78 in_tlv),
124SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), 79SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
125 80
126SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), 81SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0),
127SOC_SINGLE("Capture Mic Switch", WM8731_APANA, 1, 1, 1), 82SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
128 83
129SOC_SINGLE("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1), 84SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
85 sidetone_tlv),
130 86
131SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 87SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
132SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 88SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
@@ -260,12 +216,12 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
260 struct snd_soc_device *socdev = rtd->socdev; 216 struct snd_soc_device *socdev = rtd->socdev;
261 struct snd_soc_codec *codec = socdev->card->codec; 217 struct snd_soc_codec *codec = socdev->card->codec;
262 struct wm8731_priv *wm8731 = codec->private_data; 218 struct wm8731_priv *wm8731 = codec->private_data;
263 u16 iface = wm8731_read_reg_cache(codec, WM8731_IFACE) & 0xfff3; 219 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3;
264 int i = get_coeff(wm8731->sysclk, params_rate(params)); 220 int i = get_coeff(wm8731->sysclk, params_rate(params));
265 u16 srate = (coeff_div[i].sr << 2) | 221 u16 srate = (coeff_div[i].sr << 2) |
266 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 222 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
267 223
268 wm8731_write(codec, WM8731_SRATE, srate); 224 snd_soc_write(codec, WM8731_SRATE, srate);
269 225
270 /* bit size */ 226 /* bit size */
271 switch (params_format(params)) { 227 switch (params_format(params)) {
@@ -279,7 +235,7 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
279 break; 235 break;
280 } 236 }
281 237
282 wm8731_write(codec, WM8731_IFACE, iface); 238 snd_soc_write(codec, WM8731_IFACE, iface);
283 return 0; 239 return 0;
284} 240}
285 241
@@ -291,7 +247,7 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
291 struct snd_soc_codec *codec = socdev->card->codec; 247 struct snd_soc_codec *codec = socdev->card->codec;
292 248
293 /* set active */ 249 /* set active */
294 wm8731_write(codec, WM8731_ACTIVE, 0x0001); 250 snd_soc_write(codec, WM8731_ACTIVE, 0x0001);
295 251
296 return 0; 252 return 0;
297} 253}
@@ -306,19 +262,19 @@ static void wm8731_shutdown(struct snd_pcm_substream *substream,
306 /* deactivate */ 262 /* deactivate */
307 if (!codec->active) { 263 if (!codec->active) {
308 udelay(50); 264 udelay(50);
309 wm8731_write(codec, WM8731_ACTIVE, 0x0); 265 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
310 } 266 }
311} 267}
312 268
313static int wm8731_mute(struct snd_soc_dai *dai, int mute) 269static int wm8731_mute(struct snd_soc_dai *dai, int mute)
314{ 270{
315 struct snd_soc_codec *codec = dai->codec; 271 struct snd_soc_codec *codec = dai->codec;
316 u16 mute_reg = wm8731_read_reg_cache(codec, WM8731_APDIGI) & 0xfff7; 272 u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7;
317 273
318 if (mute) 274 if (mute)
319 wm8731_write(codec, WM8731_APDIGI, mute_reg | 0x8); 275 snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8);
320 else 276 else
321 wm8731_write(codec, WM8731_APDIGI, mute_reg); 277 snd_soc_write(codec, WM8731_APDIGI, mute_reg);
322 return 0; 278 return 0;
323} 279}
324 280
@@ -396,7 +352,7 @@ static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai,
396 } 352 }
397 353
398 /* set iface */ 354 /* set iface */
399 wm8731_write(codec, WM8731_IFACE, iface); 355 snd_soc_write(codec, WM8731_IFACE, iface);
400 return 0; 356 return 0;
401} 357}
402 358
@@ -412,12 +368,12 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
412 break; 368 break;
413 case SND_SOC_BIAS_STANDBY: 369 case SND_SOC_BIAS_STANDBY:
414 /* Clear PWROFF, gate CLKOUT, everything else as-is */ 370 /* Clear PWROFF, gate CLKOUT, everything else as-is */
415 reg = wm8731_read_reg_cache(codec, WM8731_PWR) & 0xff7f; 371 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f;
416 wm8731_write(codec, WM8731_PWR, reg | 0x0040); 372 snd_soc_write(codec, WM8731_PWR, reg | 0x0040);
417 break; 373 break;
418 case SND_SOC_BIAS_OFF: 374 case SND_SOC_BIAS_OFF:
419 wm8731_write(codec, WM8731_ACTIVE, 0x0); 375 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
420 wm8731_write(codec, WM8731_PWR, 0xffff); 376 snd_soc_write(codec, WM8731_PWR, 0xffff);
421 break; 377 break;
422 } 378 }
423 codec->bias_level = level; 379 codec->bias_level = level;
@@ -457,15 +413,17 @@ struct snd_soc_dai wm8731_dai = {
457 .rates = WM8731_RATES, 413 .rates = WM8731_RATES,
458 .formats = WM8731_FORMATS,}, 414 .formats = WM8731_FORMATS,},
459 .ops = &wm8731_dai_ops, 415 .ops = &wm8731_dai_ops,
416 .symmetric_rates = 1,
460}; 417};
461EXPORT_SYMBOL_GPL(wm8731_dai); 418EXPORT_SYMBOL_GPL(wm8731_dai);
462 419
420#ifdef CONFIG_PM
463static int wm8731_suspend(struct platform_device *pdev, pm_message_t state) 421static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
464{ 422{
465 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
466 struct snd_soc_codec *codec = socdev->card->codec; 424 struct snd_soc_codec *codec = socdev->card->codec;
467 425
468 wm8731_write(codec, WM8731_ACTIVE, 0x0); 426 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
469 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
470 return 0; 428 return 0;
471} 429}
@@ -488,6 +446,10 @@ static int wm8731_resume(struct platform_device *pdev)
488 wm8731_set_bias_level(codec, codec->suspend_bias_level); 446 wm8731_set_bias_level(codec, codec->suspend_bias_level);
489 return 0; 447 return 0;
490} 448}
449#else
450#define wm8731_suspend NULL
451#define wm8731_resume NULL
452#endif
491 453
492static int wm8731_probe(struct platform_device *pdev) 454static int wm8731_probe(struct platform_device *pdev)
493{ 455{
@@ -547,15 +509,16 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
547}; 509};
548EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 510EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
549 511
550static int wm8731_register(struct wm8731_priv *wm8731) 512static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control)
551{ 514{
552 int ret; 515 int ret;
553 struct snd_soc_codec *codec = &wm8731->codec; 516 struct snd_soc_codec *codec = &wm8731->codec;
554 u16 reg;
555 517
556 if (wm8731_codec) { 518 if (wm8731_codec) {
557 dev_err(codec->dev, "Another WM8731 is registered\n"); 519 dev_err(codec->dev, "Another WM8731 is registered\n");
558 return -EINVAL; 520 ret = -EINVAL;
521 goto err;
559 } 522 }
560 523
561 mutex_init(&codec->mutex); 524 mutex_init(&codec->mutex);
@@ -565,8 +528,6 @@ static int wm8731_register(struct wm8731_priv *wm8731)
565 codec->private_data = wm8731; 528 codec->private_data = wm8731;
566 codec->name = "WM8731"; 529 codec->name = "WM8731";
567 codec->owner = THIS_MODULE; 530 codec->owner = THIS_MODULE;
568 codec->read = wm8731_read_reg_cache;
569 codec->write = wm8731_write;
570 codec->bias_level = SND_SOC_BIAS_OFF; 531 codec->bias_level = SND_SOC_BIAS_OFF;
571 codec->set_bias_level = wm8731_set_bias_level; 532 codec->set_bias_level = wm8731_set_bias_level;
572 codec->dai = &wm8731_dai; 533 codec->dai = &wm8731_dai;
@@ -576,10 +537,16 @@ static int wm8731_register(struct wm8731_priv *wm8731)
576 537
577 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg)); 538 memcpy(codec->reg_cache, wm8731_reg, sizeof(wm8731_reg));
578 539
540 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
541 if (ret < 0) {
542 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
543 goto err;
544 }
545
579 ret = wm8731_reset(codec); 546 ret = wm8731_reset(codec);
580 if (ret < 0) { 547 if (ret < 0) {
581 dev_err(codec->dev, "Failed to issue reset\n"); 548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
582 return ret; 549 goto err;
583 } 550 }
584 551
585 wm8731_dai.dev = codec->dev; 552 wm8731_dai.dev = codec->dev;
@@ -587,35 +554,36 @@ static int wm8731_register(struct wm8731_priv *wm8731)
587 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 554 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
588 555
589 /* Latch the update bits */ 556 /* Latch the update bits */
590 reg = wm8731_read_reg_cache(codec, WM8731_LOUT1V); 557 snd_soc_update_bits(codec, WM8731_LOUT1V, 0x100, 0);
591 wm8731_write(codec, WM8731_LOUT1V, reg & ~0x0100); 558 snd_soc_update_bits(codec, WM8731_ROUT1V, 0x100, 0);
592 reg = wm8731_read_reg_cache(codec, WM8731_ROUT1V); 559 snd_soc_update_bits(codec, WM8731_LINVOL, 0x100, 0);
593 wm8731_write(codec, WM8731_ROUT1V, reg & ~0x0100); 560 snd_soc_update_bits(codec, WM8731_RINVOL, 0x100, 0);
594 reg = wm8731_read_reg_cache(codec, WM8731_LINVOL);
595 wm8731_write(codec, WM8731_LINVOL, reg & ~0x0100);
596 reg = wm8731_read_reg_cache(codec, WM8731_RINVOL);
597 wm8731_write(codec, WM8731_RINVOL, reg & ~0x0100);
598 561
599 /* Disable bypass path by default */ 562 /* Disable bypass path by default */
600 reg = wm8731_read_reg_cache(codec, WM8731_APANA); 563 snd_soc_update_bits(codec, WM8731_APANA, 0x4, 0);
601 wm8731_write(codec, WM8731_APANA, reg & ~0x4);
602 564
603 wm8731_codec = codec; 565 wm8731_codec = codec;
604 566
605 ret = snd_soc_register_codec(codec); 567 ret = snd_soc_register_codec(codec);
606 if (ret != 0) { 568 if (ret != 0) {
607 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 569 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
608 return ret; 570 goto err;
609 } 571 }
610 572
611 ret = snd_soc_register_dai(&wm8731_dai); 573 ret = snd_soc_register_dai(&wm8731_dai);
612 if (ret != 0) { 574 if (ret != 0) {
613 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 575 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
614 snd_soc_unregister_codec(codec); 576 snd_soc_unregister_codec(codec);
615 return ret; 577 goto err_codec;
616 } 578 }
617 579
618 return 0; 580 return 0;
581
582err_codec:
583 snd_soc_unregister_codec(codec);
584err:
585 kfree(wm8731);
586 return ret;
619} 587}
620 588
621static void wm8731_unregister(struct wm8731_priv *wm8731) 589static void wm8731_unregister(struct wm8731_priv *wm8731)
@@ -628,30 +596,6 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
628} 596}
629 597
630#if defined(CONFIG_SPI_MASTER) 598#if defined(CONFIG_SPI_MASTER)
631static int wm8731_spi_write(struct spi_device *spi, const char *data, int len)
632{
633 struct spi_transfer t;
634 struct spi_message m;
635 u8 msg[2];
636
637 if (len <= 0)
638 return 0;
639
640 msg[0] = data[0];
641 msg[1] = data[1];
642
643 spi_message_init(&m);
644 memset(&t, 0, (sizeof t));
645
646 t.tx_buf = &msg[0];
647 t.len = len;
648
649 spi_message_add_tail(&t, &m);
650 spi_sync(spi, &m);
651
652 return len;
653}
654
655static int __devinit wm8731_spi_probe(struct spi_device *spi) 599static int __devinit wm8731_spi_probe(struct spi_device *spi)
656{ 600{
657 struct snd_soc_codec *codec; 601 struct snd_soc_codec *codec;
@@ -663,12 +607,11 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi)
663 607
664 codec = &wm8731->codec; 608 codec = &wm8731->codec;
665 codec->control_data = spi; 609 codec->control_data = spi;
666 codec->hw_write = (hw_write_t)wm8731_spi_write;
667 codec->dev = &spi->dev; 610 codec->dev = &spi->dev;
668 611
669 dev_set_drvdata(&spi->dev, wm8731); 612 dev_set_drvdata(&spi->dev, wm8731);
670 613
671 return wm8731_register(wm8731); 614 return wm8731_register(wm8731, SND_SOC_SPI);
672} 615}
673 616
674static int __devexit wm8731_spi_remove(struct spi_device *spi) 617static int __devexit wm8731_spi_remove(struct spi_device *spi)
@@ -680,6 +623,21 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
680 return 0; 623 return 0;
681} 624}
682 625
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
683static struct spi_driver wm8731_spi_driver = { 641static struct spi_driver wm8731_spi_driver = {
684 .driver = { 642 .driver = {
685 .name = "wm8731", 643 .name = "wm8731",
@@ -687,6 +645,8 @@ static struct spi_driver wm8731_spi_driver = {
687 .owner = THIS_MODULE, 645 .owner = THIS_MODULE,
688 }, 646 },
689 .probe = wm8731_spi_probe, 647 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
690 .remove = __devexit_p(wm8731_spi_remove), 650 .remove = __devexit_p(wm8731_spi_remove),
691}; 651};
692#endif /* CONFIG_SPI_MASTER */ 652#endif /* CONFIG_SPI_MASTER */
@@ -703,14 +663,13 @@ static __devinit int wm8731_i2c_probe(struct i2c_client *i2c,
703 return -ENOMEM; 663 return -ENOMEM;
704 664
705 codec = &wm8731->codec; 665 codec = &wm8731->codec;
706 codec->hw_write = (hw_write_t)i2c_master_send;
707 666
708 i2c_set_clientdata(i2c, wm8731); 667 i2c_set_clientdata(i2c, wm8731);
709 codec->control_data = i2c; 668 codec->control_data = i2c;
710 669
711 codec->dev = &i2c->dev; 670 codec->dev = &i2c->dev;
712 671
713 return wm8731_register(wm8731); 672 return wm8731_register(wm8731, SND_SOC_I2C);
714} 673}
715 674
716static __devexit int wm8731_i2c_remove(struct i2c_client *client) 675static __devexit int wm8731_i2c_remove(struct i2c_client *client)
@@ -720,6 +679,21 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
720 return 0; 679 return 0;
721} 680}
722 681
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
723static const struct i2c_device_id wm8731_i2c_id[] = { 697static const struct i2c_device_id wm8731_i2c_id[] = {
724 { "wm8731", 0 }, 698 { "wm8731", 0 },
725 { } 699 { }
@@ -733,6 +707,8 @@ static struct i2c_driver wm8731_i2c_driver = {
733 }, 707 },
734 .probe = wm8731_i2c_probe, 708 .probe = wm8731_i2c_probe,
735 .remove = __devexit_p(wm8731_i2c_remove), 709 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
736 .id_table = wm8731_i2c_id, 712 .id_table = wm8731_i2c_id,
737}; 713};
738#endif 714#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index b64509b01a49..4ba1e7e93fb4 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -55,50 +55,7 @@ static const u16 wm8750_reg[] = {
55 0x0079, 0x0079, 0x0079, /* 40 */ 55 0x0079, 0x0079, 0x0079, /* 40 */
56}; 56};
57 57
58/* 58#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
59 * read wm8750 register cache
60 */
61static inline unsigned int wm8750_read_reg_cache(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 u16 *cache = codec->reg_cache;
65 if (reg > WM8750_CACHE_REGNUM)
66 return -1;
67 return cache[reg];
68}
69
70/*
71 * write wm8750 register cache
72 */
73static inline void wm8750_write_reg_cache(struct snd_soc_codec *codec,
74 unsigned int reg, unsigned int value)
75{
76 u16 *cache = codec->reg_cache;
77 if (reg > WM8750_CACHE_REGNUM)
78 return;
79 cache[reg] = value;
80}
81
82static int wm8750_write(struct snd_soc_codec *codec, unsigned int reg,
83 unsigned int value)
84{
85 u8 data[2];
86
87 /* data is
88 * D15..D9 WM8753 register offset
89 * D8...D0 register data
90 */
91 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
92 data[1] = value & 0x00ff;
93
94 wm8750_write_reg_cache(codec, reg, value);
95 if (codec->hw_write(codec->control_data, data, 2) == 2)
96 return 0;
97 else
98 return -EIO;
99}
100
101#define wm8750_reset(c) wm8750_write(c, WM8750_RESET, 0)
102 59
103/* 60/*
104 * WM8750 Controls 61 * WM8750 Controls
@@ -594,7 +551,7 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
594 return -EINVAL; 551 return -EINVAL;
595 } 552 }
596 553
597 wm8750_write(codec, WM8750_IFACE, iface); 554 snd_soc_write(codec, WM8750_IFACE, iface);
598 return 0; 555 return 0;
599} 556}
600 557
@@ -606,8 +563,8 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
606 struct snd_soc_device *socdev = rtd->socdev; 563 struct snd_soc_device *socdev = rtd->socdev;
607 struct snd_soc_codec *codec = socdev->card->codec; 564 struct snd_soc_codec *codec = socdev->card->codec;
608 struct wm8750_priv *wm8750 = codec->private_data; 565 struct wm8750_priv *wm8750 = codec->private_data;
609 u16 iface = wm8750_read_reg_cache(codec, WM8750_IFACE) & 0x1f3; 566 u16 iface = snd_soc_read(codec, WM8750_IFACE) & 0x1f3;
610 u16 srate = wm8750_read_reg_cache(codec, WM8750_SRATE) & 0x1c0; 567 u16 srate = snd_soc_read(codec, WM8750_SRATE) & 0x1c0;
611 int coeff = get_coeff(wm8750->sysclk, params_rate(params)); 568 int coeff = get_coeff(wm8750->sysclk, params_rate(params));
612 569
613 /* bit size */ 570 /* bit size */
@@ -626,9 +583,9 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
626 } 583 }
627 584
628 /* set iface & srate */ 585 /* set iface & srate */
629 wm8750_write(codec, WM8750_IFACE, iface); 586 snd_soc_write(codec, WM8750_IFACE, iface);
630 if (coeff >= 0) 587 if (coeff >= 0)
631 wm8750_write(codec, WM8750_SRATE, srate | 588 snd_soc_write(codec, WM8750_SRATE, srate |
632 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 589 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
633 590
634 return 0; 591 return 0;
@@ -637,35 +594,35 @@ static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
637static int wm8750_mute(struct snd_soc_dai *dai, int mute) 594static int wm8750_mute(struct snd_soc_dai *dai, int mute)
638{ 595{
639 struct snd_soc_codec *codec = dai->codec; 596 struct snd_soc_codec *codec = dai->codec;
640 u16 mute_reg = wm8750_read_reg_cache(codec, WM8750_ADCDAC) & 0xfff7; 597 u16 mute_reg = snd_soc_read(codec, WM8750_ADCDAC) & 0xfff7;
641 598
642 if (mute) 599 if (mute)
643 wm8750_write(codec, WM8750_ADCDAC, mute_reg | 0x8); 600 snd_soc_write(codec, WM8750_ADCDAC, mute_reg | 0x8);
644 else 601 else
645 wm8750_write(codec, WM8750_ADCDAC, mute_reg); 602 snd_soc_write(codec, WM8750_ADCDAC, mute_reg);
646 return 0; 603 return 0;
647} 604}
648 605
649static int wm8750_set_bias_level(struct snd_soc_codec *codec, 606static int wm8750_set_bias_level(struct snd_soc_codec *codec,
650 enum snd_soc_bias_level level) 607 enum snd_soc_bias_level level)
651{ 608{
652 u16 pwr_reg = wm8750_read_reg_cache(codec, WM8750_PWR1) & 0xfe3e; 609 u16 pwr_reg = snd_soc_read(codec, WM8750_PWR1) & 0xfe3e;
653 610
654 switch (level) { 611 switch (level) {
655 case SND_SOC_BIAS_ON: 612 case SND_SOC_BIAS_ON:
656 /* set vmid to 50k and unmute dac */ 613 /* set vmid to 50k and unmute dac */
657 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x00c0); 614 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x00c0);
658 break; 615 break;
659 case SND_SOC_BIAS_PREPARE: 616 case SND_SOC_BIAS_PREPARE:
660 /* set vmid to 5k for quick power up */ 617 /* set vmid to 5k for quick power up */
661 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 618 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
662 break; 619 break;
663 case SND_SOC_BIAS_STANDBY: 620 case SND_SOC_BIAS_STANDBY:
664 /* mute dac and set vmid to 500k, enable VREF */ 621 /* mute dac and set vmid to 500k, enable VREF */
665 wm8750_write(codec, WM8750_PWR1, pwr_reg | 0x0141); 622 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x0141);
666 break; 623 break;
667 case SND_SOC_BIAS_OFF: 624 case SND_SOC_BIAS_OFF:
668 wm8750_write(codec, WM8750_PWR1, 0x0001); 625 snd_soc_write(codec, WM8750_PWR1, 0x0001);
669 break; 626 break;
670 } 627 }
671 codec->bias_level = level; 628 codec->bias_level = level;
@@ -754,15 +711,14 @@ static int wm8750_resume(struct platform_device *pdev)
754 * initialise the WM8750 driver 711 * initialise the WM8750 driver
755 * register the mixer and dsp interfaces with the kernel 712 * register the mixer and dsp interfaces with the kernel
756 */ 713 */
757static int wm8750_init(struct snd_soc_device *socdev) 714static int wm8750_init(struct snd_soc_device *socdev,
715 enum snd_soc_control_type control)
758{ 716{
759 struct snd_soc_codec *codec = socdev->card->codec; 717 struct snd_soc_codec *codec = socdev->card->codec;
760 int reg, ret = 0; 718 int reg, ret = 0;
761 719
762 codec->name = "WM8750"; 720 codec->name = "WM8750";
763 codec->owner = THIS_MODULE; 721 codec->owner = THIS_MODULE;
764 codec->read = wm8750_read_reg_cache;
765 codec->write = wm8750_write;
766 codec->set_bias_level = wm8750_set_bias_level; 722 codec->set_bias_level = wm8750_set_bias_level;
767 codec->dai = &wm8750_dai; 723 codec->dai = &wm8750_dai;
768 codec->num_dai = 1; 724 codec->num_dai = 1;
@@ -771,13 +727,23 @@ static int wm8750_init(struct snd_soc_device *socdev)
771 if (codec->reg_cache == NULL) 727 if (codec->reg_cache == NULL)
772 return -ENOMEM; 728 return -ENOMEM;
773 729
774 wm8750_reset(codec); 730 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
731 if (ret < 0) {
732 printk(KERN_ERR "wm8750: failed to set cache I/O: %d\n", ret);
733 goto err;
734 }
735
736 ret = wm8750_reset(codec);
737 if (ret < 0) {
738 printk(KERN_ERR "wm8750: failed to reset: %d\n", ret);
739 goto err;
740 }
775 741
776 /* register pcms */ 742 /* register pcms */
777 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 743 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
778 if (ret < 0) { 744 if (ret < 0) {
779 printk(KERN_ERR "wm8750: failed to create pcms\n"); 745 printk(KERN_ERR "wm8750: failed to create pcms\n");
780 goto pcm_err; 746 goto err;
781 } 747 }
782 748
783 /* charge output caps */ 749 /* charge output caps */
@@ -786,22 +752,22 @@ static int wm8750_init(struct snd_soc_device *socdev)
786 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000)); 752 schedule_delayed_work(&codec->delayed_work, msecs_to_jiffies(1000));
787 753
788 /* set the update bits */ 754 /* set the update bits */
789 reg = wm8750_read_reg_cache(codec, WM8750_LDAC); 755 reg = snd_soc_read(codec, WM8750_LDAC);
790 wm8750_write(codec, WM8750_LDAC, reg | 0x0100); 756 snd_soc_write(codec, WM8750_LDAC, reg | 0x0100);
791 reg = wm8750_read_reg_cache(codec, WM8750_RDAC); 757 reg = snd_soc_read(codec, WM8750_RDAC);
792 wm8750_write(codec, WM8750_RDAC, reg | 0x0100); 758 snd_soc_write(codec, WM8750_RDAC, reg | 0x0100);
793 reg = wm8750_read_reg_cache(codec, WM8750_LOUT1V); 759 reg = snd_soc_read(codec, WM8750_LOUT1V);
794 wm8750_write(codec, WM8750_LOUT1V, reg | 0x0100); 760 snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100);
795 reg = wm8750_read_reg_cache(codec, WM8750_ROUT1V); 761 reg = snd_soc_read(codec, WM8750_ROUT1V);
796 wm8750_write(codec, WM8750_ROUT1V, reg | 0x0100); 762 snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100);
797 reg = wm8750_read_reg_cache(codec, WM8750_LOUT2V); 763 reg = snd_soc_read(codec, WM8750_LOUT2V);
798 wm8750_write(codec, WM8750_LOUT2V, reg | 0x0100); 764 snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100);
799 reg = wm8750_read_reg_cache(codec, WM8750_ROUT2V); 765 reg = snd_soc_read(codec, WM8750_ROUT2V);
800 wm8750_write(codec, WM8750_ROUT2V, reg | 0x0100); 766 snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100);
801 reg = wm8750_read_reg_cache(codec, WM8750_LINVOL); 767 reg = snd_soc_read(codec, WM8750_LINVOL);
802 wm8750_write(codec, WM8750_LINVOL, reg | 0x0100); 768 snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100);
803 reg = wm8750_read_reg_cache(codec, WM8750_RINVOL); 769 reg = snd_soc_read(codec, WM8750_RINVOL);
804 wm8750_write(codec, WM8750_RINVOL, reg | 0x0100); 770 snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100);
805 771
806 snd_soc_add_controls(codec, wm8750_snd_controls, 772 snd_soc_add_controls(codec, wm8750_snd_controls,
807 ARRAY_SIZE(wm8750_snd_controls)); 773 ARRAY_SIZE(wm8750_snd_controls));
@@ -816,7 +782,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
816card_err: 782card_err:
817 snd_soc_free_pcms(socdev); 783 snd_soc_free_pcms(socdev);
818 snd_soc_dapm_free(socdev); 784 snd_soc_dapm_free(socdev);
819pcm_err: 785err:
820 kfree(codec->reg_cache); 786 kfree(codec->reg_cache);
821 return ret; 787 return ret;
822} 788}
@@ -844,7 +810,7 @@ static int wm8750_i2c_probe(struct i2c_client *i2c,
844 i2c_set_clientdata(i2c, codec); 810 i2c_set_clientdata(i2c, codec);
845 codec->control_data = i2c; 811 codec->control_data = i2c;
846 812
847 ret = wm8750_init(socdev); 813 ret = wm8750_init(socdev, SND_SOC_I2C);
848 if (ret < 0) 814 if (ret < 0)
849 pr_err("failed to initialise WM8750\n"); 815 pr_err("failed to initialise WM8750\n");
850 816
@@ -924,7 +890,7 @@ static int __devinit wm8750_spi_probe(struct spi_device *spi)
924 890
925 codec->control_data = spi; 891 codec->control_data = spi;
926 892
927 ret = wm8750_init(socdev); 893 ret = wm8750_init(socdev, SND_SOC_SPI);
928 if (ret < 0) 894 if (ret < 0)
929 dev_err(&spi->dev, "failed to initialise WM8750\n"); 895 dev_err(&spi->dev, "failed to initialise WM8750\n");
930 896
@@ -945,30 +911,6 @@ static struct spi_driver wm8750_spi_driver = {
945 .probe = wm8750_spi_probe, 911 .probe = wm8750_spi_probe,
946 .remove = __devexit_p(wm8750_spi_remove), 912 .remove = __devexit_p(wm8750_spi_remove),
947}; 913};
948
949static int wm8750_spi_write(struct spi_device *spi, const char *data, int len)
950{
951 struct spi_transfer t;
952 struct spi_message m;
953 u8 msg[2];
954
955 if (len <= 0)
956 return 0;
957
958 msg[0] = data[0];
959 msg[1] = data[1];
960
961 spi_message_init(&m);
962 memset(&t, 0, (sizeof t));
963
964 t.tx_buf = &msg[0];
965 t.len = len;
966
967 spi_message_add_tail(&t, &m);
968 spi_sync(spi, &m);
969
970 return len;
971}
972#endif 914#endif
973 915
974static int wm8750_probe(struct platform_device *pdev) 916static int wm8750_probe(struct platform_device *pdev)
@@ -1002,13 +944,11 @@ static int wm8750_probe(struct platform_device *pdev)
1002 944
1003#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 945#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1004 if (setup->i2c_address) { 946 if (setup->i2c_address) {
1005 codec->hw_write = (hw_write_t)i2c_master_send;
1006 ret = wm8750_add_i2c_device(pdev, setup); 947 ret = wm8750_add_i2c_device(pdev, setup);
1007 } 948 }
1008#endif 949#endif
1009#if defined(CONFIG_SPI_MASTER) 950#if defined(CONFIG_SPI_MASTER)
1010 if (setup->spi) { 951 if (setup->spi) {
1011 codec->hw_write = (hw_write_t)wm8750_spi_write;
1012 ret = spi_register_driver(&wm8750_spi_driver); 952 ret = spi_register_driver(&wm8750_spi_driver);
1013 if (ret != 0) 953 if (ret != 0)
1014 printk(KERN_ERR "can't add spi driver"); 954 printk(KERN_ERR "can't add spi driver");
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 49c4b2898aff..d80d414cfbbd 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1766,6 +1766,21 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1766 return 0; 1766 return 0;
1767} 1767}
1768 1768
1769#ifdef CONFIG_PM
1770static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1771{
1772 return snd_soc_suspend_device(&client->dev);
1773}
1774
1775static int wm8753_i2c_resume(struct i2c_client *client)
1776{
1777 return snd_soc_resume_device(&client->dev);
1778}
1779#else
1780#define wm8753_i2c_suspend NULL
1781#define wm8753_i2c_resume NULL
1782#endif
1783
1769static const struct i2c_device_id wm8753_i2c_id[] = { 1784static const struct i2c_device_id wm8753_i2c_id[] = {
1770 { "wm8753", 0 }, 1785 { "wm8753", 0 },
1771 { } 1786 { }
@@ -1779,6 +1794,8 @@ static struct i2c_driver wm8753_i2c_driver = {
1779 }, 1794 },
1780 .probe = wm8753_i2c_probe, 1795 .probe = wm8753_i2c_probe,
1781 .remove = wm8753_i2c_remove, 1796 .remove = wm8753_i2c_remove,
1797 .suspend = wm8753_i2c_suspend,
1798 .resume = wm8753_i2c_resume,
1782 .id_table = wm8753_i2c_id, 1799 .id_table = wm8753_i2c_id,
1783}; 1800};
1784#endif 1801#endif
@@ -1834,6 +1851,22 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1834 return 0; 1851 return 0;
1835} 1852}
1836 1853
1854#ifdef CONFIG_PM
1855static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1856{
1857 return snd_soc_suspend_device(&spi->dev);
1858}
1859
1860static int wm8753_spi_resume(struct spi_device *spi)
1861{
1862 return snd_soc_resume_device(&spi->dev);
1863}
1864
1865#else
1866#define wm8753_spi_suspend NULL
1867#define wm8753_spi_resume NULL
1868#endif
1869
1837static struct spi_driver wm8753_spi_driver = { 1870static struct spi_driver wm8753_spi_driver = {
1838 .driver = { 1871 .driver = {
1839 .name = "wm8753", 1872 .name = "wm8753",
@@ -1842,6 +1875,8 @@ static struct spi_driver wm8753_spi_driver = {
1842 }, 1875 },
1843 .probe = wm8753_spi_probe, 1876 .probe = wm8753_spi_probe,
1844 .remove = __devexit_p(wm8753_spi_remove), 1877 .remove = __devexit_p(wm8753_spi_remove),
1878 .suspend = wm8753_spi_suspend,
1879 .resume = wm8753_spi_resume,
1845}; 1880};
1846#endif 1881#endif
1847 1882
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
new file mode 100644
index 000000000000..a9829aa26e53
--- /dev/null
+++ b/sound/soc/codecs/wm8776.c
@@ -0,0 +1,744 @@
1/*
2 * wm8776.c -- WM8776 ALSA SoC Audio driver
3 *
4 * Copyright 2009 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 * TODO: Input ALC/limiter support
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8776.h"
32
33static struct snd_soc_codec *wm8776_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8776;
35
36/* codec private data */
37struct wm8776_priv {
38 struct snd_soc_codec codec;
39 u16 reg_cache[WM8776_CACHEREGNUM];
40 int sysclk[2];
41};
42
43#ifdef CONFIG_SPI_MASTER
44static int wm8776_spi_write(struct spi_device *spi, const char *data, int len);
45#endif
46
47static const u16 wm8776_reg[WM8776_CACHEREGNUM] = {
48 0x79, 0x79, 0x79, 0xff, 0xff, /* 4 */
49 0xff, 0x00, 0x90, 0x00, 0x00, /* 9 */
50 0x22, 0x22, 0x22, 0x08, 0xcf, /* 14 */
51 0xcf, 0x7b, 0x00, 0x32, 0x00, /* 19 */
52 0xa6, 0x01, 0x01
53};
54
55static int wm8776_reset(struct snd_soc_codec *codec)
56{
57 return snd_soc_write(codec, WM8776_RESET, 0);
58}
59
60static const DECLARE_TLV_DB_SCALE(hp_tlv, -12100, 100, 1);
61static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
62static const DECLARE_TLV_DB_SCALE(adc_tlv, -10350, 50, 1);
63
64static const struct snd_kcontrol_new wm8776_snd_controls[] = {
65SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8776_HPLVOL, WM8776_HPRVOL,
66 0, 127, 0, hp_tlv),
67SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8776_DACLVOL, WM8776_DACRVOL,
68 0, 255, 0, dac_tlv),
69SOC_SINGLE("Digital Playback ZC Switch", WM8776_DACCTRL1, 0, 1, 0),
70
71SOC_SINGLE("Deemphasis Switch", WM8776_DACCTRL2, 0, 1, 0),
72
73SOC_DOUBLE_R_TLV("Capture Volume", WM8776_ADCLVOL, WM8776_ADCRVOL,
74 0, 255, 0, adc_tlv),
75SOC_DOUBLE("Capture Switch", WM8776_ADCMUX, 7, 6, 1, 1),
76SOC_DOUBLE_R("Capture ZC Switch", WM8776_ADCLVOL, WM8776_ADCRVOL, 8, 1, 0),
77SOC_SINGLE("Capture HPF Switch", WM8776_ADCIFCTRL, 8, 1, 1),
78};
79
80static const struct snd_kcontrol_new inmix_controls[] = {
81SOC_DAPM_SINGLE("AIN1 Switch", WM8776_ADCMUX, 0, 1, 0),
82SOC_DAPM_SINGLE("AIN2 Switch", WM8776_ADCMUX, 1, 1, 0),
83SOC_DAPM_SINGLE("AIN3 Switch", WM8776_ADCMUX, 2, 1, 0),
84SOC_DAPM_SINGLE("AIN4 Switch", WM8776_ADCMUX, 3, 1, 0),
85SOC_DAPM_SINGLE("AIN5 Switch", WM8776_ADCMUX, 4, 1, 0),
86};
87
88static const struct snd_kcontrol_new outmix_controls[] = {
89SOC_DAPM_SINGLE("DAC Switch", WM8776_OUTMUX, 0, 1, 0),
90SOC_DAPM_SINGLE("AUX Switch", WM8776_OUTMUX, 1, 1, 0),
91SOC_DAPM_SINGLE("Bypass Switch", WM8776_OUTMUX, 2, 1, 0),
92};
93
94static const struct snd_soc_dapm_widget wm8776_dapm_widgets[] = {
95SND_SOC_DAPM_INPUT("AUX"),
96SND_SOC_DAPM_INPUT("AUX"),
97
98SND_SOC_DAPM_INPUT("AIN1"),
99SND_SOC_DAPM_INPUT("AIN2"),
100SND_SOC_DAPM_INPUT("AIN3"),
101SND_SOC_DAPM_INPUT("AIN4"),
102SND_SOC_DAPM_INPUT("AIN5"),
103
104SND_SOC_DAPM_MIXER("Input Mixer", WM8776_PWRDOWN, 6, 1,
105 inmix_controls, ARRAY_SIZE(inmix_controls)),
106
107SND_SOC_DAPM_ADC("ADC", "Capture", WM8776_PWRDOWN, 1, 1),
108SND_SOC_DAPM_DAC("DAC", "Playback", WM8776_PWRDOWN, 2, 1),
109
110SND_SOC_DAPM_MIXER("Output Mixer", SND_SOC_NOPM, 0, 0,
111 outmix_controls, ARRAY_SIZE(outmix_controls)),
112
113SND_SOC_DAPM_PGA("Headphone PGA", WM8776_PWRDOWN, 3, 1, NULL, 0),
114
115SND_SOC_DAPM_OUTPUT("VOUT"),
116
117SND_SOC_DAPM_OUTPUT("HPOUTL"),
118SND_SOC_DAPM_OUTPUT("HPOUTR"),
119};
120
121static const struct snd_soc_dapm_route routes[] = {
122 { "Input Mixer", "AIN1 Switch", "AIN1" },
123 { "Input Mixer", "AIN2 Switch", "AIN2" },
124 { "Input Mixer", "AIN3 Switch", "AIN3" },
125 { "Input Mixer", "AIN4 Switch", "AIN4" },
126 { "Input Mixer", "AIN5 Switch", "AIN5" },
127
128 { "ADC", NULL, "Input Mixer" },
129
130 { "Output Mixer", "DAC Switch", "DAC" },
131 { "Output Mixer", "AUX Switch", "AUX" },
132 { "Output Mixer", "Bypass Switch", "Input Mixer" },
133
134 { "VOUT", NULL, "Output Mixer" },
135
136 { "Headphone PGA", NULL, "Output Mixer" },
137
138 { "HPOUTL", NULL, "Headphone PGA" },
139 { "HPOUTR", NULL, "Headphone PGA" },
140};
141
142static int wm8776_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
143{
144 struct snd_soc_codec *codec = dai->codec;
145 int reg, iface, master;
146
147 switch (dai->id) {
148 case WM8776_DAI_DAC:
149 reg = WM8776_DACIFCTRL;
150 master = 0x80;
151 break;
152 case WM8776_DAI_ADC:
153 reg = WM8776_ADCIFCTRL;
154 master = 0x100;
155 break;
156 default:
157 return -EINVAL;
158 }
159
160 iface = 0;
161
162 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
163 case SND_SOC_DAIFMT_CBM_CFM:
164 break;
165 case SND_SOC_DAIFMT_CBS_CFS:
166 master = 0;
167 break;
168 default:
169 return -EINVAL;
170 }
171
172 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
173 case SND_SOC_DAIFMT_I2S:
174 iface |= 0x0002;
175 break;
176 case SND_SOC_DAIFMT_RIGHT_J:
177 break;
178 case SND_SOC_DAIFMT_LEFT_J:
179 iface |= 0x0001;
180 break;
181 /* FIXME: CHECK A/B */
182 case SND_SOC_DAIFMT_DSP_A:
183 iface |= 0x0003;
184 break;
185 case SND_SOC_DAIFMT_DSP_B:
186 iface |= 0x0007;
187 break;
188 default:
189 return -EINVAL;
190 }
191
192 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
193 case SND_SOC_DAIFMT_NB_NF:
194 break;
195 case SND_SOC_DAIFMT_IB_IF:
196 iface |= 0x00c;
197 break;
198 case SND_SOC_DAIFMT_IB_NF:
199 iface |= 0x008;
200 break;
201 case SND_SOC_DAIFMT_NB_IF:
202 iface |= 0x004;
203 break;
204 default:
205 return -EINVAL;
206 }
207
208 /* Finally, write out the values */
209 snd_soc_update_bits(codec, reg, 0xf, iface);
210 snd_soc_update_bits(codec, WM8776_MSTRCTRL, 0x180, master);
211
212 return 0;
213}
214
215static int mclk_ratios[] = {
216 128,
217 192,
218 256,
219 384,
220 512,
221 768,
222};
223
224static int wm8776_hw_params(struct snd_pcm_substream *substream,
225 struct snd_pcm_hw_params *params,
226 struct snd_soc_dai *dai)
227{
228 struct snd_soc_codec *codec = dai->codec;
229 struct wm8776_priv *wm8776 = codec->private_data;
230 int iface_reg, iface;
231 int ratio_shift, master;
232 int i;
233
234 iface = 0;
235
236 switch (dai->id) {
237 case WM8776_DAI_DAC:
238 iface_reg = WM8776_DACIFCTRL;
239 master = 0x80;
240 ratio_shift = 4;
241 break;
242 case WM8776_DAI_ADC:
243 iface_reg = WM8776_ADCIFCTRL;
244 master = 0x100;
245 ratio_shift = 0;
246 break;
247 default:
248 return -EINVAL;
249 }
250
251
252 /* Set word length */
253 switch (params_format(params)) {
254 case SNDRV_PCM_FORMAT_S16_LE:
255 break;
256 case SNDRV_PCM_FORMAT_S20_3LE:
257 iface |= 0x10;
258 break;
259 case SNDRV_PCM_FORMAT_S24_LE:
260 iface |= 0x20;
261 break;
262 case SNDRV_PCM_FORMAT_S32_LE:
263 iface |= 0x30;
264 break;
265 }
266
267 /* Only need to set MCLK/LRCLK ratio if we're master */
268 if (snd_soc_read(codec, WM8776_MSTRCTRL) & master) {
269 for (i = 0; i < ARRAY_SIZE(mclk_ratios); i++) {
270 if (wm8776->sysclk[dai->id] / params_rate(params)
271 == mclk_ratios[i])
272 break;
273 }
274
275 if (i == ARRAY_SIZE(mclk_ratios)) {
276 dev_err(codec->dev,
277 "Unable to configure MCLK ratio %d/%d\n",
278 wm8776->sysclk[dai->id], params_rate(params));
279 return -EINVAL;
280 }
281
282 dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
283
284 snd_soc_update_bits(codec, WM8776_MSTRCTRL,
285 0x7 << ratio_shift, i << ratio_shift);
286 } else {
287 dev_dbg(codec->dev, "DAI in slave mode\n");
288 }
289
290 snd_soc_update_bits(codec, iface_reg, 0x30, iface);
291
292 return 0;
293}
294
295static int wm8776_mute(struct snd_soc_dai *dai, int mute)
296{
297 struct snd_soc_codec *codec = dai->codec;
298
299 return snd_soc_write(codec, WM8776_DACMUTE, !!mute);
300}
301
302static int wm8776_set_sysclk(struct snd_soc_dai *dai,
303 int clk_id, unsigned int freq, int dir)
304{
305 struct snd_soc_codec *codec = dai->codec;
306 struct wm8776_priv *wm8776 = codec->private_data;
307
308 BUG_ON(dai->id >= ARRAY_SIZE(wm8776->sysclk));
309
310 wm8776->sysclk[dai->id] = freq;
311
312 return 0;
313}
314
315static int wm8776_set_bias_level(struct snd_soc_codec *codec,
316 enum snd_soc_bias_level level)
317{
318 switch (level) {
319 case SND_SOC_BIAS_ON:
320 break;
321 case SND_SOC_BIAS_PREPARE:
322 break;
323 case SND_SOC_BIAS_STANDBY:
324 if (codec->bias_level == SND_SOC_BIAS_OFF) {
325 /* Disable the global powerdown; DAPM does the rest */
326 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
327 }
328
329 break;
330 case SND_SOC_BIAS_OFF:
331 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 1);
332 break;
333 }
334
335 codec->bias_level = level;
336 return 0;
337}
338
339#define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
340 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
341 SNDRV_PCM_RATE_96000)
342
343
344#define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
345 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
346
347static struct snd_soc_dai_ops wm8776_dac_ops = {
348 .digital_mute = wm8776_mute,
349 .hw_params = wm8776_hw_params,
350 .set_fmt = wm8776_set_fmt,
351 .set_sysclk = wm8776_set_sysclk,
352};
353
354static struct snd_soc_dai_ops wm8776_adc_ops = {
355 .hw_params = wm8776_hw_params,
356 .set_fmt = wm8776_set_fmt,
357 .set_sysclk = wm8776_set_sysclk,
358};
359
360struct snd_soc_dai wm8776_dai[] = {
361 {
362 .name = "WM8776 Playback",
363 .id = WM8776_DAI_DAC,
364 .playback = {
365 .stream_name = "Playback",
366 .channels_min = 2,
367 .channels_max = 2,
368 .rates = WM8776_RATES,
369 .formats = WM8776_FORMATS,
370 },
371 .ops = &wm8776_dac_ops,
372 },
373 {
374 .name = "WM8776 Capture",
375 .id = WM8776_DAI_ADC,
376 .capture = {
377 .stream_name = "Capture",
378 .channels_min = 2,
379 .channels_max = 2,
380 .rates = WM8776_RATES,
381 .formats = WM8776_FORMATS,
382 },
383 .ops = &wm8776_adc_ops,
384 },
385};
386EXPORT_SYMBOL_GPL(wm8776_dai);
387
388#ifdef CONFIG_PM
389static int wm8776_suspend(struct platform_device *pdev, pm_message_t state)
390{
391 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
392 struct snd_soc_codec *codec = socdev->card->codec;
393
394 wm8776_set_bias_level(codec, SND_SOC_BIAS_OFF);
395
396 return 0;
397}
398
399static int wm8776_resume(struct platform_device *pdev)
400{
401 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
402 struct snd_soc_codec *codec = socdev->card->codec;
403 int i;
404 u8 data[2];
405 u16 *cache = codec->reg_cache;
406
407 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2);
412 }
413
414 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
415
416 return 0;
417}
418#else
419#define wm8776_suspend NULL
420#define wm8776_resume NULL
421#endif
422
423static int wm8776_probe(struct platform_device *pdev)
424{
425 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
426 struct snd_soc_codec *codec;
427 int ret = 0;
428
429 if (wm8776_codec == NULL) {
430 dev_err(&pdev->dev, "Codec device not registered\n");
431 return -ENODEV;
432 }
433
434 socdev->card->codec = wm8776_codec;
435 codec = wm8776_codec;
436
437 /* register pcms */
438 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
439 if (ret < 0) {
440 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
441 goto pcm_err;
442 }
443
444 snd_soc_add_controls(codec, wm8776_snd_controls,
445 ARRAY_SIZE(wm8776_snd_controls));
446 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets,
447 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret;
457
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err:
462 return ret;
463}
464
465/* power down chip */
466static int wm8776_remove(struct platform_device *pdev)
467{
468 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
469
470 snd_soc_free_pcms(socdev);
471 snd_soc_dapm_free(socdev);
472
473 return 0;
474}
475
476struct snd_soc_codec_device soc_codec_dev_wm8776 = {
477 .probe = wm8776_probe,
478 .remove = wm8776_remove,
479 .suspend = wm8776_suspend,
480 .resume = wm8776_resume,
481};
482EXPORT_SYMBOL_GPL(soc_codec_dev_wm8776);
483
484static int wm8776_register(struct wm8776_priv *wm8776,
485 enum snd_soc_control_type control)
486{
487 int ret, i;
488 struct snd_soc_codec *codec = &wm8776->codec;
489
490 if (wm8776_codec) {
491 dev_err(codec->dev, "Another WM8776 is registered\n");
492 ret = -EINVAL;
493 goto err;
494 }
495
496 mutex_init(&codec->mutex);
497 INIT_LIST_HEAD(&codec->dapm_widgets);
498 INIT_LIST_HEAD(&codec->dapm_paths);
499
500 codec->private_data = wm8776;
501 codec->name = "WM8776";
502 codec->owner = THIS_MODULE;
503 codec->bias_level = SND_SOC_BIAS_OFF;
504 codec->set_bias_level = wm8776_set_bias_level;
505 codec->dai = wm8776_dai;
506 codec->num_dai = ARRAY_SIZE(wm8776_dai);
507 codec->reg_cache_size = WM8776_CACHEREGNUM;
508 codec->reg_cache = &wm8776->reg_cache;
509
510 memcpy(codec->reg_cache, wm8776_reg, sizeof(wm8776_reg));
511
512 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
513 if (ret < 0) {
514 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
515 goto err;
516 }
517
518 for (i = 0; i < ARRAY_SIZE(wm8776_dai); i++)
519 wm8776_dai[i].dev = codec->dev;
520
521 ret = wm8776_reset(codec);
522 if (ret < 0) {
523 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
524 goto err;
525 }
526
527 wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
528
529 /* Latch the update bits; right channel only since we always
530 * update both. */
531 snd_soc_update_bits(codec, WM8776_HPRVOL, 0x100, 0x100);
532 snd_soc_update_bits(codec, WM8776_DACRVOL, 0x100, 0x100);
533
534 wm8776_codec = codec;
535
536 ret = snd_soc_register_codec(codec);
537 if (ret != 0) {
538 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
539 goto err;
540 }
541
542 ret = snd_soc_register_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
543 if (ret != 0) {
544 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
545 goto err_codec;
546 }
547
548 return 0;
549
550err_codec:
551 snd_soc_unregister_codec(codec);
552err:
553 kfree(wm8776);
554 return ret;
555}
556
557static void wm8776_unregister(struct wm8776_priv *wm8776)
558{
559 wm8776_set_bias_level(&wm8776->codec, SND_SOC_BIAS_OFF);
560 snd_soc_unregister_dais(wm8776_dai, ARRAY_SIZE(wm8776_dai));
561 snd_soc_unregister_codec(&wm8776->codec);
562 kfree(wm8776);
563 wm8776_codec = NULL;
564}
565
566#if defined(CONFIG_SPI_MASTER)
567static int wm8776_spi_write(struct spi_device *spi, const char *data, int len)
568{
569 struct spi_transfer t;
570 struct spi_message m;
571 u8 msg[2];
572
573 if (len <= 0)
574 return 0;
575
576 msg[0] = data[0];
577 msg[1] = data[1];
578
579 spi_message_init(&m);
580 memset(&t, 0, (sizeof t));
581
582 t.tx_buf = &msg[0];
583 t.len = len;
584
585 spi_message_add_tail(&t, &m);
586 spi_sync(spi, &m);
587
588 return len;
589}
590
591static int __devinit wm8776_spi_probe(struct spi_device *spi)
592{
593 struct snd_soc_codec *codec;
594 struct wm8776_priv *wm8776;
595
596 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
597 if (wm8776 == NULL)
598 return -ENOMEM;
599
600 codec = &wm8776->codec;
601 codec->control_data = spi;
602 codec->hw_write = (hw_write_t)wm8776_spi_write;
603 codec->dev = &spi->dev;
604
605 dev_set_drvdata(&spi->dev, wm8776);
606
607 return wm8776_register(wm8776, SND_SOC_SPI);
608}
609
610static int __devexit wm8776_spi_remove(struct spi_device *spi)
611{
612 struct wm8776_priv *wm8776 = dev_get_drvdata(&spi->dev);
613
614 wm8776_unregister(wm8776);
615
616 return 0;
617}
618
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = {
635 .driver = {
636 .name = "wm8776",
637 .bus = &spi_bus_type,
638 .owner = THIS_MODULE,
639 },
640 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove),
644};
645#endif /* CONFIG_SPI_MASTER */
646
647#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
648static __devinit int wm8776_i2c_probe(struct i2c_client *i2c,
649 const struct i2c_device_id *id)
650{
651 struct wm8776_priv *wm8776;
652 struct snd_soc_codec *codec;
653
654 wm8776 = kzalloc(sizeof(struct wm8776_priv), GFP_KERNEL);
655 if (wm8776 == NULL)
656 return -ENOMEM;
657
658 codec = &wm8776->codec;
659 codec->hw_write = (hw_write_t)i2c_master_send;
660
661 i2c_set_clientdata(i2c, wm8776);
662 codec->control_data = i2c;
663
664 codec->dev = &i2c->dev;
665
666 return wm8776_register(wm8776, SND_SOC_I2C);
667}
668
669static __devexit int wm8776_i2c_remove(struct i2c_client *client)
670{
671 struct wm8776_priv *wm8776 = i2c_get_clientdata(client);
672 wm8776_unregister(wm8776);
673 return 0;
674}
675
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 },
693 { }
694};
695MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id);
696
697static struct i2c_driver wm8776_i2c_driver = {
698 .driver = {
699 .name = "wm8776",
700 .owner = THIS_MODULE,
701 },
702 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id,
707};
708#endif
709
710static int __init wm8776_modinit(void)
711{
712 int ret;
713#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
714 ret = i2c_add_driver(&wm8776_i2c_driver);
715 if (ret != 0) {
716 printk(KERN_ERR "Failed to register WM8776 I2C driver: %d\n",
717 ret);
718 }
719#endif
720#if defined(CONFIG_SPI_MASTER)
721 ret = spi_register_driver(&wm8776_spi_driver);
722 if (ret != 0) {
723 printk(KERN_ERR "Failed to register WM8776 SPI driver: %d\n",
724 ret);
725 }
726#endif
727 return 0;
728}
729module_init(wm8776_modinit);
730
731static void __exit wm8776_exit(void)
732{
733#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
734 i2c_del_driver(&wm8776_i2c_driver);
735#endif
736#if defined(CONFIG_SPI_MASTER)
737 spi_unregister_driver(&wm8776_spi_driver);
738#endif
739}
740module_exit(wm8776_exit);
741
742MODULE_DESCRIPTION("ASoC WM8776 driver");
743MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
744MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8776.h b/sound/soc/codecs/wm8776.h
new file mode 100644
index 000000000000..6606d25d2d83
--- /dev/null
+++ b/sound/soc/codecs/wm8776.h
@@ -0,0 +1,51 @@
1/*
2 * wm8776.h -- WM8776 ASoC driver
3 *
4 * Copyright 2009 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 _WM8776_H
14#define _WM8776_H
15
16/* Registers */
17
18#define WM8776_HPLVOL 0x00
19#define WM8776_HPRVOL 0x01
20#define WM8776_HPMASTER 0x02
21#define WM8776_DACLVOL 0x03
22#define WM8776_DACRVOL 0x04
23#define WM8776_DACMASTER 0x05
24#define WM8776_PHASESWAP 0x06
25#define WM8776_DACCTRL1 0x07
26#define WM8776_DACMUTE 0x08
27#define WM8776_DACCTRL2 0x09
28#define WM8776_DACIFCTRL 0x0a
29#define WM8776_ADCIFCTRL 0x0b
30#define WM8776_MSTRCTRL 0x0c
31#define WM8776_PWRDOWN 0x0d
32#define WM8776_ADCLVOL 0x0e
33#define WM8776_ADCRVOL 0x0f
34#define WM8776_ALCCTRL1 0x10
35#define WM8776_ALCCTRL2 0x11
36#define WM8776_ALCCTRL3 0x12
37#define WM8776_NOISEGATE 0x13
38#define WM8776_LIMITER 0x14
39#define WM8776_ADCMUX 0x15
40#define WM8776_OUTMUX 0x16
41#define WM8776_RESET 0x17
42
43#define WM8776_CACHEREGNUM 0x17
44
45#define WM8776_DAI_DAC 0
46#define WM8776_DAI_ADC 1
47
48extern struct snd_soc_dai wm8776_dai[];
49extern struct snd_soc_codec_device soc_codec_dev_wm8776;
50
51#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 3c78945244b8..5e9c855c0036 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -116,6 +116,7 @@
116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c 116#define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c
117 117
118#define WM8900_REG_DACCTRL_MUTE 0x004 118#define WM8900_REG_DACCTRL_MUTE 0x004
119#define WM8900_REG_DACCTRL_DAC_SB_FILT 0x100
119#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400 120#define WM8900_REG_DACCTRL_AIF_LRCLKRATE 0x400
120 121
121#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800 122#define WM8900_REG_AUDIO3_ADCLRC_DIR 0x0800
@@ -182,111 +183,20 @@ static const u16 wm8900_reg_defaults[WM8900_MAXREG] = {
182 /* Remaining registers all zero */ 183 /* Remaining registers all zero */
183}; 184};
184 185
185/* 186static int wm8900_volatile_register(unsigned int reg)
186 * read wm8900 register cache
187 */
188static inline unsigned int wm8900_read_reg_cache(struct snd_soc_codec *codec,
189 unsigned int reg)
190{
191 u16 *cache = codec->reg_cache;
192
193 BUG_ON(reg >= WM8900_MAXREG);
194
195 if (reg == WM8900_REG_ID)
196 return 0;
197
198 return cache[reg];
199}
200
201/*
202 * write wm8900 register cache
203 */
204static inline void wm8900_write_reg_cache(struct snd_soc_codec *codec,
205 u16 reg, unsigned int value)
206{
207 u16 *cache = codec->reg_cache;
208
209 BUG_ON(reg >= WM8900_MAXREG);
210
211 cache[reg] = value;
212}
213
214/*
215 * write to the WM8900 register space
216 */
217static int wm8900_write(struct snd_soc_codec *codec, unsigned int reg,
218 unsigned int value)
219{
220 u8 data[3];
221
222 if (value == wm8900_read_reg_cache(codec, reg))
223 return 0;
224
225 /* data is
226 * D15..D9 WM8900 register offset
227 * D8...D0 register data
228 */
229 data[0] = reg;
230 data[1] = value >> 8;
231 data[2] = value & 0x00ff;
232
233 wm8900_write_reg_cache(codec, reg, value);
234 if (codec->hw_write(codec->control_data, data, 3) == 3)
235 return 0;
236 else
237 return -EIO;
238}
239
240/*
241 * Read from the wm8900.
242 */
243static unsigned int wm8900_chip_read(struct snd_soc_codec *codec, u8 reg)
244{
245 struct i2c_msg xfer[2];
246 u16 data;
247 int ret;
248 struct i2c_client *client = codec->control_data;
249
250 BUG_ON(reg != WM8900_REG_ID && reg != WM8900_REG_POWER1);
251
252 /* Write register */
253 xfer[0].addr = client->addr;
254 xfer[0].flags = 0;
255 xfer[0].len = 1;
256 xfer[0].buf = &reg;
257
258 /* Read data */
259 xfer[1].addr = client->addr;
260 xfer[1].flags = I2C_M_RD;
261 xfer[1].len = 2;
262 xfer[1].buf = (u8 *)&data;
263
264 ret = i2c_transfer(client->adapter, xfer, 2);
265 if (ret != 2) {
266 printk(KERN_CRIT "i2c_transfer returned %d\n", ret);
267 return 0;
268 }
269
270 return (data >> 8) | ((data & 0xff) << 8);
271}
272
273/*
274 * Read from the WM8900 register space. Most registers can't be read
275 * and are therefore supplied from cache.
276 */
277static unsigned int wm8900_read(struct snd_soc_codec *codec, unsigned int reg)
278{ 187{
279 switch (reg) { 188 switch (reg) {
280 case WM8900_REG_ID: 189 case WM8900_REG_ID:
281 return wm8900_chip_read(codec, reg); 190 case WM8900_REG_POWER1:
191 return 1;
282 default: 192 default:
283 return wm8900_read_reg_cache(codec, reg); 193 return 0;
284 } 194 }
285} 195}
286 196
287static void wm8900_reset(struct snd_soc_codec *codec) 197static void wm8900_reset(struct snd_soc_codec *codec)
288{ 198{
289 wm8900_write(codec, WM8900_REG_RESET, 0); 199 snd_soc_write(codec, WM8900_REG_RESET, 0);
290 200
291 memcpy(codec->reg_cache, wm8900_reg_defaults, 201 memcpy(codec->reg_cache, wm8900_reg_defaults,
292 sizeof(codec->reg_cache)); 202 sizeof(codec->reg_cache));
@@ -296,14 +206,14 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
296 struct snd_kcontrol *kcontrol, int event) 206 struct snd_kcontrol *kcontrol, int event)
297{ 207{
298 struct snd_soc_codec *codec = w->codec; 208 struct snd_soc_codec *codec = w->codec;
299 u16 hpctl1 = wm8900_read(codec, WM8900_REG_HPCTL1); 209 u16 hpctl1 = snd_soc_read(codec, WM8900_REG_HPCTL1);
300 210
301 switch (event) { 211 switch (event) {
302 case SND_SOC_DAPM_PRE_PMU: 212 case SND_SOC_DAPM_PRE_PMU:
303 /* Clamp headphone outputs */ 213 /* Clamp headphone outputs */
304 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP | 214 hpctl1 = WM8900_REG_HPCTL1_HP_CLAMP_IP |
305 WM8900_REG_HPCTL1_HP_CLAMP_OP; 215 WM8900_REG_HPCTL1_HP_CLAMP_OP;
306 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 216 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
307 break; 217 break;
308 218
309 case SND_SOC_DAPM_POST_PMU: 219 case SND_SOC_DAPM_POST_PMU:
@@ -312,41 +222,41 @@ static int wm8900_hp_event(struct snd_soc_dapm_widget *w,
312 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT | 222 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT |
313 WM8900_REG_HPCTL1_HP_SHORT2 | 223 WM8900_REG_HPCTL1_HP_SHORT2 |
314 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; 224 WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
315 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 225 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
316 226
317 msleep(400); 227 msleep(400);
318 228
319 /* Enable the output stage */ 229 /* Enable the output stage */
320 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP; 230 hpctl1 &= ~WM8900_REG_HPCTL1_HP_CLAMP_OP;
321 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; 231 hpctl1 |= WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
322 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 232 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
323 233
324 /* Remove the shorts */ 234 /* Remove the shorts */
325 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2; 235 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT2;
326 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 236 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
327 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT; 237 hpctl1 &= ~WM8900_REG_HPCTL1_HP_SHORT;
328 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 238 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
329 break; 239 break;
330 240
331 case SND_SOC_DAPM_PRE_PMD: 241 case SND_SOC_DAPM_PRE_PMD:
332 /* Short the output */ 242 /* Short the output */
333 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT; 243 hpctl1 |= WM8900_REG_HPCTL1_HP_SHORT;
334 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 244 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
335 245
336 /* Disable the output stage */ 246 /* Disable the output stage */
337 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA; 247 hpctl1 &= ~WM8900_REG_HPCTL1_HP_OPSTAGE_ENA;
338 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 248 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
339 249
340 /* Clamp the outputs and power down input */ 250 /* Clamp the outputs and power down input */
341 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP | 251 hpctl1 |= WM8900_REG_HPCTL1_HP_CLAMP_IP |
342 WM8900_REG_HPCTL1_HP_CLAMP_OP; 252 WM8900_REG_HPCTL1_HP_CLAMP_OP;
343 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA; 253 hpctl1 &= ~WM8900_REG_HPCTL1_HP_IPSTAGE_ENA;
344 wm8900_write(codec, WM8900_REG_HPCTL1, hpctl1); 254 snd_soc_write(codec, WM8900_REG_HPCTL1, hpctl1);
345 break; 255 break;
346 256
347 case SND_SOC_DAPM_POST_PMD: 257 case SND_SOC_DAPM_POST_PMD:
348 /* Disable everything */ 258 /* Disable everything */
349 wm8900_write(codec, WM8900_REG_HPCTL1, 0); 259 snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
350 break; 260 break;
351 261
352 default: 262 default:
@@ -439,7 +349,6 @@ SOC_SINGLE("DAC Soft Mute Switch", WM8900_REG_DACCTRL, 6, 1, 1),
439SOC_ENUM("DAC Mute Rate", dac_mute_rate), 349SOC_ENUM("DAC Mute Rate", dac_mute_rate),
440SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0), 350SOC_SINGLE("DAC Mono Switch", WM8900_REG_DACCTRL, 9, 1, 0),
441SOC_ENUM("DAC Deemphasis", dac_deemphasis), 351SOC_ENUM("DAC Deemphasis", dac_deemphasis),
442SOC_SINGLE("DAC Sloping Stopband Filter Switch", WM8900_REG_DACCTRL, 8, 1, 0),
443SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL, 352SOC_SINGLE("DAC Sigma-Delta Modulator Clock Switch", WM8900_REG_DACCTRL,
444 12, 1, 0), 353 12, 1, 0),
445 354
@@ -723,7 +632,7 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
723 struct snd_soc_codec *codec = socdev->card->codec; 632 struct snd_soc_codec *codec = socdev->card->codec;
724 u16 reg; 633 u16 reg;
725 634
726 reg = wm8900_read(codec, WM8900_REG_AUDIO1) & ~0x60; 635 reg = snd_soc_read(codec, WM8900_REG_AUDIO1) & ~0x60;
727 636
728 switch (params_format(params)) { 637 switch (params_format(params)) {
729 case SNDRV_PCM_FORMAT_S16_LE: 638 case SNDRV_PCM_FORMAT_S16_LE:
@@ -741,7 +650,18 @@ static int wm8900_hw_params(struct snd_pcm_substream *substream,
741 return -EINVAL; 650 return -EINVAL;
742 } 651 }
743 652
744 wm8900_write(codec, WM8900_REG_AUDIO1, reg); 653 snd_soc_write(codec, WM8900_REG_AUDIO1, reg);
654
655 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
656 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
657
658 if (params_rate(params) <= 24000)
659 reg |= WM8900_REG_DACCTRL_DAC_SB_FILT;
660 else
661 reg &= ~WM8900_REG_DACCTRL_DAC_SB_FILT;
662
663 snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
664 }
745 665
746 return 0; 666 return 0;
747} 667}
@@ -834,18 +754,18 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
834 return 0; 754 return 0;
835 755
836 /* The digital side should be disabled during any change. */ 756 /* The digital side should be disabled during any change. */
837 reg = wm8900_read(codec, WM8900_REG_POWER1); 757 reg = snd_soc_read(codec, WM8900_REG_POWER1);
838 wm8900_write(codec, WM8900_REG_POWER1, 758 snd_soc_write(codec, WM8900_REG_POWER1,
839 reg & (~WM8900_REG_POWER1_FLL_ENA)); 759 reg & (~WM8900_REG_POWER1_FLL_ENA));
840 760
841 /* Disable the FLL? */ 761 /* Disable the FLL? */
842 if (!freq_in || !freq_out) { 762 if (!freq_in || !freq_out) {
843 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 763 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
844 wm8900_write(codec, WM8900_REG_CLOCKING1, 764 snd_soc_write(codec, WM8900_REG_CLOCKING1,
845 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); 765 reg & (~WM8900_REG_CLOCKING1_MCLK_SRC));
846 766
847 reg = wm8900_read(codec, WM8900_REG_FLLCTL1); 767 reg = snd_soc_read(codec, WM8900_REG_FLLCTL1);
848 wm8900_write(codec, WM8900_REG_FLLCTL1, 768 snd_soc_write(codec, WM8900_REG_FLLCTL1,
849 reg & (~WM8900_REG_FLLCTL1_OSC_ENA)); 769 reg & (~WM8900_REG_FLLCTL1_OSC_ENA));
850 770
851 wm8900->fll_in = freq_in; 771 wm8900->fll_in = freq_in;
@@ -862,33 +782,33 @@ static int wm8900_set_fll(struct snd_soc_codec *codec,
862 782
863 /* The osclilator *MUST* be enabled before we enable the 783 /* The osclilator *MUST* be enabled before we enable the
864 * digital circuit. */ 784 * digital circuit. */
865 wm8900_write(codec, WM8900_REG_FLLCTL1, 785 snd_soc_write(codec, WM8900_REG_FLLCTL1,
866 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA); 786 fll_div.fll_ratio | WM8900_REG_FLLCTL1_OSC_ENA);
867 787
868 wm8900_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5); 788 snd_soc_write(codec, WM8900_REG_FLLCTL4, fll_div.n >> 5);
869 wm8900_write(codec, WM8900_REG_FLLCTL5, 789 snd_soc_write(codec, WM8900_REG_FLLCTL5,
870 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f)); 790 (fll_div.fllclk_div << 6) | (fll_div.n & 0x1f));
871 791
872 if (fll_div.k) { 792 if (fll_div.k) {
873 wm8900_write(codec, WM8900_REG_FLLCTL2, 793 snd_soc_write(codec, WM8900_REG_FLLCTL2,
874 (fll_div.k >> 8) | 0x100); 794 (fll_div.k >> 8) | 0x100);
875 wm8900_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff); 795 snd_soc_write(codec, WM8900_REG_FLLCTL3, fll_div.k & 0xff);
876 } else 796 } else
877 wm8900_write(codec, WM8900_REG_FLLCTL2, 0); 797 snd_soc_write(codec, WM8900_REG_FLLCTL2, 0);
878 798
879 if (fll_div.fll_slow_lock_ref) 799 if (fll_div.fll_slow_lock_ref)
880 wm8900_write(codec, WM8900_REG_FLLCTL6, 800 snd_soc_write(codec, WM8900_REG_FLLCTL6,
881 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF); 801 WM8900_REG_FLLCTL6_FLL_SLOW_LOCK_REF);
882 else 802 else
883 wm8900_write(codec, WM8900_REG_FLLCTL6, 0); 803 snd_soc_write(codec, WM8900_REG_FLLCTL6, 0);
884 804
885 reg = wm8900_read(codec, WM8900_REG_POWER1); 805 reg = snd_soc_read(codec, WM8900_REG_POWER1);
886 wm8900_write(codec, WM8900_REG_POWER1, 806 snd_soc_write(codec, WM8900_REG_POWER1,
887 reg | WM8900_REG_POWER1_FLL_ENA); 807 reg | WM8900_REG_POWER1_FLL_ENA);
888 808
889reenable: 809reenable:
890 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 810 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
891 wm8900_write(codec, WM8900_REG_CLOCKING1, 811 snd_soc_write(codec, WM8900_REG_CLOCKING1,
892 reg | WM8900_REG_CLOCKING1_MCLK_SRC); 812 reg | WM8900_REG_CLOCKING1_MCLK_SRC);
893 813
894 return 0; 814 return 0;
@@ -908,38 +828,38 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
908 828
909 switch (div_id) { 829 switch (div_id) {
910 case WM8900_BCLK_DIV: 830 case WM8900_BCLK_DIV:
911 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 831 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
912 wm8900_write(codec, WM8900_REG_CLOCKING1, 832 snd_soc_write(codec, WM8900_REG_CLOCKING1,
913 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK)); 833 div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK));
914 break; 834 break;
915 case WM8900_OPCLK_DIV: 835 case WM8900_OPCLK_DIV:
916 reg = wm8900_read(codec, WM8900_REG_CLOCKING1); 836 reg = snd_soc_read(codec, WM8900_REG_CLOCKING1);
917 wm8900_write(codec, WM8900_REG_CLOCKING1, 837 snd_soc_write(codec, WM8900_REG_CLOCKING1,
918 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK)); 838 div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK));
919 break; 839 break;
920 case WM8900_DAC_LRCLK: 840 case WM8900_DAC_LRCLK:
921 reg = wm8900_read(codec, WM8900_REG_AUDIO4); 841 reg = snd_soc_read(codec, WM8900_REG_AUDIO4);
922 wm8900_write(codec, WM8900_REG_AUDIO4, 842 snd_soc_write(codec, WM8900_REG_AUDIO4,
923 div | (reg & WM8900_LRC_MASK)); 843 div | (reg & WM8900_LRC_MASK));
924 break; 844 break;
925 case WM8900_ADC_LRCLK: 845 case WM8900_ADC_LRCLK:
926 reg = wm8900_read(codec, WM8900_REG_AUDIO3); 846 reg = snd_soc_read(codec, WM8900_REG_AUDIO3);
927 wm8900_write(codec, WM8900_REG_AUDIO3, 847 snd_soc_write(codec, WM8900_REG_AUDIO3,
928 div | (reg & WM8900_LRC_MASK)); 848 div | (reg & WM8900_LRC_MASK));
929 break; 849 break;
930 case WM8900_DAC_CLKDIV: 850 case WM8900_DAC_CLKDIV:
931 reg = wm8900_read(codec, WM8900_REG_CLOCKING2); 851 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
932 wm8900_write(codec, WM8900_REG_CLOCKING2, 852 snd_soc_write(codec, WM8900_REG_CLOCKING2,
933 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV)); 853 div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV));
934 break; 854 break;
935 case WM8900_ADC_CLKDIV: 855 case WM8900_ADC_CLKDIV:
936 reg = wm8900_read(codec, WM8900_REG_CLOCKING2); 856 reg = snd_soc_read(codec, WM8900_REG_CLOCKING2);
937 wm8900_write(codec, WM8900_REG_CLOCKING2, 857 snd_soc_write(codec, WM8900_REG_CLOCKING2,
938 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV)); 858 div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV));
939 break; 859 break;
940 case WM8900_LRCLK_MODE: 860 case WM8900_LRCLK_MODE:
941 reg = wm8900_read(codec, WM8900_REG_DACCTRL); 861 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
942 wm8900_write(codec, WM8900_REG_DACCTRL, 862 snd_soc_write(codec, WM8900_REG_DACCTRL,
943 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE)); 863 div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE));
944 break; 864 break;
945 default: 865 default:
@@ -956,10 +876,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
956 struct snd_soc_codec *codec = codec_dai->codec; 876 struct snd_soc_codec *codec = codec_dai->codec;
957 unsigned int clocking1, aif1, aif3, aif4; 877 unsigned int clocking1, aif1, aif3, aif4;
958 878
959 clocking1 = wm8900_read(codec, WM8900_REG_CLOCKING1); 879 clocking1 = snd_soc_read(codec, WM8900_REG_CLOCKING1);
960 aif1 = wm8900_read(codec, WM8900_REG_AUDIO1); 880 aif1 = snd_soc_read(codec, WM8900_REG_AUDIO1);
961 aif3 = wm8900_read(codec, WM8900_REG_AUDIO3); 881 aif3 = snd_soc_read(codec, WM8900_REG_AUDIO3);
962 aif4 = wm8900_read(codec, WM8900_REG_AUDIO4); 882 aif4 = snd_soc_read(codec, WM8900_REG_AUDIO4);
963 883
964 /* set master/slave audio interface */ 884 /* set master/slave audio interface */
965 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 885 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1055,10 +975,10 @@ static int wm8900_set_dai_fmt(struct snd_soc_dai *codec_dai,
1055 return -EINVAL; 975 return -EINVAL;
1056 } 976 }
1057 977
1058 wm8900_write(codec, WM8900_REG_CLOCKING1, clocking1); 978 snd_soc_write(codec, WM8900_REG_CLOCKING1, clocking1);
1059 wm8900_write(codec, WM8900_REG_AUDIO1, aif1); 979 snd_soc_write(codec, WM8900_REG_AUDIO1, aif1);
1060 wm8900_write(codec, WM8900_REG_AUDIO3, aif3); 980 snd_soc_write(codec, WM8900_REG_AUDIO3, aif3);
1061 wm8900_write(codec, WM8900_REG_AUDIO4, aif4); 981 snd_soc_write(codec, WM8900_REG_AUDIO4, aif4);
1062 982
1063 return 0; 983 return 0;
1064} 984}
@@ -1068,14 +988,14 @@ static int wm8900_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1068 struct snd_soc_codec *codec = codec_dai->codec; 988 struct snd_soc_codec *codec = codec_dai->codec;
1069 u16 reg; 989 u16 reg;
1070 990
1071 reg = wm8900_read(codec, WM8900_REG_DACCTRL); 991 reg = snd_soc_read(codec, WM8900_REG_DACCTRL);
1072 992
1073 if (mute) 993 if (mute)
1074 reg |= WM8900_REG_DACCTRL_MUTE; 994 reg |= WM8900_REG_DACCTRL_MUTE;
1075 else 995 else
1076 reg &= ~WM8900_REG_DACCTRL_MUTE; 996 reg &= ~WM8900_REG_DACCTRL_MUTE;
1077 997
1078 wm8900_write(codec, WM8900_REG_DACCTRL, reg); 998 snd_soc_write(codec, WM8900_REG_DACCTRL, reg);
1079 999
1080 return 0; 1000 return 0;
1081} 1001}
@@ -1124,11 +1044,11 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1124 switch (level) { 1044 switch (level) {
1125 case SND_SOC_BIAS_ON: 1045 case SND_SOC_BIAS_ON:
1126 /* Enable thermal shutdown */ 1046 /* Enable thermal shutdown */
1127 reg = wm8900_read(codec, WM8900_REG_GPIO); 1047 reg = snd_soc_read(codec, WM8900_REG_GPIO);
1128 wm8900_write(codec, WM8900_REG_GPIO, 1048 snd_soc_write(codec, WM8900_REG_GPIO,
1129 reg | WM8900_REG_GPIO_TEMP_ENA); 1049 reg | WM8900_REG_GPIO_TEMP_ENA);
1130 reg = wm8900_read(codec, WM8900_REG_ADDCTL); 1050 reg = snd_soc_read(codec, WM8900_REG_ADDCTL);
1131 wm8900_write(codec, WM8900_REG_ADDCTL, 1051 snd_soc_write(codec, WM8900_REG_ADDCTL,
1132 reg | WM8900_REG_ADDCTL_TEMP_SD); 1052 reg | WM8900_REG_ADDCTL_TEMP_SD);
1133 break; 1053 break;
1134 1054
@@ -1139,69 +1059,69 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1139 /* Charge capacitors if initial power up */ 1059 /* Charge capacitors if initial power up */
1140 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1060 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1141 /* STARTUP_BIAS_ENA on */ 1061 /* STARTUP_BIAS_ENA on */
1142 wm8900_write(codec, WM8900_REG_POWER1, 1062 snd_soc_write(codec, WM8900_REG_POWER1,
1143 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1063 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1144 1064
1145 /* Startup bias mode */ 1065 /* Startup bias mode */
1146 wm8900_write(codec, WM8900_REG_ADDCTL, 1066 snd_soc_write(codec, WM8900_REG_ADDCTL,
1147 WM8900_REG_ADDCTL_BIAS_SRC | 1067 WM8900_REG_ADDCTL_BIAS_SRC |
1148 WM8900_REG_ADDCTL_VMID_SOFTST); 1068 WM8900_REG_ADDCTL_VMID_SOFTST);
1149 1069
1150 /* VMID 2x50k */ 1070 /* VMID 2x50k */
1151 wm8900_write(codec, WM8900_REG_POWER1, 1071 snd_soc_write(codec, WM8900_REG_POWER1,
1152 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1); 1072 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 0x1);
1153 1073
1154 /* Allow capacitors to charge */ 1074 /* Allow capacitors to charge */
1155 schedule_timeout_interruptible(msecs_to_jiffies(400)); 1075 schedule_timeout_interruptible(msecs_to_jiffies(400));
1156 1076
1157 /* Enable bias */ 1077 /* Enable bias */
1158 wm8900_write(codec, WM8900_REG_POWER1, 1078 snd_soc_write(codec, WM8900_REG_POWER1,
1159 WM8900_REG_POWER1_STARTUP_BIAS_ENA | 1079 WM8900_REG_POWER1_STARTUP_BIAS_ENA |
1160 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1080 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1161 1081
1162 wm8900_write(codec, WM8900_REG_ADDCTL, 0); 1082 snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
1163 1083
1164 wm8900_write(codec, WM8900_REG_POWER1, 1084 snd_soc_write(codec, WM8900_REG_POWER1,
1165 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1085 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1166 } 1086 }
1167 1087
1168 reg = wm8900_read(codec, WM8900_REG_POWER1); 1088 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1169 wm8900_write(codec, WM8900_REG_POWER1, 1089 snd_soc_write(codec, WM8900_REG_POWER1,
1170 (reg & WM8900_REG_POWER1_FLL_ENA) | 1090 (reg & WM8900_REG_POWER1_FLL_ENA) |
1171 WM8900_REG_POWER1_BIAS_ENA | 0x1); 1091 WM8900_REG_POWER1_BIAS_ENA | 0x1);
1172 wm8900_write(codec, WM8900_REG_POWER2, 1092 snd_soc_write(codec, WM8900_REG_POWER2,
1173 WM8900_REG_POWER2_SYSCLK_ENA); 1093 WM8900_REG_POWER2_SYSCLK_ENA);
1174 wm8900_write(codec, WM8900_REG_POWER3, 0); 1094 snd_soc_write(codec, WM8900_REG_POWER3, 0);
1175 break; 1095 break;
1176 1096
1177 case SND_SOC_BIAS_OFF: 1097 case SND_SOC_BIAS_OFF:
1178 /* Startup bias enable */ 1098 /* Startup bias enable */
1179 reg = wm8900_read(codec, WM8900_REG_POWER1); 1099 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1180 wm8900_write(codec, WM8900_REG_POWER1, 1100 snd_soc_write(codec, WM8900_REG_POWER1,
1181 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1101 reg & WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1182 wm8900_write(codec, WM8900_REG_ADDCTL, 1102 snd_soc_write(codec, WM8900_REG_ADDCTL,
1183 WM8900_REG_ADDCTL_BIAS_SRC | 1103 WM8900_REG_ADDCTL_BIAS_SRC |
1184 WM8900_REG_ADDCTL_VMID_SOFTST); 1104 WM8900_REG_ADDCTL_VMID_SOFTST);
1185 1105
1186 /* Discharge caps */ 1106 /* Discharge caps */
1187 wm8900_write(codec, WM8900_REG_POWER1, 1107 snd_soc_write(codec, WM8900_REG_POWER1,
1188 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1108 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
1189 schedule_timeout_interruptible(msecs_to_jiffies(500)); 1109 schedule_timeout_interruptible(msecs_to_jiffies(500));
1190 1110
1191 /* Remove clamp */ 1111 /* Remove clamp */
1192 wm8900_write(codec, WM8900_REG_HPCTL1, 0); 1112 snd_soc_write(codec, WM8900_REG_HPCTL1, 0);
1193 1113
1194 /* Power down */ 1114 /* Power down */
1195 wm8900_write(codec, WM8900_REG_ADDCTL, 0); 1115 snd_soc_write(codec, WM8900_REG_ADDCTL, 0);
1196 wm8900_write(codec, WM8900_REG_POWER1, 0); 1116 snd_soc_write(codec, WM8900_REG_POWER1, 0);
1197 wm8900_write(codec, WM8900_REG_POWER2, 0); 1117 snd_soc_write(codec, WM8900_REG_POWER2, 0);
1198 wm8900_write(codec, WM8900_REG_POWER3, 0); 1118 snd_soc_write(codec, WM8900_REG_POWER3, 0);
1199 1119
1200 /* Need to let things settle before stopping the clock 1120 /* Need to let things settle before stopping the clock
1201 * to ensure that restart works, see "Stopping the 1121 * to ensure that restart works, see "Stopping the
1202 * master clock" in the datasheet. */ 1122 * master clock" in the datasheet. */
1203 schedule_timeout_interruptible(msecs_to_jiffies(1)); 1123 schedule_timeout_interruptible(msecs_to_jiffies(1));
1204 wm8900_write(codec, WM8900_REG_POWER2, 1124 snd_soc_write(codec, WM8900_REG_POWER2,
1205 WM8900_REG_POWER2_SYSCLK_ENA); 1125 WM8900_REG_POWER2_SYSCLK_ENA);
1206 break; 1126 break;
1207 } 1127 }
@@ -1264,7 +1184,7 @@ static int wm8900_resume(struct platform_device *pdev)
1264 1184
1265 if (cache) { 1185 if (cache) {
1266 for (i = 0; i < WM8900_MAXREG; i++) 1186 for (i = 0; i < WM8900_MAXREG; i++)
1267 wm8900_write(codec, i, cache[i]); 1187 snd_soc_write(codec, i, cache[i]);
1268 kfree(cache); 1188 kfree(cache);
1269 } else 1189 } else
1270 dev_err(&pdev->dev, "Unable to allocate register cache\n"); 1190 dev_err(&pdev->dev, "Unable to allocate register cache\n");
@@ -1297,16 +1217,20 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1297 1217
1298 codec->name = "WM8900"; 1218 codec->name = "WM8900";
1299 codec->owner = THIS_MODULE; 1219 codec->owner = THIS_MODULE;
1300 codec->read = wm8900_read;
1301 codec->write = wm8900_write;
1302 codec->dai = &wm8900_dai; 1220 codec->dai = &wm8900_dai;
1303 codec->num_dai = 1; 1221 codec->num_dai = 1;
1304 codec->hw_write = (hw_write_t)i2c_master_send;
1305 codec->control_data = i2c; 1222 codec->control_data = i2c;
1306 codec->set_bias_level = wm8900_set_bias_level; 1223 codec->set_bias_level = wm8900_set_bias_level;
1224 codec->volatile_register = wm8900_volatile_register;
1307 codec->dev = &i2c->dev; 1225 codec->dev = &i2c->dev;
1308 1226
1309 reg = wm8900_read(codec, WM8900_REG_ID); 1227 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1228 if (ret != 0) {
1229 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
1230 goto err;
1231 }
1232
1233 reg = snd_soc_read(codec, WM8900_REG_ID);
1310 if (reg != 0x8900) { 1234 if (reg != 0x8900) {
1311 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg); 1235 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1312 ret = -ENODEV; 1236 ret = -ENODEV;
@@ -1314,7 +1238,7 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1314 } 1238 }
1315 1239
1316 /* Read back from the chip */ 1240 /* Read back from the chip */
1317 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1241 reg = snd_soc_read(codec, WM8900_REG_POWER1);
1318 reg = (reg >> 12) & 0xf; 1242 reg = (reg >> 12) & 0xf;
1319 dev_info(&i2c->dev, "WM8900 revision %d\n", reg); 1243 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1320 1244
@@ -1324,29 +1248,29 @@ static __devinit int wm8900_i2c_probe(struct i2c_client *i2c,
1324 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1248 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1325 1249
1326 /* Latch the volume update bits */ 1250 /* Latch the volume update bits */
1327 wm8900_write(codec, WM8900_REG_LINVOL, 1251 snd_soc_write(codec, WM8900_REG_LINVOL,
1328 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1252 snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100);
1329 wm8900_write(codec, WM8900_REG_RINVOL, 1253 snd_soc_write(codec, WM8900_REG_RINVOL,
1330 wm8900_read(codec, WM8900_REG_RINVOL) | 0x100); 1254 snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100);
1331 wm8900_write(codec, WM8900_REG_LOUT1CTL, 1255 snd_soc_write(codec, WM8900_REG_LOUT1CTL,
1332 wm8900_read(codec, WM8900_REG_LOUT1CTL) | 0x100); 1256 snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100);
1333 wm8900_write(codec, WM8900_REG_ROUT1CTL, 1257 snd_soc_write(codec, WM8900_REG_ROUT1CTL,
1334 wm8900_read(codec, WM8900_REG_ROUT1CTL) | 0x100); 1258 snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100);
1335 wm8900_write(codec, WM8900_REG_LOUT2CTL, 1259 snd_soc_write(codec, WM8900_REG_LOUT2CTL,
1336 wm8900_read(codec, WM8900_REG_LOUT2CTL) | 0x100); 1260 snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100);
1337 wm8900_write(codec, WM8900_REG_ROUT2CTL, 1261 snd_soc_write(codec, WM8900_REG_ROUT2CTL,
1338 wm8900_read(codec, WM8900_REG_ROUT2CTL) | 0x100); 1262 snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100);
1339 wm8900_write(codec, WM8900_REG_LDAC_DV, 1263 snd_soc_write(codec, WM8900_REG_LDAC_DV,
1340 wm8900_read(codec, WM8900_REG_LDAC_DV) | 0x100); 1264 snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100);
1341 wm8900_write(codec, WM8900_REG_RDAC_DV, 1265 snd_soc_write(codec, WM8900_REG_RDAC_DV,
1342 wm8900_read(codec, WM8900_REG_RDAC_DV) | 0x100); 1266 snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100);
1343 wm8900_write(codec, WM8900_REG_LADC_DV, 1267 snd_soc_write(codec, WM8900_REG_LADC_DV,
1344 wm8900_read(codec, WM8900_REG_LADC_DV) | 0x100); 1268 snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100);
1345 wm8900_write(codec, WM8900_REG_RADC_DV, 1269 snd_soc_write(codec, WM8900_REG_RADC_DV,
1346 wm8900_read(codec, WM8900_REG_RADC_DV) | 0x100); 1270 snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100);
1347 1271
1348 /* Set the DAC and mixer output bias */ 1272 /* Set the DAC and mixer output bias */
1349 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1273 snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1350 1274
1351 wm8900_dai.dev = &i2c->dev; 1275 wm8900_dai.dev = &i2c->dev;
1352 1276
@@ -1388,6 +1312,21 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1388 return 0; 1312 return 0;
1389} 1313}
1390 1314
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1391static const struct i2c_device_id wm8900_i2c_id[] = { 1330static const struct i2c_device_id wm8900_i2c_id[] = {
1392 { "wm8900", 0 }, 1331 { "wm8900", 0 },
1393 { } 1332 { }
@@ -1401,6 +1340,8 @@ static struct i2c_driver wm8900_i2c_driver = {
1401 }, 1340 },
1402 .probe = wm8900_i2c_probe, 1341 .probe = wm8900_i2c_probe,
1403 .remove = __devexit_p(wm8900_i2c_remove), 1342 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1404 .id_table = wm8900_i2c_id, 1345 .id_table = wm8900_i2c_id,
1405}; 1346};
1406 1347
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index e8d2e3e14c45..fe1307b500cf 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -225,94 +225,18 @@ struct wm8903_priv {
225 struct snd_pcm_substream *slave_substream; 225 struct snd_pcm_substream *slave_substream;
226}; 226};
227 227
228 228static int wm8903_volatile_register(unsigned int reg)
229static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
230 unsigned int reg)
231{
232 u16 *cache = codec->reg_cache;
233
234 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
235
236 return cache[reg];
237}
238
239static unsigned int wm8903_hw_read(struct snd_soc_codec *codec, u8 reg)
240{
241 struct i2c_msg xfer[2];
242 u16 data;
243 int ret;
244 struct i2c_client *client = codec->control_data;
245
246 /* Write register */
247 xfer[0].addr = client->addr;
248 xfer[0].flags = 0;
249 xfer[0].len = 1;
250 xfer[0].buf = &reg;
251
252 /* Read data */
253 xfer[1].addr = client->addr;
254 xfer[1].flags = I2C_M_RD;
255 xfer[1].len = 2;
256 xfer[1].buf = (u8 *)&data;
257
258 ret = i2c_transfer(client->adapter, xfer, 2);
259 if (ret != 2) {
260 pr_err("i2c_transfer returned %d\n", ret);
261 return 0;
262 }
263
264 return (data >> 8) | ((data & 0xff) << 8);
265}
266
267static unsigned int wm8903_read(struct snd_soc_codec *codec,
268 unsigned int reg)
269{ 229{
270 switch (reg) { 230 switch (reg) {
271 case WM8903_SW_RESET_AND_ID: 231 case WM8903_SW_RESET_AND_ID:
272 case WM8903_REVISION_NUMBER: 232 case WM8903_REVISION_NUMBER:
273 case WM8903_INTERRUPT_STATUS_1: 233 case WM8903_INTERRUPT_STATUS_1:
274 case WM8903_WRITE_SEQUENCER_4: 234 case WM8903_WRITE_SEQUENCER_4:
275 return wm8903_hw_read(codec, reg); 235 return 1;
276 236
277 default: 237 default:
278 return wm8903_read_reg_cache(codec, reg);
279 }
280}
281
282static void wm8903_write_reg_cache(struct snd_soc_codec *codec,
283 u16 reg, unsigned int value)
284{
285 u16 *cache = codec->reg_cache;
286
287 BUG_ON(reg >= ARRAY_SIZE(wm8903_reg_defaults));
288
289 switch (reg) {
290 case WM8903_SW_RESET_AND_ID:
291 case WM8903_REVISION_NUMBER:
292 break;
293
294 default:
295 cache[reg] = value;
296 break;
297 }
298}
299
300static int wm8903_write(struct snd_soc_codec *codec, unsigned int reg,
301 unsigned int value)
302{
303 u8 data[3];
304
305 wm8903_write_reg_cache(codec, reg, value);
306
307 /* Data format is 1 byte of address followed by 2 bytes of data */
308 data[0] = reg;
309 data[1] = (value >> 8) & 0xff;
310 data[2] = value & 0xff;
311
312 if (codec->hw_write(codec->control_data, data, 3) == 2)
313 return 0; 238 return 0;
314 else 239 }
315 return -EIO;
316} 240}
317 241
318static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) 242static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
@@ -323,13 +247,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
323 BUG_ON(start > 48); 247 BUG_ON(start > 48);
324 248
325 /* Enable the sequencer */ 249 /* Enable the sequencer */
326 reg[0] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_0); 250 reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
327 reg[0] |= WM8903_WSEQ_ENA; 251 reg[0] |= WM8903_WSEQ_ENA;
328 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); 252 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
329 253
330 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); 254 dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);
331 255
332 wm8903_write(codec, WM8903_WRITE_SEQUENCER_3, 256 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3,
333 start | WM8903_WSEQ_START); 257 start | WM8903_WSEQ_START);
334 258
335 /* Wait for it to complete. If we have the interrupt wired up then 259 /* Wait for it to complete. If we have the interrupt wired up then
@@ -339,13 +263,13 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)
339 do { 263 do {
340 msleep(10); 264 msleep(10);
341 265
342 reg[4] = wm8903_read(codec, WM8903_WRITE_SEQUENCER_4); 266 reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4);
343 } while (reg[4] & WM8903_WSEQ_BUSY); 267 } while (reg[4] & WM8903_WSEQ_BUSY);
344 268
345 dev_dbg(&i2c->dev, "Sequence complete\n"); 269 dev_dbg(&i2c->dev, "Sequence complete\n");
346 270
347 /* Disable the sequencer again */ 271 /* Disable the sequencer again */
348 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 272 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
349 reg[0] & ~WM8903_WSEQ_ENA); 273 reg[0] & ~WM8903_WSEQ_ENA);
350 274
351 return 0; 275 return 0;
@@ -357,12 +281,12 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
357 281
358 /* There really ought to be something better we can do here :/ */ 282 /* There really ought to be something better we can do here :/ */
359 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 283 for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
360 cache[i] = wm8903_hw_read(codec, i); 284 cache[i] = codec->hw_read(codec, i);
361} 285}
362 286
363static void wm8903_reset(struct snd_soc_codec *codec) 287static void wm8903_reset(struct snd_soc_codec *codec)
364{ 288{
365 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0); 289 snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0);
366 memcpy(codec->reg_cache, wm8903_reg_defaults, 290 memcpy(codec->reg_cache, wm8903_reg_defaults,
367 sizeof(wm8903_reg_defaults)); 291 sizeof(wm8903_reg_defaults));
368} 292}
@@ -423,52 +347,52 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
423 } 347 }
424 348
425 if (event & SND_SOC_DAPM_PRE_PMU) { 349 if (event & SND_SOC_DAPM_PRE_PMU) {
426 val = wm8903_read(codec, reg); 350 val = snd_soc_read(codec, reg);
427 351
428 /* Short the output */ 352 /* Short the output */
429 val &= ~(WM8903_OUTPUT_SHORT << shift); 353 val &= ~(WM8903_OUTPUT_SHORT << shift);
430 wm8903_write(codec, reg, val); 354 snd_soc_write(codec, reg, val);
431 } 355 }
432 356
433 if (event & SND_SOC_DAPM_POST_PMU) { 357 if (event & SND_SOC_DAPM_POST_PMU) {
434 val = wm8903_read(codec, reg); 358 val = snd_soc_read(codec, reg);
435 359
436 val |= (WM8903_OUTPUT_IN << shift); 360 val |= (WM8903_OUTPUT_IN << shift);
437 wm8903_write(codec, reg, val); 361 snd_soc_write(codec, reg, val);
438 362
439 val |= (WM8903_OUTPUT_INT << shift); 363 val |= (WM8903_OUTPUT_INT << shift);
440 wm8903_write(codec, reg, val); 364 snd_soc_write(codec, reg, val);
441 365
442 /* Turn on the output ENA_OUTP */ 366 /* Turn on the output ENA_OUTP */
443 val |= (WM8903_OUTPUT_OUT << shift); 367 val |= (WM8903_OUTPUT_OUT << shift);
444 wm8903_write(codec, reg, val); 368 snd_soc_write(codec, reg, val);
445 369
446 /* Enable the DC servo */ 370 /* Enable the DC servo */
447 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); 371 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
448 dcs_reg |= dcs_bit; 372 dcs_reg |= dcs_bit;
449 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); 373 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
450 374
451 /* Remove the short */ 375 /* Remove the short */
452 val |= (WM8903_OUTPUT_SHORT << shift); 376 val |= (WM8903_OUTPUT_SHORT << shift);
453 wm8903_write(codec, reg, val); 377 snd_soc_write(codec, reg, val);
454 } 378 }
455 379
456 if (event & SND_SOC_DAPM_PRE_PMD) { 380 if (event & SND_SOC_DAPM_PRE_PMD) {
457 val = wm8903_read(codec, reg); 381 val = snd_soc_read(codec, reg);
458 382
459 /* Short the output */ 383 /* Short the output */
460 val &= ~(WM8903_OUTPUT_SHORT << shift); 384 val &= ~(WM8903_OUTPUT_SHORT << shift);
461 wm8903_write(codec, reg, val); 385 snd_soc_write(codec, reg, val);
462 386
463 /* Disable the DC servo */ 387 /* Disable the DC servo */
464 dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); 388 dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0);
465 dcs_reg &= ~dcs_bit; 389 dcs_reg &= ~dcs_bit;
466 wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); 390 snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg);
467 391
468 /* Then disable the intermediate and output stages */ 392 /* Then disable the intermediate and output stages */
469 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | 393 val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT |
470 WM8903_OUTPUT_IN) << shift); 394 WM8903_OUTPUT_IN) << shift);
471 wm8903_write(codec, reg, val); 395 snd_soc_write(codec, reg, val);
472 } 396 }
473 397
474 return 0; 398 return 0;
@@ -492,13 +416,13 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
492 u16 reg; 416 u16 reg;
493 int ret; 417 int ret;
494 418
495 reg = wm8903_read(codec, WM8903_CLASS_W_0); 419 reg = snd_soc_read(codec, WM8903_CLASS_W_0);
496 420
497 /* Turn it off if we're about to enable bypass */ 421 /* Turn it off if we're about to enable bypass */
498 if (ucontrol->value.integer.value[0]) { 422 if (ucontrol->value.integer.value[0]) {
499 if (wm8903->class_w_users == 0) { 423 if (wm8903->class_w_users == 0) {
500 dev_dbg(&i2c->dev, "Disabling Class W\n"); 424 dev_dbg(&i2c->dev, "Disabling Class W\n");
501 wm8903_write(codec, WM8903_CLASS_W_0, reg & 425 snd_soc_write(codec, WM8903_CLASS_W_0, reg &
502 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); 426 ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V));
503 } 427 }
504 wm8903->class_w_users++; 428 wm8903->class_w_users++;
@@ -511,7 +435,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
511 if (!ucontrol->value.integer.value[0]) { 435 if (!ucontrol->value.integer.value[0]) {
512 if (wm8903->class_w_users == 1) { 436 if (wm8903->class_w_users == 1) {
513 dev_dbg(&i2c->dev, "Enabling Class W\n"); 437 dev_dbg(&i2c->dev, "Enabling Class W\n");
514 wm8903_write(codec, WM8903_CLASS_W_0, reg | 438 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
515 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 439 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
516 } 440 }
517 wm8903->class_w_users--; 441 wm8903->class_w_users--;
@@ -715,8 +639,6 @@ SOC_ENUM("DAC Soft Mute Rate", soft_mute),
715SOC_ENUM("DAC Mute Mode", mute_mode), 639SOC_ENUM("DAC Mute Mode", mute_mode),
716SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), 640SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
717SOC_ENUM("DAC De-emphasis", dac_deemphasis), 641SOC_ENUM("DAC De-emphasis", dac_deemphasis),
718SOC_SINGLE("DAC Sloping Stopband Filter Switch",
719 WM8903_DAC_DIGITAL_1, 11, 1, 0),
720SOC_ENUM("DAC Companding Mode", dac_companding), 642SOC_ENUM("DAC Companding Mode", dac_companding),
721SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), 643SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
722 644
@@ -1011,55 +933,55 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1011 switch (level) { 933 switch (level) {
1012 case SND_SOC_BIAS_ON: 934 case SND_SOC_BIAS_ON:
1013 case SND_SOC_BIAS_PREPARE: 935 case SND_SOC_BIAS_PREPARE:
1014 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0); 936 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
1015 reg &= ~(WM8903_VMID_RES_MASK); 937 reg &= ~(WM8903_VMID_RES_MASK);
1016 reg |= WM8903_VMID_RES_50K; 938 reg |= WM8903_VMID_RES_50K;
1017 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg); 939 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1018 break; 940 break;
1019 941
1020 case SND_SOC_BIAS_STANDBY: 942 case SND_SOC_BIAS_STANDBY:
1021 if (codec->bias_level == SND_SOC_BIAS_OFF) { 943 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1022 wm8903_write(codec, WM8903_CLOCK_RATES_2, 944 snd_soc_write(codec, WM8903_CLOCK_RATES_2,
1023 WM8903_CLK_SYS_ENA); 945 WM8903_CLK_SYS_ENA);
1024 946
1025 /* Change DC servo dither level in startup sequence */ 947 /* Change DC servo dither level in startup sequence */
1026 wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); 948 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11);
1027 wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); 949 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257);
1028 wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); 950 snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2);
1029 951
1030 wm8903_run_sequence(codec, 0); 952 wm8903_run_sequence(codec, 0);
1031 wm8903_sync_reg_cache(codec, codec->reg_cache); 953 wm8903_sync_reg_cache(codec, codec->reg_cache);
1032 954
1033 /* Enable low impedence charge pump output */ 955 /* Enable low impedence charge pump output */
1034 reg = wm8903_read(codec, 956 reg = snd_soc_read(codec,
1035 WM8903_CONTROL_INTERFACE_TEST_1); 957 WM8903_CONTROL_INTERFACE_TEST_1);
1036 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 958 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1037 reg | WM8903_TEST_KEY); 959 reg | WM8903_TEST_KEY);
1038 reg2 = wm8903_read(codec, WM8903_CHARGE_PUMP_TEST_1); 960 reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
1039 wm8903_write(codec, WM8903_CHARGE_PUMP_TEST_1, 961 snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
1040 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); 962 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
1041 wm8903_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, 963 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
1042 reg); 964 reg);
1043 965
1044 /* By default no bypass paths are enabled so 966 /* By default no bypass paths are enabled so
1045 * enable Class W support. 967 * enable Class W support.
1046 */ 968 */
1047 dev_dbg(&i2c->dev, "Enabling Class W\n"); 969 dev_dbg(&i2c->dev, "Enabling Class W\n");
1048 wm8903_write(codec, WM8903_CLASS_W_0, reg | 970 snd_soc_write(codec, WM8903_CLASS_W_0, reg |
1049 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 971 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V);
1050 } 972 }
1051 973
1052 reg = wm8903_read(codec, WM8903_VMID_CONTROL_0); 974 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
1053 reg &= ~(WM8903_VMID_RES_MASK); 975 reg &= ~(WM8903_VMID_RES_MASK);
1054 reg |= WM8903_VMID_RES_250K; 976 reg |= WM8903_VMID_RES_250K;
1055 wm8903_write(codec, WM8903_VMID_CONTROL_0, reg); 977 snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg);
1056 break; 978 break;
1057 979
1058 case SND_SOC_BIAS_OFF: 980 case SND_SOC_BIAS_OFF:
1059 wm8903_run_sequence(codec, 32); 981 wm8903_run_sequence(codec, 32);
1060 reg = wm8903_read(codec, WM8903_CLOCK_RATES_2); 982 reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2);
1061 reg &= ~WM8903_CLK_SYS_ENA; 983 reg &= ~WM8903_CLK_SYS_ENA;
1062 wm8903_write(codec, WM8903_CLOCK_RATES_2, reg); 984 snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg);
1063 break; 985 break;
1064 } 986 }
1065 987
@@ -1083,7 +1005,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1083 unsigned int fmt) 1005 unsigned int fmt)
1084{ 1006{
1085 struct snd_soc_codec *codec = codec_dai->codec; 1007 struct snd_soc_codec *codec = codec_dai->codec;
1086 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1); 1008 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
1087 1009
1088 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK | 1010 aif1 &= ~(WM8903_LRCLK_DIR | WM8903_BCLK_DIR | WM8903_AIF_FMT_MASK |
1089 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV); 1011 WM8903_AIF_LRCLK_INV | WM8903_AIF_BCLK_INV);
@@ -1161,7 +1083,7 @@ static int wm8903_set_dai_fmt(struct snd_soc_dai *codec_dai,
1161 return -EINVAL; 1083 return -EINVAL;
1162 } 1084 }
1163 1085
1164 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1086 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1165 1087
1166 return 0; 1088 return 0;
1167} 1089}
@@ -1171,14 +1093,14 @@ static int wm8903_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1171 struct snd_soc_codec *codec = codec_dai->codec; 1093 struct snd_soc_codec *codec = codec_dai->codec;
1172 u16 reg; 1094 u16 reg;
1173 1095
1174 reg = wm8903_read(codec, WM8903_DAC_DIGITAL_1); 1096 reg = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1175 1097
1176 if (mute) 1098 if (mute)
1177 reg |= WM8903_DAC_MUTE; 1099 reg |= WM8903_DAC_MUTE;
1178 else 1100 else
1179 reg &= ~WM8903_DAC_MUTE; 1101 reg &= ~WM8903_DAC_MUTE;
1180 1102
1181 wm8903_write(codec, WM8903_DAC_DIGITAL_1, reg); 1103 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, reg);
1182 1104
1183 return 0; 1105 return 0;
1184} 1106}
@@ -1368,17 +1290,24 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1368 int cur_val; 1290 int cur_val;
1369 int clk_sys; 1291 int clk_sys;
1370 1292
1371 u16 aif1 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_1); 1293 u16 aif1 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_1);
1372 u16 aif2 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_2); 1294 u16 aif2 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_2);
1373 u16 aif3 = wm8903_read(codec, WM8903_AUDIO_INTERFACE_3); 1295 u16 aif3 = snd_soc_read(codec, WM8903_AUDIO_INTERFACE_3);
1374 u16 clock0 = wm8903_read(codec, WM8903_CLOCK_RATES_0); 1296 u16 clock0 = snd_soc_read(codec, WM8903_CLOCK_RATES_0);
1375 u16 clock1 = wm8903_read(codec, WM8903_CLOCK_RATES_1); 1297 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
1298 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1376 1299
1377 if (substream == wm8903->slave_substream) { 1300 if (substream == wm8903->slave_substream) {
1378 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); 1301 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
1379 return 0; 1302 return 0;
1380 } 1303 }
1381 1304
1305 /* Enable sloping stopband filter for low sample rates */
1306 if (fs <= 24000)
1307 dac_digital1 |= WM8903_DAC_SB_FILT;
1308 else
1309 dac_digital1 &= ~WM8903_DAC_SB_FILT;
1310
1382 /* Configure sample rate logic for DSP - choose nearest rate */ 1311 /* Configure sample rate logic for DSP - choose nearest rate */
1383 dsp_config = 0; 1312 dsp_config = 0;
1384 best_val = abs(sample_rates[dsp_config].rate - fs); 1313 best_val = abs(sample_rates[dsp_config].rate - fs);
@@ -1498,11 +1427,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1498 aif2 |= bclk_divs[bclk_div].div; 1427 aif2 |= bclk_divs[bclk_div].div;
1499 aif3 |= bclk / fs; 1428 aif3 |= bclk / fs;
1500 1429
1501 wm8903_write(codec, WM8903_CLOCK_RATES_0, clock0); 1430 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
1502 wm8903_write(codec, WM8903_CLOCK_RATES_1, clock1); 1431 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
1503 wm8903_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1432 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
1504 wm8903_write(codec, WM8903_AUDIO_INTERFACE_2, aif2); 1433 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_2, aif2);
1505 wm8903_write(codec, WM8903_AUDIO_INTERFACE_3, aif3); 1434 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_3, aif3);
1435 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, dac_digital1);
1506 1436
1507 return 0; 1437 return 0;
1508} 1438}
@@ -1587,7 +1517,7 @@ static int wm8903_resume(struct platform_device *pdev)
1587 if (tmp_cache) { 1517 if (tmp_cache) {
1588 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++) 1518 for (i = 2; i < ARRAY_SIZE(wm8903_reg_defaults); i++)
1589 if (tmp_cache[i] != reg_cache[i]) 1519 if (tmp_cache[i] != reg_cache[i])
1590 wm8903_write(codec, i, tmp_cache[i]); 1520 snd_soc_write(codec, i, tmp_cache[i]);
1591 } else { 1521 } else {
1592 dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); 1522 dev_err(&i2c->dev, "Failed to allocate temporary cache\n");
1593 } 1523 }
@@ -1618,9 +1548,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1618 codec->dev = &i2c->dev; 1548 codec->dev = &i2c->dev;
1619 codec->name = "WM8903"; 1549 codec->name = "WM8903";
1620 codec->owner = THIS_MODULE; 1550 codec->owner = THIS_MODULE;
1621 codec->read = wm8903_read;
1622 codec->write = wm8903_write;
1623 codec->hw_write = (hw_write_t)i2c_master_send;
1624 codec->bias_level = SND_SOC_BIAS_OFF; 1551 codec->bias_level = SND_SOC_BIAS_OFF;
1625 codec->set_bias_level = wm8903_set_bias_level; 1552 codec->set_bias_level = wm8903_set_bias_level;
1626 codec->dai = &wm8903_dai; 1553 codec->dai = &wm8903_dai;
@@ -1628,18 +1555,25 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1628 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); 1555 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1629 codec->reg_cache = &wm8903->reg_cache[0]; 1556 codec->reg_cache = &wm8903->reg_cache[0];
1630 codec->private_data = wm8903; 1557 codec->private_data = wm8903;
1558 codec->volatile_register = wm8903_volatile_register;
1631 1559
1632 i2c_set_clientdata(i2c, codec); 1560 i2c_set_clientdata(i2c, codec);
1633 codec->control_data = i2c; 1561 codec->control_data = i2c;
1634 1562
1635 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID); 1563 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1564 if (ret != 0) {
1565 dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret);
1566 goto err;
1567 }
1568
1569 val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID);
1636 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1570 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1637 dev_err(&i2c->dev, 1571 dev_err(&i2c->dev,
1638 "Device with ID register %x is not a WM8903\n", val); 1572 "Device with ID register %x is not a WM8903\n", val);
1639 return -ENODEV; 1573 return -ENODEV;
1640 } 1574 }
1641 1575
1642 val = wm8903_read(codec, WM8903_REVISION_NUMBER); 1576 val = snd_soc_read(codec, WM8903_REVISION_NUMBER);
1643 dev_info(&i2c->dev, "WM8903 revision %d\n", 1577 dev_info(&i2c->dev, "WM8903 revision %d\n",
1644 val & WM8903_CHIP_REV_MASK); 1578 val & WM8903_CHIP_REV_MASK);
1645 1579
@@ -1649,35 +1583,35 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
1649 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1583 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1650 1584
1651 /* Latch volume update bits */ 1585 /* Latch volume update bits */
1652 val = wm8903_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT); 1586 val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1653 val |= WM8903_ADCVU; 1587 val |= WM8903_ADCVU;
1654 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val); 1588 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1655 wm8903_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val); 1589 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1656 1590
1657 val = wm8903_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT); 1591 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1658 val |= WM8903_DACVU; 1592 val |= WM8903_DACVU;
1659 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val); 1593 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1660 wm8903_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val); 1594 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1661 1595
1662 val = wm8903_read(codec, WM8903_ANALOGUE_OUT1_LEFT); 1596 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1663 val |= WM8903_HPOUTVU; 1597 val |= WM8903_HPOUTVU;
1664 wm8903_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val); 1598 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1665 wm8903_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val); 1599 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1666 1600
1667 val = wm8903_read(codec, WM8903_ANALOGUE_OUT2_LEFT); 1601 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1668 val |= WM8903_LINEOUTVU; 1602 val |= WM8903_LINEOUTVU;
1669 wm8903_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val); 1603 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1670 wm8903_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val); 1604 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1671 1605
1672 val = wm8903_read(codec, WM8903_ANALOGUE_OUT3_LEFT); 1606 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1673 val |= WM8903_SPKVU; 1607 val |= WM8903_SPKVU;
1674 wm8903_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val); 1608 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1675 wm8903_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); 1609 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1676 1610
1677 /* Enable DAC soft mute by default */ 1611 /* Enable DAC soft mute by default */
1678 val = wm8903_read(codec, WM8903_DAC_DIGITAL_1); 1612 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1679 val |= WM8903_DAC_MUTEMODE; 1613 val |= WM8903_DAC_MUTEMODE;
1680 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val); 1614 snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val);
1681 1615
1682 wm8903_dai.dev = &i2c->dev; 1616 wm8903_dai.dev = &i2c->dev;
1683 wm8903_codec = codec; 1617 wm8903_codec = codec;
@@ -1721,6 +1655,21 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1721 return 0; 1655 return 0;
1722} 1656}
1723 1657
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1724/* i2c codec control layer */ 1673/* i2c codec control layer */
1725static const struct i2c_device_id wm8903_i2c_id[] = { 1674static const struct i2c_device_id wm8903_i2c_id[] = {
1726 { "wm8903", 0 }, 1675 { "wm8903", 0 },
@@ -1735,6 +1684,8 @@ static struct i2c_driver wm8903_i2c_driver = {
1735 }, 1684 },
1736 .probe = wm8903_i2c_probe, 1685 .probe = wm8903_i2c_probe,
1737 .remove = __devexit_p(wm8903_i2c_remove), 1686 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1738 .id_table = wm8903_i2c_id, 1689 .id_table = wm8903_i2c_id,
1739}; 1690};
1740 1691
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index b8e17d6bc1f7..da97aae475a2 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -106,50 +106,6 @@ static u16 wm8940_reg_defaults[] = {
106 0x0000, /* Mono Mixer Control */ 106 0x0000, /* Mono Mixer Control */
107}; 107};
108 108
109static inline unsigned int wm8940_read_reg_cache(struct snd_soc_codec *codec,
110 unsigned int reg)
111{
112 u16 *cache = codec->reg_cache;
113
114 if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
115 return -1;
116
117 return cache[reg];
118}
119
120static inline int wm8940_write_reg_cache(struct snd_soc_codec *codec,
121 u16 reg, unsigned int value)
122{
123 u16 *cache = codec->reg_cache;
124
125 if (reg >= ARRAY_SIZE(wm8940_reg_defaults))
126 return -1;
127
128 cache[reg] = value;
129
130 return 0;
131}
132
133static int wm8940_write(struct snd_soc_codec *codec, unsigned int reg,
134 unsigned int value)
135{
136 int ret;
137 u8 data[3] = { reg,
138 (value & 0xff00) >> 8,
139 (value & 0x00ff)
140 };
141
142 wm8940_write_reg_cache(codec, reg, value);
143
144 ret = codec->hw_write(codec->control_data, data, 3);
145
146 if (ret < 0)
147 return ret;
148 else if (ret != 3)
149 return -EIO;
150 return 0;
151}
152
153static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; 109static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" };
154static const struct soc_enum wm8940_adc_companding_enum 110static const struct soc_enum wm8940_adc_companding_enum
155= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding); 111= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding);
@@ -348,14 +304,14 @@ error_ret:
348 return ret; 304 return ret;
349} 305}
350 306
351#define wm8940_reset(c) wm8940_write(c, WM8940_SOFTRESET, 0); 307#define wm8940_reset(c) snd_soc_write(c, WM8940_SOFTRESET, 0);
352 308
353static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, 309static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
354 unsigned int fmt) 310 unsigned int fmt)
355{ 311{
356 struct snd_soc_codec *codec = codec_dai->codec; 312 struct snd_soc_codec *codec = codec_dai->codec;
357 u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFE67; 313 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFE67;
358 u16 clk = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0x1fe; 314 u16 clk = snd_soc_read(codec, WM8940_CLOCK) & 0x1fe;
359 315
360 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 316 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
361 case SND_SOC_DAIFMT_CBM_CFM: 317 case SND_SOC_DAIFMT_CBM_CFM:
@@ -366,7 +322,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
366 default: 322 default:
367 return -EINVAL; 323 return -EINVAL;
368 } 324 }
369 wm8940_write(codec, WM8940_CLOCK, clk); 325 snd_soc_write(codec, WM8940_CLOCK, clk);
370 326
371 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 327 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
372 case SND_SOC_DAIFMT_I2S: 328 case SND_SOC_DAIFMT_I2S:
@@ -399,7 +355,7 @@ static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai,
399 break; 355 break;
400 } 356 }
401 357
402 wm8940_write(codec, WM8940_IFACE, iface); 358 snd_soc_write(codec, WM8940_IFACE, iface);
403 359
404 return 0; 360 return 0;
405} 361}
@@ -411,9 +367,9 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
411 struct snd_soc_pcm_runtime *rtd = substream->private_data; 367 struct snd_soc_pcm_runtime *rtd = substream->private_data;
412 struct snd_soc_device *socdev = rtd->socdev; 368 struct snd_soc_device *socdev = rtd->socdev;
413 struct snd_soc_codec *codec = socdev->card->codec; 369 struct snd_soc_codec *codec = socdev->card->codec;
414 u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFD9F; 370 u16 iface = snd_soc_read(codec, WM8940_IFACE) & 0xFD9F;
415 u16 addcntrl = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFF1; 371 u16 addcntrl = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFF1;
416 u16 companding = wm8940_read_reg_cache(codec, 372 u16 companding = snd_soc_read(codec,
417 WM8940_COMPANDINGCTL) & 0xFFDF; 373 WM8940_COMPANDINGCTL) & 0xFFDF;
418 int ret; 374 int ret;
419 375
@@ -442,7 +398,7 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
442 case SNDRV_PCM_RATE_48000: 398 case SNDRV_PCM_RATE_48000:
443 break; 399 break;
444 } 400 }
445 ret = wm8940_write(codec, WM8940_ADDCNTRL, addcntrl); 401 ret = snd_soc_write(codec, WM8940_ADDCNTRL, addcntrl);
446 if (ret) 402 if (ret)
447 goto error_ret; 403 goto error_ret;
448 404
@@ -462,10 +418,10 @@ static int wm8940_i2s_hw_params(struct snd_pcm_substream *substream,
462 iface |= (3 << 5); 418 iface |= (3 << 5);
463 break; 419 break;
464 } 420 }
465 ret = wm8940_write(codec, WM8940_COMPANDINGCTL, companding); 421 ret = snd_soc_write(codec, WM8940_COMPANDINGCTL, companding);
466 if (ret) 422 if (ret)
467 goto error_ret; 423 goto error_ret;
468 ret = wm8940_write(codec, WM8940_IFACE, iface); 424 ret = snd_soc_write(codec, WM8940_IFACE, iface);
469 425
470error_ret: 426error_ret:
471 return ret; 427 return ret;
@@ -474,19 +430,19 @@ error_ret:
474static int wm8940_mute(struct snd_soc_dai *dai, int mute) 430static int wm8940_mute(struct snd_soc_dai *dai, int mute)
475{ 431{
476 struct snd_soc_codec *codec = dai->codec; 432 struct snd_soc_codec *codec = dai->codec;
477 u16 mute_reg = wm8940_read_reg_cache(codec, WM8940_DAC) & 0xffbf; 433 u16 mute_reg = snd_soc_read(codec, WM8940_DAC) & 0xffbf;
478 434
479 if (mute) 435 if (mute)
480 mute_reg |= 0x40; 436 mute_reg |= 0x40;
481 437
482 return wm8940_write(codec, WM8940_DAC, mute_reg); 438 return snd_soc_write(codec, WM8940_DAC, mute_reg);
483} 439}
484 440
485static int wm8940_set_bias_level(struct snd_soc_codec *codec, 441static int wm8940_set_bias_level(struct snd_soc_codec *codec,
486 enum snd_soc_bias_level level) 442 enum snd_soc_bias_level level)
487{ 443{
488 u16 val; 444 u16 val;
489 u16 pwr_reg = wm8940_read_reg_cache(codec, WM8940_POWER1) & 0x1F0; 445 u16 pwr_reg = snd_soc_read(codec, WM8940_POWER1) & 0x1F0;
490 int ret = 0; 446 int ret = 0;
491 447
492 switch (level) { 448 switch (level) {
@@ -494,26 +450,26 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec,
494 /* ensure bufioen and biasen */ 450 /* ensure bufioen and biasen */
495 pwr_reg |= (1 << 2) | (1 << 3); 451 pwr_reg |= (1 << 2) | (1 << 3);
496 /* Enable thermal shutdown */ 452 /* Enable thermal shutdown */
497 val = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); 453 val = snd_soc_read(codec, WM8940_OUTPUTCTL);
498 ret = wm8940_write(codec, WM8940_OUTPUTCTL, val | 0x2); 454 ret = snd_soc_write(codec, WM8940_OUTPUTCTL, val | 0x2);
499 if (ret) 455 if (ret)
500 break; 456 break;
501 /* set vmid to 75k */ 457 /* set vmid to 75k */
502 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); 458 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
503 break; 459 break;
504 case SND_SOC_BIAS_PREPARE: 460 case SND_SOC_BIAS_PREPARE:
505 /* ensure bufioen and biasen */ 461 /* ensure bufioen and biasen */
506 pwr_reg |= (1 << 2) | (1 << 3); 462 pwr_reg |= (1 << 2) | (1 << 3);
507 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); 463 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1);
508 break; 464 break;
509 case SND_SOC_BIAS_STANDBY: 465 case SND_SOC_BIAS_STANDBY:
510 /* ensure bufioen and biasen */ 466 /* ensure bufioen and biasen */
511 pwr_reg |= (1 << 2) | (1 << 3); 467 pwr_reg |= (1 << 2) | (1 << 3);
512 /* set vmid to 300k for standby */ 468 /* set vmid to 300k for standby */
513 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x2); 469 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x2);
514 break; 470 break;
515 case SND_SOC_BIAS_OFF: 471 case SND_SOC_BIAS_OFF:
516 ret = wm8940_write(codec, WM8940_POWER1, pwr_reg); 472 ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg);
517 break; 473 break;
518 } 474 }
519 475
@@ -587,36 +543,36 @@ static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai,
587 u16 reg; 543 u16 reg;
588 544
589 /* Turn off PLL */ 545 /* Turn off PLL */
590 reg = wm8940_read_reg_cache(codec, WM8940_POWER1); 546 reg = snd_soc_read(codec, WM8940_POWER1);
591 wm8940_write(codec, WM8940_POWER1, reg & 0x1df); 547 snd_soc_write(codec, WM8940_POWER1, reg & 0x1df);
592 548
593 if (freq_in == 0 || freq_out == 0) { 549 if (freq_in == 0 || freq_out == 0) {
594 /* Clock CODEC directly from MCLK */ 550 /* Clock CODEC directly from MCLK */
595 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); 551 reg = snd_soc_read(codec, WM8940_CLOCK);
596 wm8940_write(codec, WM8940_CLOCK, reg & 0x0ff); 552 snd_soc_write(codec, WM8940_CLOCK, reg & 0x0ff);
597 /* Pll power down */ 553 /* Pll power down */
598 wm8940_write(codec, WM8940_PLLN, (1 << 7)); 554 snd_soc_write(codec, WM8940_PLLN, (1 << 7));
599 return 0; 555 return 0;
600 } 556 }
601 557
602 /* Pll is followed by a frequency divide by 4 */ 558 /* Pll is followed by a frequency divide by 4 */
603 pll_factors(freq_out*4, freq_in); 559 pll_factors(freq_out*4, freq_in);
604 if (pll_div.k) 560 if (pll_div.k)
605 wm8940_write(codec, WM8940_PLLN, 561 snd_soc_write(codec, WM8940_PLLN,
606 (pll_div.pre_scale << 4) | pll_div.n | (1 << 6)); 562 (pll_div.pre_scale << 4) | pll_div.n | (1 << 6));
607 else /* No factional component */ 563 else /* No factional component */
608 wm8940_write(codec, WM8940_PLLN, 564 snd_soc_write(codec, WM8940_PLLN,
609 (pll_div.pre_scale << 4) | pll_div.n); 565 (pll_div.pre_scale << 4) | pll_div.n);
610 wm8940_write(codec, WM8940_PLLK1, pll_div.k >> 18); 566 snd_soc_write(codec, WM8940_PLLK1, pll_div.k >> 18);
611 wm8940_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff); 567 snd_soc_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff);
612 wm8940_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff); 568 snd_soc_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff);
613 /* Enable the PLL */ 569 /* Enable the PLL */
614 reg = wm8940_read_reg_cache(codec, WM8940_POWER1); 570 reg = snd_soc_read(codec, WM8940_POWER1);
615 wm8940_write(codec, WM8940_POWER1, reg | 0x020); 571 snd_soc_write(codec, WM8940_POWER1, reg | 0x020);
616 572
617 /* Run CODEC from PLL instead of MCLK */ 573 /* Run CODEC from PLL instead of MCLK */
618 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); 574 reg = snd_soc_read(codec, WM8940_CLOCK);
619 wm8940_write(codec, WM8940_CLOCK, reg | 0x100); 575 snd_soc_write(codec, WM8940_CLOCK, reg | 0x100);
620 576
621 return 0; 577 return 0;
622} 578}
@@ -648,16 +604,16 @@ static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
648 604
649 switch (div_id) { 605 switch (div_id) {
650 case WM8940_BCLKDIV: 606 case WM8940_BCLKDIV:
651 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFFEF3; 607 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFFEF3;
652 ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 2)); 608 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 2));
653 break; 609 break;
654 case WM8940_MCLKDIV: 610 case WM8940_MCLKDIV:
655 reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFF1F; 611 reg = snd_soc_read(codec, WM8940_CLOCK) & 0xFF1F;
656 ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 5)); 612 ret = snd_soc_write(codec, WM8940_CLOCK, reg | (div << 5));
657 break; 613 break;
658 case WM8940_OPCLKDIV: 614 case WM8940_OPCLKDIV:
659 reg = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFCF; 615 reg = snd_soc_read(codec, WM8940_ADDCNTRL) & 0xFFCF;
660 ret = wm8940_write(codec, WM8940_ADDCNTRL, reg | (div << 4)); 616 ret = snd_soc_write(codec, WM8940_ADDCNTRL, reg | (div << 4));
661 break; 617 break;
662 } 618 }
663 return ret; 619 return ret;
@@ -808,7 +764,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8940 = {
808}; 764};
809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940); 765EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940);
810 766
811static int wm8940_register(struct wm8940_priv *wm8940) 767static int wm8940_register(struct wm8940_priv *wm8940,
768 enum snd_soc_control_type control)
812{ 769{
813 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; 770 struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data;
814 struct snd_soc_codec *codec = &wm8940->codec; 771 struct snd_soc_codec *codec = &wm8940->codec;
@@ -825,8 +782,6 @@ static int wm8940_register(struct wm8940_priv *wm8940)
825 codec->private_data = wm8940; 782 codec->private_data = wm8940;
826 codec->name = "WM8940"; 783 codec->name = "WM8940";
827 codec->owner = THIS_MODULE; 784 codec->owner = THIS_MODULE;
828 codec->read = wm8940_read_reg_cache;
829 codec->write = wm8940_write;
830 codec->bias_level = SND_SOC_BIAS_OFF; 785 codec->bias_level = SND_SOC_BIAS_OFF;
831 codec->set_bias_level = wm8940_set_bias_level; 786 codec->set_bias_level = wm8940_set_bias_level;
832 codec->dai = &wm8940_dai; 787 codec->dai = &wm8940_dai;
@@ -834,6 +789,12 @@ static int wm8940_register(struct wm8940_priv *wm8940)
834 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults); 789 codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults);
835 codec->reg_cache = &wm8940->reg_cache; 790 codec->reg_cache = &wm8940->reg_cache;
836 791
792 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
793 if (ret == 0) {
794 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
795 return ret;
796 }
797
837 memcpy(codec->reg_cache, wm8940_reg_defaults, 798 memcpy(codec->reg_cache, wm8940_reg_defaults,
838 sizeof(wm8940_reg_defaults)); 799 sizeof(wm8940_reg_defaults));
839 800
@@ -847,15 +808,15 @@ static int wm8940_register(struct wm8940_priv *wm8940)
847 808
848 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 809 wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
849 810
850 ret = wm8940_write(codec, WM8940_POWER1, 0x180); 811 ret = snd_soc_write(codec, WM8940_POWER1, 0x180);
851 if (ret < 0) 812 if (ret < 0)
852 return ret; 813 return ret;
853 814
854 if (!pdata) 815 if (!pdata)
855 dev_warn(codec->dev, "No platform data supplied\n"); 816 dev_warn(codec->dev, "No platform data supplied\n");
856 else { 817 else {
857 reg = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); 818 reg = snd_soc_read(codec, WM8940_OUTPUTCTL);
858 ret = wm8940_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi); 819 ret = snd_soc_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi);
859 if (ret < 0) 820 if (ret < 0)
860 return ret; 821 return ret;
861 } 822 }
@@ -904,7 +865,7 @@ static int wm8940_i2c_probe(struct i2c_client *i2c,
904 codec->control_data = i2c; 865 codec->control_data = i2c;
905 codec->dev = &i2c->dev; 866 codec->dev = &i2c->dev;
906 867
907 return wm8940_register(wm8940); 868 return wm8940_register(wm8940, SND_SOC_I2C);
908} 869}
909 870
910static int __devexit wm8940_i2c_remove(struct i2c_client *client) 871static int __devexit wm8940_i2c_remove(struct i2c_client *client)
@@ -916,6 +877,21 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
916 return 0; 877 return 0;
917} 878}
918 879
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
919static const struct i2c_device_id wm8940_i2c_id[] = { 895static const struct i2c_device_id wm8940_i2c_id[] = {
920 { "wm8940", 0 }, 896 { "wm8940", 0 },
921 { } 897 { }
@@ -929,6 +905,8 @@ static struct i2c_driver wm8940_i2c_driver = {
929 }, 905 },
930 .probe = wm8940_i2c_probe, 906 .probe = wm8940_i2c_probe,
931 .remove = __devexit_p(wm8940_i2c_remove), 907 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
932 .id_table = wm8940_i2c_id, 910 .id_table = wm8940_i2c_id,
933}; 911};
934 912
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index e224d8add170..f59703be61c8 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -69,61 +69,7 @@ struct wm8960_priv {
69 struct snd_soc_codec codec; 69 struct snd_soc_codec codec;
70}; 70};
71 71
72/* 72#define wm8960_reset(c) snd_soc_write(c, WM8960_RESET, 0)
73 * read wm8960 register cache
74 */
75static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec,
76 unsigned int reg)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg == WM8960_RESET)
80 return 0;
81 if (reg >= WM8960_CACHEREGNUM)
82 return -1;
83 return cache[reg];
84}
85
86/*
87 * write wm8960 register cache
88 */
89static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec,
90 u16 reg, unsigned int value)
91{
92 u16 *cache = codec->reg_cache;
93 if (reg >= WM8960_CACHEREGNUM)
94 return;
95 cache[reg] = value;
96}
97
98static inline unsigned int wm8960_read(struct snd_soc_codec *codec,
99 unsigned int reg)
100{
101 return wm8960_read_reg_cache(codec, reg);
102}
103
104/*
105 * write to the WM8960 register space
106 */
107static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg,
108 unsigned int value)
109{
110 u8 data[2];
111
112 /* data is
113 * D15..D9 WM8960 register offset
114 * D8...D0 register data
115 */
116 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
117 data[1] = value & 0x00ff;
118
119 wm8960_write_reg_cache(codec, reg, value);
120 if (codec->hw_write(codec->control_data, data, 2) == 2)
121 return 0;
122 else
123 return -EIO;
124}
125
126#define wm8960_reset(c) wm8960_write(c, WM8960_RESET, 0)
127 73
128/* enumerated controls */ 74/* enumerated controls */
129static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 75static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
@@ -420,7 +366,7 @@ static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai,
420 } 366 }
421 367
422 /* set iface */ 368 /* set iface */
423 wm8960_write(codec, WM8960_IFACE1, iface); 369 snd_soc_write(codec, WM8960_IFACE1, iface);
424 return 0; 370 return 0;
425} 371}
426 372
@@ -431,7 +377,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
431 struct snd_soc_pcm_runtime *rtd = substream->private_data; 377 struct snd_soc_pcm_runtime *rtd = substream->private_data;
432 struct snd_soc_device *socdev = rtd->socdev; 378 struct snd_soc_device *socdev = rtd->socdev;
433 struct snd_soc_codec *codec = socdev->card->codec; 379 struct snd_soc_codec *codec = socdev->card->codec;
434 u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3; 380 u16 iface = snd_soc_read(codec, WM8960_IFACE1) & 0xfff3;
435 381
436 /* bit size */ 382 /* bit size */
437 switch (params_format(params)) { 383 switch (params_format(params)) {
@@ -446,19 +392,19 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
446 } 392 }
447 393
448 /* set iface */ 394 /* set iface */
449 wm8960_write(codec, WM8960_IFACE1, iface); 395 snd_soc_write(codec, WM8960_IFACE1, iface);
450 return 0; 396 return 0;
451} 397}
452 398
453static int wm8960_mute(struct snd_soc_dai *dai, int mute) 399static int wm8960_mute(struct snd_soc_dai *dai, int mute)
454{ 400{
455 struct snd_soc_codec *codec = dai->codec; 401 struct snd_soc_codec *codec = dai->codec;
456 u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7; 402 u16 mute_reg = snd_soc_read(codec, WM8960_DACCTL1) & 0xfff7;
457 403
458 if (mute) 404 if (mute)
459 wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8); 405 snd_soc_write(codec, WM8960_DACCTL1, mute_reg | 0x8);
460 else 406 else
461 wm8960_write(codec, WM8960_DACCTL1, mute_reg); 407 snd_soc_write(codec, WM8960_DACCTL1, mute_reg);
462 return 0; 408 return 0;
463} 409}
464 410
@@ -474,16 +420,16 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
474 420
475 case SND_SOC_BIAS_PREPARE: 421 case SND_SOC_BIAS_PREPARE:
476 /* Set VMID to 2x50k */ 422 /* Set VMID to 2x50k */
477 reg = wm8960_read(codec, WM8960_POWER1); 423 reg = snd_soc_read(codec, WM8960_POWER1);
478 reg &= ~0x180; 424 reg &= ~0x180;
479 reg |= 0x80; 425 reg |= 0x80;
480 wm8960_write(codec, WM8960_POWER1, reg); 426 snd_soc_write(codec, WM8960_POWER1, reg);
481 break; 427 break;
482 428
483 case SND_SOC_BIAS_STANDBY: 429 case SND_SOC_BIAS_STANDBY:
484 if (codec->bias_level == SND_SOC_BIAS_OFF) { 430 if (codec->bias_level == SND_SOC_BIAS_OFF) {
485 /* Enable anti-pop features */ 431 /* Enable anti-pop features */
486 wm8960_write(codec, WM8960_APOP1, 432 snd_soc_write(codec, WM8960_APOP1,
487 WM8960_POBCTRL | WM8960_SOFT_ST | 433 WM8960_POBCTRL | WM8960_SOFT_ST |
488 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 434 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
489 435
@@ -491,43 +437,43 @@ static int wm8960_set_bias_level(struct snd_soc_codec *codec,
491 reg = WM8960_DISOP; 437 reg = WM8960_DISOP;
492 if (pdata) 438 if (pdata)
493 reg |= pdata->dres << 4; 439 reg |= pdata->dres << 4;
494 wm8960_write(codec, WM8960_APOP2, reg); 440 snd_soc_write(codec, WM8960_APOP2, reg);
495 441
496 msleep(400); 442 msleep(400);
497 443
498 wm8960_write(codec, WM8960_APOP2, 0); 444 snd_soc_write(codec, WM8960_APOP2, 0);
499 445
500 /* Enable & ramp VMID at 2x50k */ 446 /* Enable & ramp VMID at 2x50k */
501 reg = wm8960_read(codec, WM8960_POWER1); 447 reg = snd_soc_read(codec, WM8960_POWER1);
502 reg |= 0x80; 448 reg |= 0x80;
503 wm8960_write(codec, WM8960_POWER1, reg); 449 snd_soc_write(codec, WM8960_POWER1, reg);
504 msleep(100); 450 msleep(100);
505 451
506 /* Enable VREF */ 452 /* Enable VREF */
507 wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF); 453 snd_soc_write(codec, WM8960_POWER1, reg | WM8960_VREF);
508 454
509 /* Disable anti-pop features */ 455 /* Disable anti-pop features */
510 wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN); 456 snd_soc_write(codec, WM8960_APOP1, WM8960_BUFIOEN);
511 } 457 }
512 458
513 /* Set VMID to 2x250k */ 459 /* Set VMID to 2x250k */
514 reg = wm8960_read(codec, WM8960_POWER1); 460 reg = snd_soc_read(codec, WM8960_POWER1);
515 reg &= ~0x180; 461 reg &= ~0x180;
516 reg |= 0x100; 462 reg |= 0x100;
517 wm8960_write(codec, WM8960_POWER1, reg); 463 snd_soc_write(codec, WM8960_POWER1, reg);
518 break; 464 break;
519 465
520 case SND_SOC_BIAS_OFF: 466 case SND_SOC_BIAS_OFF:
521 /* Enable anti-pop features */ 467 /* Enable anti-pop features */
522 wm8960_write(codec, WM8960_APOP1, 468 snd_soc_write(codec, WM8960_APOP1,
523 WM8960_POBCTRL | WM8960_SOFT_ST | 469 WM8960_POBCTRL | WM8960_SOFT_ST |
524 WM8960_BUFDCOPEN | WM8960_BUFIOEN); 470 WM8960_BUFDCOPEN | WM8960_BUFIOEN);
525 471
526 /* Disable VMID and VREF, let them discharge */ 472 /* Disable VMID and VREF, let them discharge */
527 wm8960_write(codec, WM8960_POWER1, 0); 473 snd_soc_write(codec, WM8960_POWER1, 0);
528 msleep(600); 474 msleep(600);
529 475
530 wm8960_write(codec, WM8960_APOP1, 0); 476 snd_soc_write(codec, WM8960_APOP1, 0);
531 break; 477 break;
532 } 478 }
533 479
@@ -610,33 +556,33 @@ static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai,
610 556
611 /* Disable the PLL: even if we are changing the frequency the 557 /* Disable the PLL: even if we are changing the frequency the
612 * PLL needs to be disabled while we do so. */ 558 * PLL needs to be disabled while we do so. */
613 wm8960_write(codec, WM8960_CLOCK1, 559 snd_soc_write(codec, WM8960_CLOCK1,
614 wm8960_read(codec, WM8960_CLOCK1) & ~1); 560 snd_soc_read(codec, WM8960_CLOCK1) & ~1);
615 wm8960_write(codec, WM8960_POWER2, 561 snd_soc_write(codec, WM8960_POWER2,
616 wm8960_read(codec, WM8960_POWER2) & ~1); 562 snd_soc_read(codec, WM8960_POWER2) & ~1);
617 563
618 if (!freq_in || !freq_out) 564 if (!freq_in || !freq_out)
619 return 0; 565 return 0;
620 566
621 reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f; 567 reg = snd_soc_read(codec, WM8960_PLL1) & ~0x3f;
622 reg |= pll_div.pre_div << 4; 568 reg |= pll_div.pre_div << 4;
623 reg |= pll_div.n; 569 reg |= pll_div.n;
624 570
625 if (pll_div.k) { 571 if (pll_div.k) {
626 reg |= 0x20; 572 reg |= 0x20;
627 573
628 wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); 574 snd_soc_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f);
629 wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); 575 snd_soc_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff);
630 wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); 576 snd_soc_write(codec, WM8960_PLL4, pll_div.k & 0x1ff);
631 } 577 }
632 wm8960_write(codec, WM8960_PLL1, reg); 578 snd_soc_write(codec, WM8960_PLL1, reg);
633 579
634 /* Turn it on */ 580 /* Turn it on */
635 wm8960_write(codec, WM8960_POWER2, 581 snd_soc_write(codec, WM8960_POWER2,
636 wm8960_read(codec, WM8960_POWER2) | 1); 582 snd_soc_read(codec, WM8960_POWER2) | 1);
637 msleep(250); 583 msleep(250);
638 wm8960_write(codec, WM8960_CLOCK1, 584 snd_soc_write(codec, WM8960_CLOCK1,
639 wm8960_read(codec, WM8960_CLOCK1) | 1); 585 snd_soc_read(codec, WM8960_CLOCK1) | 1);
640 586
641 return 0; 587 return 0;
642} 588}
@@ -649,28 +595,28 @@ static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
649 595
650 switch (div_id) { 596 switch (div_id) {
651 case WM8960_SYSCLKSEL: 597 case WM8960_SYSCLKSEL:
652 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe; 598 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1fe;
653 wm8960_write(codec, WM8960_CLOCK1, reg | div); 599 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
654 break; 600 break;
655 case WM8960_SYSCLKDIV: 601 case WM8960_SYSCLKDIV:
656 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9; 602 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1f9;
657 wm8960_write(codec, WM8960_CLOCK1, reg | div); 603 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
658 break; 604 break;
659 case WM8960_DACDIV: 605 case WM8960_DACDIV:
660 reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7; 606 reg = snd_soc_read(codec, WM8960_CLOCK1) & 0x1c7;
661 wm8960_write(codec, WM8960_CLOCK1, reg | div); 607 snd_soc_write(codec, WM8960_CLOCK1, reg | div);
662 break; 608 break;
663 case WM8960_OPCLKDIV: 609 case WM8960_OPCLKDIV:
664 reg = wm8960_read(codec, WM8960_PLL1) & 0x03f; 610 reg = snd_soc_read(codec, WM8960_PLL1) & 0x03f;
665 wm8960_write(codec, WM8960_PLL1, reg | div); 611 snd_soc_write(codec, WM8960_PLL1, reg | div);
666 break; 612 break;
667 case WM8960_DCLKDIV: 613 case WM8960_DCLKDIV:
668 reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f; 614 reg = snd_soc_read(codec, WM8960_CLOCK2) & 0x03f;
669 wm8960_write(codec, WM8960_CLOCK2, reg | div); 615 snd_soc_write(codec, WM8960_CLOCK2, reg | div);
670 break; 616 break;
671 case WM8960_TOCLKSEL: 617 case WM8960_TOCLKSEL:
672 reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd; 618 reg = snd_soc_read(codec, WM8960_ADDCTL1) & 0x1fd;
673 wm8960_write(codec, WM8960_ADDCTL1, reg | div); 619 snd_soc_write(codec, WM8960_ADDCTL1, reg | div);
674 break; 620 break;
675 default: 621 default:
676 return -EINVAL; 622 return -EINVAL;
@@ -801,7 +747,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8960 = {
801}; 747};
802EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960); 748EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960);
803 749
804static int wm8960_register(struct wm8960_priv *wm8960) 750static int wm8960_register(struct wm8960_priv *wm8960,
751 enum snd_soc_control_type control)
805{ 752{
806 struct wm8960_data *pdata = wm8960->codec.dev->platform_data; 753 struct wm8960_data *pdata = wm8960->codec.dev->platform_data;
807 struct snd_soc_codec *codec = &wm8960->codec; 754 struct snd_soc_codec *codec = &wm8960->codec;
@@ -810,7 +757,8 @@ static int wm8960_register(struct wm8960_priv *wm8960)
810 757
811 if (wm8960_codec) { 758 if (wm8960_codec) {
812 dev_err(codec->dev, "Another WM8960 is registered\n"); 759 dev_err(codec->dev, "Another WM8960 is registered\n");
813 return -EINVAL; 760 ret = -EINVAL;
761 goto err;
814 } 762 }
815 763
816 if (!pdata) { 764 if (!pdata) {
@@ -829,8 +777,6 @@ static int wm8960_register(struct wm8960_priv *wm8960)
829 codec->private_data = wm8960; 777 codec->private_data = wm8960;
830 codec->name = "WM8960"; 778 codec->name = "WM8960";
831 codec->owner = THIS_MODULE; 779 codec->owner = THIS_MODULE;
832 codec->read = wm8960_read_reg_cache;
833 codec->write = wm8960_write;
834 codec->bias_level = SND_SOC_BIAS_OFF; 780 codec->bias_level = SND_SOC_BIAS_OFF;
835 codec->set_bias_level = wm8960_set_bias_level; 781 codec->set_bias_level = wm8960_set_bias_level;
836 codec->dai = &wm8960_dai; 782 codec->dai = &wm8960_dai;
@@ -840,10 +786,16 @@ static int wm8960_register(struct wm8960_priv *wm8960)
840 786
841 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg)); 787 memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg));
842 788
789 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
790 if (ret < 0) {
791 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
792 goto err;
793 }
794
843 ret = wm8960_reset(codec); 795 ret = wm8960_reset(codec);
844 if (ret < 0) { 796 if (ret < 0) {
845 dev_err(codec->dev, "Failed to issue reset\n"); 797 dev_err(codec->dev, "Failed to issue reset\n");
846 return ret; 798 goto err;
847 } 799 }
848 800
849 wm8960_dai.dev = codec->dev; 801 wm8960_dai.dev = codec->dev;
@@ -851,43 +803,48 @@ static int wm8960_register(struct wm8960_priv *wm8960)
851 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 803 wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
852 804
853 /* Latch the update bits */ 805 /* Latch the update bits */
854 reg = wm8960_read(codec, WM8960_LINVOL); 806 reg = snd_soc_read(codec, WM8960_LINVOL);
855 wm8960_write(codec, WM8960_LINVOL, reg | 0x100); 807 snd_soc_write(codec, WM8960_LINVOL, reg | 0x100);
856 reg = wm8960_read(codec, WM8960_RINVOL); 808 reg = snd_soc_read(codec, WM8960_RINVOL);
857 wm8960_write(codec, WM8960_RINVOL, reg | 0x100); 809 snd_soc_write(codec, WM8960_RINVOL, reg | 0x100);
858 reg = wm8960_read(codec, WM8960_LADC); 810 reg = snd_soc_read(codec, WM8960_LADC);
859 wm8960_write(codec, WM8960_LADC, reg | 0x100); 811 snd_soc_write(codec, WM8960_LADC, reg | 0x100);
860 reg = wm8960_read(codec, WM8960_RADC); 812 reg = snd_soc_read(codec, WM8960_RADC);
861 wm8960_write(codec, WM8960_RADC, reg | 0x100); 813 snd_soc_write(codec, WM8960_RADC, reg | 0x100);
862 reg = wm8960_read(codec, WM8960_LDAC); 814 reg = snd_soc_read(codec, WM8960_LDAC);
863 wm8960_write(codec, WM8960_LDAC, reg | 0x100); 815 snd_soc_write(codec, WM8960_LDAC, reg | 0x100);
864 reg = wm8960_read(codec, WM8960_RDAC); 816 reg = snd_soc_read(codec, WM8960_RDAC);
865 wm8960_write(codec, WM8960_RDAC, reg | 0x100); 817 snd_soc_write(codec, WM8960_RDAC, reg | 0x100);
866 reg = wm8960_read(codec, WM8960_LOUT1); 818 reg = snd_soc_read(codec, WM8960_LOUT1);
867 wm8960_write(codec, WM8960_LOUT1, reg | 0x100); 819 snd_soc_write(codec, WM8960_LOUT1, reg | 0x100);
868 reg = wm8960_read(codec, WM8960_ROUT1); 820 reg = snd_soc_read(codec, WM8960_ROUT1);
869 wm8960_write(codec, WM8960_ROUT1, reg | 0x100); 821 snd_soc_write(codec, WM8960_ROUT1, reg | 0x100);
870 reg = wm8960_read(codec, WM8960_LOUT2); 822 reg = snd_soc_read(codec, WM8960_LOUT2);
871 wm8960_write(codec, WM8960_LOUT2, reg | 0x100); 823 snd_soc_write(codec, WM8960_LOUT2, reg | 0x100);
872 reg = wm8960_read(codec, WM8960_ROUT2); 824 reg = snd_soc_read(codec, WM8960_ROUT2);
873 wm8960_write(codec, WM8960_ROUT2, reg | 0x100); 825 snd_soc_write(codec, WM8960_ROUT2, reg | 0x100);
874 826
875 wm8960_codec = codec; 827 wm8960_codec = codec;
876 828
877 ret = snd_soc_register_codec(codec); 829 ret = snd_soc_register_codec(codec);
878 if (ret != 0) { 830 if (ret != 0) {
879 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 831 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
880 return ret; 832 goto err;
881 } 833 }
882 834
883 ret = snd_soc_register_dai(&wm8960_dai); 835 ret = snd_soc_register_dai(&wm8960_dai);
884 if (ret != 0) { 836 if (ret != 0) {
885 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 837 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
886 snd_soc_unregister_codec(codec); 838 goto err_codec;
887 return ret;
888 } 839 }
889 840
890 return 0; 841 return 0;
842
843err_codec:
844 snd_soc_unregister_codec(codec);
845err:
846 kfree(wm8960);
847 return ret;
891} 848}
892 849
893static void wm8960_unregister(struct wm8960_priv *wm8960) 850static void wm8960_unregister(struct wm8960_priv *wm8960)
@@ -910,14 +867,13 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c,
910 return -ENOMEM; 867 return -ENOMEM;
911 868
912 codec = &wm8960->codec; 869 codec = &wm8960->codec;
913 codec->hw_write = (hw_write_t)i2c_master_send;
914 870
915 i2c_set_clientdata(i2c, wm8960); 871 i2c_set_clientdata(i2c, wm8960);
916 codec->control_data = i2c; 872 codec->control_data = i2c;
917 873
918 codec->dev = &i2c->dev; 874 codec->dev = &i2c->dev;
919 875
920 return wm8960_register(wm8960); 876 return wm8960_register(wm8960, SND_SOC_I2C);
921} 877}
922 878
923static __devexit int wm8960_i2c_remove(struct i2c_client *client) 879static __devexit int wm8960_i2c_remove(struct i2c_client *client)
@@ -927,6 +883,21 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
927 return 0; 883 return 0;
928} 884}
929 885
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
930static const struct i2c_device_id wm8960_i2c_id[] = { 901static const struct i2c_device_id wm8960_i2c_id[] = {
931 { "wm8960", 0 }, 902 { "wm8960", 0 },
932 { } 903 { }
@@ -940,6 +911,8 @@ static struct i2c_driver wm8960_i2c_driver = {
940 }, 911 },
941 .probe = wm8960_i2c_probe, 912 .probe = wm8960_i2c_probe,
942 .remove = __devexit_p(wm8960_i2c_remove), 913 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
943 .id_table = wm8960_i2c_id, 916 .id_table = wm8960_i2c_id,
944}; 917};
945 918
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
new file mode 100644
index 000000000000..503032085899
--- /dev/null
+++ b/sound/soc/codecs/wm8961.c
@@ -0,0 +1,1265 @@
1/*
2 * wm8961.c -- WM8961 ALSA SoC Audio driver
3 *
4 * Author: Mark Brown
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 * Currently unimplemented features:
11 * - ALC
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8961.h"
30
31#define WM8961_MAX_REGISTER 0xFC
32
33static u16 wm8961_reg_defaults[] = {
34 0x009F, /* R0 - Left Input volume */
35 0x009F, /* R1 - Right Input volume */
36 0x0000, /* R2 - LOUT1 volume */
37 0x0000, /* R3 - ROUT1 volume */
38 0x0020, /* R4 - Clocking1 */
39 0x0008, /* R5 - ADC & DAC Control 1 */
40 0x0000, /* R6 - ADC & DAC Control 2 */
41 0x000A, /* R7 - Audio Interface 0 */
42 0x01F4, /* R8 - Clocking2 */
43 0x0000, /* R9 - Audio Interface 1 */
44 0x00FF, /* R10 - Left DAC volume */
45 0x00FF, /* R11 - Right DAC volume */
46 0x0000, /* R12 */
47 0x0000, /* R13 */
48 0x0040, /* R14 - Audio Interface 2 */
49 0x0000, /* R15 - Software Reset */
50 0x0000, /* R16 */
51 0x007B, /* R17 - ALC1 */
52 0x0000, /* R18 - ALC2 */
53 0x0032, /* R19 - ALC3 */
54 0x0000, /* R20 - Noise Gate */
55 0x00C0, /* R21 - Left ADC volume */
56 0x00C0, /* R22 - Right ADC volume */
57 0x0120, /* R23 - Additional control(1) */
58 0x0000, /* R24 - Additional control(2) */
59 0x0000, /* R25 - Pwr Mgmt (1) */
60 0x0000, /* R26 - Pwr Mgmt (2) */
61 0x0000, /* R27 - Additional Control (3) */
62 0x0000, /* R28 - Anti-pop */
63 0x0000, /* R29 */
64 0x005F, /* R30 - Clocking 3 */
65 0x0000, /* R31 */
66 0x0000, /* R32 - ADCL signal path */
67 0x0000, /* R33 - ADCR signal path */
68 0x0000, /* R34 */
69 0x0000, /* R35 */
70 0x0000, /* R36 */
71 0x0000, /* R37 */
72 0x0000, /* R38 */
73 0x0000, /* R39 */
74 0x0000, /* R40 - LOUT2 volume */
75 0x0000, /* R41 - ROUT2 volume */
76 0x0000, /* R42 */
77 0x0000, /* R43 */
78 0x0000, /* R44 */
79 0x0000, /* R45 */
80 0x0000, /* R46 */
81 0x0000, /* R47 - Pwr Mgmt (3) */
82 0x0023, /* R48 - Additional Control (4) */
83 0x0000, /* R49 - Class D Control 1 */
84 0x0000, /* R50 */
85 0x0003, /* R51 - Class D Control 2 */
86 0x0000, /* R52 */
87 0x0000, /* R53 */
88 0x0000, /* R54 */
89 0x0000, /* R55 */
90 0x0106, /* R56 - Clocking 4 */
91 0x0000, /* R57 - DSP Sidetone 0 */
92 0x0000, /* R58 - DSP Sidetone 1 */
93 0x0000, /* R59 */
94 0x0000, /* R60 - DC Servo 0 */
95 0x0000, /* R61 - DC Servo 1 */
96 0x0000, /* R62 */
97 0x015E, /* R63 - DC Servo 3 */
98 0x0010, /* R64 */
99 0x0010, /* R65 - DC Servo 5 */
100 0x0000, /* R66 */
101 0x0001, /* R67 */
102 0x0003, /* R68 - Analogue PGA Bias */
103 0x0000, /* R69 - Analogue HP 0 */
104 0x0060, /* R70 */
105 0x01FB, /* R71 - Analogue HP 2 */
106 0x0000, /* R72 - Charge Pump 1 */
107 0x0065, /* R73 */
108 0x005F, /* R74 */
109 0x0059, /* R75 */
110 0x006B, /* R76 */
111 0x0038, /* R77 */
112 0x000C, /* R78 */
113 0x000A, /* R79 */
114 0x006B, /* R80 */
115 0x0000, /* R81 */
116 0x0000, /* R82 - Charge Pump B */
117 0x0087, /* R83 */
118 0x0000, /* R84 */
119 0x005C, /* R85 */
120 0x0000, /* R86 */
121 0x0000, /* R87 - Write Sequencer 1 */
122 0x0000, /* R88 - Write Sequencer 2 */
123 0x0000, /* R89 - Write Sequencer 3 */
124 0x0000, /* R90 - Write Sequencer 4 */
125 0x0000, /* R91 - Write Sequencer 5 */
126 0x0000, /* R92 - Write Sequencer 6 */
127 0x0000, /* R93 - Write Sequencer 7 */
128 0x0000, /* R94 */
129 0x0000, /* R95 */
130 0x0000, /* R96 */
131 0x0000, /* R97 */
132 0x0000, /* R98 */
133 0x0000, /* R99 */
134 0x0000, /* R100 */
135 0x0000, /* R101 */
136 0x0000, /* R102 */
137 0x0000, /* R103 */
138 0x0000, /* R104 */
139 0x0000, /* R105 */
140 0x0000, /* R106 */
141 0x0000, /* R107 */
142 0x0000, /* R108 */
143 0x0000, /* R109 */
144 0x0000, /* R110 */
145 0x0000, /* R111 */
146 0x0000, /* R112 */
147 0x0000, /* R113 */
148 0x0000, /* R114 */
149 0x0000, /* R115 */
150 0x0000, /* R116 */
151 0x0000, /* R117 */
152 0x0000, /* R118 */
153 0x0000, /* R119 */
154 0x0000, /* R120 */
155 0x0000, /* R121 */
156 0x0000, /* R122 */
157 0x0000, /* R123 */
158 0x0000, /* R124 */
159 0x0000, /* R125 */
160 0x0000, /* R126 */
161 0x0000, /* R127 */
162 0x0000, /* R128 */
163 0x0000, /* R129 */
164 0x0000, /* R130 */
165 0x0000, /* R131 */
166 0x0000, /* R132 */
167 0x0000, /* R133 */
168 0x0000, /* R134 */
169 0x0000, /* R135 */
170 0x0000, /* R136 */
171 0x0000, /* R137 */
172 0x0000, /* R138 */
173 0x0000, /* R139 */
174 0x0000, /* R140 */
175 0x0000, /* R141 */
176 0x0000, /* R142 */
177 0x0000, /* R143 */
178 0x0000, /* R144 */
179 0x0000, /* R145 */
180 0x0000, /* R146 */
181 0x0000, /* R147 */
182 0x0000, /* R148 */
183 0x0000, /* R149 */
184 0x0000, /* R150 */
185 0x0000, /* R151 */
186 0x0000, /* R152 */
187 0x0000, /* R153 */
188 0x0000, /* R154 */
189 0x0000, /* R155 */
190 0x0000, /* R156 */
191 0x0000, /* R157 */
192 0x0000, /* R158 */
193 0x0000, /* R159 */
194 0x0000, /* R160 */
195 0x0000, /* R161 */
196 0x0000, /* R162 */
197 0x0000, /* R163 */
198 0x0000, /* R164 */
199 0x0000, /* R165 */
200 0x0000, /* R166 */
201 0x0000, /* R167 */
202 0x0000, /* R168 */
203 0x0000, /* R169 */
204 0x0000, /* R170 */
205 0x0000, /* R171 */
206 0x0000, /* R172 */
207 0x0000, /* R173 */
208 0x0000, /* R174 */
209 0x0000, /* R175 */
210 0x0000, /* R176 */
211 0x0000, /* R177 */
212 0x0000, /* R178 */
213 0x0000, /* R179 */
214 0x0000, /* R180 */
215 0x0000, /* R181 */
216 0x0000, /* R182 */
217 0x0000, /* R183 */
218 0x0000, /* R184 */
219 0x0000, /* R185 */
220 0x0000, /* R186 */
221 0x0000, /* R187 */
222 0x0000, /* R188 */
223 0x0000, /* R189 */
224 0x0000, /* R190 */
225 0x0000, /* R191 */
226 0x0000, /* R192 */
227 0x0000, /* R193 */
228 0x0000, /* R194 */
229 0x0000, /* R195 */
230 0x0030, /* R196 */
231 0x0006, /* R197 */
232 0x0000, /* R198 */
233 0x0060, /* R199 */
234 0x0000, /* R200 */
235 0x003F, /* R201 */
236 0x0000, /* R202 */
237 0x0000, /* R203 */
238 0x0000, /* R204 */
239 0x0001, /* R205 */
240 0x0000, /* R206 */
241 0x0181, /* R207 */
242 0x0005, /* R208 */
243 0x0008, /* R209 */
244 0x0008, /* R210 */
245 0x0000, /* R211 */
246 0x013B, /* R212 */
247 0x0000, /* R213 */
248 0x0000, /* R214 */
249 0x0000, /* R215 */
250 0x0000, /* R216 */
251 0x0070, /* R217 */
252 0x0000, /* R218 */
253 0x0000, /* R219 */
254 0x0000, /* R220 */
255 0x0000, /* R221 */
256 0x0000, /* R222 */
257 0x0003, /* R223 */
258 0x0000, /* R224 */
259 0x0000, /* R225 */
260 0x0001, /* R226 */
261 0x0008, /* R227 */
262 0x0000, /* R228 */
263 0x0000, /* R229 */
264 0x0000, /* R230 */
265 0x0000, /* R231 */
266 0x0004, /* R232 */
267 0x0000, /* R233 */
268 0x0000, /* R234 */
269 0x0000, /* R235 */
270 0x0000, /* R236 */
271 0x0000, /* R237 */
272 0x0080, /* R238 */
273 0x0000, /* R239 */
274 0x0000, /* R240 */
275 0x0000, /* R241 */
276 0x0000, /* R242 */
277 0x0000, /* R243 */
278 0x0000, /* R244 */
279 0x0052, /* R245 */
280 0x0110, /* R246 */
281 0x0040, /* R247 */
282 0x0000, /* R248 */
283 0x0030, /* R249 */
284 0x0000, /* R250 */
285 0x0000, /* R251 */
286 0x0001, /* R252 - General test 1 */
287};
288
289struct wm8961_priv {
290 struct snd_soc_codec codec;
291 int sysclk;
292 u16 reg_cache[WM8961_MAX_REGISTER];
293};
294
295static int wm8961_volatile_register(unsigned int reg)
296{
297 switch (reg) {
298 case WM8961_SOFTWARE_RESET:
299 case WM8961_WRITE_SEQUENCER_7:
300 case WM8961_DC_SERVO_1:
301 return 1;
302
303 default:
304 return 0;
305 }
306}
307
308static int wm8961_reset(struct snd_soc_codec *codec)
309{
310 return snd_soc_write(codec, WM8961_SOFTWARE_RESET, 0);
311}
312
313/*
314 * The headphone output supports special anti-pop sequences giving
315 * silent power up and power down.
316 */
317static int wm8961_hp_event(struct snd_soc_dapm_widget *w,
318 struct snd_kcontrol *kcontrol, int event)
319{
320 struct snd_soc_codec *codec = w->codec;
321 u16 hp_reg = snd_soc_read(codec, WM8961_ANALOGUE_HP_0);
322 u16 cp_reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_1);
323 u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
324 u16 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
325 int timeout = 500;
326
327 if (event & SND_SOC_DAPM_POST_PMU) {
328 /* Make sure the output is shorted */
329 hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
330 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
331
332 /* Enable the charge pump */
333 cp_reg |= WM8961_CP_ENA;
334 snd_soc_write(codec, WM8961_CHARGE_PUMP_1, cp_reg);
335 mdelay(5);
336
337 /* Enable the PGA */
338 pwr_reg |= WM8961_LOUT1_PGA | WM8961_ROUT1_PGA;
339 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
340
341 /* Enable the amplifier */
342 hp_reg |= WM8961_HPR_ENA | WM8961_HPL_ENA;
343 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
344
345 /* Second stage enable */
346 hp_reg |= WM8961_HPR_ENA_DLY | WM8961_HPL_ENA_DLY;
347 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
348
349 /* Enable the DC servo & trigger startup */
350 dcs_reg |=
351 WM8961_DCS_ENA_CHAN_HPR | WM8961_DCS_TRIG_STARTUP_HPR |
352 WM8961_DCS_ENA_CHAN_HPL | WM8961_DCS_TRIG_STARTUP_HPL;
353 dev_dbg(codec->dev, "Enabling DC servo\n");
354
355 snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
356 do {
357 msleep(1);
358 dcs_reg = snd_soc_read(codec, WM8961_DC_SERVO_1);
359 } while (--timeout &&
360 dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
361 WM8961_DCS_TRIG_STARTUP_HPL));
362 if (dcs_reg & (WM8961_DCS_TRIG_STARTUP_HPR |
363 WM8961_DCS_TRIG_STARTUP_HPL))
364 dev_err(codec->dev, "DC servo timed out\n");
365 else
366 dev_dbg(codec->dev, "DC servo startup complete\n");
367
368 /* Enable the output stage */
369 hp_reg |= WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP;
370 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
371
372 /* Remove the short on the output stage */
373 hp_reg |= WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT;
374 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
375 }
376
377 if (event & SND_SOC_DAPM_PRE_PMD) {
378 /* Short the output */
379 hp_reg &= ~(WM8961_HPR_RMV_SHORT | WM8961_HPL_RMV_SHORT);
380 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
381
382 /* Disable the output stage */
383 hp_reg &= ~(WM8961_HPR_ENA_OUTP | WM8961_HPL_ENA_OUTP);
384 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
385
386 /* Disable DC offset cancellation */
387 dcs_reg &= ~(WM8961_DCS_ENA_CHAN_HPR |
388 WM8961_DCS_ENA_CHAN_HPL);
389 snd_soc_write(codec, WM8961_DC_SERVO_1, dcs_reg);
390
391 /* Finish up */
392 hp_reg &= ~(WM8961_HPR_ENA_DLY | WM8961_HPR_ENA |
393 WM8961_HPL_ENA_DLY | WM8961_HPL_ENA);
394 snd_soc_write(codec, WM8961_ANALOGUE_HP_0, hp_reg);
395
396 /* Disable the PGA */
397 pwr_reg &= ~(WM8961_LOUT1_PGA | WM8961_ROUT1_PGA);
398 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
399
400 /* Disable the charge pump */
401 dev_dbg(codec->dev, "Disabling charge pump\n");
402 snd_soc_write(codec, WM8961_CHARGE_PUMP_1,
403 cp_reg & ~WM8961_CP_ENA);
404 }
405
406 return 0;
407}
408
409static int wm8961_spk_event(struct snd_soc_dapm_widget *w,
410 struct snd_kcontrol *kcontrol, int event)
411{
412 struct snd_soc_codec *codec = w->codec;
413 u16 pwr_reg = snd_soc_read(codec, WM8961_PWR_MGMT_2);
414 u16 spk_reg = snd_soc_read(codec, WM8961_CLASS_D_CONTROL_1);
415
416 if (event & SND_SOC_DAPM_POST_PMU) {
417 /* Enable the PGA */
418 pwr_reg |= WM8961_SPKL_PGA | WM8961_SPKR_PGA;
419 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
420
421 /* Enable the amplifier */
422 spk_reg |= WM8961_SPKL_ENA | WM8961_SPKR_ENA;
423 snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
424 }
425
426 if (event & SND_SOC_DAPM_PRE_PMD) {
427 /* Enable the amplifier */
428 spk_reg &= ~(WM8961_SPKL_ENA | WM8961_SPKR_ENA);
429 snd_soc_write(codec, WM8961_CLASS_D_CONTROL_1, spk_reg);
430
431 /* Enable the PGA */
432 pwr_reg &= ~(WM8961_SPKL_PGA | WM8961_SPKR_PGA);
433 snd_soc_write(codec, WM8961_PWR_MGMT_2, pwr_reg);
434 }
435
436 return 0;
437}
438
439static const char *adc_hpf_text[] = {
440 "Hi-fi", "Voice 1", "Voice 2", "Voice 3",
441};
442
443static const struct soc_enum adc_hpf =
444 SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_2, 7, 4, adc_hpf_text);
445
446static const char *dac_deemph_text[] = {
447 "None", "32kHz", "44.1kHz", "48kHz",
448};
449
450static const struct soc_enum dac_deemph =
451 SOC_ENUM_SINGLE(WM8961_ADC_DAC_CONTROL_1, 1, 4, dac_deemph_text);
452
453static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
454static const DECLARE_TLV_DB_SCALE(hp_sec_tlv, -700, 100, 0);
455static const DECLARE_TLV_DB_SCALE(adc_tlv, -7200, 75, 1);
456static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
457static unsigned int boost_tlv[] = {
458 TLV_DB_RANGE_HEAD(4),
459 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
460 1, 1, TLV_DB_SCALE_ITEM(13, 0, 0),
461 2, 2, TLV_DB_SCALE_ITEM(20, 0, 0),
462 3, 3, TLV_DB_SCALE_ITEM(29, 0, 0),
463};
464static const DECLARE_TLV_DB_SCALE(pga_tlv, -2325, 75, 0);
465
466static const struct snd_kcontrol_new wm8961_snd_controls[] = {
467SOC_DOUBLE_R_TLV("Headphone Volume", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
468 0, 127, 0, out_tlv),
469SOC_DOUBLE_TLV("Headphone Secondary Volume", WM8961_ANALOGUE_HP_2,
470 6, 3, 7, 0, hp_sec_tlv),
471SOC_DOUBLE_R("Headphone ZC Switch", WM8961_LOUT1_VOLUME, WM8961_ROUT1_VOLUME,
472 7, 1, 0),
473
474SOC_DOUBLE_R_TLV("Speaker Volume", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
475 0, 127, 0, out_tlv),
476SOC_DOUBLE_R("Speaker ZC Switch", WM8961_LOUT2_VOLUME, WM8961_ROUT2_VOLUME,
477 7, 1, 0),
478SOC_SINGLE("Speaker AC Gain", WM8961_CLASS_D_CONTROL_2, 0, 7, 0),
479
480SOC_SINGLE("DAC x128 OSR Switch", WM8961_ADC_DAC_CONTROL_2, 0, 1, 0),
481SOC_ENUM("DAC Deemphasis", dac_deemph),
482SOC_SINGLE("DAC Soft Mute Switch", WM8961_ADC_DAC_CONTROL_2, 3, 1, 0),
483
484SOC_DOUBLE_R_TLV("Sidetone Volume", WM8961_DSP_SIDETONE_0,
485 WM8961_DSP_SIDETONE_1, 4, 12, 0, sidetone_tlv),
486
487SOC_SINGLE("ADC High Pass Filter Switch", WM8961_ADC_DAC_CONTROL_1, 0, 1, 0),
488SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
489
490SOC_DOUBLE_R_TLV("Capture Volume",
491 WM8961_LEFT_ADC_VOLUME, WM8961_RIGHT_ADC_VOLUME,
492 1, 119, 0, adc_tlv),
493SOC_DOUBLE_R_TLV("Capture Boost Volume",
494 WM8961_ADCL_SIGNAL_PATH, WM8961_ADCR_SIGNAL_PATH,
495 4, 3, 0, boost_tlv),
496SOC_DOUBLE_R_TLV("Capture PGA Volume",
497 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
498 0, 62, 0, pga_tlv),
499SOC_DOUBLE_R("Capture PGA ZC Switch",
500 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
501 6, 1, 1),
502SOC_DOUBLE_R("Capture PGA Switch",
503 WM8961_LEFT_INPUT_VOLUME, WM8961_RIGHT_INPUT_VOLUME,
504 7, 1, 1),
505};
506
507static const char *sidetone_text[] = {
508 "None", "Left", "Right"
509};
510
511static const struct soc_enum dacl_sidetone =
512 SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_0, 2, 3, sidetone_text);
513
514static const struct soc_enum dacr_sidetone =
515 SOC_ENUM_SINGLE(WM8961_DSP_SIDETONE_1, 2, 3, sidetone_text);
516
517static const struct snd_kcontrol_new dacl_mux =
518 SOC_DAPM_ENUM("DACL Sidetone", dacl_sidetone);
519
520static const struct snd_kcontrol_new dacr_mux =
521 SOC_DAPM_ENUM("DACR Sidetone", dacr_sidetone);
522
523static const struct snd_soc_dapm_widget wm8961_dapm_widgets[] = {
524SND_SOC_DAPM_INPUT("LINPUT"),
525SND_SOC_DAPM_INPUT("RINPUT"),
526
527SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8961_CLOCKING2, 4, 0, NULL, 0),
528
529SND_SOC_DAPM_PGA("Left Input", WM8961_PWR_MGMT_1, 5, 0, NULL, 0),
530SND_SOC_DAPM_PGA("Right Input", WM8961_PWR_MGMT_1, 4, 0, NULL, 0),
531
532SND_SOC_DAPM_ADC("ADCL", "HiFi Capture", WM8961_PWR_MGMT_1, 3, 0),
533SND_SOC_DAPM_ADC("ADCR", "HiFi Capture", WM8961_PWR_MGMT_1, 2, 0),
534
535SND_SOC_DAPM_MICBIAS("MICBIAS", WM8961_PWR_MGMT_1, 1, 0),
536
537SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &dacl_mux),
538SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &dacr_mux),
539
540SND_SOC_DAPM_DAC("DACL", "HiFi Playback", WM8961_PWR_MGMT_2, 8, 0),
541SND_SOC_DAPM_DAC("DACR", "HiFi Playback", WM8961_PWR_MGMT_2, 7, 0),
542
543/* Handle as a mono path for DCS */
544SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM,
545 4, 0, NULL, 0, wm8961_hp_event,
546 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
547SND_SOC_DAPM_PGA_E("Speaker Output", SND_SOC_NOPM,
548 4, 0, NULL, 0, wm8961_spk_event,
549 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
550
551SND_SOC_DAPM_OUTPUT("HP_L"),
552SND_SOC_DAPM_OUTPUT("HP_R"),
553SND_SOC_DAPM_OUTPUT("SPK_LN"),
554SND_SOC_DAPM_OUTPUT("SPK_LP"),
555SND_SOC_DAPM_OUTPUT("SPK_RN"),
556SND_SOC_DAPM_OUTPUT("SPK_RP"),
557};
558
559
560static const struct snd_soc_dapm_route audio_paths[] = {
561 { "DACL", NULL, "CLK_DSP" },
562 { "DACL", NULL, "DACL Sidetone" },
563 { "DACR", NULL, "CLK_DSP" },
564 { "DACR", NULL, "DACR Sidetone" },
565
566 { "DACL Sidetone", "Left", "ADCL" },
567 { "DACL Sidetone", "Right", "ADCR" },
568
569 { "DACR Sidetone", "Left", "ADCL" },
570 { "DACR Sidetone", "Right", "ADCR" },
571
572 { "HP_L", NULL, "Headphone Output" },
573 { "HP_R", NULL, "Headphone Output" },
574 { "Headphone Output", NULL, "DACL" },
575 { "Headphone Output", NULL, "DACR" },
576
577 { "SPK_LN", NULL, "Speaker Output" },
578 { "SPK_LP", NULL, "Speaker Output" },
579 { "SPK_RN", NULL, "Speaker Output" },
580 { "SPK_RP", NULL, "Speaker Output" },
581
582 { "Speaker Output", NULL, "DACL" },
583 { "Speaker Output", NULL, "DACR" },
584
585 { "ADCL", NULL, "Left Input" },
586 { "ADCL", NULL, "CLK_DSP" },
587 { "ADCR", NULL, "Right Input" },
588 { "ADCR", NULL, "CLK_DSP" },
589
590 { "Left Input", NULL, "LINPUT" },
591 { "Right Input", NULL, "RINPUT" },
592
593};
594
595/* Values for CLK_SYS_RATE */
596static struct {
597 int ratio;
598 u16 val;
599} wm8961_clk_sys_ratio[] = {
600 { 64, 0 },
601 { 128, 1 },
602 { 192, 2 },
603 { 256, 3 },
604 { 384, 4 },
605 { 512, 5 },
606 { 768, 6 },
607 { 1024, 7 },
608 { 1408, 8 },
609 { 1536, 9 },
610};
611
612/* Values for SAMPLE_RATE */
613static struct {
614 int rate;
615 u16 val;
616} wm8961_srate[] = {
617 { 48000, 0 },
618 { 44100, 0 },
619 { 32000, 1 },
620 { 22050, 2 },
621 { 24000, 2 },
622 { 16000, 3 },
623 { 11250, 4 },
624 { 12000, 4 },
625 { 8000, 5 },
626};
627
628static int wm8961_hw_params(struct snd_pcm_substream *substream,
629 struct snd_pcm_hw_params *params,
630 struct snd_soc_dai *dai)
631{
632 struct snd_soc_codec *codec = dai->codec;
633 struct wm8961_priv *wm8961 = codec->private_data;
634 int i, best, target, fs;
635 u16 reg;
636
637 fs = params_rate(params);
638
639 if (!wm8961->sysclk) {
640 dev_err(codec->dev, "MCLK has not been specified\n");
641 return -EINVAL;
642 }
643
644 /* Find the closest sample rate for the filters */
645 best = 0;
646 for (i = 0; i < ARRAY_SIZE(wm8961_srate); i++) {
647 if (abs(wm8961_srate[i].rate - fs) <
648 abs(wm8961_srate[best].rate - fs))
649 best = i;
650 }
651 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_3);
652 reg &= ~WM8961_SAMPLE_RATE_MASK;
653 reg |= wm8961_srate[best].val;
654 snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_3, reg);
655 dev_dbg(codec->dev, "Selected SRATE %dHz for %dHz\n",
656 wm8961_srate[best].rate, fs);
657
658 /* Select a CLK_SYS/fs ratio equal to or higher than required */
659 target = wm8961->sysclk / fs;
660
661 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && target < 64) {
662 dev_err(codec->dev,
663 "SYSCLK must be at least 64*fs for DAC\n");
664 return -EINVAL;
665 }
666 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE && target < 256) {
667 dev_err(codec->dev,
668 "SYSCLK must be at least 256*fs for ADC\n");
669 return -EINVAL;
670 }
671
672 for (i = 0; i < ARRAY_SIZE(wm8961_clk_sys_ratio); i++) {
673 if (wm8961_clk_sys_ratio[i].ratio >= target)
674 break;
675 }
676 if (i == ARRAY_SIZE(wm8961_clk_sys_ratio)) {
677 dev_err(codec->dev, "Unable to generate CLK_SYS_RATE\n");
678 return -EINVAL;
679 }
680 dev_dbg(codec->dev, "Selected CLK_SYS_RATE of %d for %d/%d=%d\n",
681 wm8961_clk_sys_ratio[i].ratio, wm8961->sysclk, fs,
682 wm8961->sysclk / fs);
683
684 reg = snd_soc_read(codec, WM8961_CLOCKING_4);
685 reg &= ~WM8961_CLK_SYS_RATE_MASK;
686 reg |= wm8961_clk_sys_ratio[i].val << WM8961_CLK_SYS_RATE_SHIFT;
687 snd_soc_write(codec, WM8961_CLOCKING_4, reg);
688
689 reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
690 reg &= ~WM8961_WL_MASK;
691 switch (params_format(params)) {
692 case SNDRV_PCM_FORMAT_S16_LE:
693 break;
694 case SNDRV_PCM_FORMAT_S20_3LE:
695 reg |= 1 << WM8961_WL_SHIFT;
696 break;
697 case SNDRV_PCM_FORMAT_S24_LE:
698 reg |= 2 << WM8961_WL_SHIFT;
699 break;
700 case SNDRV_PCM_FORMAT_S32_LE:
701 reg |= 3 << WM8961_WL_SHIFT;
702 break;
703 default:
704 return -EINVAL;
705 }
706 snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, reg);
707
708 /* Sloping stop-band filter is recommended for <= 24kHz */
709 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
710 if (fs <= 24000)
711 reg |= WM8961_DACSLOPE;
712 else
713 reg &= WM8961_DACSLOPE;
714 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
715
716 return 0;
717}
718
719static int wm8961_set_sysclk(struct snd_soc_dai *dai, int clk_id,
720 unsigned int freq,
721 int dir)
722{
723 struct snd_soc_codec *codec = dai->codec;
724 struct wm8961_priv *wm8961 = codec->private_data;
725 u16 reg = snd_soc_read(codec, WM8961_CLOCKING1);
726
727 if (freq > 33000000) {
728 dev_err(codec->dev, "MCLK must be <33MHz\n");
729 return -EINVAL;
730 }
731
732 if (freq > 16500000) {
733 dev_dbg(codec->dev, "Using MCLK/2 for %dHz MCLK\n", freq);
734 reg |= WM8961_MCLKDIV;
735 freq /= 2;
736 } else {
737 dev_dbg(codec->dev, "Using MCLK/1 for %dHz MCLK\n", freq);
738 reg &= WM8961_MCLKDIV;
739 }
740
741 snd_soc_write(codec, WM8961_CLOCKING1, reg);
742
743 wm8961->sysclk = freq;
744
745 return 0;
746}
747
748static int wm8961_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
749{
750 struct snd_soc_codec *codec = dai->codec;
751 u16 aif = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_0);
752
753 aif &= ~(WM8961_BCLKINV | WM8961_LRP |
754 WM8961_MS | WM8961_FORMAT_MASK);
755
756 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
757 case SND_SOC_DAIFMT_CBM_CFM:
758 aif |= WM8961_MS;
759 break;
760 case SND_SOC_DAIFMT_CBS_CFS:
761 break;
762 default:
763 return -EINVAL;
764 }
765
766 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
767 case SND_SOC_DAIFMT_RIGHT_J:
768 break;
769
770 case SND_SOC_DAIFMT_LEFT_J:
771 aif |= 1;
772 break;
773
774 case SND_SOC_DAIFMT_I2S:
775 aif |= 2;
776 break;
777
778 case SND_SOC_DAIFMT_DSP_B:
779 aif |= WM8961_LRP;
780 case SND_SOC_DAIFMT_DSP_A:
781 aif |= 3;
782 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
783 case SND_SOC_DAIFMT_NB_NF:
784 case SND_SOC_DAIFMT_IB_NF:
785 break;
786 default:
787 return -EINVAL;
788 }
789 break;
790
791 default:
792 return -EINVAL;
793 }
794
795 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
796 case SND_SOC_DAIFMT_NB_NF:
797 break;
798 case SND_SOC_DAIFMT_NB_IF:
799 aif |= WM8961_LRP;
800 break;
801 case SND_SOC_DAIFMT_IB_NF:
802 aif |= WM8961_BCLKINV;
803 break;
804 case SND_SOC_DAIFMT_IB_IF:
805 aif |= WM8961_BCLKINV | WM8961_LRP;
806 break;
807 default:
808 return -EINVAL;
809 }
810
811 return snd_soc_write(codec, WM8961_AUDIO_INTERFACE_0, aif);
812}
813
814static int wm8961_set_tristate(struct snd_soc_dai *dai, int tristate)
815{
816 struct snd_soc_codec *codec = dai->codec;
817 u16 reg = snd_soc_read(codec, WM8961_ADDITIONAL_CONTROL_2);
818
819 if (tristate)
820 reg |= WM8961_TRIS;
821 else
822 reg &= ~WM8961_TRIS;
823
824 return snd_soc_write(codec, WM8961_ADDITIONAL_CONTROL_2, reg);
825}
826
827static int wm8961_digital_mute(struct snd_soc_dai *dai, int mute)
828{
829 struct snd_soc_codec *codec = dai->codec;
830 u16 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_1);
831
832 if (mute)
833 reg |= WM8961_DACMU;
834 else
835 reg &= ~WM8961_DACMU;
836
837 msleep(17);
838
839 return snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_1, reg);
840}
841
842static int wm8961_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div)
843{
844 struct snd_soc_codec *codec = dai->codec;
845 u16 reg;
846
847 switch (div_id) {
848 case WM8961_BCLK:
849 reg = snd_soc_read(codec, WM8961_CLOCKING2);
850 reg &= ~WM8961_BCLKDIV_MASK;
851 reg |= div;
852 snd_soc_write(codec, WM8961_CLOCKING2, reg);
853 break;
854
855 case WM8961_LRCLK:
856 reg = snd_soc_read(codec, WM8961_AUDIO_INTERFACE_2);
857 reg &= ~WM8961_LRCLK_RATE_MASK;
858 reg |= div;
859 snd_soc_write(codec, WM8961_AUDIO_INTERFACE_2, reg);
860 break;
861
862 default:
863 return -EINVAL;
864 }
865
866 return 0;
867}
868
869static int wm8961_set_bias_level(struct snd_soc_codec *codec,
870 enum snd_soc_bias_level level)
871{
872 u16 reg;
873
874 /* This is all slightly unusual since we have no bypass paths
875 * and the output amplifier structure means we can just slam
876 * the biases straight up rather than having to ramp them
877 * slowly.
878 */
879 switch (level) {
880 case SND_SOC_BIAS_ON:
881 break;
882
883 case SND_SOC_BIAS_PREPARE:
884 if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
885 /* Enable bias generation */
886 reg = snd_soc_read(codec, WM8961_ANTI_POP);
887 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
888 snd_soc_write(codec, WM8961_ANTI_POP, reg);
889
890 /* VMID=2*50k, VREF */
891 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
892 reg &= ~WM8961_VMIDSEL_MASK;
893 reg |= (1 << WM8961_VMIDSEL_SHIFT) | WM8961_VREF;
894 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
895 }
896 break;
897
898 case SND_SOC_BIAS_STANDBY:
899 if (codec->bias_level == SND_SOC_BIAS_PREPARE) {
900 /* VREF off */
901 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
902 reg &= ~WM8961_VREF;
903 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
904
905 /* Bias generation off */
906 reg = snd_soc_read(codec, WM8961_ANTI_POP);
907 reg &= ~(WM8961_BUFIOEN | WM8961_BUFDCOPEN);
908 snd_soc_write(codec, WM8961_ANTI_POP, reg);
909
910 /* VMID off */
911 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
912 reg &= ~WM8961_VMIDSEL_MASK;
913 snd_soc_write(codec, WM8961_PWR_MGMT_1, reg);
914 }
915 break;
916
917 case SND_SOC_BIAS_OFF:
918 break;
919 }
920
921 codec->bias_level = level;
922
923 return 0;
924}
925
926
927#define WM8961_RATES SNDRV_PCM_RATE_8000_48000
928
929#define WM8961_FORMATS \
930 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
931 SNDRV_PCM_FMTBIT_S24_LE)
932
933static struct snd_soc_dai_ops wm8961_dai_ops = {
934 .hw_params = wm8961_hw_params,
935 .set_sysclk = wm8961_set_sysclk,
936 .set_fmt = wm8961_set_fmt,
937 .digital_mute = wm8961_digital_mute,
938 .set_tristate = wm8961_set_tristate,
939 .set_clkdiv = wm8961_set_clkdiv,
940};
941
942struct snd_soc_dai wm8961_dai = {
943 .name = "WM8961",
944 .playback = {
945 .stream_name = "HiFi Playback",
946 .channels_min = 1,
947 .channels_max = 2,
948 .rates = WM8961_RATES,
949 .formats = WM8961_FORMATS,},
950 .capture = {
951 .stream_name = "HiFi Capture",
952 .channels_min = 1,
953 .channels_max = 2,
954 .rates = WM8961_RATES,
955 .formats = WM8961_FORMATS,},
956 .ops = &wm8961_dai_ops,
957};
958EXPORT_SYMBOL_GPL(wm8961_dai);
959
960
961static struct snd_soc_codec *wm8961_codec;
962
963static int wm8961_probe(struct platform_device *pdev)
964{
965 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
966 struct snd_soc_codec *codec;
967 int ret = 0;
968
969 if (wm8961_codec == NULL) {
970 dev_err(&pdev->dev, "Codec device not registered\n");
971 return -ENODEV;
972 }
973
974 socdev->card->codec = wm8961_codec;
975 codec = wm8961_codec;
976
977 /* register pcms */
978 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
979 if (ret < 0) {
980 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
981 goto pcm_err;
982 }
983
984 snd_soc_add_controls(codec, wm8961_snd_controls,
985 ARRAY_SIZE(wm8961_snd_controls));
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets));
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec);
990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996
997 return ret;
998
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err:
1003 return ret;
1004}
1005
1006static int wm8961_remove(struct platform_device *pdev)
1007{
1008 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1009
1010 snd_soc_free_pcms(socdev);
1011 snd_soc_dapm_free(socdev);
1012
1013 return 0;
1014}
1015
1016#ifdef CONFIG_PM
1017static int wm8961_suspend(struct platform_device *pdev, pm_message_t state)
1018{
1019 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1020 struct snd_soc_codec *codec = socdev->card->codec;
1021
1022 wm8961_set_bias_level(codec, SND_SOC_BIAS_OFF);
1023
1024 return 0;
1025}
1026
1027static int wm8961_resume(struct platform_device *pdev)
1028{
1029 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1030 struct snd_soc_codec *codec = socdev->card->codec;
1031 u16 *reg_cache = codec->reg_cache;
1032 int i;
1033
1034 for (i = 0; i < codec->reg_cache_size; i++) {
1035 if (i == WM8961_SOFTWARE_RESET)
1036 continue;
1037
1038 snd_soc_write(codec, i, reg_cache[i]);
1039 }
1040
1041 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1042
1043 return 0;
1044}
1045#else
1046#define wm8961_suspend NULL
1047#define wm8961_resume NULL
1048#endif
1049
1050struct snd_soc_codec_device soc_codec_dev_wm8961 = {
1051 .probe = wm8961_probe,
1052 .remove = wm8961_remove,
1053 .suspend = wm8961_suspend,
1054 .resume = wm8961_resume,
1055};
1056EXPORT_SYMBOL_GPL(soc_codec_dev_wm8961);
1057
1058static int wm8961_register(struct wm8961_priv *wm8961)
1059{
1060 struct snd_soc_codec *codec = &wm8961->codec;
1061 int ret;
1062 u16 reg;
1063
1064 if (wm8961_codec) {
1065 dev_err(codec->dev, "Another WM8961 is registered\n");
1066 ret = -EINVAL;
1067 goto err;
1068 }
1069
1070 mutex_init(&codec->mutex);
1071 INIT_LIST_HEAD(&codec->dapm_widgets);
1072 INIT_LIST_HEAD(&codec->dapm_paths);
1073
1074 codec->private_data = wm8961;
1075 codec->name = "WM8961";
1076 codec->owner = THIS_MODULE;
1077 codec->dai = &wm8961_dai;
1078 codec->num_dai = 1;
1079 codec->reg_cache_size = ARRAY_SIZE(wm8961->reg_cache);
1080 codec->reg_cache = &wm8961->reg_cache;
1081 codec->bias_level = SND_SOC_BIAS_OFF;
1082 codec->set_bias_level = wm8961_set_bias_level;
1083 codec->volatile_register = wm8961_volatile_register;
1084
1085 memcpy(codec->reg_cache, wm8961_reg_defaults,
1086 sizeof(wm8961_reg_defaults));
1087
1088 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1089 if (ret != 0) {
1090 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1091 goto err;
1092 }
1093
1094 reg = snd_soc_read(codec, WM8961_SOFTWARE_RESET);
1095 if (reg != 0x1801) {
1096 dev_err(codec->dev, "Device is not a WM8961: ID=0x%x\n", reg);
1097 ret = -EINVAL;
1098 goto err;
1099 }
1100
1101 /* This isn't volatile - readback doesn't correspond to write */
1102 reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME);
1103 dev_info(codec->dev, "WM8961 family %d revision %c\n",
1104 (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT,
1105 ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT)
1106 + 'A');
1107
1108 ret = wm8961_reset(codec);
1109 if (ret < 0) {
1110 dev_err(codec->dev, "Failed to issue reset\n");
1111 return ret;
1112 }
1113
1114 /* Enable class W */
1115 reg = snd_soc_read(codec, WM8961_CHARGE_PUMP_B);
1116 reg |= WM8961_CP_DYN_PWR_MASK;
1117 snd_soc_write(codec, WM8961_CHARGE_PUMP_B, reg);
1118
1119 /* Latch volume update bits (right channel only, we always
1120 * write both out) and default ZC on. */
1121 reg = snd_soc_read(codec, WM8961_ROUT1_VOLUME);
1122 snd_soc_write(codec, WM8961_ROUT1_VOLUME,
1123 reg | WM8961_LO1ZC | WM8961_OUT1VU);
1124 snd_soc_write(codec, WM8961_LOUT1_VOLUME, reg | WM8961_LO1ZC);
1125 reg = snd_soc_read(codec, WM8961_ROUT2_VOLUME);
1126 snd_soc_write(codec, WM8961_ROUT2_VOLUME,
1127 reg | WM8961_SPKRZC | WM8961_SPKVU);
1128 snd_soc_write(codec, WM8961_LOUT2_VOLUME, reg | WM8961_SPKLZC);
1129
1130 reg = snd_soc_read(codec, WM8961_RIGHT_ADC_VOLUME);
1131 snd_soc_write(codec, WM8961_RIGHT_ADC_VOLUME, reg | WM8961_ADCVU);
1132 reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME);
1133 snd_soc_write(codec, WM8961_RIGHT_INPUT_VOLUME, reg | WM8961_IPVU);
1134
1135 /* Use soft mute by default */
1136 reg = snd_soc_read(codec, WM8961_ADC_DAC_CONTROL_2);
1137 reg |= WM8961_DACSMM;
1138 snd_soc_write(codec, WM8961_ADC_DAC_CONTROL_2, reg);
1139
1140 /* Use automatic clocking mode by default; for now this is all
1141 * we support.
1142 */
1143 reg = snd_soc_read(codec, WM8961_CLOCKING_3);
1144 reg &= ~WM8961_MANUAL_MODE;
1145 snd_soc_write(codec, WM8961_CLOCKING_3, reg);
1146
1147 wm8961_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1148
1149 wm8961_dai.dev = codec->dev;
1150
1151 wm8961_codec = codec;
1152
1153 ret = snd_soc_register_codec(codec);
1154 if (ret != 0) {
1155 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1156 return ret;
1157 }
1158
1159 ret = snd_soc_register_dai(&wm8961_dai);
1160 if (ret != 0) {
1161 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1162 snd_soc_unregister_codec(codec);
1163 return ret;
1164 }
1165
1166 return 0;
1167
1168err:
1169 kfree(wm8961);
1170 return ret;
1171}
1172
1173static void wm8961_unregister(struct wm8961_priv *wm8961)
1174{
1175 wm8961_set_bias_level(&wm8961->codec, SND_SOC_BIAS_OFF);
1176 snd_soc_unregister_dai(&wm8961_dai);
1177 snd_soc_unregister_codec(&wm8961->codec);
1178 kfree(wm8961);
1179 wm8961_codec = NULL;
1180}
1181
1182static __devinit int wm8961_i2c_probe(struct i2c_client *i2c,
1183 const struct i2c_device_id *id)
1184{
1185 struct wm8961_priv *wm8961;
1186 struct snd_soc_codec *codec;
1187
1188 wm8961 = kzalloc(sizeof(struct wm8961_priv), GFP_KERNEL);
1189 if (wm8961 == NULL)
1190 return -ENOMEM;
1191
1192 codec = &wm8961->codec;
1193
1194 i2c_set_clientdata(i2c, wm8961);
1195 codec->control_data = i2c;
1196
1197 codec->dev = &i2c->dev;
1198
1199 return wm8961_register(wm8961);
1200}
1201
1202static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1203{
1204 struct wm8961_priv *wm8961 = i2c_get_clientdata(client);
1205 wm8961_unregister(wm8961);
1206 return 0;
1207}
1208
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 },
1226 { }
1227};
1228MODULE_DEVICE_TABLE(i2c, wm8961_i2c_id);
1229
1230static struct i2c_driver wm8961_i2c_driver = {
1231 .driver = {
1232 .name = "wm8961",
1233 .owner = THIS_MODULE,
1234 },
1235 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id,
1240};
1241
1242static int __init wm8961_modinit(void)
1243{
1244 int ret;
1245
1246 ret = i2c_add_driver(&wm8961_i2c_driver);
1247 if (ret != 0) {
1248 printk(KERN_ERR "Failed to register WM8961 I2C driver: %d\n",
1249 ret);
1250 }
1251
1252 return ret;
1253}
1254module_init(wm8961_modinit);
1255
1256static void __exit wm8961_exit(void)
1257{
1258 i2c_del_driver(&wm8961_i2c_driver);
1259}
1260module_exit(wm8961_exit);
1261
1262
1263MODULE_DESCRIPTION("ASoC WM8961 driver");
1264MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1265MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8961.h b/sound/soc/codecs/wm8961.h
new file mode 100644
index 000000000000..5513bfd720d6
--- /dev/null
+++ b/sound/soc/codecs/wm8961.h
@@ -0,0 +1,866 @@
1/*
2 * wm8961.h -- WM8961 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8961_H
10#define _WM8961_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8961;
15extern struct snd_soc_dai wm8961_dai;
16
17#define WM8961_BCLK 1
18#define WM8961_LRCLK 2
19
20#define WM8961_BCLK_DIV_1 0
21#define WM8961_BCLK_DIV_1_5 1
22#define WM8961_BCLK_DIV_2 2
23#define WM8961_BCLK_DIV_3 3
24#define WM8961_BCLK_DIV_4 4
25#define WM8961_BCLK_DIV_5_5 5
26#define WM8961_BCLK_DIV_6 6
27#define WM8961_BCLK_DIV_8 7
28#define WM8961_BCLK_DIV_11 8
29#define WM8961_BCLK_DIV_12 9
30#define WM8961_BCLK_DIV_16 10
31#define WM8961_BCLK_DIV_24 11
32#define WM8961_BCLK_DIV_32 13
33
34
35/*
36 * Register values.
37 */
38#define WM8961_LEFT_INPUT_VOLUME 0x00
39#define WM8961_RIGHT_INPUT_VOLUME 0x01
40#define WM8961_LOUT1_VOLUME 0x02
41#define WM8961_ROUT1_VOLUME 0x03
42#define WM8961_CLOCKING1 0x04
43#define WM8961_ADC_DAC_CONTROL_1 0x05
44#define WM8961_ADC_DAC_CONTROL_2 0x06
45#define WM8961_AUDIO_INTERFACE_0 0x07
46#define WM8961_CLOCKING2 0x08
47#define WM8961_AUDIO_INTERFACE_1 0x09
48#define WM8961_LEFT_DAC_VOLUME 0x0A
49#define WM8961_RIGHT_DAC_VOLUME 0x0B
50#define WM8961_AUDIO_INTERFACE_2 0x0E
51#define WM8961_SOFTWARE_RESET 0x0F
52#define WM8961_ALC1 0x11
53#define WM8961_ALC2 0x12
54#define WM8961_ALC3 0x13
55#define WM8961_NOISE_GATE 0x14
56#define WM8961_LEFT_ADC_VOLUME 0x15
57#define WM8961_RIGHT_ADC_VOLUME 0x16
58#define WM8961_ADDITIONAL_CONTROL_1 0x17
59#define WM8961_ADDITIONAL_CONTROL_2 0x18
60#define WM8961_PWR_MGMT_1 0x19
61#define WM8961_PWR_MGMT_2 0x1A
62#define WM8961_ADDITIONAL_CONTROL_3 0x1B
63#define WM8961_ANTI_POP 0x1C
64#define WM8961_CLOCKING_3 0x1E
65#define WM8961_ADCL_SIGNAL_PATH 0x20
66#define WM8961_ADCR_SIGNAL_PATH 0x21
67#define WM8961_LOUT2_VOLUME 0x28
68#define WM8961_ROUT2_VOLUME 0x29
69#define WM8961_PWR_MGMT_3 0x2F
70#define WM8961_ADDITIONAL_CONTROL_4 0x30
71#define WM8961_CLASS_D_CONTROL_1 0x31
72#define WM8961_CLASS_D_CONTROL_2 0x33
73#define WM8961_CLOCKING_4 0x38
74#define WM8961_DSP_SIDETONE_0 0x39
75#define WM8961_DSP_SIDETONE_1 0x3A
76#define WM8961_DC_SERVO_0 0x3C
77#define WM8961_DC_SERVO_1 0x3D
78#define WM8961_DC_SERVO_3 0x3F
79#define WM8961_DC_SERVO_5 0x41
80#define WM8961_ANALOGUE_PGA_BIAS 0x44
81#define WM8961_ANALOGUE_HP_0 0x45
82#define WM8961_ANALOGUE_HP_2 0x47
83#define WM8961_CHARGE_PUMP_1 0x48
84#define WM8961_CHARGE_PUMP_B 0x52
85#define WM8961_WRITE_SEQUENCER_1 0x57
86#define WM8961_WRITE_SEQUENCER_2 0x58
87#define WM8961_WRITE_SEQUENCER_3 0x59
88#define WM8961_WRITE_SEQUENCER_4 0x5A
89#define WM8961_WRITE_SEQUENCER_5 0x5B
90#define WM8961_WRITE_SEQUENCER_6 0x5C
91#define WM8961_WRITE_SEQUENCER_7 0x5D
92#define WM8961_GENERAL_TEST_1 0xFC
93
94
95/*
96 * Field Definitions.
97 */
98
99/*
100 * R0 (0x00) - Left Input volume
101 */
102#define WM8961_IPVU 0x0100 /* IPVU */
103#define WM8961_IPVU_MASK 0x0100 /* IPVU */
104#define WM8961_IPVU_SHIFT 8 /* IPVU */
105#define WM8961_IPVU_WIDTH 1 /* IPVU */
106#define WM8961_LINMUTE 0x0080 /* LINMUTE */
107#define WM8961_LINMUTE_MASK 0x0080 /* LINMUTE */
108#define WM8961_LINMUTE_SHIFT 7 /* LINMUTE */
109#define WM8961_LINMUTE_WIDTH 1 /* LINMUTE */
110#define WM8961_LIZC 0x0040 /* LIZC */
111#define WM8961_LIZC_MASK 0x0040 /* LIZC */
112#define WM8961_LIZC_SHIFT 6 /* LIZC */
113#define WM8961_LIZC_WIDTH 1 /* LIZC */
114#define WM8961_LINVOL_MASK 0x003F /* LINVOL - [5:0] */
115#define WM8961_LINVOL_SHIFT 0 /* LINVOL - [5:0] */
116#define WM8961_LINVOL_WIDTH 6 /* LINVOL - [5:0] */
117
118/*
119 * R1 (0x01) - Right Input volume
120 */
121#define WM8961_DEVICE_ID_MASK 0xF000 /* DEVICE_ID - [15:12] */
122#define WM8961_DEVICE_ID_SHIFT 12 /* DEVICE_ID - [15:12] */
123#define WM8961_DEVICE_ID_WIDTH 4 /* DEVICE_ID - [15:12] */
124#define WM8961_CHIP_REV_MASK 0x0E00 /* CHIP_REV - [11:9] */
125#define WM8961_CHIP_REV_SHIFT 9 /* CHIP_REV - [11:9] */
126#define WM8961_CHIP_REV_WIDTH 3 /* CHIP_REV - [11:9] */
127#define WM8961_IPVU 0x0100 /* IPVU */
128#define WM8961_IPVU_MASK 0x0100 /* IPVU */
129#define WM8961_IPVU_SHIFT 8 /* IPVU */
130#define WM8961_IPVU_WIDTH 1 /* IPVU */
131#define WM8961_RINMUTE 0x0080 /* RINMUTE */
132#define WM8961_RINMUTE_MASK 0x0080 /* RINMUTE */
133#define WM8961_RINMUTE_SHIFT 7 /* RINMUTE */
134#define WM8961_RINMUTE_WIDTH 1 /* RINMUTE */
135#define WM8961_RIZC 0x0040 /* RIZC */
136#define WM8961_RIZC_MASK 0x0040 /* RIZC */
137#define WM8961_RIZC_SHIFT 6 /* RIZC */
138#define WM8961_RIZC_WIDTH 1 /* RIZC */
139#define WM8961_RINVOL_MASK 0x003F /* RINVOL - [5:0] */
140#define WM8961_RINVOL_SHIFT 0 /* RINVOL - [5:0] */
141#define WM8961_RINVOL_WIDTH 6 /* RINVOL - [5:0] */
142
143/*
144 * R2 (0x02) - LOUT1 volume
145 */
146#define WM8961_OUT1VU 0x0100 /* OUT1VU */
147#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
148#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
149#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
150#define WM8961_LO1ZC 0x0080 /* LO1ZC */
151#define WM8961_LO1ZC_MASK 0x0080 /* LO1ZC */
152#define WM8961_LO1ZC_SHIFT 7 /* LO1ZC */
153#define WM8961_LO1ZC_WIDTH 1 /* LO1ZC */
154#define WM8961_LOUT1VOL_MASK 0x007F /* LOUT1VOL - [6:0] */
155#define WM8961_LOUT1VOL_SHIFT 0 /* LOUT1VOL - [6:0] */
156#define WM8961_LOUT1VOL_WIDTH 7 /* LOUT1VOL - [6:0] */
157
158/*
159 * R3 (0x03) - ROUT1 volume
160 */
161#define WM8961_OUT1VU 0x0100 /* OUT1VU */
162#define WM8961_OUT1VU_MASK 0x0100 /* OUT1VU */
163#define WM8961_OUT1VU_SHIFT 8 /* OUT1VU */
164#define WM8961_OUT1VU_WIDTH 1 /* OUT1VU */
165#define WM8961_RO1ZC 0x0080 /* RO1ZC */
166#define WM8961_RO1ZC_MASK 0x0080 /* RO1ZC */
167#define WM8961_RO1ZC_SHIFT 7 /* RO1ZC */
168#define WM8961_RO1ZC_WIDTH 1 /* RO1ZC */
169#define WM8961_ROUT1VOL_MASK 0x007F /* ROUT1VOL - [6:0] */
170#define WM8961_ROUT1VOL_SHIFT 0 /* ROUT1VOL - [6:0] */
171#define WM8961_ROUT1VOL_WIDTH 7 /* ROUT1VOL - [6:0] */
172
173/*
174 * R4 (0x04) - Clocking1
175 */
176#define WM8961_ADCDIV_MASK 0x01C0 /* ADCDIV - [8:6] */
177#define WM8961_ADCDIV_SHIFT 6 /* ADCDIV - [8:6] */
178#define WM8961_ADCDIV_WIDTH 3 /* ADCDIV - [8:6] */
179#define WM8961_DACDIV_MASK 0x0038 /* DACDIV - [5:3] */
180#define WM8961_DACDIV_SHIFT 3 /* DACDIV - [5:3] */
181#define WM8961_DACDIV_WIDTH 3 /* DACDIV - [5:3] */
182#define WM8961_MCLKDIV 0x0004 /* MCLKDIV */
183#define WM8961_MCLKDIV_MASK 0x0004 /* MCLKDIV */
184#define WM8961_MCLKDIV_SHIFT 2 /* MCLKDIV */
185#define WM8961_MCLKDIV_WIDTH 1 /* MCLKDIV */
186
187/*
188 * R5 (0x05) - ADC & DAC Control 1
189 */
190#define WM8961_ADCPOL_MASK 0x0060 /* ADCPOL - [6:5] */
191#define WM8961_ADCPOL_SHIFT 5 /* ADCPOL - [6:5] */
192#define WM8961_ADCPOL_WIDTH 2 /* ADCPOL - [6:5] */
193#define WM8961_DACMU 0x0008 /* DACMU */
194#define WM8961_DACMU_MASK 0x0008 /* DACMU */
195#define WM8961_DACMU_SHIFT 3 /* DACMU */
196#define WM8961_DACMU_WIDTH 1 /* DACMU */
197#define WM8961_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
198#define WM8961_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
199#define WM8961_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
200#define WM8961_ADCHPD 0x0001 /* ADCHPD */
201#define WM8961_ADCHPD_MASK 0x0001 /* ADCHPD */
202#define WM8961_ADCHPD_SHIFT 0 /* ADCHPD */
203#define WM8961_ADCHPD_WIDTH 1 /* ADCHPD */
204
205/*
206 * R6 (0x06) - ADC & DAC Control 2
207 */
208#define WM8961_ADC_HPF_CUT_MASK 0x0180 /* ADC_HPF_CUT - [8:7] */
209#define WM8961_ADC_HPF_CUT_SHIFT 7 /* ADC_HPF_CUT - [8:7] */
210#define WM8961_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [8:7] */
211#define WM8961_DACPOL_MASK 0x0060 /* DACPOL - [6:5] */
212#define WM8961_DACPOL_SHIFT 5 /* DACPOL - [6:5] */
213#define WM8961_DACPOL_WIDTH 2 /* DACPOL - [6:5] */
214#define WM8961_DACSMM 0x0008 /* DACSMM */
215#define WM8961_DACSMM_MASK 0x0008 /* DACSMM */
216#define WM8961_DACSMM_SHIFT 3 /* DACSMM */
217#define WM8961_DACSMM_WIDTH 1 /* DACSMM */
218#define WM8961_DACMR 0x0004 /* DACMR */
219#define WM8961_DACMR_MASK 0x0004 /* DACMR */
220#define WM8961_DACMR_SHIFT 2 /* DACMR */
221#define WM8961_DACMR_WIDTH 1 /* DACMR */
222#define WM8961_DACSLOPE 0x0002 /* DACSLOPE */
223#define WM8961_DACSLOPE_MASK 0x0002 /* DACSLOPE */
224#define WM8961_DACSLOPE_SHIFT 1 /* DACSLOPE */
225#define WM8961_DACSLOPE_WIDTH 1 /* DACSLOPE */
226#define WM8961_DAC_OSR128 0x0001 /* DAC_OSR128 */
227#define WM8961_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
228#define WM8961_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
229#define WM8961_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
230
231/*
232 * R7 (0x07) - Audio Interface 0
233 */
234#define WM8961_ALRSWAP 0x0100 /* ALRSWAP */
235#define WM8961_ALRSWAP_MASK 0x0100 /* ALRSWAP */
236#define WM8961_ALRSWAP_SHIFT 8 /* ALRSWAP */
237#define WM8961_ALRSWAP_WIDTH 1 /* ALRSWAP */
238#define WM8961_BCLKINV 0x0080 /* BCLKINV */
239#define WM8961_BCLKINV_MASK 0x0080 /* BCLKINV */
240#define WM8961_BCLKINV_SHIFT 7 /* BCLKINV */
241#define WM8961_BCLKINV_WIDTH 1 /* BCLKINV */
242#define WM8961_MS 0x0040 /* MS */
243#define WM8961_MS_MASK 0x0040 /* MS */
244#define WM8961_MS_SHIFT 6 /* MS */
245#define WM8961_MS_WIDTH 1 /* MS */
246#define WM8961_DLRSWAP 0x0020 /* DLRSWAP */
247#define WM8961_DLRSWAP_MASK 0x0020 /* DLRSWAP */
248#define WM8961_DLRSWAP_SHIFT 5 /* DLRSWAP */
249#define WM8961_DLRSWAP_WIDTH 1 /* DLRSWAP */
250#define WM8961_LRP 0x0010 /* LRP */
251#define WM8961_LRP_MASK 0x0010 /* LRP */
252#define WM8961_LRP_SHIFT 4 /* LRP */
253#define WM8961_LRP_WIDTH 1 /* LRP */
254#define WM8961_WL_MASK 0x000C /* WL - [3:2] */
255#define WM8961_WL_SHIFT 2 /* WL - [3:2] */
256#define WM8961_WL_WIDTH 2 /* WL - [3:2] */
257#define WM8961_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
258#define WM8961_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
259#define WM8961_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
260
261/*
262 * R8 (0x08) - Clocking2
263 */
264#define WM8961_DCLKDIV_MASK 0x01C0 /* DCLKDIV - [8:6] */
265#define WM8961_DCLKDIV_SHIFT 6 /* DCLKDIV - [8:6] */
266#define WM8961_DCLKDIV_WIDTH 3 /* DCLKDIV - [8:6] */
267#define WM8961_CLK_SYS_ENA 0x0020 /* CLK_SYS_ENA */
268#define WM8961_CLK_SYS_ENA_MASK 0x0020 /* CLK_SYS_ENA */
269#define WM8961_CLK_SYS_ENA_SHIFT 5 /* CLK_SYS_ENA */
270#define WM8961_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
271#define WM8961_CLK_DSP_ENA 0x0010 /* CLK_DSP_ENA */
272#define WM8961_CLK_DSP_ENA_MASK 0x0010 /* CLK_DSP_ENA */
273#define WM8961_CLK_DSP_ENA_SHIFT 4 /* CLK_DSP_ENA */
274#define WM8961_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
275#define WM8961_BCLKDIV_MASK 0x000F /* BCLKDIV - [3:0] */
276#define WM8961_BCLKDIV_SHIFT 0 /* BCLKDIV - [3:0] */
277#define WM8961_BCLKDIV_WIDTH 4 /* BCLKDIV - [3:0] */
278
279/*
280 * R9 (0x09) - Audio Interface 1
281 */
282#define WM8961_DACCOMP_MASK 0x0018 /* DACCOMP - [4:3] */
283#define WM8961_DACCOMP_SHIFT 3 /* DACCOMP - [4:3] */
284#define WM8961_DACCOMP_WIDTH 2 /* DACCOMP - [4:3] */
285#define WM8961_ADCCOMP_MASK 0x0006 /* ADCCOMP - [2:1] */
286#define WM8961_ADCCOMP_SHIFT 1 /* ADCCOMP - [2:1] */
287#define WM8961_ADCCOMP_WIDTH 2 /* ADCCOMP - [2:1] */
288#define WM8961_LOOPBACK 0x0001 /* LOOPBACK */
289#define WM8961_LOOPBACK_MASK 0x0001 /* LOOPBACK */
290#define WM8961_LOOPBACK_SHIFT 0 /* LOOPBACK */
291#define WM8961_LOOPBACK_WIDTH 1 /* LOOPBACK */
292
293/*
294 * R10 (0x0A) - Left DAC volume
295 */
296#define WM8961_DACVU 0x0100 /* DACVU */
297#define WM8961_DACVU_MASK 0x0100 /* DACVU */
298#define WM8961_DACVU_SHIFT 8 /* DACVU */
299#define WM8961_DACVU_WIDTH 1 /* DACVU */
300#define WM8961_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
301#define WM8961_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
302#define WM8961_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
303
304/*
305 * R11 (0x0B) - Right DAC volume
306 */
307#define WM8961_DACVU 0x0100 /* DACVU */
308#define WM8961_DACVU_MASK 0x0100 /* DACVU */
309#define WM8961_DACVU_SHIFT 8 /* DACVU */
310#define WM8961_DACVU_WIDTH 1 /* DACVU */
311#define WM8961_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
312#define WM8961_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
313#define WM8961_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
314
315/*
316 * R14 (0x0E) - Audio Interface 2
317 */
318#define WM8961_LRCLK_RATE_MASK 0x01FF /* LRCLK_RATE - [8:0] */
319#define WM8961_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [8:0] */
320#define WM8961_LRCLK_RATE_WIDTH 9 /* LRCLK_RATE - [8:0] */
321
322/*
323 * R15 (0x0F) - Software Reset
324 */
325#define WM8961_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
326#define WM8961_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
327#define WM8961_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
328
329/*
330 * R17 (0x11) - ALC1
331 */
332#define WM8961_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
333#define WM8961_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
334#define WM8961_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
335#define WM8961_MAXGAIN_MASK 0x0070 /* MAXGAIN - [6:4] */
336#define WM8961_MAXGAIN_SHIFT 4 /* MAXGAIN - [6:4] */
337#define WM8961_MAXGAIN_WIDTH 3 /* MAXGAIN - [6:4] */
338#define WM8961_ALCL_MASK 0x000F /* ALCL - [3:0] */
339#define WM8961_ALCL_SHIFT 0 /* ALCL - [3:0] */
340#define WM8961_ALCL_WIDTH 4 /* ALCL - [3:0] */
341
342/*
343 * R18 (0x12) - ALC2
344 */
345#define WM8961_ALCZC 0x0080 /* ALCZC */
346#define WM8961_ALCZC_MASK 0x0080 /* ALCZC */
347#define WM8961_ALCZC_SHIFT 7 /* ALCZC */
348#define WM8961_ALCZC_WIDTH 1 /* ALCZC */
349#define WM8961_MINGAIN_MASK 0x0070 /* MINGAIN - [6:4] */
350#define WM8961_MINGAIN_SHIFT 4 /* MINGAIN - [6:4] */
351#define WM8961_MINGAIN_WIDTH 3 /* MINGAIN - [6:4] */
352#define WM8961_HLD_MASK 0x000F /* HLD - [3:0] */
353#define WM8961_HLD_SHIFT 0 /* HLD - [3:0] */
354#define WM8961_HLD_WIDTH 4 /* HLD - [3:0] */
355
356/*
357 * R19 (0x13) - ALC3
358 */
359#define WM8961_ALCMODE 0x0100 /* ALCMODE */
360#define WM8961_ALCMODE_MASK 0x0100 /* ALCMODE */
361#define WM8961_ALCMODE_SHIFT 8 /* ALCMODE */
362#define WM8961_ALCMODE_WIDTH 1 /* ALCMODE */
363#define WM8961_DCY_MASK 0x00F0 /* DCY - [7:4] */
364#define WM8961_DCY_SHIFT 4 /* DCY - [7:4] */
365#define WM8961_DCY_WIDTH 4 /* DCY - [7:4] */
366#define WM8961_ATK_MASK 0x000F /* ATK - [3:0] */
367#define WM8961_ATK_SHIFT 0 /* ATK - [3:0] */
368#define WM8961_ATK_WIDTH 4 /* ATK - [3:0] */
369
370/*
371 * R20 (0x14) - Noise Gate
372 */
373#define WM8961_NGTH_MASK 0x00F8 /* NGTH - [7:3] */
374#define WM8961_NGTH_SHIFT 3 /* NGTH - [7:3] */
375#define WM8961_NGTH_WIDTH 5 /* NGTH - [7:3] */
376#define WM8961_NGG 0x0002 /* NGG */
377#define WM8961_NGG_MASK 0x0002 /* NGG */
378#define WM8961_NGG_SHIFT 1 /* NGG */
379#define WM8961_NGG_WIDTH 1 /* NGG */
380#define WM8961_NGAT 0x0001 /* NGAT */
381#define WM8961_NGAT_MASK 0x0001 /* NGAT */
382#define WM8961_NGAT_SHIFT 0 /* NGAT */
383#define WM8961_NGAT_WIDTH 1 /* NGAT */
384
385/*
386 * R21 (0x15) - Left ADC volume
387 */
388#define WM8961_ADCVU 0x0100 /* ADCVU */
389#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
390#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
391#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
392#define WM8961_LADCVOL_MASK 0x00FF /* LADCVOL - [7:0] */
393#define WM8961_LADCVOL_SHIFT 0 /* LADCVOL - [7:0] */
394#define WM8961_LADCVOL_WIDTH 8 /* LADCVOL - [7:0] */
395
396/*
397 * R22 (0x16) - Right ADC volume
398 */
399#define WM8961_ADCVU 0x0100 /* ADCVU */
400#define WM8961_ADCVU_MASK 0x0100 /* ADCVU */
401#define WM8961_ADCVU_SHIFT 8 /* ADCVU */
402#define WM8961_ADCVU_WIDTH 1 /* ADCVU */
403#define WM8961_RADCVOL_MASK 0x00FF /* RADCVOL - [7:0] */
404#define WM8961_RADCVOL_SHIFT 0 /* RADCVOL - [7:0] */
405#define WM8961_RADCVOL_WIDTH 8 /* RADCVOL - [7:0] */
406
407/*
408 * R23 (0x17) - Additional control(1)
409 */
410#define WM8961_TSDEN 0x0100 /* TSDEN */
411#define WM8961_TSDEN_MASK 0x0100 /* TSDEN */
412#define WM8961_TSDEN_SHIFT 8 /* TSDEN */
413#define WM8961_TSDEN_WIDTH 1 /* TSDEN */
414#define WM8961_DMONOMIX 0x0010 /* DMONOMIX */
415#define WM8961_DMONOMIX_MASK 0x0010 /* DMONOMIX */
416#define WM8961_DMONOMIX_SHIFT 4 /* DMONOMIX */
417#define WM8961_DMONOMIX_WIDTH 1 /* DMONOMIX */
418#define WM8961_TOEN 0x0001 /* TOEN */
419#define WM8961_TOEN_MASK 0x0001 /* TOEN */
420#define WM8961_TOEN_SHIFT 0 /* TOEN */
421#define WM8961_TOEN_WIDTH 1 /* TOEN */
422
423/*
424 * R24 (0x18) - Additional control(2)
425 */
426#define WM8961_TRIS 0x0008 /* TRIS */
427#define WM8961_TRIS_MASK 0x0008 /* TRIS */
428#define WM8961_TRIS_SHIFT 3 /* TRIS */
429#define WM8961_TRIS_WIDTH 1 /* TRIS */
430
431/*
432 * R25 (0x19) - Pwr Mgmt (1)
433 */
434#define WM8961_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
435#define WM8961_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
436#define WM8961_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
437#define WM8961_VREF 0x0040 /* VREF */
438#define WM8961_VREF_MASK 0x0040 /* VREF */
439#define WM8961_VREF_SHIFT 6 /* VREF */
440#define WM8961_VREF_WIDTH 1 /* VREF */
441#define WM8961_AINL 0x0020 /* AINL */
442#define WM8961_AINL_MASK 0x0020 /* AINL */
443#define WM8961_AINL_SHIFT 5 /* AINL */
444#define WM8961_AINL_WIDTH 1 /* AINL */
445#define WM8961_AINR 0x0010 /* AINR */
446#define WM8961_AINR_MASK 0x0010 /* AINR */
447#define WM8961_AINR_SHIFT 4 /* AINR */
448#define WM8961_AINR_WIDTH 1 /* AINR */
449#define WM8961_ADCL 0x0008 /* ADCL */
450#define WM8961_ADCL_MASK 0x0008 /* ADCL */
451#define WM8961_ADCL_SHIFT 3 /* ADCL */
452#define WM8961_ADCL_WIDTH 1 /* ADCL */
453#define WM8961_ADCR 0x0004 /* ADCR */
454#define WM8961_ADCR_MASK 0x0004 /* ADCR */
455#define WM8961_ADCR_SHIFT 2 /* ADCR */
456#define WM8961_ADCR_WIDTH 1 /* ADCR */
457#define WM8961_MICB 0x0002 /* MICB */
458#define WM8961_MICB_MASK 0x0002 /* MICB */
459#define WM8961_MICB_SHIFT 1 /* MICB */
460#define WM8961_MICB_WIDTH 1 /* MICB */
461
462/*
463 * R26 (0x1A) - Pwr Mgmt (2)
464 */
465#define WM8961_DACL 0x0100 /* DACL */
466#define WM8961_DACL_MASK 0x0100 /* DACL */
467#define WM8961_DACL_SHIFT 8 /* DACL */
468#define WM8961_DACL_WIDTH 1 /* DACL */
469#define WM8961_DACR 0x0080 /* DACR */
470#define WM8961_DACR_MASK 0x0080 /* DACR */
471#define WM8961_DACR_SHIFT 7 /* DACR */
472#define WM8961_DACR_WIDTH 1 /* DACR */
473#define WM8961_LOUT1_PGA 0x0040 /* LOUT1_PGA */
474#define WM8961_LOUT1_PGA_MASK 0x0040 /* LOUT1_PGA */
475#define WM8961_LOUT1_PGA_SHIFT 6 /* LOUT1_PGA */
476#define WM8961_LOUT1_PGA_WIDTH 1 /* LOUT1_PGA */
477#define WM8961_ROUT1_PGA 0x0020 /* ROUT1_PGA */
478#define WM8961_ROUT1_PGA_MASK 0x0020 /* ROUT1_PGA */
479#define WM8961_ROUT1_PGA_SHIFT 5 /* ROUT1_PGA */
480#define WM8961_ROUT1_PGA_WIDTH 1 /* ROUT1_PGA */
481#define WM8961_SPKL_PGA 0x0010 /* SPKL_PGA */
482#define WM8961_SPKL_PGA_MASK 0x0010 /* SPKL_PGA */
483#define WM8961_SPKL_PGA_SHIFT 4 /* SPKL_PGA */
484#define WM8961_SPKL_PGA_WIDTH 1 /* SPKL_PGA */
485#define WM8961_SPKR_PGA 0x0008 /* SPKR_PGA */
486#define WM8961_SPKR_PGA_MASK 0x0008 /* SPKR_PGA */
487#define WM8961_SPKR_PGA_SHIFT 3 /* SPKR_PGA */
488#define WM8961_SPKR_PGA_WIDTH 1 /* SPKR_PGA */
489
490/*
491 * R27 (0x1B) - Additional Control (3)
492 */
493#define WM8961_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
494#define WM8961_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
495#define WM8961_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
496
497/*
498 * R28 (0x1C) - Anti-pop
499 */
500#define WM8961_BUFDCOPEN 0x0010 /* BUFDCOPEN */
501#define WM8961_BUFDCOPEN_MASK 0x0010 /* BUFDCOPEN */
502#define WM8961_BUFDCOPEN_SHIFT 4 /* BUFDCOPEN */
503#define WM8961_BUFDCOPEN_WIDTH 1 /* BUFDCOPEN */
504#define WM8961_BUFIOEN 0x0008 /* BUFIOEN */
505#define WM8961_BUFIOEN_MASK 0x0008 /* BUFIOEN */
506#define WM8961_BUFIOEN_SHIFT 3 /* BUFIOEN */
507#define WM8961_BUFIOEN_WIDTH 1 /* BUFIOEN */
508#define WM8961_SOFT_ST 0x0004 /* SOFT_ST */
509#define WM8961_SOFT_ST_MASK 0x0004 /* SOFT_ST */
510#define WM8961_SOFT_ST_SHIFT 2 /* SOFT_ST */
511#define WM8961_SOFT_ST_WIDTH 1 /* SOFT_ST */
512
513/*
514 * R30 (0x1E) - Clocking 3
515 */
516#define WM8961_CLK_TO_DIV_MASK 0x0180 /* CLK_TO_DIV - [8:7] */
517#define WM8961_CLK_TO_DIV_SHIFT 7 /* CLK_TO_DIV - [8:7] */
518#define WM8961_CLK_TO_DIV_WIDTH 2 /* CLK_TO_DIV - [8:7] */
519#define WM8961_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
520#define WM8961_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
521#define WM8961_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
522#define WM8961_MANUAL_MODE 0x0001 /* MANUAL_MODE */
523#define WM8961_MANUAL_MODE_MASK 0x0001 /* MANUAL_MODE */
524#define WM8961_MANUAL_MODE_SHIFT 0 /* MANUAL_MODE */
525#define WM8961_MANUAL_MODE_WIDTH 1 /* MANUAL_MODE */
526
527/*
528 * R32 (0x20) - ADCL signal path
529 */
530#define WM8961_LMICBOOST_MASK 0x0030 /* LMICBOOST - [5:4] */
531#define WM8961_LMICBOOST_SHIFT 4 /* LMICBOOST - [5:4] */
532#define WM8961_LMICBOOST_WIDTH 2 /* LMICBOOST - [5:4] */
533
534/*
535 * R33 (0x21) - ADCR signal path
536 */
537#define WM8961_RMICBOOST_MASK 0x0030 /* RMICBOOST - [5:4] */
538#define WM8961_RMICBOOST_SHIFT 4 /* RMICBOOST - [5:4] */
539#define WM8961_RMICBOOST_WIDTH 2 /* RMICBOOST - [5:4] */
540
541/*
542 * R40 (0x28) - LOUT2 volume
543 */
544#define WM8961_SPKVU 0x0100 /* SPKVU */
545#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
546#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
547#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
548#define WM8961_SPKLZC 0x0080 /* SPKLZC */
549#define WM8961_SPKLZC_MASK 0x0080 /* SPKLZC */
550#define WM8961_SPKLZC_SHIFT 7 /* SPKLZC */
551#define WM8961_SPKLZC_WIDTH 1 /* SPKLZC */
552#define WM8961_SPKLVOL_MASK 0x007F /* SPKLVOL - [6:0] */
553#define WM8961_SPKLVOL_SHIFT 0 /* SPKLVOL - [6:0] */
554#define WM8961_SPKLVOL_WIDTH 7 /* SPKLVOL - [6:0] */
555
556/*
557 * R41 (0x29) - ROUT2 volume
558 */
559#define WM8961_SPKVU 0x0100 /* SPKVU */
560#define WM8961_SPKVU_MASK 0x0100 /* SPKVU */
561#define WM8961_SPKVU_SHIFT 8 /* SPKVU */
562#define WM8961_SPKVU_WIDTH 1 /* SPKVU */
563#define WM8961_SPKRZC 0x0080 /* SPKRZC */
564#define WM8961_SPKRZC_MASK 0x0080 /* SPKRZC */
565#define WM8961_SPKRZC_SHIFT 7 /* SPKRZC */
566#define WM8961_SPKRZC_WIDTH 1 /* SPKRZC */
567#define WM8961_SPKRVOL_MASK 0x007F /* SPKRVOL - [6:0] */
568#define WM8961_SPKRVOL_SHIFT 0 /* SPKRVOL - [6:0] */
569#define WM8961_SPKRVOL_WIDTH 7 /* SPKRVOL - [6:0] */
570
571/*
572 * R47 (0x2F) - Pwr Mgmt (3)
573 */
574#define WM8961_TEMP_SHUT 0x0002 /* TEMP_SHUT */
575#define WM8961_TEMP_SHUT_MASK 0x0002 /* TEMP_SHUT */
576#define WM8961_TEMP_SHUT_SHIFT 1 /* TEMP_SHUT */
577#define WM8961_TEMP_SHUT_WIDTH 1 /* TEMP_SHUT */
578#define WM8961_TEMP_WARN 0x0001 /* TEMP_WARN */
579#define WM8961_TEMP_WARN_MASK 0x0001 /* TEMP_WARN */
580#define WM8961_TEMP_WARN_SHIFT 0 /* TEMP_WARN */
581#define WM8961_TEMP_WARN_WIDTH 1 /* TEMP_WARN */
582
583/*
584 * R48 (0x30) - Additional Control (4)
585 */
586#define WM8961_TSENSEN 0x0002 /* TSENSEN */
587#define WM8961_TSENSEN_MASK 0x0002 /* TSENSEN */
588#define WM8961_TSENSEN_SHIFT 1 /* TSENSEN */
589#define WM8961_TSENSEN_WIDTH 1 /* TSENSEN */
590#define WM8961_MBSEL 0x0001 /* MBSEL */
591#define WM8961_MBSEL_MASK 0x0001 /* MBSEL */
592#define WM8961_MBSEL_SHIFT 0 /* MBSEL */
593#define WM8961_MBSEL_WIDTH 1 /* MBSEL */
594
595/*
596 * R49 (0x31) - Class D Control 1
597 */
598#define WM8961_SPKR_ENA 0x0080 /* SPKR_ENA */
599#define WM8961_SPKR_ENA_MASK 0x0080 /* SPKR_ENA */
600#define WM8961_SPKR_ENA_SHIFT 7 /* SPKR_ENA */
601#define WM8961_SPKR_ENA_WIDTH 1 /* SPKR_ENA */
602#define WM8961_SPKL_ENA 0x0040 /* SPKL_ENA */
603#define WM8961_SPKL_ENA_MASK 0x0040 /* SPKL_ENA */
604#define WM8961_SPKL_ENA_SHIFT 6 /* SPKL_ENA */
605#define WM8961_SPKL_ENA_WIDTH 1 /* SPKL_ENA */
606
607/*
608 * R51 (0x33) - Class D Control 2
609 */
610#define WM8961_CLASSD_ACGAIN_MASK 0x0007 /* CLASSD_ACGAIN - [2:0] */
611#define WM8961_CLASSD_ACGAIN_SHIFT 0 /* CLASSD_ACGAIN - [2:0] */
612#define WM8961_CLASSD_ACGAIN_WIDTH 3 /* CLASSD_ACGAIN - [2:0] */
613
614/*
615 * R56 (0x38) - Clocking 4
616 */
617#define WM8961_CLK_DCS_DIV_MASK 0x01E0 /* CLK_DCS_DIV - [8:5] */
618#define WM8961_CLK_DCS_DIV_SHIFT 5 /* CLK_DCS_DIV - [8:5] */
619#define WM8961_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [8:5] */
620#define WM8961_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
621#define WM8961_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
622#define WM8961_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
623
624/*
625 * R57 (0x39) - DSP Sidetone 0
626 */
627#define WM8961_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
628#define WM8961_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
629#define WM8961_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
630#define WM8961_ADC_TO_DACR_MASK 0x000C /* ADC_TO_DACR - [3:2] */
631#define WM8961_ADC_TO_DACR_SHIFT 2 /* ADC_TO_DACR - [3:2] */
632#define WM8961_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [3:2] */
633
634/*
635 * R58 (0x3A) - DSP Sidetone 1
636 */
637#define WM8961_ADCL_DAC_SVOL_MASK 0x00F0 /* ADCL_DAC_SVOL - [7:4] */
638#define WM8961_ADCL_DAC_SVOL_SHIFT 4 /* ADCL_DAC_SVOL - [7:4] */
639#define WM8961_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [7:4] */
640#define WM8961_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
641#define WM8961_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
642#define WM8961_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
643
644/*
645 * R60 (0x3C) - DC Servo 0
646 */
647#define WM8961_DCS_ENA_CHAN_INL 0x0080 /* DCS_ENA_CHAN_INL */
648#define WM8961_DCS_ENA_CHAN_INL_MASK 0x0080 /* DCS_ENA_CHAN_INL */
649#define WM8961_DCS_ENA_CHAN_INL_SHIFT 7 /* DCS_ENA_CHAN_INL */
650#define WM8961_DCS_ENA_CHAN_INL_WIDTH 1 /* DCS_ENA_CHAN_INL */
651#define WM8961_DCS_TRIG_STARTUP_INL 0x0040 /* DCS_TRIG_STARTUP_INL */
652#define WM8961_DCS_TRIG_STARTUP_INL_MASK 0x0040 /* DCS_TRIG_STARTUP_INL */
653#define WM8961_DCS_TRIG_STARTUP_INL_SHIFT 6 /* DCS_TRIG_STARTUP_INL */
654#define WM8961_DCS_TRIG_STARTUP_INL_WIDTH 1 /* DCS_TRIG_STARTUP_INL */
655#define WM8961_DCS_TRIG_SERIES_INL 0x0010 /* DCS_TRIG_SERIES_INL */
656#define WM8961_DCS_TRIG_SERIES_INL_MASK 0x0010 /* DCS_TRIG_SERIES_INL */
657#define WM8961_DCS_TRIG_SERIES_INL_SHIFT 4 /* DCS_TRIG_SERIES_INL */
658#define WM8961_DCS_TRIG_SERIES_INL_WIDTH 1 /* DCS_TRIG_SERIES_INL */
659#define WM8961_DCS_ENA_CHAN_INR 0x0008 /* DCS_ENA_CHAN_INR */
660#define WM8961_DCS_ENA_CHAN_INR_MASK 0x0008 /* DCS_ENA_CHAN_INR */
661#define WM8961_DCS_ENA_CHAN_INR_SHIFT 3 /* DCS_ENA_CHAN_INR */
662#define WM8961_DCS_ENA_CHAN_INR_WIDTH 1 /* DCS_ENA_CHAN_INR */
663#define WM8961_DCS_TRIG_STARTUP_INR 0x0004 /* DCS_TRIG_STARTUP_INR */
664#define WM8961_DCS_TRIG_STARTUP_INR_MASK 0x0004 /* DCS_TRIG_STARTUP_INR */
665#define WM8961_DCS_TRIG_STARTUP_INR_SHIFT 2 /* DCS_TRIG_STARTUP_INR */
666#define WM8961_DCS_TRIG_STARTUP_INR_WIDTH 1 /* DCS_TRIG_STARTUP_INR */
667#define WM8961_DCS_TRIG_SERIES_INR 0x0001 /* DCS_TRIG_SERIES_INR */
668#define WM8961_DCS_TRIG_SERIES_INR_MASK 0x0001 /* DCS_TRIG_SERIES_INR */
669#define WM8961_DCS_TRIG_SERIES_INR_SHIFT 0 /* DCS_TRIG_SERIES_INR */
670#define WM8961_DCS_TRIG_SERIES_INR_WIDTH 1 /* DCS_TRIG_SERIES_INR */
671
672/*
673 * R61 (0x3D) - DC Servo 1
674 */
675#define WM8961_DCS_ENA_CHAN_HPL 0x0080 /* DCS_ENA_CHAN_HPL */
676#define WM8961_DCS_ENA_CHAN_HPL_MASK 0x0080 /* DCS_ENA_CHAN_HPL */
677#define WM8961_DCS_ENA_CHAN_HPL_SHIFT 7 /* DCS_ENA_CHAN_HPL */
678#define WM8961_DCS_ENA_CHAN_HPL_WIDTH 1 /* DCS_ENA_CHAN_HPL */
679#define WM8961_DCS_TRIG_STARTUP_HPL 0x0040 /* DCS_TRIG_STARTUP_HPL */
680#define WM8961_DCS_TRIG_STARTUP_HPL_MASK 0x0040 /* DCS_TRIG_STARTUP_HPL */
681#define WM8961_DCS_TRIG_STARTUP_HPL_SHIFT 6 /* DCS_TRIG_STARTUP_HPL */
682#define WM8961_DCS_TRIG_STARTUP_HPL_WIDTH 1 /* DCS_TRIG_STARTUP_HPL */
683#define WM8961_DCS_TRIG_SERIES_HPL 0x0010 /* DCS_TRIG_SERIES_HPL */
684#define WM8961_DCS_TRIG_SERIES_HPL_MASK 0x0010 /* DCS_TRIG_SERIES_HPL */
685#define WM8961_DCS_TRIG_SERIES_HPL_SHIFT 4 /* DCS_TRIG_SERIES_HPL */
686#define WM8961_DCS_TRIG_SERIES_HPL_WIDTH 1 /* DCS_TRIG_SERIES_HPL */
687#define WM8961_DCS_ENA_CHAN_HPR 0x0008 /* DCS_ENA_CHAN_HPR */
688#define WM8961_DCS_ENA_CHAN_HPR_MASK 0x0008 /* DCS_ENA_CHAN_HPR */
689#define WM8961_DCS_ENA_CHAN_HPR_SHIFT 3 /* DCS_ENA_CHAN_HPR */
690#define WM8961_DCS_ENA_CHAN_HPR_WIDTH 1 /* DCS_ENA_CHAN_HPR */
691#define WM8961_DCS_TRIG_STARTUP_HPR 0x0004 /* DCS_TRIG_STARTUP_HPR */
692#define WM8961_DCS_TRIG_STARTUP_HPR_MASK 0x0004 /* DCS_TRIG_STARTUP_HPR */
693#define WM8961_DCS_TRIG_STARTUP_HPR_SHIFT 2 /* DCS_TRIG_STARTUP_HPR */
694#define WM8961_DCS_TRIG_STARTUP_HPR_WIDTH 1 /* DCS_TRIG_STARTUP_HPR */
695#define WM8961_DCS_TRIG_SERIES_HPR 0x0001 /* DCS_TRIG_SERIES_HPR */
696#define WM8961_DCS_TRIG_SERIES_HPR_MASK 0x0001 /* DCS_TRIG_SERIES_HPR */
697#define WM8961_DCS_TRIG_SERIES_HPR_SHIFT 0 /* DCS_TRIG_SERIES_HPR */
698#define WM8961_DCS_TRIG_SERIES_HPR_WIDTH 1 /* DCS_TRIG_SERIES_HPR */
699
700/*
701 * R63 (0x3F) - DC Servo 3
702 */
703#define WM8961_DCS_FILT_BW_SERIES_MASK 0x0030 /* DCS_FILT_BW_SERIES - [5:4] */
704#define WM8961_DCS_FILT_BW_SERIES_SHIFT 4 /* DCS_FILT_BW_SERIES - [5:4] */
705#define WM8961_DCS_FILT_BW_SERIES_WIDTH 2 /* DCS_FILT_BW_SERIES - [5:4] */
706
707/*
708 * R65 (0x41) - DC Servo 5
709 */
710#define WM8961_DCS_SERIES_NO_HP_MASK 0x007F /* DCS_SERIES_NO_HP - [6:0] */
711#define WM8961_DCS_SERIES_NO_HP_SHIFT 0 /* DCS_SERIES_NO_HP - [6:0] */
712#define WM8961_DCS_SERIES_NO_HP_WIDTH 7 /* DCS_SERIES_NO_HP - [6:0] */
713
714/*
715 * R68 (0x44) - Analogue PGA Bias
716 */
717#define WM8961_HP_PGAS_BIAS_MASK 0x0007 /* HP_PGAS_BIAS - [2:0] */
718#define WM8961_HP_PGAS_BIAS_SHIFT 0 /* HP_PGAS_BIAS - [2:0] */
719#define WM8961_HP_PGAS_BIAS_WIDTH 3 /* HP_PGAS_BIAS - [2:0] */
720
721/*
722 * R69 (0x45) - Analogue HP 0
723 */
724#define WM8961_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
725#define WM8961_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
726#define WM8961_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
727#define WM8961_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
728#define WM8961_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
729#define WM8961_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
730#define WM8961_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
731#define WM8961_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
732#define WM8961_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
733#define WM8961_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
734#define WM8961_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
735#define WM8961_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
736#define WM8961_HPL_ENA 0x0010 /* HPL_ENA */
737#define WM8961_HPL_ENA_MASK 0x0010 /* HPL_ENA */
738#define WM8961_HPL_ENA_SHIFT 4 /* HPL_ENA */
739#define WM8961_HPL_ENA_WIDTH 1 /* HPL_ENA */
740#define WM8961_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
741#define WM8961_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
742#define WM8961_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
743#define WM8961_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
744#define WM8961_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
745#define WM8961_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
746#define WM8961_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
747#define WM8961_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
748#define WM8961_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
749#define WM8961_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
750#define WM8961_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
751#define WM8961_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
752#define WM8961_HPR_ENA 0x0001 /* HPR_ENA */
753#define WM8961_HPR_ENA_MASK 0x0001 /* HPR_ENA */
754#define WM8961_HPR_ENA_SHIFT 0 /* HPR_ENA */
755#define WM8961_HPR_ENA_WIDTH 1 /* HPR_ENA */
756
757/*
758 * R71 (0x47) - Analogue HP 2
759 */
760#define WM8961_HPL_VOL_MASK 0x01C0 /* HPL_VOL - [8:6] */
761#define WM8961_HPL_VOL_SHIFT 6 /* HPL_VOL - [8:6] */
762#define WM8961_HPL_VOL_WIDTH 3 /* HPL_VOL - [8:6] */
763#define WM8961_HPR_VOL_MASK 0x0038 /* HPR_VOL - [5:3] */
764#define WM8961_HPR_VOL_SHIFT 3 /* HPR_VOL - [5:3] */
765#define WM8961_HPR_VOL_WIDTH 3 /* HPR_VOL - [5:3] */
766#define WM8961_HP_BIAS_BOOST_MASK 0x0007 /* HP_BIAS_BOOST - [2:0] */
767#define WM8961_HP_BIAS_BOOST_SHIFT 0 /* HP_BIAS_BOOST - [2:0] */
768#define WM8961_HP_BIAS_BOOST_WIDTH 3 /* HP_BIAS_BOOST - [2:0] */
769
770/*
771 * R72 (0x48) - Charge Pump 1
772 */
773#define WM8961_CP_ENA 0x0001 /* CP_ENA */
774#define WM8961_CP_ENA_MASK 0x0001 /* CP_ENA */
775#define WM8961_CP_ENA_SHIFT 0 /* CP_ENA */
776#define WM8961_CP_ENA_WIDTH 1 /* CP_ENA */
777
778/*
779 * R82 (0x52) - Charge Pump B
780 */
781#define WM8961_CP_DYN_PWR_MASK 0x0003 /* CP_DYN_PWR - [1:0] */
782#define WM8961_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR - [1:0] */
783#define WM8961_CP_DYN_PWR_WIDTH 2 /* CP_DYN_PWR - [1:0] */
784
785/*
786 * R87 (0x57) - Write Sequencer 1
787 */
788#define WM8961_WSEQ_ENA 0x0020 /* WSEQ_ENA */
789#define WM8961_WSEQ_ENA_MASK 0x0020 /* WSEQ_ENA */
790#define WM8961_WSEQ_ENA_SHIFT 5 /* WSEQ_ENA */
791#define WM8961_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
792#define WM8961_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
793#define WM8961_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
794#define WM8961_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
795
796/*
797 * R88 (0x58) - Write Sequencer 2
798 */
799#define WM8961_WSEQ_EOS 0x0100 /* WSEQ_EOS */
800#define WM8961_WSEQ_EOS_MASK 0x0100 /* WSEQ_EOS */
801#define WM8961_WSEQ_EOS_SHIFT 8 /* WSEQ_EOS */
802#define WM8961_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
803#define WM8961_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
804#define WM8961_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
805#define WM8961_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
806
807/*
808 * R89 (0x59) - Write Sequencer 3
809 */
810#define WM8961_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
811#define WM8961_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
812#define WM8961_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
813
814/*
815 * R90 (0x5A) - Write Sequencer 4
816 */
817#define WM8961_WSEQ_ABORT 0x0100 /* WSEQ_ABORT */
818#define WM8961_WSEQ_ABORT_MASK 0x0100 /* WSEQ_ABORT */
819#define WM8961_WSEQ_ABORT_SHIFT 8 /* WSEQ_ABORT */
820#define WM8961_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
821#define WM8961_WSEQ_START 0x0080 /* WSEQ_START */
822#define WM8961_WSEQ_START_MASK 0x0080 /* WSEQ_START */
823#define WM8961_WSEQ_START_SHIFT 7 /* WSEQ_START */
824#define WM8961_WSEQ_START_WIDTH 1 /* WSEQ_START */
825#define WM8961_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
826#define WM8961_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
827#define WM8961_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
828
829/*
830 * R91 (0x5B) - Write Sequencer 5
831 */
832#define WM8961_WSEQ_DATA_WIDTH_MASK 0x0070 /* WSEQ_DATA_WIDTH - [6:4] */
833#define WM8961_WSEQ_DATA_WIDTH_SHIFT 4 /* WSEQ_DATA_WIDTH - [6:4] */
834#define WM8961_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [6:4] */
835#define WM8961_WSEQ_DATA_START_MASK 0x000F /* WSEQ_DATA_START - [3:0] */
836#define WM8961_WSEQ_DATA_START_SHIFT 0 /* WSEQ_DATA_START - [3:0] */
837#define WM8961_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [3:0] */
838
839/*
840 * R92 (0x5C) - Write Sequencer 6
841 */
842#define WM8961_WSEQ_DELAY_MASK 0x000F /* WSEQ_DELAY - [3:0] */
843#define WM8961_WSEQ_DELAY_SHIFT 0 /* WSEQ_DELAY - [3:0] */
844#define WM8961_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [3:0] */
845
846/*
847 * R93 (0x5D) - Write Sequencer 7
848 */
849#define WM8961_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
850#define WM8961_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
851#define WM8961_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
852#define WM8961_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
853
854/*
855 * R252 (0xFC) - General test 1
856 */
857#define WM8961_ARA_ENA 0x0002 /* ARA_ENA */
858#define WM8961_ARA_ENA_MASK 0x0002 /* ARA_ENA */
859#define WM8961_ARA_ENA_SHIFT 1 /* ARA_ENA */
860#define WM8961_ARA_ENA_WIDTH 1 /* ARA_ENA */
861#define WM8961_AUTO_INC 0x0001 /* AUTO_INC */
862#define WM8961_AUTO_INC_MASK 0x0001 /* AUTO_INC */
863#define WM8961_AUTO_INC_SHIFT 0 /* AUTO_INC */
864#define WM8961_AUTO_INC_WIDTH 1 /* AUTO_INC */
865
866#endif
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 032dca22dbd3..d66efb0546ea 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -59,44 +59,7 @@ static const u16 wm8971_reg[] = {
59 0x0079, 0x0079, 0x0079, /* 40 */ 59 0x0079, 0x0079, 0x0079, /* 40 */
60}; 60};
61 61
62static inline unsigned int wm8971_read_reg_cache(struct snd_soc_codec *codec, 62#define wm8971_reset(c) snd_soc_write(c, WM8971_RESET, 0)
63 unsigned int reg)
64{
65 u16 *cache = codec->reg_cache;
66 if (reg < WM8971_REG_COUNT)
67 return cache[reg];
68
69 return -1;
70}
71
72static inline void wm8971_write_reg_cache(struct snd_soc_codec *codec,
73 unsigned int reg, unsigned int value)
74{
75 u16 *cache = codec->reg_cache;
76 if (reg < WM8971_REG_COUNT)
77 cache[reg] = value;
78}
79
80static int wm8971_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 data[2];
84
85 /* data is
86 * D15..D9 WM8753 register offset
87 * D8...D0 register data
88 */
89 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
90 data[1] = value & 0x00ff;
91
92 wm8971_write_reg_cache (codec, reg, value);
93 if (codec->hw_write(codec->control_data, data, 2) == 2)
94 return 0;
95 else
96 return -EIO;
97}
98
99#define wm8971_reset(c) wm8971_write(c, WM8971_RESET, 0)
100 63
101/* WM8971 Controls */ 64/* WM8971 Controls */
102static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" }; 65static const char *wm8971_bass[] = { "Linear Control", "Adaptive Boost" };
@@ -521,7 +484,7 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
521 return -EINVAL; 484 return -EINVAL;
522 } 485 }
523 486
524 wm8971_write(codec, WM8971_IFACE, iface); 487 snd_soc_write(codec, WM8971_IFACE, iface);
525 return 0; 488 return 0;
526} 489}
527 490
@@ -533,8 +496,8 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
533 struct snd_soc_device *socdev = rtd->socdev; 496 struct snd_soc_device *socdev = rtd->socdev;
534 struct snd_soc_codec *codec = socdev->card->codec; 497 struct snd_soc_codec *codec = socdev->card->codec;
535 struct wm8971_priv *wm8971 = codec->private_data; 498 struct wm8971_priv *wm8971 = codec->private_data;
536 u16 iface = wm8971_read_reg_cache(codec, WM8971_IFACE) & 0x1f3; 499 u16 iface = snd_soc_read(codec, WM8971_IFACE) & 0x1f3;
537 u16 srate = wm8971_read_reg_cache(codec, WM8971_SRATE) & 0x1c0; 500 u16 srate = snd_soc_read(codec, WM8971_SRATE) & 0x1c0;
538 int coeff = get_coeff(wm8971->sysclk, params_rate(params)); 501 int coeff = get_coeff(wm8971->sysclk, params_rate(params));
539 502
540 /* bit size */ 503 /* bit size */
@@ -553,9 +516,9 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
553 } 516 }
554 517
555 /* set iface & srate */ 518 /* set iface & srate */
556 wm8971_write(codec, WM8971_IFACE, iface); 519 snd_soc_write(codec, WM8971_IFACE, iface);
557 if (coeff >= 0) 520 if (coeff >= 0)
558 wm8971_write(codec, WM8971_SRATE, srate | 521 snd_soc_write(codec, WM8971_SRATE, srate |
559 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 522 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
560 523
561 return 0; 524 return 0;
@@ -564,33 +527,33 @@ static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
564static int wm8971_mute(struct snd_soc_dai *dai, int mute) 527static int wm8971_mute(struct snd_soc_dai *dai, int mute)
565{ 528{
566 struct snd_soc_codec *codec = dai->codec; 529 struct snd_soc_codec *codec = dai->codec;
567 u16 mute_reg = wm8971_read_reg_cache(codec, WM8971_ADCDAC) & 0xfff7; 530 u16 mute_reg = snd_soc_read(codec, WM8971_ADCDAC) & 0xfff7;
568 531
569 if (mute) 532 if (mute)
570 wm8971_write(codec, WM8971_ADCDAC, mute_reg | 0x8); 533 snd_soc_write(codec, WM8971_ADCDAC, mute_reg | 0x8);
571 else 534 else
572 wm8971_write(codec, WM8971_ADCDAC, mute_reg); 535 snd_soc_write(codec, WM8971_ADCDAC, mute_reg);
573 return 0; 536 return 0;
574} 537}
575 538
576static int wm8971_set_bias_level(struct snd_soc_codec *codec, 539static int wm8971_set_bias_level(struct snd_soc_codec *codec,
577 enum snd_soc_bias_level level) 540 enum snd_soc_bias_level level)
578{ 541{
579 u16 pwr_reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 542 u16 pwr_reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
580 543
581 switch (level) { 544 switch (level) {
582 case SND_SOC_BIAS_ON: 545 case SND_SOC_BIAS_ON:
583 /* set vmid to 50k and unmute dac */ 546 /* set vmid to 50k and unmute dac */
584 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x00c1); 547 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x00c1);
585 break; 548 break;
586 case SND_SOC_BIAS_PREPARE: 549 case SND_SOC_BIAS_PREPARE:
587 break; 550 break;
588 case SND_SOC_BIAS_STANDBY: 551 case SND_SOC_BIAS_STANDBY:
589 /* mute dac and set vmid to 500k, enable VREF */ 552 /* mute dac and set vmid to 500k, enable VREF */
590 wm8971_write(codec, WM8971_PWR1, pwr_reg | 0x0140); 553 snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140);
591 break; 554 break;
592 case SND_SOC_BIAS_OFF: 555 case SND_SOC_BIAS_OFF:
593 wm8971_write(codec, WM8971_PWR1, 0x0001); 556 snd_soc_write(codec, WM8971_PWR1, 0x0001);
594 break; 557 break;
595 } 558 }
596 codec->bias_level = level; 559 codec->bias_level = level;
@@ -667,8 +630,8 @@ static int wm8971_resume(struct platform_device *pdev)
667 630
668 /* charge wm8971 caps */ 631 /* charge wm8971 caps */
669 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 632 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) {
670 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 633 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
671 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0); 634 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
672 codec->bias_level = SND_SOC_BIAS_ON; 635 codec->bias_level = SND_SOC_BIAS_ON;
673 queue_delayed_work(wm8971_workq, &codec->delayed_work, 636 queue_delayed_work(wm8971_workq, &codec->delayed_work,
674 msecs_to_jiffies(1000)); 637 msecs_to_jiffies(1000));
@@ -677,15 +640,14 @@ static int wm8971_resume(struct platform_device *pdev)
677 return 0; 640 return 0;
678} 641}
679 642
680static int wm8971_init(struct snd_soc_device *socdev) 643static int wm8971_init(struct snd_soc_device *socdev,
644 enum snd_soc_control_type control)
681{ 645{
682 struct snd_soc_codec *codec = socdev->card->codec; 646 struct snd_soc_codec *codec = socdev->card->codec;
683 int reg, ret = 0; 647 int reg, ret = 0;
684 648
685 codec->name = "WM8971"; 649 codec->name = "WM8971";
686 codec->owner = THIS_MODULE; 650 codec->owner = THIS_MODULE;
687 codec->read = wm8971_read_reg_cache;
688 codec->write = wm8971_write;
689 codec->set_bias_level = wm8971_set_bias_level; 651 codec->set_bias_level = wm8971_set_bias_level;
690 codec->dai = &wm8971_dai; 652 codec->dai = &wm8971_dai;
691 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg); 653 codec->reg_cache_size = ARRAY_SIZE(wm8971_reg);
@@ -695,42 +657,48 @@ static int wm8971_init(struct snd_soc_device *socdev)
695 if (codec->reg_cache == NULL) 657 if (codec->reg_cache == NULL)
696 return -ENOMEM; 658 return -ENOMEM;
697 659
660 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
661 if (ret < 0) {
662 printk(KERN_ERR "wm8971: failed to set cache I/O: %d\n", ret);
663 goto err;
664 }
665
698 wm8971_reset(codec); 666 wm8971_reset(codec);
699 667
700 /* register pcms */ 668 /* register pcms */
701 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 669 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
702 if (ret < 0) { 670 if (ret < 0) {
703 printk(KERN_ERR "wm8971: failed to create pcms\n"); 671 printk(KERN_ERR "wm8971: failed to create pcms\n");
704 goto pcm_err; 672 goto err;
705 } 673 }
706 674
707 /* charge output caps - set vmid to 5k for quick power up */ 675 /* charge output caps - set vmid to 5k for quick power up */
708 reg = wm8971_read_reg_cache(codec, WM8971_PWR1) & 0xfe3e; 676 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
709 wm8971_write(codec, WM8971_PWR1, reg | 0x01c0); 677 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
710 codec->bias_level = SND_SOC_BIAS_STANDBY; 678 codec->bias_level = SND_SOC_BIAS_STANDBY;
711 queue_delayed_work(wm8971_workq, &codec->delayed_work, 679 queue_delayed_work(wm8971_workq, &codec->delayed_work,
712 msecs_to_jiffies(1000)); 680 msecs_to_jiffies(1000));
713 681
714 /* set the update bits */ 682 /* set the update bits */
715 reg = wm8971_read_reg_cache(codec, WM8971_LDAC); 683 reg = snd_soc_read(codec, WM8971_LDAC);
716 wm8971_write(codec, WM8971_LDAC, reg | 0x0100); 684 snd_soc_write(codec, WM8971_LDAC, reg | 0x0100);
717 reg = wm8971_read_reg_cache(codec, WM8971_RDAC); 685 reg = snd_soc_read(codec, WM8971_RDAC);
718 wm8971_write(codec, WM8971_RDAC, reg | 0x0100); 686 snd_soc_write(codec, WM8971_RDAC, reg | 0x0100);
719 687
720 reg = wm8971_read_reg_cache(codec, WM8971_LOUT1V); 688 reg = snd_soc_read(codec, WM8971_LOUT1V);
721 wm8971_write(codec, WM8971_LOUT1V, reg | 0x0100); 689 snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100);
722 reg = wm8971_read_reg_cache(codec, WM8971_ROUT1V); 690 reg = snd_soc_read(codec, WM8971_ROUT1V);
723 wm8971_write(codec, WM8971_ROUT1V, reg | 0x0100); 691 snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100);
724 692
725 reg = wm8971_read_reg_cache(codec, WM8971_LOUT2V); 693 reg = snd_soc_read(codec, WM8971_LOUT2V);
726 wm8971_write(codec, WM8971_LOUT2V, reg | 0x0100); 694 snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100);
727 reg = wm8971_read_reg_cache(codec, WM8971_ROUT2V); 695 reg = snd_soc_read(codec, WM8971_ROUT2V);
728 wm8971_write(codec, WM8971_ROUT2V, reg | 0x0100); 696 snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100);
729 697
730 reg = wm8971_read_reg_cache(codec, WM8971_LINVOL); 698 reg = snd_soc_read(codec, WM8971_LINVOL);
731 wm8971_write(codec, WM8971_LINVOL, reg | 0x0100); 699 snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100);
732 reg = wm8971_read_reg_cache(codec, WM8971_RINVOL); 700 reg = snd_soc_read(codec, WM8971_RINVOL);
733 wm8971_write(codec, WM8971_RINVOL, reg | 0x0100); 701 snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100);
734 702
735 snd_soc_add_controls(codec, wm8971_snd_controls, 703 snd_soc_add_controls(codec, wm8971_snd_controls,
736 ARRAY_SIZE(wm8971_snd_controls)); 704 ARRAY_SIZE(wm8971_snd_controls));
@@ -745,7 +713,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
745card_err: 713card_err:
746 snd_soc_free_pcms(socdev); 714 snd_soc_free_pcms(socdev);
747 snd_soc_dapm_free(socdev); 715 snd_soc_dapm_free(socdev);
748pcm_err: 716err:
749 kfree(codec->reg_cache); 717 kfree(codec->reg_cache);
750 return ret; 718 return ret;
751} 719}
@@ -767,7 +735,7 @@ static int wm8971_i2c_probe(struct i2c_client *i2c,
767 735
768 codec->control_data = i2c; 736 codec->control_data = i2c;
769 737
770 ret = wm8971_init(socdev); 738 ret = wm8971_init(socdev, SND_SOC_I2C);
771 if (ret < 0) 739 if (ret < 0)
772 pr_err("failed to initialise WM8971\n"); 740 pr_err("failed to initialise WM8971\n");
773 741
@@ -877,7 +845,6 @@ static int wm8971_probe(struct platform_device *pdev)
877 845
878#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE) 846#if defined (CONFIG_I2C) || defined (CONFIG_I2C_MODULE)
879 if (setup->i2c_address) { 847 if (setup->i2c_address) {
880 codec->hw_write = (hw_write_t)i2c_master_send;
881 ret = wm8971_add_i2c_device(pdev, setup); 848 ret = wm8971_add_i2c_device(pdev, setup);
882 } 849 }
883#endif 850#endif
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
new file mode 100644
index 000000000000..d8a013ab3177
--- /dev/null
+++ b/sound/soc/codecs/wm8974.c
@@ -0,0 +1,808 @@
1/*
2 * wm8974.c -- WM8974 ALSA Soc Audio driver
3 *
4 * Copyright 2006-2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood <linux@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/version.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "wm8974.h"
31
32static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
33 0x0000, 0x0000, 0x0000, 0x0000,
34 0x0050, 0x0000, 0x0140, 0x0000,
35 0x0000, 0x0000, 0x0000, 0x00ff,
36 0x0000, 0x0000, 0x0100, 0x00ff,
37 0x0000, 0x0000, 0x012c, 0x002c,
38 0x002c, 0x002c, 0x002c, 0x0000,
39 0x0032, 0x0000, 0x0000, 0x0000,
40 0x0000, 0x0000, 0x0000, 0x0000,
41 0x0038, 0x000b, 0x0032, 0x0000,
42 0x0008, 0x000c, 0x0093, 0x00e9,
43 0x0000, 0x0000, 0x0000, 0x0000,
44 0x0003, 0x0010, 0x0000, 0x0000,
45 0x0000, 0x0002, 0x0000, 0x0000,
46 0x0000, 0x0000, 0x0039, 0x0000,
47 0x0000,
48};
49
50#define WM8974_POWER1_BIASEN 0x08
51#define WM8974_POWER1_BUFIOEN 0x10
52
53struct wm8974_priv {
54 struct snd_soc_codec codec;
55 u16 reg_cache[WM8974_CACHEREGNUM];
56};
57
58static struct snd_soc_codec *wm8974_codec;
59
60#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
61
62static const char *wm8974_companding[] = {"Off", "NC", "u-law", "A-law" };
63static const char *wm8974_deemp[] = {"None", "32kHz", "44.1kHz", "48kHz" };
64static const char *wm8974_eqmode[] = {"Capture", "Playback" };
65static const char *wm8974_bw[] = {"Narrow", "Wide" };
66static const char *wm8974_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz" };
67static const char *wm8974_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz" };
68static const char *wm8974_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz" };
69static const char *wm8974_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz" };
70static const char *wm8974_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz" };
71static const char *wm8974_alc[] = {"ALC", "Limiter" };
72
73static const struct soc_enum wm8974_enum[] = {
74 SOC_ENUM_SINGLE(WM8974_COMP, 1, 4, wm8974_companding), /* adc */
75 SOC_ENUM_SINGLE(WM8974_COMP, 3, 4, wm8974_companding), /* dac */
76 SOC_ENUM_SINGLE(WM8974_DAC, 4, 4, wm8974_deemp),
77 SOC_ENUM_SINGLE(WM8974_EQ1, 8, 2, wm8974_eqmode),
78
79 SOC_ENUM_SINGLE(WM8974_EQ1, 5, 4, wm8974_eq1),
80 SOC_ENUM_SINGLE(WM8974_EQ2, 8, 2, wm8974_bw),
81 SOC_ENUM_SINGLE(WM8974_EQ2, 5, 4, wm8974_eq2),
82 SOC_ENUM_SINGLE(WM8974_EQ3, 8, 2, wm8974_bw),
83
84 SOC_ENUM_SINGLE(WM8974_EQ3, 5, 4, wm8974_eq3),
85 SOC_ENUM_SINGLE(WM8974_EQ4, 8, 2, wm8974_bw),
86 SOC_ENUM_SINGLE(WM8974_EQ4, 5, 4, wm8974_eq4),
87 SOC_ENUM_SINGLE(WM8974_EQ5, 8, 2, wm8974_bw),
88
89 SOC_ENUM_SINGLE(WM8974_EQ5, 5, 4, wm8974_eq5),
90 SOC_ENUM_SINGLE(WM8974_ALC3, 8, 2, wm8974_alc),
91};
92
93static const char *wm8974_auxmode_text[] = { "Buffer", "Mixer" };
94
95static const struct soc_enum wm8974_auxmode =
96 SOC_ENUM_SINGLE(WM8974_INPUT, 3, 2, wm8974_auxmode_text);
97
98static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
99static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
100static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
101static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
102
103static const struct snd_kcontrol_new wm8974_snd_controls[] = {
104
105SOC_SINGLE("Digital Loopback Switch", WM8974_COMP, 0, 1, 0),
106
107SOC_ENUM("DAC Companding", wm8974_enum[1]),
108SOC_ENUM("ADC Companding", wm8974_enum[0]),
109
110SOC_ENUM("Playback De-emphasis", wm8974_enum[2]),
111SOC_SINGLE("DAC Inversion Switch", WM8974_DAC, 0, 1, 0),
112
113SOC_SINGLE_TLV("PCM Volume", WM8974_DACVOL, 0, 255, 0, digital_tlv),
114
115SOC_SINGLE("High Pass Filter Switch", WM8974_ADC, 8, 1, 0),
116SOC_SINGLE("High Pass Cut Off", WM8974_ADC, 4, 7, 0),
117SOC_SINGLE("ADC Inversion Switch", WM8974_ADC, 0, 1, 0),
118
119SOC_SINGLE_TLV("Capture Volume", WM8974_ADCVOL, 0, 255, 0, digital_tlv),
120
121SOC_ENUM("Equaliser Function", wm8974_enum[3]),
122SOC_ENUM("EQ1 Cut Off", wm8974_enum[4]),
123SOC_SINGLE_TLV("EQ1 Volume", WM8974_EQ1, 0, 24, 1, eq_tlv),
124
125SOC_ENUM("Equaliser EQ2 Bandwith", wm8974_enum[5]),
126SOC_ENUM("EQ2 Cut Off", wm8974_enum[6]),
127SOC_SINGLE_TLV("EQ2 Volume", WM8974_EQ2, 0, 24, 1, eq_tlv),
128
129SOC_ENUM("Equaliser EQ3 Bandwith", wm8974_enum[7]),
130SOC_ENUM("EQ3 Cut Off", wm8974_enum[8]),
131SOC_SINGLE_TLV("EQ3 Volume", WM8974_EQ3, 0, 24, 1, eq_tlv),
132
133SOC_ENUM("Equaliser EQ4 Bandwith", wm8974_enum[9]),
134SOC_ENUM("EQ4 Cut Off", wm8974_enum[10]),
135SOC_SINGLE_TLV("EQ4 Volume", WM8974_EQ4, 0, 24, 1, eq_tlv),
136
137SOC_ENUM("Equaliser EQ5 Bandwith", wm8974_enum[11]),
138SOC_ENUM("EQ5 Cut Off", wm8974_enum[12]),
139SOC_SINGLE_TLV("EQ5 Volume", WM8974_EQ5, 0, 24, 1, eq_tlv),
140
141SOC_SINGLE("DAC Playback Limiter Switch", WM8974_DACLIM1, 8, 1, 0),
142SOC_SINGLE("DAC Playback Limiter Decay", WM8974_DACLIM1, 4, 15, 0),
143SOC_SINGLE("DAC Playback Limiter Attack", WM8974_DACLIM1, 0, 15, 0),
144
145SOC_SINGLE("DAC Playback Limiter Threshold", WM8974_DACLIM2, 4, 7, 0),
146SOC_SINGLE("DAC Playback Limiter Boost", WM8974_DACLIM2, 0, 15, 0),
147
148SOC_SINGLE("ALC Enable Switch", WM8974_ALC1, 8, 1, 0),
149SOC_SINGLE("ALC Capture Max Gain", WM8974_ALC1, 3, 7, 0),
150SOC_SINGLE("ALC Capture Min Gain", WM8974_ALC1, 0, 7, 0),
151
152SOC_SINGLE("ALC Capture ZC Switch", WM8974_ALC2, 8, 1, 0),
153SOC_SINGLE("ALC Capture Hold", WM8974_ALC2, 4, 7, 0),
154SOC_SINGLE("ALC Capture Target", WM8974_ALC2, 0, 15, 0),
155
156SOC_ENUM("ALC Capture Mode", wm8974_enum[13]),
157SOC_SINGLE("ALC Capture Decay", WM8974_ALC3, 4, 15, 0),
158SOC_SINGLE("ALC Capture Attack", WM8974_ALC3, 0, 15, 0),
159
160SOC_SINGLE("ALC Capture Noise Gate Switch", WM8974_NGATE, 3, 1, 0),
161SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8974_NGATE, 0, 7, 0),
162
163SOC_SINGLE("Capture PGA ZC Switch", WM8974_INPPGA, 7, 1, 0),
164SOC_SINGLE_TLV("Capture PGA Volume", WM8974_INPPGA, 0, 63, 0, inpga_tlv),
165
166SOC_SINGLE("Speaker Playback ZC Switch", WM8974_SPKVOL, 7, 1, 0),
167SOC_SINGLE("Speaker Playback Switch", WM8974_SPKVOL, 6, 1, 1),
168SOC_SINGLE_TLV("Speaker Playback Volume", WM8974_SPKVOL, 0, 63, 0, spk_tlv),
169
170SOC_ENUM("Aux Mode", wm8974_auxmode),
171
172SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
173SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
174};
175
176/* Speaker Output Mixer */
177static const struct snd_kcontrol_new wm8974_speaker_mixer_controls[] = {
178SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_SPKMIX, 1, 1, 0),
179SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_SPKMIX, 5, 1, 0),
180SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_SPKMIX, 0, 1, 1),
181};
182
183/* Mono Output Mixer */
184static const struct snd_kcontrol_new wm8974_mono_mixer_controls[] = {
185SOC_DAPM_SINGLE("Line Bypass Switch", WM8974_MONOMIX, 1, 1, 0),
186SOC_DAPM_SINGLE("Aux Playback Switch", WM8974_MONOMIX, 2, 1, 0),
187SOC_DAPM_SINGLE("PCM Playback Switch", WM8974_MONOMIX, 0, 1, 0),
188};
189
190/* Boost mixer */
191static const struct snd_kcontrol_new wm8974_boost_mixer[] = {
192SOC_DAPM_SINGLE("Aux Switch", WM8974_INPPGA, 6, 1, 0),
193};
194
195/* Input PGA */
196static const struct snd_kcontrol_new wm8974_inpga[] = {
197SOC_DAPM_SINGLE("Aux Switch", WM8974_INPUT, 2, 1, 0),
198SOC_DAPM_SINGLE("MicN Switch", WM8974_INPUT, 1, 1, 0),
199SOC_DAPM_SINGLE("MicP Switch", WM8974_INPUT, 0, 1, 0),
200};
201
202/* AUX Input boost vol */
203static const struct snd_kcontrol_new wm8974_aux_boost_controls =
204SOC_DAPM_SINGLE("Aux Volume", WM8974_ADCBOOST, 0, 7, 0);
205
206/* Mic Input boost vol */
207static const struct snd_kcontrol_new wm8974_mic_boost_controls =
208SOC_DAPM_SINGLE("Mic Volume", WM8974_ADCBOOST, 4, 7, 0);
209
210static const struct snd_soc_dapm_widget wm8974_dapm_widgets[] = {
211SND_SOC_DAPM_MIXER("Speaker Mixer", WM8974_POWER3, 2, 0,
212 &wm8974_speaker_mixer_controls[0],
213 ARRAY_SIZE(wm8974_speaker_mixer_controls)),
214SND_SOC_DAPM_MIXER("Mono Mixer", WM8974_POWER3, 3, 0,
215 &wm8974_mono_mixer_controls[0],
216 ARRAY_SIZE(wm8974_mono_mixer_controls)),
217SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8974_POWER3, 0, 0),
218SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8974_POWER2, 0, 0),
219SND_SOC_DAPM_PGA("Aux Input", WM8974_POWER1, 6, 0, NULL, 0),
220SND_SOC_DAPM_PGA("SpkN Out", WM8974_POWER3, 5, 0, NULL, 0),
221SND_SOC_DAPM_PGA("SpkP Out", WM8974_POWER3, 6, 0, NULL, 0),
222SND_SOC_DAPM_PGA("Mono Out", WM8974_POWER3, 7, 0, NULL, 0),
223
224SND_SOC_DAPM_MIXER("Input PGA", WM8974_POWER2, 2, 0, wm8974_inpga,
225 ARRAY_SIZE(wm8974_inpga)),
226SND_SOC_DAPM_MIXER("Boost Mixer", WM8974_POWER2, 4, 0,
227 wm8974_boost_mixer, ARRAY_SIZE(wm8974_boost_mixer)),
228
229SND_SOC_DAPM_MICBIAS("Mic Bias", WM8974_POWER1, 4, 0),
230
231SND_SOC_DAPM_INPUT("MICN"),
232SND_SOC_DAPM_INPUT("MICP"),
233SND_SOC_DAPM_INPUT("AUX"),
234SND_SOC_DAPM_OUTPUT("MONOOUT"),
235SND_SOC_DAPM_OUTPUT("SPKOUTP"),
236SND_SOC_DAPM_OUTPUT("SPKOUTN"),
237};
238
239static const struct snd_soc_dapm_route audio_map[] = {
240 /* Mono output mixer */
241 {"Mono Mixer", "PCM Playback Switch", "DAC"},
242 {"Mono Mixer", "Aux Playback Switch", "Aux Input"},
243 {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"},
244
245 /* Speaker output mixer */
246 {"Speaker Mixer", "PCM Playback Switch", "DAC"},
247 {"Speaker Mixer", "Aux Playback Switch", "Aux Input"},
248 {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"},
249
250 /* Outputs */
251 {"Mono Out", NULL, "Mono Mixer"},
252 {"MONOOUT", NULL, "Mono Out"},
253 {"SpkN Out", NULL, "Speaker Mixer"},
254 {"SpkP Out", NULL, "Speaker Mixer"},
255 {"SPKOUTN", NULL, "SpkN Out"},
256 {"SPKOUTP", NULL, "SpkP Out"},
257
258 /* Boost Mixer */
259 {"ADC", NULL, "Boost Mixer"},
260 {"Boost Mixer", "Aux Switch", "Aux Input"},
261 {"Boost Mixer", NULL, "Input PGA"},
262 {"Boost Mixer", NULL, "MICP"},
263
264 /* Input PGA */
265 {"Input PGA", "Aux Switch", "Aux Input"},
266 {"Input PGA", "MicN Switch", "MICN"},
267 {"Input PGA", "MicP Switch", "MICP"},
268
269 /* Inputs */
270 {"Aux Input", NULL, "AUX"},
271};
272
273static int wm8974_add_widgets(struct snd_soc_codec *codec)
274{
275 snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets,
276 ARRAY_SIZE(wm8974_dapm_widgets));
277
278 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
279
280 snd_soc_dapm_new_widgets(codec);
281 return 0;
282}
283
284struct pll_ {
285 unsigned int pre_div:4; /* prescale - 1 */
286 unsigned int n:4;
287 unsigned int k;
288};
289
290static struct pll_ pll_div;
291
292/* The size in bits of the pll divide multiplied by 10
293 * to allow rounding later */
294#define FIXED_PLL_SIZE ((1 << 24) * 10)
295
296static void pll_factors(unsigned int target, unsigned int source)
297{
298 unsigned long long Kpart;
299 unsigned int K, Ndiv, Nmod;
300
301 Ndiv = target / source;
302 if (Ndiv < 6) {
303 source >>= 1;
304 pll_div.pre_div = 1;
305 Ndiv = target / source;
306 } else
307 pll_div.pre_div = 0;
308
309 if ((Ndiv < 6) || (Ndiv > 12))
310 printk(KERN_WARNING
311 "WM8974 N value %u outwith recommended range!\n",
312 Ndiv);
313
314 pll_div.n = Ndiv;
315 Nmod = target % source;
316 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
317
318 do_div(Kpart, source);
319
320 K = Kpart & 0xFFFFFFFF;
321
322 /* Check if we need to round */
323 if ((K % 10) >= 5)
324 K += 5;
325
326 /* Move down to proper range now rounding is done */
327 K /= 10;
328
329 pll_div.k = K;
330}
331
332static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
333 int pll_id, unsigned int freq_in, unsigned int freq_out)
334{
335 struct snd_soc_codec *codec = codec_dai->codec;
336 u16 reg;
337
338 if (freq_in == 0 || freq_out == 0) {
339 /* Clock CODEC directly from MCLK */
340 reg = snd_soc_read(codec, WM8974_CLOCK);
341 snd_soc_write(codec, WM8974_CLOCK, reg & 0x0ff);
342
343 /* Turn off PLL */
344 reg = snd_soc_read(codec, WM8974_POWER1);
345 snd_soc_write(codec, WM8974_POWER1, reg & 0x1df);
346 return 0;
347 }
348
349 pll_factors(freq_out*4, freq_in);
350
351 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
352 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
353 snd_soc_write(codec, WM8974_PLLK2, (pll_div.k >> 9) & 0x1ff);
354 snd_soc_write(codec, WM8974_PLLK3, pll_div.k & 0x1ff);
355 reg = snd_soc_read(codec, WM8974_POWER1);
356 snd_soc_write(codec, WM8974_POWER1, reg | 0x020);
357
358 /* Run CODEC from PLL instead of MCLK */
359 reg = snd_soc_read(codec, WM8974_CLOCK);
360 snd_soc_write(codec, WM8974_CLOCK, reg | 0x100);
361
362 return 0;
363}
364
365/*
366 * Configure WM8974 clock dividers.
367 */
368static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
369 int div_id, int div)
370{
371 struct snd_soc_codec *codec = codec_dai->codec;
372 u16 reg;
373
374 switch (div_id) {
375 case WM8974_OPCLKDIV:
376 reg = snd_soc_read(codec, WM8974_GPIO) & 0x1cf;
377 snd_soc_write(codec, WM8974_GPIO, reg | div);
378 break;
379 case WM8974_MCLKDIV:
380 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
381 snd_soc_write(codec, WM8974_CLOCK, reg | div);
382 break;
383 case WM8974_ADCCLK:
384 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
385 snd_soc_write(codec, WM8974_ADC, reg | div);
386 break;
387 case WM8974_DACCLK:
388 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
389 snd_soc_write(codec, WM8974_DAC, reg | div);
390 break;
391 case WM8974_BCLKDIV:
392 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
393 snd_soc_write(codec, WM8974_CLOCK, reg | div);
394 break;
395 default:
396 return -EINVAL;
397 }
398
399 return 0;
400}
401
402static int wm8974_set_dai_fmt(struct snd_soc_dai *codec_dai,
403 unsigned int fmt)
404{
405 struct snd_soc_codec *codec = codec_dai->codec;
406 u16 iface = 0;
407 u16 clk = snd_soc_read(codec, WM8974_CLOCK) & 0x1fe;
408
409 /* set master/slave audio interface */
410 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
411 case SND_SOC_DAIFMT_CBM_CFM:
412 clk |= 0x0001;
413 break;
414 case SND_SOC_DAIFMT_CBS_CFS:
415 break;
416 default:
417 return -EINVAL;
418 }
419
420 /* interface format */
421 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
422 case SND_SOC_DAIFMT_I2S:
423 iface |= 0x0010;
424 break;
425 case SND_SOC_DAIFMT_RIGHT_J:
426 break;
427 case SND_SOC_DAIFMT_LEFT_J:
428 iface |= 0x0008;
429 break;
430 case SND_SOC_DAIFMT_DSP_A:
431 iface |= 0x00018;
432 break;
433 default:
434 return -EINVAL;
435 }
436
437 /* clock inversion */
438 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
439 case SND_SOC_DAIFMT_NB_NF:
440 break;
441 case SND_SOC_DAIFMT_IB_IF:
442 iface |= 0x0180;
443 break;
444 case SND_SOC_DAIFMT_IB_NF:
445 iface |= 0x0100;
446 break;
447 case SND_SOC_DAIFMT_NB_IF:
448 iface |= 0x0080;
449 break;
450 default:
451 return -EINVAL;
452 }
453
454 snd_soc_write(codec, WM8974_IFACE, iface);
455 snd_soc_write(codec, WM8974_CLOCK, clk);
456 return 0;
457}
458
459static int wm8974_pcm_hw_params(struct snd_pcm_substream *substream,
460 struct snd_pcm_hw_params *params,
461 struct snd_soc_dai *dai)
462{
463 struct snd_soc_codec *codec = dai->codec;
464 u16 iface = snd_soc_read(codec, WM8974_IFACE) & 0x19f;
465 u16 adn = snd_soc_read(codec, WM8974_ADD) & 0x1f1;
466
467 /* bit size */
468 switch (params_format(params)) {
469 case SNDRV_PCM_FORMAT_S16_LE:
470 break;
471 case SNDRV_PCM_FORMAT_S20_3LE:
472 iface |= 0x0020;
473 break;
474 case SNDRV_PCM_FORMAT_S24_LE:
475 iface |= 0x0040;
476 break;
477 case SNDRV_PCM_FORMAT_S32_LE:
478 iface |= 0x0060;
479 break;
480 }
481
482 /* filter coefficient */
483 switch (params_rate(params)) {
484 case SNDRV_PCM_RATE_8000:
485 adn |= 0x5 << 1;
486 break;
487 case SNDRV_PCM_RATE_11025:
488 adn |= 0x4 << 1;
489 break;
490 case SNDRV_PCM_RATE_16000:
491 adn |= 0x3 << 1;
492 break;
493 case SNDRV_PCM_RATE_22050:
494 adn |= 0x2 << 1;
495 break;
496 case SNDRV_PCM_RATE_32000:
497 adn |= 0x1 << 1;
498 break;
499 case SNDRV_PCM_RATE_44100:
500 case SNDRV_PCM_RATE_48000:
501 break;
502 }
503
504 snd_soc_write(codec, WM8974_IFACE, iface);
505 snd_soc_write(codec, WM8974_ADD, adn);
506 return 0;
507}
508
509static int wm8974_mute(struct snd_soc_dai *dai, int mute)
510{
511 struct snd_soc_codec *codec = dai->codec;
512 u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
513
514 if (mute)
515 snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
516 else
517 snd_soc_write(codec, WM8974_DAC, mute_reg);
518 return 0;
519}
520
521/* liam need to make this lower power with dapm */
522static int wm8974_set_bias_level(struct snd_soc_codec *codec,
523 enum snd_soc_bias_level level)
524{
525 u16 power1 = snd_soc_read(codec, WM8974_POWER1) & ~0x3;
526
527 switch (level) {
528 case SND_SOC_BIAS_ON:
529 case SND_SOC_BIAS_PREPARE:
530 power1 |= 0x1; /* VMID 50k */
531 snd_soc_write(codec, WM8974_POWER1, power1);
532 break;
533
534 case SND_SOC_BIAS_STANDBY:
535 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
536
537 if (codec->bias_level == SND_SOC_BIAS_OFF) {
538 /* Initial cap charge at VMID 5k */
539 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
540 mdelay(100);
541 }
542
543 power1 |= 0x2; /* VMID 500k */
544 snd_soc_write(codec, WM8974_POWER1, power1);
545 break;
546
547 case SND_SOC_BIAS_OFF:
548 snd_soc_write(codec, WM8974_POWER1, 0);
549 snd_soc_write(codec, WM8974_POWER2, 0);
550 snd_soc_write(codec, WM8974_POWER3, 0);
551 break;
552 }
553
554 codec->bias_level = level;
555 return 0;
556}
557
558#define WM8974_RATES (SNDRV_PCM_RATE_8000_48000)
559
560#define WM8974_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
561 SNDRV_PCM_FMTBIT_S24_LE)
562
563static struct snd_soc_dai_ops wm8974_ops = {
564 .hw_params = wm8974_pcm_hw_params,
565 .digital_mute = wm8974_mute,
566 .set_fmt = wm8974_set_dai_fmt,
567 .set_clkdiv = wm8974_set_dai_clkdiv,
568 .set_pll = wm8974_set_dai_pll,
569};
570
571struct snd_soc_dai wm8974_dai = {
572 .name = "WM8974 HiFi",
573 .playback = {
574 .stream_name = "Playback",
575 .channels_min = 1,
576 .channels_max = 2, /* Only 1 channel of data */
577 .rates = WM8974_RATES,
578 .formats = WM8974_FORMATS,},
579 .capture = {
580 .stream_name = "Capture",
581 .channels_min = 1,
582 .channels_max = 2, /* Only 1 channel of data */
583 .rates = WM8974_RATES,
584 .formats = WM8974_FORMATS,},
585 .ops = &wm8974_ops,
586 .symmetric_rates = 1,
587};
588EXPORT_SYMBOL_GPL(wm8974_dai);
589
590static int wm8974_suspend(struct platform_device *pdev, pm_message_t state)
591{
592 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
593 struct snd_soc_codec *codec = socdev->card->codec;
594
595 wm8974_set_bias_level(codec, SND_SOC_BIAS_OFF);
596 return 0;
597}
598
599static int wm8974_resume(struct platform_device *pdev)
600{
601 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
602 struct snd_soc_codec *codec = socdev->card->codec;
603 int i;
604 u8 data[2];
605 u16 *cache = codec->reg_cache;
606
607 /* Sync reg_cache with the hardware */
608 for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) {
609 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
610 data[1] = cache[i] & 0x00ff;
611 codec->hw_write(codec->control_data, data, 2);
612 }
613 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
614 wm8974_set_bias_level(codec, codec->suspend_bias_level);
615 return 0;
616}
617
618static int wm8974_probe(struct platform_device *pdev)
619{
620 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
621 struct snd_soc_codec *codec;
622 int ret = 0;
623
624 if (wm8974_codec == NULL) {
625 dev_err(&pdev->dev, "Codec device not registered\n");
626 return -ENODEV;
627 }
628
629 socdev->card->codec = wm8974_codec;
630 codec = wm8974_codec;
631
632 /* register pcms */
633 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
634 if (ret < 0) {
635 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
636 goto pcm_err;
637 }
638
639 snd_soc_add_controls(codec, wm8974_snd_controls,
640 ARRAY_SIZE(wm8974_snd_controls));
641 wm8974_add_widgets(codec);
642 ret = snd_soc_init_card(socdev);
643 if (ret < 0) {
644 dev_err(codec->dev, "failed to register card: %d\n", ret);
645 goto card_err;
646 }
647
648 return ret;
649
650card_err:
651 snd_soc_free_pcms(socdev);
652 snd_soc_dapm_free(socdev);
653pcm_err:
654 return ret;
655}
656
657/* power down chip */
658static int wm8974_remove(struct platform_device *pdev)
659{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661
662 snd_soc_free_pcms(socdev);
663 snd_soc_dapm_free(socdev);
664
665 return 0;
666}
667
668struct snd_soc_codec_device soc_codec_dev_wm8974 = {
669 .probe = wm8974_probe,
670 .remove = wm8974_remove,
671 .suspend = wm8974_suspend,
672 .resume = wm8974_resume,
673};
674EXPORT_SYMBOL_GPL(soc_codec_dev_wm8974);
675
676static __devinit int wm8974_register(struct wm8974_priv *wm8974)
677{
678 int ret;
679 struct snd_soc_codec *codec = &wm8974->codec;
680
681 if (wm8974_codec) {
682 dev_err(codec->dev, "Another WM8974 is registered\n");
683 return -EINVAL;
684 }
685
686 mutex_init(&codec->mutex);
687 INIT_LIST_HEAD(&codec->dapm_widgets);
688 INIT_LIST_HEAD(&codec->dapm_paths);
689
690 codec->private_data = wm8974;
691 codec->name = "WM8974";
692 codec->owner = THIS_MODULE;
693 codec->bias_level = SND_SOC_BIAS_OFF;
694 codec->set_bias_level = wm8974_set_bias_level;
695 codec->dai = &wm8974_dai;
696 codec->num_dai = 1;
697 codec->reg_cache_size = WM8974_CACHEREGNUM;
698 codec->reg_cache = &wm8974->reg_cache;
699
700 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
701 if (ret < 0) {
702 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
703 goto err;
704 }
705
706 memcpy(codec->reg_cache, wm8974_reg, sizeof(wm8974_reg));
707
708 ret = wm8974_reset(codec);
709 if (ret < 0) {
710 dev_err(codec->dev, "Failed to issue reset\n");
711 goto err;
712 }
713
714 wm8974_dai.dev = codec->dev;
715
716 wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
717
718 wm8974_codec = codec;
719
720 ret = snd_soc_register_codec(codec);
721 if (ret != 0) {
722 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
723 goto err;
724 }
725
726 ret = snd_soc_register_dai(&wm8974_dai);
727 if (ret != 0) {
728 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
729 goto err_codec;
730 }
731
732 return 0;
733
734err_codec:
735 snd_soc_unregister_codec(codec);
736err:
737 kfree(wm8974);
738 return ret;
739}
740
741static __devexit void wm8974_unregister(struct wm8974_priv *wm8974)
742{
743 wm8974_set_bias_level(&wm8974->codec, SND_SOC_BIAS_OFF);
744 snd_soc_unregister_dai(&wm8974_dai);
745 snd_soc_unregister_codec(&wm8974->codec);
746 kfree(wm8974);
747 wm8974_codec = NULL;
748}
749
750static __devinit int wm8974_i2c_probe(struct i2c_client *i2c,
751 const struct i2c_device_id *id)
752{
753 struct wm8974_priv *wm8974;
754 struct snd_soc_codec *codec;
755
756 wm8974 = kzalloc(sizeof(struct wm8974_priv), GFP_KERNEL);
757 if (wm8974 == NULL)
758 return -ENOMEM;
759
760 codec = &wm8974->codec;
761 codec->hw_write = (hw_write_t)i2c_master_send;
762
763 i2c_set_clientdata(i2c, wm8974);
764 codec->control_data = i2c;
765
766 codec->dev = &i2c->dev;
767
768 return wm8974_register(wm8974);
769}
770
771static __devexit int wm8974_i2c_remove(struct i2c_client *client)
772{
773 struct wm8974_priv *wm8974 = i2c_get_clientdata(client);
774 wm8974_unregister(wm8974);
775 return 0;
776}
777
778static const struct i2c_device_id wm8974_i2c_id[] = {
779 { "wm8974", 0 },
780 { }
781};
782MODULE_DEVICE_TABLE(i2c, wm8974_i2c_id);
783
784static struct i2c_driver wm8974_i2c_driver = {
785 .driver = {
786 .name = "WM8974",
787 .owner = THIS_MODULE,
788 },
789 .probe = wm8974_i2c_probe,
790 .remove = __devexit_p(wm8974_i2c_remove),
791 .id_table = wm8974_i2c_id,
792};
793
794static int __init wm8974_modinit(void)
795{
796 return i2c_add_driver(&wm8974_i2c_driver);
797}
798module_init(wm8974_modinit);
799
800static void __exit wm8974_exit(void)
801{
802 i2c_del_driver(&wm8974_i2c_driver);
803}
804module_exit(wm8974_exit);
805
806MODULE_DESCRIPTION("ASoC WM8974 driver");
807MODULE_AUTHOR("Liam Girdwood");
808MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
new file mode 100644
index 000000000000..98de9562d4d2
--- /dev/null
+++ b/sound/soc/codecs/wm8974.h
@@ -0,0 +1,99 @@
1/*
2 * wm8974.h -- WM8974 Soc Audio driver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _WM8974_H
10#define _WM8974_H
11
12/* WM8974 register space */
13
14#define WM8974_RESET 0x0
15#define WM8974_POWER1 0x1
16#define WM8974_POWER2 0x2
17#define WM8974_POWER3 0x3
18#define WM8974_IFACE 0x4
19#define WM8974_COMP 0x5
20#define WM8974_CLOCK 0x6
21#define WM8974_ADD 0x7
22#define WM8974_GPIO 0x8
23#define WM8974_DAC 0xa
24#define WM8974_DACVOL 0xb
25#define WM8974_ADC 0xe
26#define WM8974_ADCVOL 0xf
27#define WM8974_EQ1 0x12
28#define WM8974_EQ2 0x13
29#define WM8974_EQ3 0x14
30#define WM8974_EQ4 0x15
31#define WM8974_EQ5 0x16
32#define WM8974_DACLIM1 0x18
33#define WM8974_DACLIM2 0x19
34#define WM8974_NOTCH1 0x1b
35#define WM8974_NOTCH2 0x1c
36#define WM8974_NOTCH3 0x1d
37#define WM8974_NOTCH4 0x1e
38#define WM8974_ALC1 0x20
39#define WM8974_ALC2 0x21
40#define WM8974_ALC3 0x22
41#define WM8974_NGATE 0x23
42#define WM8974_PLLN 0x24
43#define WM8974_PLLK1 0x25
44#define WM8974_PLLK2 0x26
45#define WM8974_PLLK3 0x27
46#define WM8974_ATTEN 0x28
47#define WM8974_INPUT 0x2c
48#define WM8974_INPPGA 0x2d
49#define WM8974_ADCBOOST 0x2f
50#define WM8974_OUTPUT 0x31
51#define WM8974_SPKMIX 0x32
52#define WM8974_SPKVOL 0x36
53#define WM8974_MONOMIX 0x38
54
55#define WM8974_CACHEREGNUM 57
56
57/* Clock divider Id's */
58#define WM8974_OPCLKDIV 0
59#define WM8974_MCLKDIV 1
60#define WM8974_ADCCLK 2
61#define WM8974_DACCLK 3
62#define WM8974_BCLKDIV 4
63
64/* DAC clock dividers */
65#define WM8974_DACCLK_F2 (1 << 3)
66#define WM8974_DACCLK_F4 (0 << 3)
67
68/* ADC clock dividers */
69#define WM8974_ADCCLK_F2 (1 << 3)
70#define WM8974_ADCCLK_F4 (0 << 3)
71
72/* PLL Out dividers */
73#define WM8974_OPCLKDIV_1 (0 << 4)
74#define WM8974_OPCLKDIV_2 (1 << 4)
75#define WM8974_OPCLKDIV_3 (2 << 4)
76#define WM8974_OPCLKDIV_4 (3 << 4)
77
78/* BCLK clock dividers */
79#define WM8974_BCLKDIV_1 (0 << 2)
80#define WM8974_BCLKDIV_2 (1 << 2)
81#define WM8974_BCLKDIV_4 (2 << 2)
82#define WM8974_BCLKDIV_8 (3 << 2)
83#define WM8974_BCLKDIV_16 (4 << 2)
84#define WM8974_BCLKDIV_32 (5 << 2)
85
86/* MCLK clock dividers */
87#define WM8974_MCLKDIV_1 (0 << 5)
88#define WM8974_MCLKDIV_1_5 (1 << 5)
89#define WM8974_MCLKDIV_2 (2 << 5)
90#define WM8974_MCLKDIV_3 (3 << 5)
91#define WM8974_MCLKDIV_4 (4 << 5)
92#define WM8974_MCLKDIV_6 (5 << 5)
93#define WM8974_MCLKDIV_8 (6 << 5)
94#define WM8974_MCLKDIV_12 (7 << 5)
95
96extern struct snd_soc_dai wm8974_dai;
97extern struct snd_soc_codec_device soc_codec_dev_wm8974;
98
99#endif
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 8c0fdf84aac3..3f530f8a972a 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -57,50 +57,7 @@ struct wm8988_priv {
57}; 57};
58 58
59 59
60/* 60#define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0)
61 * read wm8988 register cache
62 */
63static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec,
64 unsigned int reg)
65{
66 u16 *cache = codec->reg_cache;
67 if (reg > WM8988_NUM_REG)
68 return -1;
69 return cache[reg];
70}
71
72/*
73 * write wm8988 register cache
74 */
75static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec,
76 unsigned int reg, unsigned int value)
77{
78 u16 *cache = codec->reg_cache;
79 if (reg > WM8988_NUM_REG)
80 return;
81 cache[reg] = value;
82}
83
84static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg,
85 unsigned int value)
86{
87 u8 data[2];
88
89 /* data is
90 * D15..D9 WM8753 register offset
91 * D8...D0 register data
92 */
93 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
94 data[1] = value & 0x00ff;
95
96 wm8988_write_reg_cache(codec, reg, value);
97 if (codec->hw_write(codec->control_data, data, 2) == 2)
98 return 0;
99 else
100 return -EIO;
101}
102
103#define wm8988_reset(c) wm8988_write(c, WM8988_RESET, 0)
104 61
105/* 62/*
106 * WM8988 Controls 63 * WM8988 Controls
@@ -226,15 +183,15 @@ static int wm8988_lrc_control(struct snd_soc_dapm_widget *w,
226 struct snd_kcontrol *kcontrol, int event) 183 struct snd_kcontrol *kcontrol, int event)
227{ 184{
228 struct snd_soc_codec *codec = w->codec; 185 struct snd_soc_codec *codec = w->codec;
229 u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2); 186 u16 adctl2 = snd_soc_read(codec, WM8988_ADCTL2);
230 187
231 /* Use the DAC to gate LRC if active, otherwise use ADC */ 188 /* Use the DAC to gate LRC if active, otherwise use ADC */
232 if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180) 189 if (snd_soc_read(codec, WM8988_PWR2) & 0x180)
233 adctl2 &= ~0x4; 190 adctl2 &= ~0x4;
234 else 191 else
235 adctl2 |= 0x4; 192 adctl2 |= 0x4;
236 193
237 return wm8988_write(codec, WM8988_ADCTL2, adctl2); 194 return snd_soc_write(codec, WM8988_ADCTL2, adctl2);
238} 195}
239 196
240static const char *wm8988_line_texts[] = { 197static const char *wm8988_line_texts[] = {
@@ -619,7 +576,7 @@ static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai,
619 return -EINVAL; 576 return -EINVAL;
620 } 577 }
621 578
622 wm8988_write(codec, WM8988_IFACE, iface); 579 snd_soc_write(codec, WM8988_IFACE, iface);
623 return 0; 580 return 0;
624} 581}
625 582
@@ -653,8 +610,8 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
653 struct snd_soc_device *socdev = rtd->socdev; 610 struct snd_soc_device *socdev = rtd->socdev;
654 struct snd_soc_codec *codec = socdev->card->codec; 611 struct snd_soc_codec *codec = socdev->card->codec;
655 struct wm8988_priv *wm8988 = codec->private_data; 612 struct wm8988_priv *wm8988 = codec->private_data;
656 u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3; 613 u16 iface = snd_soc_read(codec, WM8988_IFACE) & 0x1f3;
657 u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180; 614 u16 srate = snd_soc_read(codec, WM8988_SRATE) & 0x180;
658 int coeff; 615 int coeff;
659 616
660 coeff = get_coeff(wm8988->sysclk, params_rate(params)); 617 coeff = get_coeff(wm8988->sysclk, params_rate(params));
@@ -685,9 +642,9 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
685 } 642 }
686 643
687 /* set iface & srate */ 644 /* set iface & srate */
688 wm8988_write(codec, WM8988_IFACE, iface); 645 snd_soc_write(codec, WM8988_IFACE, iface);
689 if (coeff >= 0) 646 if (coeff >= 0)
690 wm8988_write(codec, WM8988_SRATE, srate | 647 snd_soc_write(codec, WM8988_SRATE, srate |
691 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); 648 (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb);
692 649
693 return 0; 650 return 0;
@@ -696,19 +653,19 @@ static int wm8988_pcm_hw_params(struct snd_pcm_substream *substream,
696static int wm8988_mute(struct snd_soc_dai *dai, int mute) 653static int wm8988_mute(struct snd_soc_dai *dai, int mute)
697{ 654{
698 struct snd_soc_codec *codec = dai->codec; 655 struct snd_soc_codec *codec = dai->codec;
699 u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7; 656 u16 mute_reg = snd_soc_read(codec, WM8988_ADCDAC) & 0xfff7;
700 657
701 if (mute) 658 if (mute)
702 wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8); 659 snd_soc_write(codec, WM8988_ADCDAC, mute_reg | 0x8);
703 else 660 else
704 wm8988_write(codec, WM8988_ADCDAC, mute_reg); 661 snd_soc_write(codec, WM8988_ADCDAC, mute_reg);
705 return 0; 662 return 0;
706} 663}
707 664
708static int wm8988_set_bias_level(struct snd_soc_codec *codec, 665static int wm8988_set_bias_level(struct snd_soc_codec *codec,
709 enum snd_soc_bias_level level) 666 enum snd_soc_bias_level level)
710{ 667{
711 u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1; 668 u16 pwr_reg = snd_soc_read(codec, WM8988_PWR1) & ~0x1c1;
712 669
713 switch (level) { 670 switch (level) {
714 case SND_SOC_BIAS_ON: 671 case SND_SOC_BIAS_ON:
@@ -716,24 +673,24 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
716 673
717 case SND_SOC_BIAS_PREPARE: 674 case SND_SOC_BIAS_PREPARE:
718 /* VREF, VMID=2x50k, digital enabled */ 675 /* VREF, VMID=2x50k, digital enabled */
719 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); 676 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x00c0);
720 break; 677 break;
721 678
722 case SND_SOC_BIAS_STANDBY: 679 case SND_SOC_BIAS_STANDBY:
723 if (codec->bias_level == SND_SOC_BIAS_OFF) { 680 if (codec->bias_level == SND_SOC_BIAS_OFF) {
724 /* VREF, VMID=2x5k */ 681 /* VREF, VMID=2x5k */
725 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 682 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
726 683
727 /* Charge caps */ 684 /* Charge caps */
728 msleep(100); 685 msleep(100);
729 } 686 }
730 687
731 /* VREF, VMID=2*500k, digital stopped */ 688 /* VREF, VMID=2*500k, digital stopped */
732 wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141); 689 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x0141);
733 break; 690 break;
734 691
735 case SND_SOC_BIAS_OFF: 692 case SND_SOC_BIAS_OFF:
736 wm8988_write(codec, WM8988_PWR1, 0x0000); 693 snd_soc_write(codec, WM8988_PWR1, 0x0000);
737 break; 694 break;
738 } 695 }
739 codec->bias_level = level; 696 codec->bias_level = level;
@@ -868,7 +825,8 @@ struct snd_soc_codec_device soc_codec_dev_wm8988 = {
868}; 825};
869EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988); 826EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988);
870 827
871static int wm8988_register(struct wm8988_priv *wm8988) 828static int wm8988_register(struct wm8988_priv *wm8988,
829 enum snd_soc_control_type control)
872{ 830{
873 struct snd_soc_codec *codec = &wm8988->codec; 831 struct snd_soc_codec *codec = &wm8988->codec;
874 int ret; 832 int ret;
@@ -887,8 +845,6 @@ static int wm8988_register(struct wm8988_priv *wm8988)
887 codec->private_data = wm8988; 845 codec->private_data = wm8988;
888 codec->name = "WM8988"; 846 codec->name = "WM8988";
889 codec->owner = THIS_MODULE; 847 codec->owner = THIS_MODULE;
890 codec->read = wm8988_read_reg_cache;
891 codec->write = wm8988_write;
892 codec->dai = &wm8988_dai; 848 codec->dai = &wm8988_dai;
893 codec->num_dai = 1; 849 codec->num_dai = 1;
894 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache); 850 codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache);
@@ -899,23 +855,29 @@ static int wm8988_register(struct wm8988_priv *wm8988)
899 memcpy(codec->reg_cache, wm8988_reg, 855 memcpy(codec->reg_cache, wm8988_reg,
900 sizeof(wm8988_reg)); 856 sizeof(wm8988_reg));
901 857
858 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
859 if (ret < 0) {
860 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
861 goto err;
862 }
863
902 ret = wm8988_reset(codec); 864 ret = wm8988_reset(codec);
903 if (ret < 0) { 865 if (ret < 0) {
904 dev_err(codec->dev, "Failed to issue reset\n"); 866 dev_err(codec->dev, "Failed to issue reset\n");
905 return ret; 867 goto err;
906 } 868 }
907 869
908 /* set the update bits (we always update left then right) */ 870 /* set the update bits (we always update left then right) */
909 reg = wm8988_read_reg_cache(codec, WM8988_RADC); 871 reg = snd_soc_read(codec, WM8988_RADC);
910 wm8988_write(codec, WM8988_RADC, reg | 0x100); 872 snd_soc_write(codec, WM8988_RADC, reg | 0x100);
911 reg = wm8988_read_reg_cache(codec, WM8988_RDAC); 873 reg = snd_soc_read(codec, WM8988_RDAC);
912 wm8988_write(codec, WM8988_RDAC, reg | 0x0100); 874 snd_soc_write(codec, WM8988_RDAC, reg | 0x0100);
913 reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V); 875 reg = snd_soc_read(codec, WM8988_ROUT1V);
914 wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100); 876 snd_soc_write(codec, WM8988_ROUT1V, reg | 0x0100);
915 reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V); 877 reg = snd_soc_read(codec, WM8988_ROUT2V);
916 wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100); 878 snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100);
917 reg = wm8988_read_reg_cache(codec, WM8988_RINVOL); 879 reg = snd_soc_read(codec, WM8988_RINVOL);
918 wm8988_write(codec, WM8988_RINVOL, reg | 0x0100); 880 snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100);
919 881
920 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); 882 wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY);
921 883
@@ -926,18 +888,20 @@ static int wm8988_register(struct wm8988_priv *wm8988)
926 ret = snd_soc_register_codec(codec); 888 ret = snd_soc_register_codec(codec);
927 if (ret != 0) { 889 if (ret != 0) {
928 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 890 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
929 return ret; 891 goto err;
930 } 892 }
931 893
932 ret = snd_soc_register_dai(&wm8988_dai); 894 ret = snd_soc_register_dai(&wm8988_dai);
933 if (ret != 0) { 895 if (ret != 0) {
934 dev_err(codec->dev, "Failed to register DAI: %d\n", ret); 896 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
935 snd_soc_unregister_codec(codec); 897 snd_soc_unregister_codec(codec);
936 return ret; 898 goto err_codec;
937 } 899 }
938 900
939 return 0; 901 return 0;
940 902
903err_codec:
904 snd_soc_unregister_codec(codec);
941err: 905err:
942 kfree(wm8988); 906 kfree(wm8988);
943 return ret; 907 return ret;
@@ -964,14 +928,13 @@ static int wm8988_i2c_probe(struct i2c_client *i2c,
964 return -ENOMEM; 928 return -ENOMEM;
965 929
966 codec = &wm8988->codec; 930 codec = &wm8988->codec;
967 codec->hw_write = (hw_write_t)i2c_master_send;
968 931
969 i2c_set_clientdata(i2c, wm8988); 932 i2c_set_clientdata(i2c, wm8988);
970 codec->control_data = i2c; 933 codec->control_data = i2c;
971 934
972 codec->dev = &i2c->dev; 935 codec->dev = &i2c->dev;
973 936
974 return wm8988_register(wm8988); 937 return wm8988_register(wm8988, SND_SOC_I2C);
975} 938}
976 939
977static int wm8988_i2c_remove(struct i2c_client *client) 940static int wm8988_i2c_remove(struct i2c_client *client)
@@ -981,6 +944,21 @@ static int wm8988_i2c_remove(struct i2c_client *client)
981 return 0; 944 return 0;
982} 945}
983 946
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
984static const struct i2c_device_id wm8988_i2c_id[] = { 962static const struct i2c_device_id wm8988_i2c_id[] = {
985 { "wm8988", 0 }, 963 { "wm8988", 0 },
986 { } 964 { }
@@ -994,35 +972,13 @@ static struct i2c_driver wm8988_i2c_driver = {
994 }, 972 },
995 .probe = wm8988_i2c_probe, 973 .probe = wm8988_i2c_probe,
996 .remove = wm8988_i2c_remove, 974 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
997 .id_table = wm8988_i2c_id, 977 .id_table = wm8988_i2c_id,
998}; 978};
999#endif 979#endif
1000 980
1001#if defined(CONFIG_SPI_MASTER) 981#if defined(CONFIG_SPI_MASTER)
1002static int wm8988_spi_write(struct spi_device *spi, const char *data, int len)
1003{
1004 struct spi_transfer t;
1005 struct spi_message m;
1006 u8 msg[2];
1007
1008 if (len <= 0)
1009 return 0;
1010
1011 msg[0] = data[0];
1012 msg[1] = data[1];
1013
1014 spi_message_init(&m);
1015 memset(&t, 0, (sizeof t));
1016
1017 t.tx_buf = &msg[0];
1018 t.len = len;
1019
1020 spi_message_add_tail(&t, &m);
1021 spi_sync(spi, &m);
1022
1023 return len;
1024}
1025
1026static int __devinit wm8988_spi_probe(struct spi_device *spi) 982static int __devinit wm8988_spi_probe(struct spi_device *spi)
1027{ 983{
1028 struct wm8988_priv *wm8988; 984 struct wm8988_priv *wm8988;
@@ -1033,13 +989,12 @@ static int __devinit wm8988_spi_probe(struct spi_device *spi)
1033 return -ENOMEM; 989 return -ENOMEM;
1034 990
1035 codec = &wm8988->codec; 991 codec = &wm8988->codec;
1036 codec->hw_write = (hw_write_t)wm8988_spi_write;
1037 codec->control_data = spi; 992 codec->control_data = spi;
1038 codec->dev = &spi->dev; 993 codec->dev = &spi->dev;
1039 994
1040 dev_set_drvdata(&spi->dev, wm8988); 995 dev_set_drvdata(&spi->dev, wm8988);
1041 996
1042 return wm8988_register(wm8988); 997 return wm8988_register(wm8988, SND_SOC_SPI);
1043} 998}
1044 999
1045static int __devexit wm8988_spi_remove(struct spi_device *spi) 1000static int __devexit wm8988_spi_remove(struct spi_device *spi)
@@ -1051,6 +1006,21 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1051 return 0; 1006 return 0;
1052} 1007}
1053 1008
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1054static struct spi_driver wm8988_spi_driver = { 1024static struct spi_driver wm8988_spi_driver = {
1055 .driver = { 1025 .driver = {
1056 .name = "wm8988", 1026 .name = "wm8988",
@@ -1059,6 +1029,8 @@ static struct spi_driver wm8988_spi_driver = {
1059 }, 1029 },
1060 .probe = wm8988_spi_probe, 1030 .probe = wm8988_spi_probe,
1061 .remove = __devexit_p(wm8988_spi_remove), 1031 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1062}; 1034};
1063#endif 1035#endif
1064 1036
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index d029818350e9..2d702db4131d 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -108,53 +108,7 @@ static const u16 wm8990_reg[] = {
108 0x0000, /* R63 - Driver internal */ 108 0x0000, /* R63 - Driver internal */
109}; 109};
110 110
111/* 111#define wm8990_reset(c) snd_soc_write(c, WM8990_RESET, 0)
112 * read wm8990 register cache
113 */
114static inline unsigned int wm8990_read_reg_cache(struct snd_soc_codec *codec,
115 unsigned int reg)
116{
117 u16 *cache = codec->reg_cache;
118 BUG_ON(reg >= ARRAY_SIZE(wm8990_reg));
119 return cache[reg];
120}
121
122/*
123 * write wm8990 register cache
124 */
125static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
126 unsigned int reg, unsigned int value)
127{
128 u16 *cache = codec->reg_cache;
129
130 /* Reset register and reserved registers are uncached */
131 if (reg == 0 || reg >= ARRAY_SIZE(wm8990_reg))
132 return;
133
134 cache[reg] = value;
135}
136
137/*
138 * write to the wm8990 register space
139 */
140static int wm8990_write(struct snd_soc_codec *codec, unsigned int reg,
141 unsigned int value)
142{
143 u8 data[3];
144
145 data[0] = reg & 0xFF;
146 data[1] = (value >> 8) & 0xFF;
147 data[2] = value & 0xFF;
148
149 wm8990_write_reg_cache(codec, reg, value);
150
151 if (codec->hw_write(codec->control_data, data, 3) == 2)
152 return 0;
153 else
154 return -EIO;
155}
156
157#define wm8990_reset(c) wm8990_write(c, WM8990_RESET, 0)
158 112
159static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600); 113static const DECLARE_TLV_DB_LINEAR(rec_mix_tlv, -1500, 600);
160 114
@@ -187,8 +141,8 @@ static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
187 return ret; 141 return ret;
188 142
189 /* now hit the volume update bits (always bit 8) */ 143 /* now hit the volume update bits (always bit 8) */
190 val = wm8990_read_reg_cache(codec, reg); 144 val = snd_soc_read(codec, reg);
191 return wm8990_write(codec, reg, val | 0x0100); 145 return snd_soc_write(codec, reg, val | 0x0100);
192} 146}
193 147
194#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\ 148#define SOC_WM899X_OUTPGA_SINGLE_R_TLV(xname, reg, shift, max, invert,\
@@ -427,8 +381,8 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
427{ 381{
428 u16 reg, fakepower; 382 u16 reg, fakepower;
429 383
430 reg = wm8990_read_reg_cache(w->codec, WM8990_POWER_MANAGEMENT_2); 384 reg = snd_soc_read(w->codec, WM8990_POWER_MANAGEMENT_2);
431 fakepower = wm8990_read_reg_cache(w->codec, WM8990_INTDRIVBITS); 385 fakepower = snd_soc_read(w->codec, WM8990_INTDRIVBITS);
432 386
433 if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) | 387 if (fakepower & ((1 << WM8990_INMIXL_PWR_BIT) |
434 (1 << WM8990_AINLMUX_PWR_BIT))) { 388 (1 << WM8990_AINLMUX_PWR_BIT))) {
@@ -443,7 +397,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w,
443 } else { 397 } else {
444 reg &= ~WM8990_AINL_ENA; 398 reg &= ~WM8990_AINL_ENA;
445 } 399 }
446 wm8990_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); 400 snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg);
447 401
448 return 0; 402 return 0;
449} 403}
@@ -457,7 +411,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
457 411
458 switch (reg_shift) { 412 switch (reg_shift) {
459 case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) : 413 case WM8990_SPEAKER_MIXER | (WM8990_LDSPK_BIT << 8) :
460 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER1); 414 reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER1);
461 if (reg & WM8990_LDLO) { 415 if (reg & WM8990_LDLO) {
462 printk(KERN_WARNING 416 printk(KERN_WARNING
463 "Cannot set as Output Mixer 1 LDLO Set\n"); 417 "Cannot set as Output Mixer 1 LDLO Set\n");
@@ -465,7 +419,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
465 } 419 }
466 break; 420 break;
467 case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8): 421 case WM8990_SPEAKER_MIXER | (WM8990_RDSPK_BIT << 8):
468 reg = wm8990_read_reg_cache(w->codec, WM8990_OUTPUT_MIXER2); 422 reg = snd_soc_read(w->codec, WM8990_OUTPUT_MIXER2);
469 if (reg & WM8990_RDRO) { 423 if (reg & WM8990_RDRO) {
470 printk(KERN_WARNING 424 printk(KERN_WARNING
471 "Cannot set as Output Mixer 2 RDRO Set\n"); 425 "Cannot set as Output Mixer 2 RDRO Set\n");
@@ -473,7 +427,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
473 } 427 }
474 break; 428 break;
475 case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8): 429 case WM8990_OUTPUT_MIXER1 | (WM8990_LDLO_BIT << 8):
476 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER); 430 reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
477 if (reg & WM8990_LDSPK) { 431 if (reg & WM8990_LDSPK) {
478 printk(KERN_WARNING 432 printk(KERN_WARNING
479 "Cannot set as Speaker Mixer LDSPK Set\n"); 433 "Cannot set as Speaker Mixer LDSPK Set\n");
@@ -481,7 +435,7 @@ static int outmixer_event(struct snd_soc_dapm_widget *w,
481 } 435 }
482 break; 436 break;
483 case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8): 437 case WM8990_OUTPUT_MIXER2 | (WM8990_RDRO_BIT << 8):
484 reg = wm8990_read_reg_cache(w->codec, WM8990_SPEAKER_MIXER); 438 reg = snd_soc_read(w->codec, WM8990_SPEAKER_MIXER);
485 if (reg & WM8990_RDSPK) { 439 if (reg & WM8990_RDSPK) {
486 printk(KERN_WARNING 440 printk(KERN_WARNING
487 "Cannot set as Speaker Mixer RDSPK Set\n"); 441 "Cannot set as Speaker Mixer RDSPK Set\n");
@@ -1029,24 +983,24 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai,
1029 pll_factors(&pll_div, freq_out * 4, freq_in); 983 pll_factors(&pll_div, freq_out * 4, freq_in);
1030 984
1031 /* Turn on PLL */ 985 /* Turn on PLL */
1032 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 986 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1033 reg |= WM8990_PLL_ENA; 987 reg |= WM8990_PLL_ENA;
1034 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg); 988 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1035 989
1036 /* sysclk comes from PLL */ 990 /* sysclk comes from PLL */
1037 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2); 991 reg = snd_soc_read(codec, WM8990_CLOCKING_2);
1038 wm8990_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); 992 snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC);
1039 993
1040 /* set up N , fractional mode and pre-divisor if neccessary */ 994 /* set up N , fractional mode and pre-divisor if neccessary */
1041 wm8990_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | 995 snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM |
1042 (pll_div.div2?WM8990_PRESCALE:0)); 996 (pll_div.div2?WM8990_PRESCALE:0));
1043 wm8990_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); 997 snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8));
1044 wm8990_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); 998 snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF));
1045 } else { 999 } else {
1046 /* Turn on PLL */ 1000 /* Turn on PLL */
1047 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 1001 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1048 reg &= ~WM8990_PLL_ENA; 1002 reg &= ~WM8990_PLL_ENA;
1049 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg); 1003 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg);
1050 } 1004 }
1051 return 0; 1005 return 0;
1052} 1006}
@@ -1073,8 +1027,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
1073 struct snd_soc_codec *codec = codec_dai->codec; 1027 struct snd_soc_codec *codec = codec_dai->codec;
1074 u16 audio1, audio3; 1028 u16 audio1, audio3;
1075 1029
1076 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); 1030 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1077 audio3 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_3); 1031 audio3 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_3);
1078 1032
1079 /* set master/slave audio interface */ 1033 /* set master/slave audio interface */
1080 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1034 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -1115,8 +1069,8 @@ static int wm8990_set_dai_fmt(struct snd_soc_dai *codec_dai,
1115 return -EINVAL; 1069 return -EINVAL;
1116 } 1070 }
1117 1071
1118 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1); 1072 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1119 wm8990_write(codec, WM8990_AUDIO_INTERFACE_3, audio3); 1073 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_3, audio3);
1120 return 0; 1074 return 0;
1121} 1075}
1122 1076
@@ -1128,24 +1082,24 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1128 1082
1129 switch (div_id) { 1083 switch (div_id) {
1130 case WM8990_MCLK_DIV: 1084 case WM8990_MCLK_DIV:
1131 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1085 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1132 ~WM8990_MCLK_DIV_MASK; 1086 ~WM8990_MCLK_DIV_MASK;
1133 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1087 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1134 break; 1088 break;
1135 case WM8990_DACCLK_DIV: 1089 case WM8990_DACCLK_DIV:
1136 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1090 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1137 ~WM8990_DAC_CLKDIV_MASK; 1091 ~WM8990_DAC_CLKDIV_MASK;
1138 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1092 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1139 break; 1093 break;
1140 case WM8990_ADCCLK_DIV: 1094 case WM8990_ADCCLK_DIV:
1141 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_2) & 1095 reg = snd_soc_read(codec, WM8990_CLOCKING_2) &
1142 ~WM8990_ADC_CLKDIV_MASK; 1096 ~WM8990_ADC_CLKDIV_MASK;
1143 wm8990_write(codec, WM8990_CLOCKING_2, reg | div); 1097 snd_soc_write(codec, WM8990_CLOCKING_2, reg | div);
1144 break; 1098 break;
1145 case WM8990_BCLK_DIV: 1099 case WM8990_BCLK_DIV:
1146 reg = wm8990_read_reg_cache(codec, WM8990_CLOCKING_1) & 1100 reg = snd_soc_read(codec, WM8990_CLOCKING_1) &
1147 ~WM8990_BCLK_DIV_MASK; 1101 ~WM8990_BCLK_DIV_MASK;
1148 wm8990_write(codec, WM8990_CLOCKING_1, reg | div); 1102 snd_soc_write(codec, WM8990_CLOCKING_1, reg | div);
1149 break; 1103 break;
1150 default: 1104 default:
1151 return -EINVAL; 1105 return -EINVAL;
@@ -1164,7 +1118,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1164 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1165 struct snd_soc_device *socdev = rtd->socdev; 1119 struct snd_soc_device *socdev = rtd->socdev;
1166 struct snd_soc_codec *codec = socdev->card->codec; 1120 struct snd_soc_codec *codec = socdev->card->codec;
1167 u16 audio1 = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_1); 1121 u16 audio1 = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_1);
1168 1122
1169 audio1 &= ~WM8990_AIF_WL_MASK; 1123 audio1 &= ~WM8990_AIF_WL_MASK;
1170 /* bit size */ 1124 /* bit size */
@@ -1182,7 +1136,7 @@ static int wm8990_hw_params(struct snd_pcm_substream *substream,
1182 break; 1136 break;
1183 } 1137 }
1184 1138
1185 wm8990_write(codec, WM8990_AUDIO_INTERFACE_1, audio1); 1139 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_1, audio1);
1186 return 0; 1140 return 0;
1187} 1141}
1188 1142
@@ -1191,12 +1145,12 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute)
1191 struct snd_soc_codec *codec = dai->codec; 1145 struct snd_soc_codec *codec = dai->codec;
1192 u16 val; 1146 u16 val;
1193 1147
1194 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE; 1148 val = snd_soc_read(codec, WM8990_DAC_CTRL) & ~WM8990_DAC_MUTE;
1195 1149
1196 if (mute) 1150 if (mute)
1197 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1151 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1198 else 1152 else
1199 wm8990_write(codec, WM8990_DAC_CTRL, val); 1153 snd_soc_write(codec, WM8990_DAC_CTRL, val);
1200 1154
1201 return 0; 1155 return 0;
1202} 1156}
@@ -1212,21 +1166,21 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1212 1166
1213 case SND_SOC_BIAS_PREPARE: 1167 case SND_SOC_BIAS_PREPARE:
1214 /* VMID=2*50k */ 1168 /* VMID=2*50k */
1215 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) & 1169 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
1216 ~WM8990_VMID_MODE_MASK; 1170 ~WM8990_VMID_MODE_MASK;
1217 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2); 1171 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1218 break; 1172 break;
1219 1173
1220 case SND_SOC_BIAS_STANDBY: 1174 case SND_SOC_BIAS_STANDBY:
1221 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1175 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1222 /* Enable all output discharge bits */ 1176 /* Enable all output discharge bits */
1223 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1177 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1224 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1178 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1225 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | 1179 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1226 WM8990_DIS_ROUT); 1180 WM8990_DIS_ROUT);
1227 1181
1228 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */ 1182 /* Enable POBCTRL, SOFT_ST, VMIDTOG and BUFDCOPEN */
1229 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1183 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1230 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1184 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1231 WM8990_VMIDTOG); 1185 WM8990_VMIDTOG);
1232 1186
@@ -1234,83 +1188,83 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1234 msleep(msecs_to_jiffies(300)); 1188 msleep(msecs_to_jiffies(300));
1235 1189
1236 /* Disable VMIDTOG */ 1190 /* Disable VMIDTOG */
1237 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1191 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1238 WM8990_BUFDCOPEN | WM8990_POBCTRL); 1192 WM8990_BUFDCOPEN | WM8990_POBCTRL);
1239 1193
1240 /* disable all output discharge bits */ 1194 /* disable all output discharge bits */
1241 wm8990_write(codec, WM8990_ANTIPOP1, 0); 1195 snd_soc_write(codec, WM8990_ANTIPOP1, 0);
1242 1196
1243 /* Enable outputs */ 1197 /* Enable outputs */
1244 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00); 1198 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1b00);
1245 1199
1246 msleep(msecs_to_jiffies(50)); 1200 msleep(msecs_to_jiffies(50));
1247 1201
1248 /* Enable VMID at 2x50k */ 1202 /* Enable VMID at 2x50k */
1249 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02); 1203 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f02);
1250 1204
1251 msleep(msecs_to_jiffies(100)); 1205 msleep(msecs_to_jiffies(100));
1252 1206
1253 /* Enable VREF */ 1207 /* Enable VREF */
1254 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1208 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1255 1209
1256 msleep(msecs_to_jiffies(600)); 1210 msleep(msecs_to_jiffies(600));
1257 1211
1258 /* Enable BUFIOEN */ 1212 /* Enable BUFIOEN */
1259 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1213 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1260 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1214 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1261 WM8990_BUFIOEN); 1215 WM8990_BUFIOEN);
1262 1216
1263 /* Disable outputs */ 1217 /* Disable outputs */
1264 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3); 1218 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x3);
1265 1219
1266 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1220 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1267 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN); 1221 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1268 1222
1269 /* Enable workaround for ADC clocking issue. */ 1223 /* Enable workaround for ADC clocking issue. */
1270 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2); 1224 snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
1271 wm8990_write(codec, WM8990_EXT_CTL1, 0xa003); 1225 snd_soc_write(codec, WM8990_EXT_CTL1, 0xa003);
1272 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0); 1226 snd_soc_write(codec, WM8990_EXT_ACCESS_ENA, 0);
1273 } 1227 }
1274 1228
1275 /* VMID=2*250k */ 1229 /* VMID=2*250k */
1276 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) & 1230 val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) &
1277 ~WM8990_VMID_MODE_MASK; 1231 ~WM8990_VMID_MODE_MASK;
1278 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4); 1232 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1279 break; 1233 break;
1280 1234
1281 case SND_SOC_BIAS_OFF: 1235 case SND_SOC_BIAS_OFF:
1282 /* Enable POBCTRL and SOFT_ST */ 1236 /* Enable POBCTRL and SOFT_ST */
1283 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1237 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1284 WM8990_POBCTRL | WM8990_BUFIOEN); 1238 WM8990_POBCTRL | WM8990_BUFIOEN);
1285 1239
1286 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */ 1240 /* Enable POBCTRL, SOFT_ST and BUFDCOPEN */
1287 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST | 1241 snd_soc_write(codec, WM8990_ANTIPOP2, WM8990_SOFTST |
1288 WM8990_BUFDCOPEN | WM8990_POBCTRL | 1242 WM8990_BUFDCOPEN | WM8990_POBCTRL |
1289 WM8990_BUFIOEN); 1243 WM8990_BUFIOEN);
1290 1244
1291 /* mute DAC */ 1245 /* mute DAC */
1292 val = wm8990_read_reg_cache(codec, WM8990_DAC_CTRL); 1246 val = snd_soc_read(codec, WM8990_DAC_CTRL);
1293 wm8990_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); 1247 snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE);
1294 1248
1295 /* Enable any disabled outputs */ 1249 /* Enable any disabled outputs */
1296 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); 1250 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03);
1297 1251
1298 /* Disable VMID */ 1252 /* Disable VMID */
1299 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01); 1253 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f01);
1300 1254
1301 msleep(msecs_to_jiffies(300)); 1255 msleep(msecs_to_jiffies(300));
1302 1256
1303 /* Enable all output discharge bits */ 1257 /* Enable all output discharge bits */
1304 wm8990_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1258 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1305 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1259 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
1306 WM8990_DIS_OUT4 | WM8990_DIS_LOUT | 1260 WM8990_DIS_OUT4 | WM8990_DIS_LOUT |
1307 WM8990_DIS_ROUT); 1261 WM8990_DIS_ROUT);
1308 1262
1309 /* Disable VREF */ 1263 /* Disable VREF */
1310 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0); 1264 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x0);
1311 1265
1312 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1266 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1313 wm8990_write(codec, WM8990_ANTIPOP2, 0x0); 1267 snd_soc_write(codec, WM8990_ANTIPOP2, 0x0);
1314 break; 1268 break;
1315 } 1269 }
1316 1270
@@ -1411,8 +1365,6 @@ static int wm8990_init(struct snd_soc_device *socdev)
1411 1365
1412 codec->name = "WM8990"; 1366 codec->name = "WM8990";
1413 codec->owner = THIS_MODULE; 1367 codec->owner = THIS_MODULE;
1414 codec->read = wm8990_read_reg_cache;
1415 codec->write = wm8990_write;
1416 codec->set_bias_level = wm8990_set_bias_level; 1368 codec->set_bias_level = wm8990_set_bias_level;
1417 codec->dai = &wm8990_dai; 1369 codec->dai = &wm8990_dai;
1418 codec->num_dai = 2; 1370 codec->num_dai = 2;
@@ -1422,6 +1374,12 @@ static int wm8990_init(struct snd_soc_device *socdev)
1422 if (codec->reg_cache == NULL) 1374 if (codec->reg_cache == NULL)
1423 return -ENOMEM; 1375 return -ENOMEM;
1424 1376
1377 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1378 if (ret < 0) {
1379 printk(KERN_ERR "wm8990: failed to set cache I/O: %d\n", ret);
1380 goto pcm_err;
1381 }
1382
1425 wm8990_reset(codec); 1383 wm8990_reset(codec);
1426 1384
1427 /* register pcms */ 1385 /* register pcms */
@@ -1435,18 +1393,18 @@ static int wm8990_init(struct snd_soc_device *socdev)
1435 codec->bias_level = SND_SOC_BIAS_OFF; 1393 codec->bias_level = SND_SOC_BIAS_OFF;
1436 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1394 wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1437 1395
1438 reg = wm8990_read_reg_cache(codec, WM8990_AUDIO_INTERFACE_4); 1396 reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4);
1439 wm8990_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1); 1397 snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1);
1440 1398
1441 reg = wm8990_read_reg_cache(codec, WM8990_GPIO1_GPIO2) & 1399 reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) &
1442 ~WM8990_GPIO1_SEL_MASK; 1400 ~WM8990_GPIO1_SEL_MASK;
1443 wm8990_write(codec, WM8990_GPIO1_GPIO2, reg | 1); 1401 snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1);
1444 1402
1445 reg = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_2); 1403 reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2);
1446 wm8990_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA); 1404 snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA);
1447 1405
1448 wm8990_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1406 snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8));
1449 wm8990_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); 1407 snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8));
1450 1408
1451 snd_soc_add_controls(codec, wm8990_snd_controls, 1409 snd_soc_add_controls(codec, wm8990_snd_controls,
1452 ARRAY_SIZE(wm8990_snd_controls)); 1410 ARRAY_SIZE(wm8990_snd_controls));
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
new file mode 100644
index 000000000000..d9987999e92c
--- /dev/null
+++ b/sound/soc/codecs/wm8993.c
@@ -0,0 +1,1675 @@
1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 *
4 * Copyright 2009 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/spi/spi.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/tlv.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/wm8993.h>
28
29#include "wm8993.h"
30#include "wm_hubs.h"
31
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */
35 0x6000, /* R2 - Power Management (2) */
36 0x0000, /* R3 - Power Management (3) */
37 0x4050, /* R4 - Audio Interface (1) */
38 0x4000, /* R5 - Audio Interface (2) */
39 0x01C8, /* R6 - Clocking 1 */
40 0x0000, /* R7 - Clocking 2 */
41 0x0000, /* R8 - Audio Interface (3) */
42 0x0040, /* R9 - Audio Interface (4) */
43 0x0004, /* R10 - DAC CTRL */
44 0x00C0, /* R11 - Left DAC Digital Volume */
45 0x00C0, /* R12 - Right DAC Digital Volume */
46 0x0000, /* R13 - Digital Side Tone */
47 0x0300, /* R14 - ADC CTRL */
48 0x00C0, /* R15 - Left ADC Digital Volume */
49 0x00C0, /* R16 - Right ADC Digital Volume */
50 0x0000, /* R17 */
51 0x0000, /* R18 - GPIO CTRL 1 */
52 0x0010, /* R19 - GPIO1 */
53 0x0000, /* R20 - IRQ_DEBOUNCE */
54 0x0000, /* R21 */
55 0x8000, /* R22 - GPIOCTRL 2 */
56 0x0800, /* R23 - GPIO_POL */
57 0x008B, /* R24 - Left Line Input 1&2 Volume */
58 0x008B, /* R25 - Left Line Input 3&4 Volume */
59 0x008B, /* R26 - Right Line Input 1&2 Volume */
60 0x008B, /* R27 - Right Line Input 3&4 Volume */
61 0x006D, /* R28 - Left Output Volume */
62 0x006D, /* R29 - Right Output Volume */
63 0x0066, /* R30 - Line Outputs Volume */
64 0x0020, /* R31 - HPOUT2 Volume */
65 0x0079, /* R32 - Left OPGA Volume */
66 0x0079, /* R33 - Right OPGA Volume */
67 0x0003, /* R34 - SPKMIXL Attenuation */
68 0x0003, /* R35 - SPKMIXR Attenuation */
69 0x0011, /* R36 - SPKOUT Mixers */
70 0x0100, /* R37 - SPKOUT Boost */
71 0x0079, /* R38 - Speaker Volume Left */
72 0x0079, /* R39 - Speaker Volume Right */
73 0x0000, /* R40 - Input Mixer2 */
74 0x0000, /* R41 - Input Mixer3 */
75 0x0000, /* R42 - Input Mixer4 */
76 0x0000, /* R43 - Input Mixer5 */
77 0x0000, /* R44 - Input Mixer6 */
78 0x0000, /* R45 - Output Mixer1 */
79 0x0000, /* R46 - Output Mixer2 */
80 0x0000, /* R47 - Output Mixer3 */
81 0x0000, /* R48 - Output Mixer4 */
82 0x0000, /* R49 - Output Mixer5 */
83 0x0000, /* R50 - Output Mixer6 */
84 0x0000, /* R51 - HPOUT2 Mixer */
85 0x0000, /* R52 - Line Mixer1 */
86 0x0000, /* R53 - Line Mixer2 */
87 0x0000, /* R54 - Speaker Mixer */
88 0x0000, /* R55 - Additional Control */
89 0x0000, /* R56 - AntiPOP1 */
90 0x0000, /* R57 - AntiPOP2 */
91 0x0000, /* R58 - MICBIAS */
92 0x0000, /* R59 */
93 0x0000, /* R60 - FLL Control 1 */
94 0x0000, /* R61 - FLL Control 2 */
95 0x0000, /* R62 - FLL Control 3 */
96 0x2EE0, /* R63 - FLL Control 4 */
97 0x0002, /* R64 - FLL Control 5 */
98 0x2287, /* R65 - Clocking 3 */
99 0x025F, /* R66 - Clocking 4 */
100 0x0000, /* R67 - MW Slave Control */
101 0x0000, /* R68 */
102 0x0002, /* R69 - Bus Control 1 */
103 0x0000, /* R70 - Write Sequencer 0 */
104 0x0000, /* R71 - Write Sequencer 1 */
105 0x0000, /* R72 - Write Sequencer 2 */
106 0x0000, /* R73 - Write Sequencer 3 */
107 0x0000, /* R74 - Write Sequencer 4 */
108 0x0000, /* R75 - Write Sequencer 5 */
109 0x1F25, /* R76 - Charge Pump 1 */
110 0x0000, /* R77 */
111 0x0000, /* R78 */
112 0x0000, /* R79 */
113 0x0000, /* R80 */
114 0x0000, /* R81 - Class W 0 */
115 0x0000, /* R82 */
116 0x0000, /* R83 */
117 0x0000, /* R84 - DC Servo 0 */
118 0x054A, /* R85 - DC Servo 1 */
119 0x0000, /* R86 */
120 0x0000, /* R87 - DC Servo 3 */
121 0x0000, /* R88 - DC Servo Readback 0 */
122 0x0000, /* R89 - DC Servo Readback 1 */
123 0x0000, /* R90 - DC Servo Readback 2 */
124 0x0000, /* R91 */
125 0x0000, /* R92 */
126 0x0000, /* R93 */
127 0x0000, /* R94 */
128 0x0000, /* R95 */
129 0x0100, /* R96 - Analogue HP 0 */
130 0x0000, /* R97 */
131 0x0000, /* R98 - EQ1 */
132 0x000C, /* R99 - EQ2 */
133 0x000C, /* R100 - EQ3 */
134 0x000C, /* R101 - EQ4 */
135 0x000C, /* R102 - EQ5 */
136 0x000C, /* R103 - EQ6 */
137 0x0FCA, /* R104 - EQ7 */
138 0x0400, /* R105 - EQ8 */
139 0x00D8, /* R106 - EQ9 */
140 0x1EB5, /* R107 - EQ10 */
141 0xF145, /* R108 - EQ11 */
142 0x0B75, /* R109 - EQ12 */
143 0x01C5, /* R110 - EQ13 */
144 0x1C58, /* R111 - EQ14 */
145 0xF373, /* R112 - EQ15 */
146 0x0A54, /* R113 - EQ16 */
147 0x0558, /* R114 - EQ17 */
148 0x168E, /* R115 - EQ18 */
149 0xF829, /* R116 - EQ19 */
150 0x07AD, /* R117 - EQ20 */
151 0x1103, /* R118 - EQ21 */
152 0x0564, /* R119 - EQ22 */
153 0x0559, /* R120 - EQ23 */
154 0x4000, /* R121 - EQ24 */
155 0x0000, /* R122 - Digital Pulls */
156 0x0F08, /* R123 - DRC Control 1 */
157 0x0000, /* R124 - DRC Control 2 */
158 0x0080, /* R125 - DRC Control 3 */
159 0x0000, /* R126 - DRC Control 4 */
160};
161
162static struct {
163 int ratio;
164 int clk_sys_rate;
165} clk_sys_rates[] = {
166 { 64, 0 },
167 { 128, 1 },
168 { 192, 2 },
169 { 256, 3 },
170 { 384, 4 },
171 { 512, 5 },
172 { 768, 6 },
173 { 1024, 7 },
174 { 1408, 8 },
175 { 1536, 9 },
176};
177
178static struct {
179 int rate;
180 int sample_rate;
181} sample_rates[] = {
182 { 8000, 0 },
183 { 11025, 1 },
184 { 12000, 1 },
185 { 16000, 2 },
186 { 22050, 3 },
187 { 24000, 3 },
188 { 32000, 4 },
189 { 44100, 5 },
190 { 48000, 5 },
191};
192
193static struct {
194 int div; /* *10 due to .5s */
195 int bclk_div;
196} bclk_divs[] = {
197 { 10, 0 },
198 { 15, 1 },
199 { 20, 2 },
200 { 30, 3 },
201 { 40, 4 },
202 { 55, 5 },
203 { 60, 6 },
204 { 80, 7 },
205 { 110, 8 },
206 { 120, 9 },
207 { 160, 10 },
208 { 220, 11 },
209 { 240, 12 },
210 { 320, 13 },
211 { 440, 14 },
212 { 480, 15 },
213};
214
215struct wm8993_priv {
216 u16 reg_cache[WM8993_REGISTER_COUNT];
217 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec;
219 int master;
220 int sysclk_source;
221 int tdm_slots;
222 int tdm_width;
223 unsigned int mclk_rate;
224 unsigned int sysclk_rate;
225 unsigned int fs;
226 unsigned int bclk;
227 int class_w_users;
228 unsigned int fll_fref;
229 unsigned int fll_fout;
230};
231
232static unsigned int wm8993_read_hw(struct snd_soc_codec *codec, u8 reg)
233{
234 struct i2c_msg xfer[2];
235 u16 data;
236 int ret;
237 struct i2c_client *i2c = codec->control_data;
238
239 /* Write register */
240 xfer[0].addr = i2c->addr;
241 xfer[0].flags = 0;
242 xfer[0].len = 1;
243 xfer[0].buf = &reg;
244
245 /* Read data */
246 xfer[1].addr = i2c->addr;
247 xfer[1].flags = I2C_M_RD;
248 xfer[1].len = 2;
249 xfer[1].buf = (u8 *)&data;
250
251 ret = i2c_transfer(i2c->adapter, xfer, 2);
252 if (ret != 2) {
253 dev_err(codec->dev, "Failed to read 0x%x: %d\n", reg, ret);
254 return 0;
255 }
256
257 return (data >> 8) | ((data & 0xff) << 8);
258}
259
260static int wm8993_volatile(unsigned int reg)
261{
262 switch (reg) {
263 case WM8993_SOFTWARE_RESET:
264 case WM8993_DC_SERVO_0:
265 case WM8993_DC_SERVO_READBACK_0:
266 case WM8993_DC_SERVO_READBACK_1:
267 case WM8993_DC_SERVO_READBACK_2:
268 return 1;
269 default:
270 return 0;
271 }
272}
273
274static unsigned int wm8993_read(struct snd_soc_codec *codec,
275 unsigned int reg)
276{
277 u16 *reg_cache = codec->reg_cache;
278
279 BUG_ON(reg > WM8993_MAX_REGISTER);
280
281 if (wm8993_volatile(reg))
282 return wm8993_read_hw(codec, reg);
283 else
284 return reg_cache[reg];
285}
286
287static int wm8993_write(struct snd_soc_codec *codec, unsigned int reg,
288 unsigned int value)
289{
290 u16 *reg_cache = codec->reg_cache;
291 u8 data[3];
292 int ret;
293
294 BUG_ON(reg > WM8993_MAX_REGISTER);
295
296 /* data is
297 * D15..D9 WM8993 register offset
298 * D8...D0 register data
299 */
300 data[0] = reg;
301 data[1] = value >> 8;
302 data[2] = value & 0x00ff;
303
304 if (!wm8993_volatile(reg))
305 reg_cache[reg] = value;
306
307 ret = codec->hw_write(codec->control_data, data, 3);
308
309 if (ret == 3)
310 return 0;
311 if (ret < 0)
312 return ret;
313 return -EIO;
314}
315
316struct _fll_div {
317 u16 fll_fratio;
318 u16 fll_outdiv;
319 u16 fll_clk_ref_div;
320 u16 n;
321 u16 k;
322};
323
324/* The size in bits of the FLL divide multiplied by 10
325 * to allow rounding later */
326#define FIXED_FLL_SIZE ((1 << 16) * 10)
327
328static struct {
329 unsigned int min;
330 unsigned int max;
331 u16 fll_fratio;
332 int ratio;
333} fll_fratios[] = {
334 { 0, 64000, 4, 16 },
335 { 64000, 128000, 3, 8 },
336 { 128000, 256000, 2, 4 },
337 { 256000, 1000000, 1, 2 },
338 { 1000000, 13500000, 0, 1 },
339};
340
341static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
342 unsigned int Fout)
343{
344 u64 Kpart;
345 unsigned int K, Ndiv, Nmod, target;
346 unsigned int div;
347 int i;
348
349 /* Fref must be <=13.5MHz */
350 div = 1;
351 fll_div->fll_clk_ref_div = 0;
352 while ((Fref / div) > 13500000) {
353 div *= 2;
354 fll_div->fll_clk_ref_div++;
355
356 if (div > 8) {
357 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
358 Fref);
359 return -EINVAL;
360 }
361 }
362
363 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
364
365 /* Apply the division for our remaining calculations */
366 Fref /= div;
367
368 /* Fvco should be 90-100MHz; don't check the upper bound */
369 div = 0;
370 target = Fout * 2;
371 while (target < 90000000) {
372 div++;
373 target *= 2;
374 if (div > 7) {
375 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
376 Fout);
377 return -EINVAL;
378 }
379 }
380 fll_div->fll_outdiv = div;
381
382 pr_debug("Fvco=%dHz\n", target);
383
384 /* Find an appropraite FLL_FRATIO and factor it out of the target */
385 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
386 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
387 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
388 target /= fll_fratios[i].ratio;
389 break;
390 }
391 }
392 if (i == ARRAY_SIZE(fll_fratios)) {
393 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
394 return -EINVAL;
395 }
396
397 /* Now, calculate N.K */
398 Ndiv = target / Fref;
399
400 fll_div->n = Ndiv;
401 Nmod = target % Fref;
402 pr_debug("Nmod=%d\n", Nmod);
403
404 /* Calculate fractional part - scale up so we can round. */
405 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
406
407 do_div(Kpart, Fref);
408
409 K = Kpart & 0xFFFFFFFF;
410
411 if ((K % 10) >= 5)
412 K += 5;
413
414 /* Move down to proper range now rounding is done */
415 fll_div->k = K / 10;
416
417 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
418 fll_div->n, fll_div->k,
419 fll_div->fll_fratio, fll_div->fll_outdiv,
420 fll_div->fll_clk_ref_div);
421
422 return 0;
423}
424
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id,
426 unsigned int Fref, unsigned int Fout)
427{
428 struct snd_soc_codec *codec = dai->codec;
429 struct wm8993_priv *wm8993 = codec->private_data;
430 u16 reg1, reg4, reg5;
431 struct _fll_div fll_div;
432 int ret;
433
434 /* Any change? */
435 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout)
436 return 0;
437
438 /* Disable the FLL */
439 if (Fout == 0) {
440 dev_dbg(codec->dev, "FLL disabled\n");
441 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0;
443
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
447
448 return 0;
449 }
450
451 ret = fll_factors(&fll_div, Fref, Fout);
452 if (ret != 0)
453 return ret;
454
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457
458 switch (fll_id) {
459 case WM8993_FLL_MCLK:
460 break;
461
462 case WM8993_FLL_LRCLK:
463 reg5 |= 1;
464 break;
465
466 case WM8993_FLL_BCLK:
467 reg5 |= 2;
468 break;
469
470 default:
471 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
472 return -EINVAL;
473 }
474
475 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
480
481 /* Apply the configuration */
482 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK;
484 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1);
487
488 wm8993_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4);
497
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5);
501
502 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506
507 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout;
509
510 return 0;
511}
512
513static int configure_clock(struct snd_soc_codec *codec)
514{
515 struct wm8993_priv *wm8993 = codec->private_data;
516 unsigned int reg;
517
518 /* This should be done on init() for bypass paths */
519 switch (wm8993->sysclk_source) {
520 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522
523 reg = wm8993_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV;
527 wm8993->sysclk_rate = wm8993->mclk_rate / 2;
528 } else {
529 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate;
531 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg);
533 break;
534
535 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout);
538
539 reg = wm8993_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV;
543 wm8993->sysclk_rate = wm8993->fll_fout / 2;
544 } else {
545 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout;
547 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg);
549 break;
550
551 default:
552 dev_err(codec->dev, "System clock not configured\n");
553 return -EINVAL;
554 }
555
556 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8993->sysclk_rate);
557
558 return 0;
559}
560
561static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
562static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0);
563static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0);
564static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0);
565static const unsigned int drc_max_tlv[] = {
566 TLV_DB_RANGE_HEAD(4),
567 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
568 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0),
569};
570static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0);
571static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -1800, 300, 0);
572static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
573static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
574static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
575
576static const char *dac_deemph_text[] = {
577 "None",
578 "32kHz",
579 "44.1kHz",
580 "48kHz",
581};
582
583static const struct soc_enum dac_deemph =
584 SOC_ENUM_SINGLE(WM8993_DAC_CTRL, 4, 4, dac_deemph_text);
585
586static const char *adc_hpf_text[] = {
587 "Hi-Fi",
588 "Voice 1",
589 "Voice 2",
590 "Voice 3",
591};
592
593static const struct soc_enum adc_hpf =
594 SOC_ENUM_SINGLE(WM8993_ADC_CTRL, 5, 4, adc_hpf_text);
595
596static const char *drc_path_text[] = {
597 "ADC",
598 "DAC"
599};
600
601static const struct soc_enum drc_path =
602 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 14, 2, drc_path_text);
603
604static const char *drc_r0_text[] = {
605 "1",
606 "1/2",
607 "1/4",
608 "1/8",
609 "1/16",
610 "0",
611};
612
613static const struct soc_enum drc_r0 =
614 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 8, 6, drc_r0_text);
615
616static const char *drc_r1_text[] = {
617 "1",
618 "1/2",
619 "1/4",
620 "1/8",
621 "0",
622};
623
624static const struct soc_enum drc_r1 =
625 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_4, 13, 5, drc_r1_text);
626
627static const char *drc_attack_text[] = {
628 "Reserved",
629 "181us",
630 "363us",
631 "726us",
632 "1.45ms",
633 "2.9ms",
634 "5.8ms",
635 "11.6ms",
636 "23.2ms",
637 "46.4ms",
638 "92.8ms",
639 "185.6ms",
640};
641
642static const struct soc_enum drc_attack =
643 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 12, 12, drc_attack_text);
644
645static const char *drc_decay_text[] = {
646 "186ms",
647 "372ms",
648 "743ms",
649 "1.49s",
650 "2.97ms",
651 "5.94ms",
652 "11.89ms",
653 "23.78ms",
654 "47.56ms",
655};
656
657static const struct soc_enum drc_decay =
658 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_2, 8, 9, drc_decay_text);
659
660static const char *drc_ff_text[] = {
661 "5 samples",
662 "9 samples",
663};
664
665static const struct soc_enum drc_ff =
666 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 7, 2, drc_ff_text);
667
668static const char *drc_qr_rate_text[] = {
669 "0.725ms",
670 "1.45ms",
671 "5.8ms",
672};
673
674static const struct soc_enum drc_qr_rate =
675 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_3, 0, 3, drc_qr_rate_text);
676
677static const char *drc_smooth_text[] = {
678 "Low",
679 "Medium",
680 "High",
681};
682
683static const struct soc_enum drc_smooth =
684 SOC_ENUM_SINGLE(WM8993_DRC_CONTROL_1, 4, 3, drc_smooth_text);
685
686static const struct snd_kcontrol_new wm8993_snd_controls[] = {
687SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
688 5, 9, 12, 0, sidetone_tlv),
689
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp),
696SOC_ENUM("DRC R0", drc_r0),
697SOC_ENUM("DRC R1", drc_r1),
698SOC_SINGLE_TLV("DRC Minimum Volume", WM8993_DRC_CONTROL_1, 2, 3, 1,
699 drc_min_tlv),
700SOC_SINGLE_TLV("DRC Maximum Volume", WM8993_DRC_CONTROL_1, 0, 3, 0,
701 drc_max_tlv),
702SOC_ENUM("DRC Attack Rate", drc_attack),
703SOC_ENUM("DRC Decay Rate", drc_decay),
704SOC_ENUM("DRC FF Delay", drc_ff),
705SOC_SINGLE("DRC Anti-clip Switch", WM8993_DRC_CONTROL_1, 9, 1, 0),
706SOC_SINGLE("DRC Quick Release Switch", WM8993_DRC_CONTROL_1, 10, 1, 0),
707SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
708 drc_qr_tlv),
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv),
715
716SOC_SINGLE("EQ Switch", WM8993_EQ1, 0, 1, 0),
717
718SOC_DOUBLE_R_TLV("Capture Volume", WM8993_LEFT_ADC_DIGITAL_VOLUME,
719 WM8993_RIGHT_ADC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
720SOC_SINGLE("ADC High Pass Filter Switch", WM8993_ADC_CTRL, 8, 1, 0),
721SOC_ENUM("ADC High Pass Filter Mode", adc_hpf),
722
723SOC_DOUBLE_R_TLV("Playback Volume", WM8993_LEFT_DAC_DIGITAL_VOLUME,
724 WM8993_RIGHT_DAC_DIGITAL_VOLUME, 1, 96, 0, digital_tlv),
725SOC_SINGLE_TLV("Playback Boost Volume", WM8993_AUDIO_INTERFACE_2, 10, 3, 0,
726 dac_boost_tlv),
727SOC_ENUM("DAC Deemphasis", dac_deemph),
728
729SOC_SINGLE_TLV("SPKL DAC Volume", WM8993_SPKMIXL_ATTENUATION,
730 2, 1, 1, wm_hubs_spkmix_tlv),
731
732SOC_SINGLE_TLV("SPKR DAC Volume", WM8993_SPKMIXR_ATTENUATION,
733 2, 1, 1, wm_hubs_spkmix_tlv),
734};
735
736static const struct snd_kcontrol_new wm8993_eq_controls[] = {
737SOC_SINGLE_TLV("EQ1 Volume", WM8993_EQ2, 0, 24, 0, eq_tlv),
738SOC_SINGLE_TLV("EQ2 Volume", WM8993_EQ3, 0, 24, 0, eq_tlv),
739SOC_SINGLE_TLV("EQ3 Volume", WM8993_EQ4, 0, 24, 0, eq_tlv),
740SOC_SINGLE_TLV("EQ4 Volume", WM8993_EQ5, 0, 24, 0, eq_tlv),
741SOC_SINGLE_TLV("EQ5 Volume", WM8993_EQ6, 0, 24, 0, eq_tlv),
742};
743
744static int clk_sys_event(struct snd_soc_dapm_widget *w,
745 struct snd_kcontrol *kcontrol, int event)
746{
747 struct snd_soc_codec *codec = w->codec;
748
749 switch (event) {
750 case SND_SOC_DAPM_PRE_PMU:
751 return configure_clock(codec);
752
753 case SND_SOC_DAPM_POST_PMD:
754 break;
755 }
756
757 return 0;
758}
759
760/*
761 * When used with DAC outputs only the WM8993 charge pump supports
762 * operation in class W mode, providing very low power consumption
763 * when used with digital sources. Enable and disable this mode
764 * automatically depending on the mixer configuration.
765 *
766 * Currently the only supported paths are the direct DAC->headphone
767 * paths (which provide minimum power consumption anyway).
768 */
769static int class_w_put(struct snd_kcontrol *kcontrol,
770 struct snd_ctl_elem_value *ucontrol)
771{
772 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
773 struct snd_soc_codec *codec = widget->codec;
774 struct wm8993_priv *wm8993 = codec->private_data;
775 int ret;
776
777 /* Turn it off if we're using the main output mixer */
778 if (ucontrol->value.integer.value[0] == 0) {
779 if (wm8993->class_w_users == 0) {
780 dev_dbg(codec->dev, "Disabling Class W\n");
781 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
782 WM8993_CP_DYN_FREQ |
783 WM8993_CP_DYN_V,
784 0);
785 }
786 wm8993->class_w_users++;
787 }
788
789 /* Implement the change */
790 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
791
792 /* Enable it if we're using the direct DAC path */
793 if (ucontrol->value.integer.value[0] == 1) {
794 if (wm8993->class_w_users == 1) {
795 dev_dbg(codec->dev, "Enabling Class W\n");
796 snd_soc_update_bits(codec, WM8993_CLASS_W_0,
797 WM8993_CP_DYN_FREQ |
798 WM8993_CP_DYN_V,
799 WM8993_CP_DYN_FREQ |
800 WM8993_CP_DYN_V);
801 }
802 wm8993->class_w_users--;
803 }
804
805 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
806 wm8993->class_w_users);
807
808 return ret;
809}
810
811#define SOC_DAPM_ENUM_W(xname, xenum) \
812{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
813 .info = snd_soc_info_enum_double, \
814 .get = snd_soc_dapm_get_enum_double, \
815 .put = class_w_put, \
816 .private_value = (unsigned long)&xenum }
817
818static const char *hp_mux_text[] = {
819 "Mixer",
820 "DAC",
821};
822
823static const struct soc_enum hpl_enum =
824 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER1, 8, 2, hp_mux_text);
825
826static const struct snd_kcontrol_new hpl_mux =
827 SOC_DAPM_ENUM_W("Left Headphone Mux", hpl_enum);
828
829static const struct soc_enum hpr_enum =
830 SOC_ENUM_SINGLE(WM8993_OUTPUT_MIXER2, 8, 2, hp_mux_text);
831
832static const struct snd_kcontrol_new hpr_mux =
833 SOC_DAPM_ENUM_W("Right Headphone Mux", hpr_enum);
834
835static const struct snd_kcontrol_new left_speaker_mixer[] = {
836SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 7, 1, 0),
837SOC_DAPM_SINGLE("IN1LP Switch", WM8993_SPEAKER_MIXER, 5, 1, 0),
838SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 3, 1, 0),
839SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
840};
841
842static const struct snd_kcontrol_new right_speaker_mixer[] = {
843SOC_DAPM_SINGLE("Input Switch", WM8993_SPEAKER_MIXER, 6, 1, 0),
844SOC_DAPM_SINGLE("IN1RP Switch", WM8993_SPEAKER_MIXER, 4, 1, 0),
845SOC_DAPM_SINGLE("Output Switch", WM8993_SPEAKER_MIXER, 2, 1, 0),
846SOC_DAPM_SINGLE("DAC Switch", WM8993_SPEAKER_MIXER, 0, 1, 0),
847};
848
849static const char *aif_text[] = {
850 "Left", "Right"
851};
852
853static const struct soc_enum aifoutl_enum =
854 SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 15, 2, aif_text);
855
856static const struct snd_kcontrol_new aifoutl_mux =
857 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
858
859static const struct soc_enum aifoutr_enum =
860 SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_1, 14, 2, aif_text);
861
862static const struct snd_kcontrol_new aifoutr_mux =
863 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
864
865static const struct soc_enum aifinl_enum =
866 SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 15, 2, aif_text);
867
868static const struct snd_kcontrol_new aifinl_mux =
869 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
870
871static const struct soc_enum aifinr_enum =
872 SOC_ENUM_SINGLE(WM8993_AUDIO_INTERFACE_2, 14, 2, aif_text);
873
874static const struct snd_kcontrol_new aifinr_mux =
875 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
876
877static const char *sidetone_text[] = {
878 "None", "Left", "Right"
879};
880
881static const struct soc_enum sidetonel_enum =
882 SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 2, 3, sidetone_text);
883
884static const struct snd_kcontrol_new sidetonel_mux =
885 SOC_DAPM_ENUM("Left Sidetone", sidetonel_enum);
886
887static const struct soc_enum sidetoner_enum =
888 SOC_ENUM_SINGLE(WM8993_DIGITAL_SIDE_TONE, 0, 3, sidetone_text);
889
890static const struct snd_kcontrol_new sidetoner_mux =
891 SOC_DAPM_ENUM("Right Sidetone", sidetoner_enum);
892
893static const struct snd_soc_dapm_widget wm8993_dapm_widgets[] = {
894SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event,
895 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
896SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0),
897SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0),
898
899SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0),
900SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0),
901
902SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
903SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
904
905SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
906SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
907
908SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
909SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
910
911SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
912SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
913
914SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &sidetonel_mux),
915SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &sidetoner_mux),
916
917SND_SOC_DAPM_DAC("DACL", NULL, WM8993_POWER_MANAGEMENT_3, 1, 0),
918SND_SOC_DAPM_DAC("DACR", NULL, WM8993_POWER_MANAGEMENT_3, 0, 0),
919
920SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
921SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
922
923SND_SOC_DAPM_MIXER("SPKL", WM8993_POWER_MANAGEMENT_3, 8, 0,
924 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
925SND_SOC_DAPM_MIXER("SPKR", WM8993_POWER_MANAGEMENT_3, 9, 0,
926 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
927
928};
929
930static const struct snd_soc_dapm_route routes[] = {
931 { "ADCL", NULL, "CLK_SYS" },
932 { "ADCL", NULL, "CLK_DSP" },
933 { "ADCR", NULL, "CLK_SYS" },
934 { "ADCR", NULL, "CLK_DSP" },
935
936 { "AIFOUTL Mux", "Left", "ADCL" },
937 { "AIFOUTL Mux", "Right", "ADCR" },
938 { "AIFOUTR Mux", "Left", "ADCL" },
939 { "AIFOUTR Mux", "Right", "ADCR" },
940
941 { "AIFOUTL", NULL, "AIFOUTL Mux" },
942 { "AIFOUTR", NULL, "AIFOUTR Mux" },
943
944 { "DACL Mux", "Left", "AIFINL" },
945 { "DACL Mux", "Right", "AIFINR" },
946 { "DACR Mux", "Left", "AIFINL" },
947 { "DACR Mux", "Right", "AIFINR" },
948
949 { "DACL Sidetone", "Left", "ADCL" },
950 { "DACL Sidetone", "Right", "ADCR" },
951 { "DACR Sidetone", "Left", "ADCL" },
952 { "DACR Sidetone", "Right", "ADCR" },
953
954 { "DACL", NULL, "CLK_SYS" },
955 { "DACL", NULL, "CLK_DSP" },
956 { "DACL", NULL, "DACL Mux" },
957 { "DACL", NULL, "DACL Sidetone" },
958 { "DACR", NULL, "CLK_SYS" },
959 { "DACR", NULL, "CLK_DSP" },
960 { "DACR", NULL, "DACR Mux" },
961 { "DACR", NULL, "DACR Sidetone" },
962
963 { "Left Output Mixer", "DAC Switch", "DACL" },
964
965 { "Right Output Mixer", "DAC Switch", "DACR" },
966
967 { "Left Output PGA", NULL, "CLK_SYS" },
968
969 { "Right Output PGA", NULL, "CLK_SYS" },
970
971 { "SPKL", "DAC Switch", "DACL" },
972 { "SPKL", NULL, "CLK_SYS" },
973
974 { "SPKR", "DAC Switch", "DACR" },
975 { "SPKR", NULL, "CLK_SYS" },
976
977 { "Left Headphone Mux", "DAC", "DACL" },
978 { "Right Headphone Mux", "DAC", "DACR" },
979};
980
981static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level)
983{
984 struct wm8993_priv *wm8993 = codec->private_data;
985
986 switch (level) {
987 case SND_SOC_BIAS_ON:
988 case SND_SOC_BIAS_PREPARE:
989 /* VMID=2*40k */
990 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
991 WM8993_VMID_SEL_MASK, 0x2);
992 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
993 WM8993_TSHUT_ENA, WM8993_TSHUT_ENA);
994 break;
995
996 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) {
998 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA |
1001 WM8993_VMID_BUF_ENA |
1002 WM8993_VMID_RAMP_MASK |
1003 WM8993_BIAS_SRC,
1004 WM8993_STARTUP_BIAS_ENA |
1005 WM8993_VMID_BUF_ENA |
1006 WM8993_VMID_RAMP_MASK |
1007 WM8993_BIAS_SRC);
1008
1009 /* If either line output is single ended we
1010 * need the VMID buffer */
1011 if (!wm8993->pdata.lineout1_diff ||
1012 !wm8993->pdata.lineout2_diff)
1013 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1014 WM8993_LINEOUT_VMID_BUF_ENA,
1015 WM8993_LINEOUT_VMID_BUF_ENA);
1016
1017 /* VMID=2*40k */
1018 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1019 WM8993_VMID_SEL_MASK |
1020 WM8993_BIAS_ENA,
1021 WM8993_BIAS_ENA | 0x2);
1022 msleep(32);
1023
1024 /* Switch to normal bias */
1025 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1026 WM8993_BIAS_SRC |
1027 WM8993_STARTUP_BIAS_ENA, 0);
1028 }
1029
1030 /* VMID=2*240k */
1031 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1032 WM8993_VMID_SEL_MASK, 0x4);
1033
1034 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_2,
1035 WM8993_TSHUT_ENA, 0);
1036 break;
1037
1038 case SND_SOC_BIAS_OFF:
1039 snd_soc_update_bits(codec, WM8993_ANTIPOP1,
1040 WM8993_LINEOUT_VMID_BUF_ENA, 0);
1041
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0);
1045 break;
1046 }
1047
1048 codec->bias_level = level;
1049
1050 return 0;
1051}
1052
1053static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai,
1054 int clk_id, unsigned int freq, int dir)
1055{
1056 struct snd_soc_codec *codec = codec_dai->codec;
1057 struct wm8993_priv *wm8993 = codec->private_data;
1058
1059 switch (clk_id) {
1060 case WM8993_SYSCLK_MCLK:
1061 wm8993->mclk_rate = freq;
1062 case WM8993_SYSCLK_FLL:
1063 wm8993->sysclk_source = clk_id;
1064 break;
1065
1066 default:
1067 return -EINVAL;
1068 }
1069
1070 return 0;
1071}
1072
1073static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1074 unsigned int fmt)
1075{
1076 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4);
1080
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
1083 aif4 &= ~WM8993_LRCLK_DIR;
1084
1085 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1086 case SND_SOC_DAIFMT_CBS_CFS:
1087 wm8993->master = 0;
1088 break;
1089 case SND_SOC_DAIFMT_CBS_CFM:
1090 aif4 |= WM8993_LRCLK_DIR;
1091 wm8993->master = 1;
1092 break;
1093 case SND_SOC_DAIFMT_CBM_CFS:
1094 aif1 |= WM8993_BCLK_DIR;
1095 wm8993->master = 1;
1096 break;
1097 case SND_SOC_DAIFMT_CBM_CFM:
1098 aif1 |= WM8993_BCLK_DIR;
1099 aif4 |= WM8993_LRCLK_DIR;
1100 wm8993->master = 1;
1101 break;
1102 default:
1103 return -EINVAL;
1104 }
1105
1106 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1107 case SND_SOC_DAIFMT_DSP_B:
1108 aif1 |= WM8993_AIF_LRCLK_INV;
1109 case SND_SOC_DAIFMT_DSP_A:
1110 aif1 |= 0x18;
1111 break;
1112 case SND_SOC_DAIFMT_I2S:
1113 aif1 |= 0x10;
1114 break;
1115 case SND_SOC_DAIFMT_RIGHT_J:
1116 break;
1117 case SND_SOC_DAIFMT_LEFT_J:
1118 aif1 |= 0x8;
1119 break;
1120 default:
1121 return -EINVAL;
1122 }
1123
1124 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1125 case SND_SOC_DAIFMT_DSP_A:
1126 case SND_SOC_DAIFMT_DSP_B:
1127 /* frame inversion not valid for DSP modes */
1128 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1129 case SND_SOC_DAIFMT_NB_NF:
1130 break;
1131 case SND_SOC_DAIFMT_IB_NF:
1132 aif1 |= WM8993_AIF_BCLK_INV;
1133 break;
1134 default:
1135 return -EINVAL;
1136 }
1137 break;
1138
1139 case SND_SOC_DAIFMT_I2S:
1140 case SND_SOC_DAIFMT_RIGHT_J:
1141 case SND_SOC_DAIFMT_LEFT_J:
1142 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1143 case SND_SOC_DAIFMT_NB_NF:
1144 break;
1145 case SND_SOC_DAIFMT_IB_IF:
1146 aif1 |= WM8993_AIF_BCLK_INV | WM8993_AIF_LRCLK_INV;
1147 break;
1148 case SND_SOC_DAIFMT_IB_NF:
1149 aif1 |= WM8993_AIF_BCLK_INV;
1150 break;
1151 case SND_SOC_DAIFMT_NB_IF:
1152 aif1 |= WM8993_AIF_LRCLK_INV;
1153 break;
1154 default:
1155 return -EINVAL;
1156 }
1157 break;
1158 default:
1159 return -EINVAL;
1160 }
1161
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164
1165 return 0;
1166}
1167
1168static int wm8993_hw_params(struct snd_pcm_substream *substream,
1169 struct snd_pcm_hw_params *params,
1170 struct snd_soc_dai *dai)
1171{
1172 struct snd_soc_codec *codec = dai->codec;
1173 struct wm8993_priv *wm8993 = codec->private_data;
1174 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4;
1176
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK;
1185
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188
1189 /* What BCLK do we need? */
1190 wm8993->fs = params_rate(params);
1191 wm8993->bclk = 2 * wm8993->fs;
1192 if (wm8993->tdm_slots) {
1193 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1194 wm8993->tdm_slots, wm8993->tdm_width);
1195 wm8993->bclk *= wm8993->tdm_width * wm8993->tdm_slots;
1196 } else {
1197 switch (params_format(params)) {
1198 case SNDRV_PCM_FORMAT_S16_LE:
1199 wm8993->bclk *= 16;
1200 break;
1201 case SNDRV_PCM_FORMAT_S20_3LE:
1202 wm8993->bclk *= 20;
1203 aif1 |= 0x8;
1204 break;
1205 case SNDRV_PCM_FORMAT_S24_LE:
1206 wm8993->bclk *= 24;
1207 aif1 |= 0x10;
1208 break;
1209 case SNDRV_PCM_FORMAT_S32_LE:
1210 wm8993->bclk *= 32;
1211 aif1 |= 0x18;
1212 break;
1213 default:
1214 return -EINVAL;
1215 }
1216 }
1217
1218 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8993->bclk);
1219
1220 ret = configure_clock(codec);
1221 if (ret != 0)
1222 return ret;
1223
1224 /* Select nearest CLK_SYS_RATE */
1225 best = 0;
1226 best_val = abs((wm8993->sysclk_rate / clk_sys_rates[0].ratio)
1227 - wm8993->fs);
1228 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1229 cur_val = abs((wm8993->sysclk_rate /
1230 clk_sys_rates[i].ratio) - wm8993->fs);;
1231 if (cur_val < best_val) {
1232 best = i;
1233 best_val = cur_val;
1234 }
1235 }
1236 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1237 clk_sys_rates[best].ratio);
1238 clocking3 |= (clk_sys_rates[best].clk_sys_rate
1239 << WM8993_CLK_SYS_RATE_SHIFT);
1240
1241 /* SAMPLE_RATE */
1242 best = 0;
1243 best_val = abs(wm8993->fs - sample_rates[0].rate);
1244 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1245 /* Closest match */
1246 cur_val = abs(wm8993->fs - sample_rates[i].rate);
1247 if (cur_val < best_val) {
1248 best = i;
1249 best_val = cur_val;
1250 }
1251 }
1252 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1253 sample_rates[best].rate);
1254 clocking3 |= (sample_rates[best].sample_rate
1255 << WM8993_SAMPLE_RATE_SHIFT);
1256
1257 /* BCLK_DIV */
1258 best = 0;
1259 best_val = INT_MAX;
1260 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1261 cur_val = ((wm8993->sysclk_rate * 10) / bclk_divs[i].div)
1262 - wm8993->bclk;
1263 if (cur_val < 0) /* Table is sorted */
1264 break;
1265 if (cur_val < best_val) {
1266 best = i;
1267 best_val = cur_val;
1268 }
1269 }
1270 wm8993->bclk = (wm8993->sysclk_rate * 10) / bclk_divs[best].div;
1271 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1272 bclk_divs[best].div, wm8993->bclk);
1273 clocking1 |= bclk_divs[best].bclk_div << WM8993_BCLK_DIV_SHIFT;
1274
1275 /* LRCLK is a simple fraction of BCLK */
1276 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs;
1278
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283
1284 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s;
1288
1289 best = 0;
1290 best_val = abs(wm8993->pdata.retune_configs[0].rate
1291 - wm8993->fs);
1292 for (i = 0; i < wm8993->pdata.num_retune_configs; i++) {
1293 cur_val = abs(wm8993->pdata.retune_configs[i].rate
1294 - wm8993->fs);
1295 if (cur_val < best_val) {
1296 best_val = cur_val;
1297 best = i;
1298 }
1299 }
1300 s = &wm8993->pdata.retune_configs[best];
1301
1302 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1303 s->name, s->rate);
1304
1305 /* Disable EQ while we reconfigure */
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]);
1310
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 }
1313
1314 return 0;
1315}
1316
1317static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1318{
1319 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg;
1321
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL);
1323
1324 if (mute)
1325 reg |= WM8993_DAC_MUTE;
1326 else
1327 reg &= ~WM8993_DAC_MUTE;
1328
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg);
1330
1331 return 0;
1332}
1333
1334static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1335 unsigned int rx_mask, int slots, int slot_width)
1336{
1337 struct snd_soc_codec *codec = dai->codec;
1338 struct wm8993_priv *wm8993 = codec->private_data;
1339 int aif1 = 0;
1340 int aif2 = 0;
1341
1342 /* Don't need to validate anything if we're turning off TDM */
1343 if (slots == 0) {
1344 wm8993->tdm_slots = 0;
1345 goto out;
1346 }
1347
1348 /* Note that we allow configurations we can't handle ourselves -
1349 * for example, we can generate clocks for slots 2 and up even if
1350 * we can't use those slots ourselves.
1351 */
1352 aif1 |= WM8993_AIFADC_TDM;
1353 aif2 |= WM8993_AIFDAC_TDM;
1354
1355 switch (rx_mask) {
1356 case 3:
1357 break;
1358 case 0xc:
1359 aif1 |= WM8993_AIFADC_TDM_CHAN;
1360 break;
1361 default:
1362 return -EINVAL;
1363 }
1364
1365
1366 switch (tx_mask) {
1367 case 3:
1368 break;
1369 case 0xc:
1370 aif2 |= WM8993_AIFDAC_TDM_CHAN;
1371 break;
1372 default:
1373 return -EINVAL;
1374 }
1375
1376out:
1377 wm8993->tdm_width = slot_width;
1378 wm8993->tdm_slots = slots / 2;
1379
1380 snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_1,
1381 WM8993_AIFADC_TDM | WM8993_AIFADC_TDM_CHAN, aif1);
1382 snd_soc_update_bits(codec, WM8993_AUDIO_INTERFACE_2,
1383 WM8993_AIFDAC_TDM | WM8993_AIFDAC_TDM_CHAN, aif2);
1384
1385 return 0;
1386}
1387
1388static struct snd_soc_dai_ops wm8993_ops = {
1389 .set_sysclk = wm8993_set_sysclk,
1390 .set_fmt = wm8993_set_dai_fmt,
1391 .hw_params = wm8993_hw_params,
1392 .digital_mute = wm8993_digital_mute,
1393 .set_pll = wm8993_set_fll,
1394 .set_tdm_slot = wm8993_set_tdm_slot,
1395};
1396
1397#define WM8993_RATES SNDRV_PCM_RATE_8000_48000
1398
1399#define WM8993_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1400 SNDRV_PCM_FMTBIT_S20_3LE |\
1401 SNDRV_PCM_FMTBIT_S24_LE |\
1402 SNDRV_PCM_FMTBIT_S32_LE)
1403
1404struct snd_soc_dai wm8993_dai = {
1405 .name = "WM8993",
1406 .playback = {
1407 .stream_name = "Playback",
1408 .channels_min = 1,
1409 .channels_max = 2,
1410 .rates = WM8993_RATES,
1411 .formats = WM8993_FORMATS,
1412 },
1413 .capture = {
1414 .stream_name = "Capture",
1415 .channels_min = 1,
1416 .channels_max = 2,
1417 .rates = WM8993_RATES,
1418 .formats = WM8993_FORMATS,
1419 },
1420 .ops = &wm8993_ops,
1421 .symmetric_rates = 1,
1422};
1423EXPORT_SYMBOL_GPL(wm8993_dai);
1424
1425static struct snd_soc_codec *wm8993_codec;
1426
1427static int wm8993_probe(struct platform_device *pdev)
1428{
1429 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1430 struct snd_soc_codec *codec;
1431 struct wm8993_priv *wm8993;
1432 int ret = 0;
1433
1434 if (!wm8993_codec) {
1435 dev_err(&pdev->dev, "I2C device not yet probed\n");
1436 goto err;
1437 }
1438
1439 socdev->card->codec = wm8993_codec;
1440 codec = wm8993_codec;
1441 wm8993 = codec->private_data;
1442
1443 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1444 if (ret < 0) {
1445 dev_err(codec->dev, "failed to create pcms\n");
1446 goto err;
1447 }
1448
1449 snd_soc_add_controls(codec, wm8993_snd_controls,
1450 ARRAY_SIZE(wm8993_snd_controls));
1451 if (wm8993->pdata.num_retune_configs != 0) {
1452 dev_dbg(codec->dev, "Using ReTune Mobile\n");
1453 } else {
1454 dev_dbg(codec->dev, "No ReTune Mobile, using normal EQ\n");
1455 snd_soc_add_controls(codec, wm8993_eq_controls,
1456 ARRAY_SIZE(wm8993_eq_controls));
1457 }
1458
1459 snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets,
1460 ARRAY_SIZE(wm8993_dapm_widgets));
1461 wm_hubs_add_analogue_controls(codec);
1462
1463 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1465 wm8993->pdata.lineout2_diff);
1466
1467 snd_soc_dapm_new_widgets(codec);
1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret;
1476
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err:
1481 return ret;
1482}
1483
1484static int wm8993_remove(struct platform_device *pdev)
1485{
1486 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1487
1488 snd_soc_free_pcms(socdev);
1489 snd_soc_dapm_free(socdev);
1490
1491 return 0;
1492}
1493
1494struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1495 .probe = wm8993_probe,
1496 .remove = wm8993_remove,
1497};
1498EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1499
1500static int wm8993_i2c_probe(struct i2c_client *i2c,
1501 const struct i2c_device_id *id)
1502{
1503 struct wm8993_priv *wm8993;
1504 struct snd_soc_codec *codec;
1505 unsigned int val;
1506 int ret;
1507
1508 if (wm8993_codec) {
1509 dev_err(&i2c->dev, "A WM8993 is already registered\n");
1510 return -EINVAL;
1511 }
1512
1513 wm8993 = kzalloc(sizeof(struct wm8993_priv), GFP_KERNEL);
1514 if (wm8993 == NULL)
1515 return -ENOMEM;
1516
1517 codec = &wm8993->codec;
1518 if (i2c->dev.platform_data)
1519 memcpy(&wm8993->pdata, i2c->dev.platform_data,
1520 sizeof(wm8993->pdata));
1521
1522 mutex_init(&codec->mutex);
1523 INIT_LIST_HEAD(&codec->dapm_widgets);
1524 INIT_LIST_HEAD(&codec->dapm_paths);
1525
1526 codec->name = "WM8993";
1527 codec->read = wm8993_read;
1528 codec->write = wm8993_write;
1529 codec->hw_write = (hw_write_t)i2c_master_send;
1530 codec->reg_cache = wm8993->reg_cache;
1531 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1532 codec->bias_level = SND_SOC_BIAS_OFF;
1533 codec->set_bias_level = wm8993_set_bias_level;
1534 codec->dai = &wm8993_dai;
1535 codec->num_dai = 1;
1536 codec->private_data = wm8993;
1537
1538 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1539 sizeof(wm8993->reg_cache));
1540
1541 i2c_set_clientdata(i2c, wm8993);
1542 codec->control_data = i2c;
1543 wm8993_codec = codec;
1544
1545 codec->dev = &i2c->dev;
1546
1547 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET);
1548 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1549 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1550 ret = -EINVAL;
1551 goto err;
1552 }
1553
1554 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1555 if (ret != 0)
1556 goto err;
1557
1558 /* By default we're using the output mixers */
1559 wm8993->class_w_users = 2;
1560
1561 /* Latch volume update bits and default ZC on */
1562 snd_soc_update_bits(codec, WM8993_RIGHT_DAC_DIGITAL_VOLUME,
1563 WM8993_DAC_VU, WM8993_DAC_VU);
1564 snd_soc_update_bits(codec, WM8993_RIGHT_ADC_DIGITAL_VOLUME,
1565 WM8993_ADC_VU, WM8993_ADC_VU);
1566
1567 /* Manualy manage the HPOUT sequencing for independent stereo
1568 * control. */
1569 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
1570 WM8993_HPOUT1_AUTO_PU, 0);
1571
1572 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574
1575 if (!wm8993->pdata.lineout1_diff)
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
1577 WM8993_LINEOUT1_MODE,
1578 WM8993_LINEOUT1_MODE);
1579 if (!wm8993->pdata.lineout2_diff)
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
1581 WM8993_LINEOUT2_MODE,
1582 WM8993_LINEOUT2_MODE);
1583
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0)
1604 goto err;
1605
1606 wm8993_dai.dev = codec->dev;
1607
1608 ret = snd_soc_register_dai(&wm8993_dai);
1609 if (ret != 0)
1610 goto err_bias;
1611
1612 ret = snd_soc_register_codec(codec);
1613
1614 return 0;
1615
1616err_bias:
1617 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1618err:
1619 wm8993_codec = NULL;
1620 kfree(wm8993);
1621 return ret;
1622}
1623
1624static int wm8993_i2c_remove(struct i2c_client *client)
1625{
1626 struct wm8993_priv *wm8993 = i2c_get_clientdata(client);
1627
1628 snd_soc_unregister_codec(&wm8993->codec);
1629 snd_soc_unregister_dai(&wm8993_dai);
1630
1631 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1632 kfree(wm8993);
1633
1634 return 0;
1635}
1636
1637static const struct i2c_device_id wm8993_i2c_id[] = {
1638 { "wm8993", 0 },
1639 { }
1640};
1641MODULE_DEVICE_TABLE(i2c, wm8993_i2c_id);
1642
1643static struct i2c_driver wm8993_i2c_driver = {
1644 .driver = {
1645 .name = "WM8993",
1646 .owner = THIS_MODULE,
1647 },
1648 .probe = wm8993_i2c_probe,
1649 .remove = wm8993_i2c_remove,
1650 .id_table = wm8993_i2c_id,
1651};
1652
1653
1654static int __init wm8993_modinit(void)
1655{
1656 int ret;
1657
1658 ret = i2c_add_driver(&wm8993_i2c_driver);
1659 if (ret != 0)
1660 pr_err("WM8993: Unable to register I2C driver: %d\n", ret);
1661
1662 return ret;
1663}
1664module_init(wm8993_modinit);
1665
1666static void __exit wm8993_exit(void)
1667{
1668 i2c_del_driver(&wm8993_i2c_driver);
1669}
1670module_exit(wm8993_exit);
1671
1672
1673MODULE_DESCRIPTION("ASoC WM8993 driver");
1674MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1675MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8993.h b/sound/soc/codecs/wm8993.h
new file mode 100644
index 000000000000..30e71ca88dad
--- /dev/null
+++ b/sound/soc/codecs/wm8993.h
@@ -0,0 +1,2132 @@
1#ifndef WM8993_H
2#define WM8993_H
3
4extern struct snd_soc_dai wm8993_dai;
5extern struct snd_soc_codec_device soc_codec_dev_wm8993;
6
7#define WM8993_SYSCLK_MCLK 1
8#define WM8993_SYSCLK_FLL 2
9
10#define WM8993_FLL_MCLK 1
11#define WM8993_FLL_BCLK 2
12#define WM8993_FLL_LRCLK 3
13
14/*
15 * Register values.
16 */
17#define WM8993_SOFTWARE_RESET 0x00
18#define WM8993_POWER_MANAGEMENT_1 0x01
19#define WM8993_POWER_MANAGEMENT_2 0x02
20#define WM8993_POWER_MANAGEMENT_3 0x03
21#define WM8993_AUDIO_INTERFACE_1 0x04
22#define WM8993_AUDIO_INTERFACE_2 0x05
23#define WM8993_CLOCKING_1 0x06
24#define WM8993_CLOCKING_2 0x07
25#define WM8993_AUDIO_INTERFACE_3 0x08
26#define WM8993_AUDIO_INTERFACE_4 0x09
27#define WM8993_DAC_CTRL 0x0A
28#define WM8993_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8993_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8993_DIGITAL_SIDE_TONE 0x0D
31#define WM8993_ADC_CTRL 0x0E
32#define WM8993_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8993_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8993_GPIO_CTRL_1 0x12
35#define WM8993_GPIO1 0x13
36#define WM8993_IRQ_DEBOUNCE 0x14
37#define WM8993_GPIOCTRL_2 0x16
38#define WM8993_GPIO_POL 0x17
39#define WM8993_LEFT_LINE_INPUT_1_2_VOLUME 0x18
40#define WM8993_LEFT_LINE_INPUT_3_4_VOLUME 0x19
41#define WM8993_RIGHT_LINE_INPUT_1_2_VOLUME 0x1A
42#define WM8993_RIGHT_LINE_INPUT_3_4_VOLUME 0x1B
43#define WM8993_LEFT_OUTPUT_VOLUME 0x1C
44#define WM8993_RIGHT_OUTPUT_VOLUME 0x1D
45#define WM8993_LINE_OUTPUTS_VOLUME 0x1E
46#define WM8993_HPOUT2_VOLUME 0x1F
47#define WM8993_LEFT_OPGA_VOLUME 0x20
48#define WM8993_RIGHT_OPGA_VOLUME 0x21
49#define WM8993_SPKMIXL_ATTENUATION 0x22
50#define WM8993_SPKMIXR_ATTENUATION 0x23
51#define WM8993_SPKOUT_MIXERS 0x24
52#define WM8993_SPKOUT_BOOST 0x25
53#define WM8993_SPEAKER_VOLUME_LEFT 0x26
54#define WM8993_SPEAKER_VOLUME_RIGHT 0x27
55#define WM8993_INPUT_MIXER2 0x28
56#define WM8993_INPUT_MIXER3 0x29
57#define WM8993_INPUT_MIXER4 0x2A
58#define WM8993_INPUT_MIXER5 0x2B
59#define WM8993_INPUT_MIXER6 0x2C
60#define WM8993_OUTPUT_MIXER1 0x2D
61#define WM8993_OUTPUT_MIXER2 0x2E
62#define WM8993_OUTPUT_MIXER3 0x2F
63#define WM8993_OUTPUT_MIXER4 0x30
64#define WM8993_OUTPUT_MIXER5 0x31
65#define WM8993_OUTPUT_MIXER6 0x32
66#define WM8993_HPOUT2_MIXER 0x33
67#define WM8993_LINE_MIXER1 0x34
68#define WM8993_LINE_MIXER2 0x35
69#define WM8993_SPEAKER_MIXER 0x36
70#define WM8993_ADDITIONAL_CONTROL 0x37
71#define WM8993_ANTIPOP1 0x38
72#define WM8993_ANTIPOP2 0x39
73#define WM8993_MICBIAS 0x3A
74#define WM8993_FLL_CONTROL_1 0x3C
75#define WM8993_FLL_CONTROL_2 0x3D
76#define WM8993_FLL_CONTROL_3 0x3E
77#define WM8993_FLL_CONTROL_4 0x3F
78#define WM8993_FLL_CONTROL_5 0x40
79#define WM8993_CLOCKING_3 0x41
80#define WM8993_CLOCKING_4 0x42
81#define WM8993_MW_SLAVE_CONTROL 0x43
82#define WM8993_BUS_CONTROL_1 0x45
83#define WM8993_WRITE_SEQUENCER_0 0x46
84#define WM8993_WRITE_SEQUENCER_1 0x47
85#define WM8993_WRITE_SEQUENCER_2 0x48
86#define WM8993_WRITE_SEQUENCER_3 0x49
87#define WM8993_WRITE_SEQUENCER_4 0x4A
88#define WM8993_WRITE_SEQUENCER_5 0x4B
89#define WM8993_CHARGE_PUMP_1 0x4C
90#define WM8993_CLASS_W_0 0x51
91#define WM8993_DC_SERVO_0 0x54
92#define WM8993_DC_SERVO_1 0x55
93#define WM8993_DC_SERVO_3 0x57
94#define WM8993_DC_SERVO_READBACK_0 0x58
95#define WM8993_DC_SERVO_READBACK_1 0x59
96#define WM8993_DC_SERVO_READBACK_2 0x5A
97#define WM8993_ANALOGUE_HP_0 0x60
98#define WM8993_EQ1 0x62
99#define WM8993_EQ2 0x63
100#define WM8993_EQ3 0x64
101#define WM8993_EQ4 0x65
102#define WM8993_EQ5 0x66
103#define WM8993_EQ6 0x67
104#define WM8993_EQ7 0x68
105#define WM8993_EQ8 0x69
106#define WM8993_EQ9 0x6A
107#define WM8993_EQ10 0x6B
108#define WM8993_EQ11 0x6C
109#define WM8993_EQ12 0x6D
110#define WM8993_EQ13 0x6E
111#define WM8993_EQ14 0x6F
112#define WM8993_EQ15 0x70
113#define WM8993_EQ16 0x71
114#define WM8993_EQ17 0x72
115#define WM8993_EQ18 0x73
116#define WM8993_EQ19 0x74
117#define WM8993_EQ20 0x75
118#define WM8993_EQ21 0x76
119#define WM8993_EQ22 0x77
120#define WM8993_EQ23 0x78
121#define WM8993_EQ24 0x79
122#define WM8993_DIGITAL_PULLS 0x7A
123#define WM8993_DRC_CONTROL_1 0x7B
124#define WM8993_DRC_CONTROL_2 0x7C
125#define WM8993_DRC_CONTROL_3 0x7D
126#define WM8993_DRC_CONTROL_4 0x7E
127
128#define WM8993_REGISTER_COUNT 0x7F
129#define WM8993_MAX_REGISTER 0x7E
130
131/*
132 * Field Definitions.
133 */
134
135/*
136 * R0 (0x00) - Software Reset
137 */
138#define WM8993_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
139#define WM8993_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
140#define WM8993_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
141
142/*
143 * R1 (0x01) - Power Management (1)
144 */
145#define WM8993_SPKOUTR_ENA 0x2000 /* SPKOUTR_ENA */
146#define WM8993_SPKOUTR_ENA_MASK 0x2000 /* SPKOUTR_ENA */
147#define WM8993_SPKOUTR_ENA_SHIFT 13 /* SPKOUTR_ENA */
148#define WM8993_SPKOUTR_ENA_WIDTH 1 /* SPKOUTR_ENA */
149#define WM8993_SPKOUTL_ENA 0x1000 /* SPKOUTL_ENA */
150#define WM8993_SPKOUTL_ENA_MASK 0x1000 /* SPKOUTL_ENA */
151#define WM8993_SPKOUTL_ENA_SHIFT 12 /* SPKOUTL_ENA */
152#define WM8993_SPKOUTL_ENA_WIDTH 1 /* SPKOUTL_ENA */
153#define WM8993_HPOUT2_ENA 0x0800 /* HPOUT2_ENA */
154#define WM8993_HPOUT2_ENA_MASK 0x0800 /* HPOUT2_ENA */
155#define WM8993_HPOUT2_ENA_SHIFT 11 /* HPOUT2_ENA */
156#define WM8993_HPOUT2_ENA_WIDTH 1 /* HPOUT2_ENA */
157#define WM8993_HPOUT1L_ENA 0x0200 /* HPOUT1L_ENA */
158#define WM8993_HPOUT1L_ENA_MASK 0x0200 /* HPOUT1L_ENA */
159#define WM8993_HPOUT1L_ENA_SHIFT 9 /* HPOUT1L_ENA */
160#define WM8993_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
161#define WM8993_HPOUT1R_ENA 0x0100 /* HPOUT1R_ENA */
162#define WM8993_HPOUT1R_ENA_MASK 0x0100 /* HPOUT1R_ENA */
163#define WM8993_HPOUT1R_ENA_SHIFT 8 /* HPOUT1R_ENA */
164#define WM8993_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
165#define WM8993_MICB2_ENA 0x0020 /* MICB2_ENA */
166#define WM8993_MICB2_ENA_MASK 0x0020 /* MICB2_ENA */
167#define WM8993_MICB2_ENA_SHIFT 5 /* MICB2_ENA */
168#define WM8993_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
169#define WM8993_MICB1_ENA 0x0010 /* MICB1_ENA */
170#define WM8993_MICB1_ENA_MASK 0x0010 /* MICB1_ENA */
171#define WM8993_MICB1_ENA_SHIFT 4 /* MICB1_ENA */
172#define WM8993_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
173#define WM8993_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */
174#define WM8993_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */
175#define WM8993_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */
176#define WM8993_BIAS_ENA 0x0001 /* BIAS_ENA */
177#define WM8993_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
178#define WM8993_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
179#define WM8993_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
180
181/*
182 * R2 (0x02) - Power Management (2)
183 */
184#define WM8993_TSHUT_ENA 0x4000 /* TSHUT_ENA */
185#define WM8993_TSHUT_ENA_MASK 0x4000 /* TSHUT_ENA */
186#define WM8993_TSHUT_ENA_SHIFT 14 /* TSHUT_ENA */
187#define WM8993_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */
188#define WM8993_TSHUT_OPDIS 0x2000 /* TSHUT_OPDIS */
189#define WM8993_TSHUT_OPDIS_MASK 0x2000 /* TSHUT_OPDIS */
190#define WM8993_TSHUT_OPDIS_SHIFT 13 /* TSHUT_OPDIS */
191#define WM8993_TSHUT_OPDIS_WIDTH 1 /* TSHUT_OPDIS */
192#define WM8993_OPCLK_ENA 0x0800 /* OPCLK_ENA */
193#define WM8993_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
194#define WM8993_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
195#define WM8993_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
196#define WM8993_MIXINL_ENA 0x0200 /* MIXINL_ENA */
197#define WM8993_MIXINL_ENA_MASK 0x0200 /* MIXINL_ENA */
198#define WM8993_MIXINL_ENA_SHIFT 9 /* MIXINL_ENA */
199#define WM8993_MIXINL_ENA_WIDTH 1 /* MIXINL_ENA */
200#define WM8993_MIXINR_ENA 0x0100 /* MIXINR_ENA */
201#define WM8993_MIXINR_ENA_MASK 0x0100 /* MIXINR_ENA */
202#define WM8993_MIXINR_ENA_SHIFT 8 /* MIXINR_ENA */
203#define WM8993_MIXINR_ENA_WIDTH 1 /* MIXINR_ENA */
204#define WM8993_IN2L_ENA 0x0080 /* IN2L_ENA */
205#define WM8993_IN2L_ENA_MASK 0x0080 /* IN2L_ENA */
206#define WM8993_IN2L_ENA_SHIFT 7 /* IN2L_ENA */
207#define WM8993_IN2L_ENA_WIDTH 1 /* IN2L_ENA */
208#define WM8993_IN1L_ENA 0x0040 /* IN1L_ENA */
209#define WM8993_IN1L_ENA_MASK 0x0040 /* IN1L_ENA */
210#define WM8993_IN1L_ENA_SHIFT 6 /* IN1L_ENA */
211#define WM8993_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
212#define WM8993_IN2R_ENA 0x0020 /* IN2R_ENA */
213#define WM8993_IN2R_ENA_MASK 0x0020 /* IN2R_ENA */
214#define WM8993_IN2R_ENA_SHIFT 5 /* IN2R_ENA */
215#define WM8993_IN2R_ENA_WIDTH 1 /* IN2R_ENA */
216#define WM8993_IN1R_ENA 0x0010 /* IN1R_ENA */
217#define WM8993_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
218#define WM8993_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
219#define WM8993_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
220#define WM8993_ADCL_ENA 0x0002 /* ADCL_ENA */
221#define WM8993_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
222#define WM8993_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
223#define WM8993_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
224#define WM8993_ADCR_ENA 0x0001 /* ADCR_ENA */
225#define WM8993_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
226#define WM8993_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
227#define WM8993_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
228
229/*
230 * R3 (0x03) - Power Management (3)
231 */
232#define WM8993_LINEOUT1N_ENA 0x2000 /* LINEOUT1N_ENA */
233#define WM8993_LINEOUT1N_ENA_MASK 0x2000 /* LINEOUT1N_ENA */
234#define WM8993_LINEOUT1N_ENA_SHIFT 13 /* LINEOUT1N_ENA */
235#define WM8993_LINEOUT1N_ENA_WIDTH 1 /* LINEOUT1N_ENA */
236#define WM8993_LINEOUT1P_ENA 0x1000 /* LINEOUT1P_ENA */
237#define WM8993_LINEOUT1P_ENA_MASK 0x1000 /* LINEOUT1P_ENA */
238#define WM8993_LINEOUT1P_ENA_SHIFT 12 /* LINEOUT1P_ENA */
239#define WM8993_LINEOUT1P_ENA_WIDTH 1 /* LINEOUT1P_ENA */
240#define WM8993_LINEOUT2N_ENA 0x0800 /* LINEOUT2N_ENA */
241#define WM8993_LINEOUT2N_ENA_MASK 0x0800 /* LINEOUT2N_ENA */
242#define WM8993_LINEOUT2N_ENA_SHIFT 11 /* LINEOUT2N_ENA */
243#define WM8993_LINEOUT2N_ENA_WIDTH 1 /* LINEOUT2N_ENA */
244#define WM8993_LINEOUT2P_ENA 0x0400 /* LINEOUT2P_ENA */
245#define WM8993_LINEOUT2P_ENA_MASK 0x0400 /* LINEOUT2P_ENA */
246#define WM8993_LINEOUT2P_ENA_SHIFT 10 /* LINEOUT2P_ENA */
247#define WM8993_LINEOUT2P_ENA_WIDTH 1 /* LINEOUT2P_ENA */
248#define WM8993_SPKRVOL_ENA 0x0200 /* SPKRVOL_ENA */
249#define WM8993_SPKRVOL_ENA_MASK 0x0200 /* SPKRVOL_ENA */
250#define WM8993_SPKRVOL_ENA_SHIFT 9 /* SPKRVOL_ENA */
251#define WM8993_SPKRVOL_ENA_WIDTH 1 /* SPKRVOL_ENA */
252#define WM8993_SPKLVOL_ENA 0x0100 /* SPKLVOL_ENA */
253#define WM8993_SPKLVOL_ENA_MASK 0x0100 /* SPKLVOL_ENA */
254#define WM8993_SPKLVOL_ENA_SHIFT 8 /* SPKLVOL_ENA */
255#define WM8993_SPKLVOL_ENA_WIDTH 1 /* SPKLVOL_ENA */
256#define WM8993_MIXOUTLVOL_ENA 0x0080 /* MIXOUTLVOL_ENA */
257#define WM8993_MIXOUTLVOL_ENA_MASK 0x0080 /* MIXOUTLVOL_ENA */
258#define WM8993_MIXOUTLVOL_ENA_SHIFT 7 /* MIXOUTLVOL_ENA */
259#define WM8993_MIXOUTLVOL_ENA_WIDTH 1 /* MIXOUTLVOL_ENA */
260#define WM8993_MIXOUTRVOL_ENA 0x0040 /* MIXOUTRVOL_ENA */
261#define WM8993_MIXOUTRVOL_ENA_MASK 0x0040 /* MIXOUTRVOL_ENA */
262#define WM8993_MIXOUTRVOL_ENA_SHIFT 6 /* MIXOUTRVOL_ENA */
263#define WM8993_MIXOUTRVOL_ENA_WIDTH 1 /* MIXOUTRVOL_ENA */
264#define WM8993_MIXOUTL_ENA 0x0020 /* MIXOUTL_ENA */
265#define WM8993_MIXOUTL_ENA_MASK 0x0020 /* MIXOUTL_ENA */
266#define WM8993_MIXOUTL_ENA_SHIFT 5 /* MIXOUTL_ENA */
267#define WM8993_MIXOUTL_ENA_WIDTH 1 /* MIXOUTL_ENA */
268#define WM8993_MIXOUTR_ENA 0x0010 /* MIXOUTR_ENA */
269#define WM8993_MIXOUTR_ENA_MASK 0x0010 /* MIXOUTR_ENA */
270#define WM8993_MIXOUTR_ENA_SHIFT 4 /* MIXOUTR_ENA */
271#define WM8993_MIXOUTR_ENA_WIDTH 1 /* MIXOUTR_ENA */
272#define WM8993_DACL_ENA 0x0002 /* DACL_ENA */
273#define WM8993_DACL_ENA_MASK 0x0002 /* DACL_ENA */
274#define WM8993_DACL_ENA_SHIFT 1 /* DACL_ENA */
275#define WM8993_DACL_ENA_WIDTH 1 /* DACL_ENA */
276#define WM8993_DACR_ENA 0x0001 /* DACR_ENA */
277#define WM8993_DACR_ENA_MASK 0x0001 /* DACR_ENA */
278#define WM8993_DACR_ENA_SHIFT 0 /* DACR_ENA */
279#define WM8993_DACR_ENA_WIDTH 1 /* DACR_ENA */
280
281/*
282 * R4 (0x04) - Audio Interface (1)
283 */
284#define WM8993_AIFADCL_SRC 0x8000 /* AIFADCL_SRC */
285#define WM8993_AIFADCL_SRC_MASK 0x8000 /* AIFADCL_SRC */
286#define WM8993_AIFADCL_SRC_SHIFT 15 /* AIFADCL_SRC */
287#define WM8993_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
288#define WM8993_AIFADCR_SRC 0x4000 /* AIFADCR_SRC */
289#define WM8993_AIFADCR_SRC_MASK 0x4000 /* AIFADCR_SRC */
290#define WM8993_AIFADCR_SRC_SHIFT 14 /* AIFADCR_SRC */
291#define WM8993_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
292#define WM8993_AIFADC_TDM 0x2000 /* AIFADC_TDM */
293#define WM8993_AIFADC_TDM_MASK 0x2000 /* AIFADC_TDM */
294#define WM8993_AIFADC_TDM_SHIFT 13 /* AIFADC_TDM */
295#define WM8993_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
296#define WM8993_AIFADC_TDM_CHAN 0x1000 /* AIFADC_TDM_CHAN */
297#define WM8993_AIFADC_TDM_CHAN_MASK 0x1000 /* AIFADC_TDM_CHAN */
298#define WM8993_AIFADC_TDM_CHAN_SHIFT 12 /* AIFADC_TDM_CHAN */
299#define WM8993_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
300#define WM8993_BCLK_DIR 0x0200 /* BCLK_DIR */
301#define WM8993_BCLK_DIR_MASK 0x0200 /* BCLK_DIR */
302#define WM8993_BCLK_DIR_SHIFT 9 /* BCLK_DIR */
303#define WM8993_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
304#define WM8993_AIF_BCLK_INV 0x0100 /* AIF_BCLK_INV */
305#define WM8993_AIF_BCLK_INV_MASK 0x0100 /* AIF_BCLK_INV */
306#define WM8993_AIF_BCLK_INV_SHIFT 8 /* AIF_BCLK_INV */
307#define WM8993_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
308#define WM8993_AIF_LRCLK_INV 0x0080 /* AIF_LRCLK_INV */
309#define WM8993_AIF_LRCLK_INV_MASK 0x0080 /* AIF_LRCLK_INV */
310#define WM8993_AIF_LRCLK_INV_SHIFT 7 /* AIF_LRCLK_INV */
311#define WM8993_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
312#define WM8993_AIF_WL_MASK 0x0060 /* AIF_WL - [6:5] */
313#define WM8993_AIF_WL_SHIFT 5 /* AIF_WL - [6:5] */
314#define WM8993_AIF_WL_WIDTH 2 /* AIF_WL - [6:5] */
315#define WM8993_AIF_FMT_MASK 0x0018 /* AIF_FMT - [4:3] */
316#define WM8993_AIF_FMT_SHIFT 3 /* AIF_FMT - [4:3] */
317#define WM8993_AIF_FMT_WIDTH 2 /* AIF_FMT - [4:3] */
318
319/*
320 * R5 (0x05) - Audio Interface (2)
321 */
322#define WM8993_AIFDACL_SRC 0x8000 /* AIFDACL_SRC */
323#define WM8993_AIFDACL_SRC_MASK 0x8000 /* AIFDACL_SRC */
324#define WM8993_AIFDACL_SRC_SHIFT 15 /* AIFDACL_SRC */
325#define WM8993_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
326#define WM8993_AIFDACR_SRC 0x4000 /* AIFDACR_SRC */
327#define WM8993_AIFDACR_SRC_MASK 0x4000 /* AIFDACR_SRC */
328#define WM8993_AIFDACR_SRC_SHIFT 14 /* AIFDACR_SRC */
329#define WM8993_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
330#define WM8993_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
331#define WM8993_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
332#define WM8993_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
333#define WM8993_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
334#define WM8993_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
335#define WM8993_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
336#define WM8993_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
337#define WM8993_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
338#define WM8993_DAC_BOOST_MASK 0x0C00 /* DAC_BOOST - [11:10] */
339#define WM8993_DAC_BOOST_SHIFT 10 /* DAC_BOOST - [11:10] */
340#define WM8993_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [11:10] */
341#define WM8993_DAC_COMP 0x0010 /* DAC_COMP */
342#define WM8993_DAC_COMP_MASK 0x0010 /* DAC_COMP */
343#define WM8993_DAC_COMP_SHIFT 4 /* DAC_COMP */
344#define WM8993_DAC_COMP_WIDTH 1 /* DAC_COMP */
345#define WM8993_DAC_COMPMODE 0x0008 /* DAC_COMPMODE */
346#define WM8993_DAC_COMPMODE_MASK 0x0008 /* DAC_COMPMODE */
347#define WM8993_DAC_COMPMODE_SHIFT 3 /* DAC_COMPMODE */
348#define WM8993_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
349#define WM8993_ADC_COMP 0x0004 /* ADC_COMP */
350#define WM8993_ADC_COMP_MASK 0x0004 /* ADC_COMP */
351#define WM8993_ADC_COMP_SHIFT 2 /* ADC_COMP */
352#define WM8993_ADC_COMP_WIDTH 1 /* ADC_COMP */
353#define WM8993_ADC_COMPMODE 0x0002 /* ADC_COMPMODE */
354#define WM8993_ADC_COMPMODE_MASK 0x0002 /* ADC_COMPMODE */
355#define WM8993_ADC_COMPMODE_SHIFT 1 /* ADC_COMPMODE */
356#define WM8993_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
357#define WM8993_LOOPBACK 0x0001 /* LOOPBACK */
358#define WM8993_LOOPBACK_MASK 0x0001 /* LOOPBACK */
359#define WM8993_LOOPBACK_SHIFT 0 /* LOOPBACK */
360#define WM8993_LOOPBACK_WIDTH 1 /* LOOPBACK */
361
362/*
363 * R6 (0x06) - Clocking 1
364 */
365#define WM8993_TOCLK_RATE 0x8000 /* TOCLK_RATE */
366#define WM8993_TOCLK_RATE_MASK 0x8000 /* TOCLK_RATE */
367#define WM8993_TOCLK_RATE_SHIFT 15 /* TOCLK_RATE */
368#define WM8993_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
369#define WM8993_TOCLK_ENA 0x4000 /* TOCLK_ENA */
370#define WM8993_TOCLK_ENA_MASK 0x4000 /* TOCLK_ENA */
371#define WM8993_TOCLK_ENA_SHIFT 14 /* TOCLK_ENA */
372#define WM8993_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
373#define WM8993_OPCLK_DIV_MASK 0x1E00 /* OPCLK_DIV - [12:9] */
374#define WM8993_OPCLK_DIV_SHIFT 9 /* OPCLK_DIV - [12:9] */
375#define WM8993_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [12:9] */
376#define WM8993_DCLK_DIV_MASK 0x01C0 /* DCLK_DIV - [8:6] */
377#define WM8993_DCLK_DIV_SHIFT 6 /* DCLK_DIV - [8:6] */
378#define WM8993_DCLK_DIV_WIDTH 3 /* DCLK_DIV - [8:6] */
379#define WM8993_BCLK_DIV_MASK 0x001E /* BCLK_DIV - [4:1] */
380#define WM8993_BCLK_DIV_SHIFT 1 /* BCLK_DIV - [4:1] */
381#define WM8993_BCLK_DIV_WIDTH 4 /* BCLK_DIV - [4:1] */
382
383/*
384 * R7 (0x07) - Clocking 2
385 */
386#define WM8993_MCLK_SRC 0x8000 /* MCLK_SRC */
387#define WM8993_MCLK_SRC_MASK 0x8000 /* MCLK_SRC */
388#define WM8993_MCLK_SRC_SHIFT 15 /* MCLK_SRC */
389#define WM8993_MCLK_SRC_WIDTH 1 /* MCLK_SRC */
390#define WM8993_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
391#define WM8993_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
392#define WM8993_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
393#define WM8993_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
394#define WM8993_MCLK_DIV 0x1000 /* MCLK_DIV */
395#define WM8993_MCLK_DIV_MASK 0x1000 /* MCLK_DIV */
396#define WM8993_MCLK_DIV_SHIFT 12 /* MCLK_DIV */
397#define WM8993_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
398#define WM8993_MCLK_INV 0x0400 /* MCLK_INV */
399#define WM8993_MCLK_INV_MASK 0x0400 /* MCLK_INV */
400#define WM8993_MCLK_INV_SHIFT 10 /* MCLK_INV */
401#define WM8993_MCLK_INV_WIDTH 1 /* MCLK_INV */
402#define WM8993_ADC_DIV_MASK 0x00E0 /* ADC_DIV - [7:5] */
403#define WM8993_ADC_DIV_SHIFT 5 /* ADC_DIV - [7:5] */
404#define WM8993_ADC_DIV_WIDTH 3 /* ADC_DIV - [7:5] */
405#define WM8993_DAC_DIV_MASK 0x001C /* DAC_DIV - [4:2] */
406#define WM8993_DAC_DIV_SHIFT 2 /* DAC_DIV - [4:2] */
407#define WM8993_DAC_DIV_WIDTH 3 /* DAC_DIV - [4:2] */
408
409/*
410 * R8 (0x08) - Audio Interface (3)
411 */
412#define WM8993_AIF_MSTR1 0x8000 /* AIF_MSTR1 */
413#define WM8993_AIF_MSTR1_MASK 0x8000 /* AIF_MSTR1 */
414#define WM8993_AIF_MSTR1_SHIFT 15 /* AIF_MSTR1 */
415#define WM8993_AIF_MSTR1_WIDTH 1 /* AIF_MSTR1 */
416
417/*
418 * R9 (0x09) - Audio Interface (4)
419 */
420#define WM8993_AIF_TRIS 0x2000 /* AIF_TRIS */
421#define WM8993_AIF_TRIS_MASK 0x2000 /* AIF_TRIS */
422#define WM8993_AIF_TRIS_SHIFT 13 /* AIF_TRIS */
423#define WM8993_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
424#define WM8993_LRCLK_DIR 0x0800 /* LRCLK_DIR */
425#define WM8993_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
426#define WM8993_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
427#define WM8993_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
428#define WM8993_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
429#define WM8993_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
430#define WM8993_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
431
432/*
433 * R10 (0x0A) - DAC CTRL
434 */
435#define WM8993_DAC_OSR128 0x2000 /* DAC_OSR128 */
436#define WM8993_DAC_OSR128_MASK 0x2000 /* DAC_OSR128 */
437#define WM8993_DAC_OSR128_SHIFT 13 /* DAC_OSR128 */
438#define WM8993_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
439#define WM8993_DAC_MONO 0x0200 /* DAC_MONO */
440#define WM8993_DAC_MONO_MASK 0x0200 /* DAC_MONO */
441#define WM8993_DAC_MONO_SHIFT 9 /* DAC_MONO */
442#define WM8993_DAC_MONO_WIDTH 1 /* DAC_MONO */
443#define WM8993_DAC_SB_FILT 0x0100 /* DAC_SB_FILT */
444#define WM8993_DAC_SB_FILT_MASK 0x0100 /* DAC_SB_FILT */
445#define WM8993_DAC_SB_FILT_SHIFT 8 /* DAC_SB_FILT */
446#define WM8993_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
447#define WM8993_DAC_MUTERATE 0x0080 /* DAC_MUTERATE */
448#define WM8993_DAC_MUTERATE_MASK 0x0080 /* DAC_MUTERATE */
449#define WM8993_DAC_MUTERATE_SHIFT 7 /* DAC_MUTERATE */
450#define WM8993_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
451#define WM8993_DAC_UNMUTE_RAMP 0x0040 /* DAC_UNMUTE_RAMP */
452#define WM8993_DAC_UNMUTE_RAMP_MASK 0x0040 /* DAC_UNMUTE_RAMP */
453#define WM8993_DAC_UNMUTE_RAMP_SHIFT 6 /* DAC_UNMUTE_RAMP */
454#define WM8993_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
455#define WM8993_DEEMPH_MASK 0x0030 /* DEEMPH - [5:4] */
456#define WM8993_DEEMPH_SHIFT 4 /* DEEMPH - [5:4] */
457#define WM8993_DEEMPH_WIDTH 2 /* DEEMPH - [5:4] */
458#define WM8993_DAC_MUTE 0x0004 /* DAC_MUTE */
459#define WM8993_DAC_MUTE_MASK 0x0004 /* DAC_MUTE */
460#define WM8993_DAC_MUTE_SHIFT 2 /* DAC_MUTE */
461#define WM8993_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
462#define WM8993_DACL_DATINV 0x0002 /* DACL_DATINV */
463#define WM8993_DACL_DATINV_MASK 0x0002 /* DACL_DATINV */
464#define WM8993_DACL_DATINV_SHIFT 1 /* DACL_DATINV */
465#define WM8993_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
466#define WM8993_DACR_DATINV 0x0001 /* DACR_DATINV */
467#define WM8993_DACR_DATINV_MASK 0x0001 /* DACR_DATINV */
468#define WM8993_DACR_DATINV_SHIFT 0 /* DACR_DATINV */
469#define WM8993_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
470
471/*
472 * R11 (0x0B) - Left DAC Digital Volume
473 */
474#define WM8993_DAC_VU 0x0100 /* DAC_VU */
475#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
476#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
477#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
478#define WM8993_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
479#define WM8993_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
480#define WM8993_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
481
482/*
483 * R12 (0x0C) - Right DAC Digital Volume
484 */
485#define WM8993_DAC_VU 0x0100 /* DAC_VU */
486#define WM8993_DAC_VU_MASK 0x0100 /* DAC_VU */
487#define WM8993_DAC_VU_SHIFT 8 /* DAC_VU */
488#define WM8993_DAC_VU_WIDTH 1 /* DAC_VU */
489#define WM8993_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
490#define WM8993_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
491#define WM8993_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
492
493/*
494 * R13 (0x0D) - Digital Side Tone
495 */
496#define WM8993_ADCL_DAC_SVOL_MASK 0x1E00 /* ADCL_DAC_SVOL - [12:9] */
497#define WM8993_ADCL_DAC_SVOL_SHIFT 9 /* ADCL_DAC_SVOL - [12:9] */
498#define WM8993_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [12:9] */
499#define WM8993_ADCR_DAC_SVOL_MASK 0x01E0 /* ADCR_DAC_SVOL - [8:5] */
500#define WM8993_ADCR_DAC_SVOL_SHIFT 5 /* ADCR_DAC_SVOL - [8:5] */
501#define WM8993_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [8:5] */
502#define WM8993_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
503#define WM8993_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
504#define WM8993_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
505#define WM8993_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
506#define WM8993_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
507#define WM8993_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
508
509/*
510 * R14 (0x0E) - ADC CTRL
511 */
512#define WM8993_ADC_OSR128 0x0200 /* ADC_OSR128 */
513#define WM8993_ADC_OSR128_MASK 0x0200 /* ADC_OSR128 */
514#define WM8993_ADC_OSR128_SHIFT 9 /* ADC_OSR128 */
515#define WM8993_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
516#define WM8993_ADC_HPF 0x0100 /* ADC_HPF */
517#define WM8993_ADC_HPF_MASK 0x0100 /* ADC_HPF */
518#define WM8993_ADC_HPF_SHIFT 8 /* ADC_HPF */
519#define WM8993_ADC_HPF_WIDTH 1 /* ADC_HPF */
520#define WM8993_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
521#define WM8993_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
522#define WM8993_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
523#define WM8993_ADCL_DATINV 0x0002 /* ADCL_DATINV */
524#define WM8993_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
525#define WM8993_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
526#define WM8993_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
527#define WM8993_ADCR_DATINV 0x0001 /* ADCR_DATINV */
528#define WM8993_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
529#define WM8993_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
530#define WM8993_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
531
532/*
533 * R15 (0x0F) - Left ADC Digital Volume
534 */
535#define WM8993_ADC_VU 0x0100 /* ADC_VU */
536#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
537#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
538#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
539#define WM8993_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
540#define WM8993_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
541#define WM8993_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
542
543/*
544 * R16 (0x10) - Right ADC Digital Volume
545 */
546#define WM8993_ADC_VU 0x0100 /* ADC_VU */
547#define WM8993_ADC_VU_MASK 0x0100 /* ADC_VU */
548#define WM8993_ADC_VU_SHIFT 8 /* ADC_VU */
549#define WM8993_ADC_VU_WIDTH 1 /* ADC_VU */
550#define WM8993_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
551#define WM8993_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
552#define WM8993_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
553
554/*
555 * R18 (0x12) - GPIO CTRL 1
556 */
557#define WM8993_JD2_SC_EINT 0x8000 /* JD2_SC_EINT */
558#define WM8993_JD2_SC_EINT_MASK 0x8000 /* JD2_SC_EINT */
559#define WM8993_JD2_SC_EINT_SHIFT 15 /* JD2_SC_EINT */
560#define WM8993_JD2_SC_EINT_WIDTH 1 /* JD2_SC_EINT */
561#define WM8993_JD2_EINT 0x4000 /* JD2_EINT */
562#define WM8993_JD2_EINT_MASK 0x4000 /* JD2_EINT */
563#define WM8993_JD2_EINT_SHIFT 14 /* JD2_EINT */
564#define WM8993_JD2_EINT_WIDTH 1 /* JD2_EINT */
565#define WM8993_WSEQ_EINT 0x2000 /* WSEQ_EINT */
566#define WM8993_WSEQ_EINT_MASK 0x2000 /* WSEQ_EINT */
567#define WM8993_WSEQ_EINT_SHIFT 13 /* WSEQ_EINT */
568#define WM8993_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
569#define WM8993_IRQ 0x1000 /* IRQ */
570#define WM8993_IRQ_MASK 0x1000 /* IRQ */
571#define WM8993_IRQ_SHIFT 12 /* IRQ */
572#define WM8993_IRQ_WIDTH 1 /* IRQ */
573#define WM8993_TEMPOK_EINT 0x0800 /* TEMPOK_EINT */
574#define WM8993_TEMPOK_EINT_MASK 0x0800 /* TEMPOK_EINT */
575#define WM8993_TEMPOK_EINT_SHIFT 11 /* TEMPOK_EINT */
576#define WM8993_TEMPOK_EINT_WIDTH 1 /* TEMPOK_EINT */
577#define WM8993_JD1_SC_EINT 0x0400 /* JD1_SC_EINT */
578#define WM8993_JD1_SC_EINT_MASK 0x0400 /* JD1_SC_EINT */
579#define WM8993_JD1_SC_EINT_SHIFT 10 /* JD1_SC_EINT */
580#define WM8993_JD1_SC_EINT_WIDTH 1 /* JD1_SC_EINT */
581#define WM8993_JD1_EINT 0x0200 /* JD1_EINT */
582#define WM8993_JD1_EINT_MASK 0x0200 /* JD1_EINT */
583#define WM8993_JD1_EINT_SHIFT 9 /* JD1_EINT */
584#define WM8993_JD1_EINT_WIDTH 1 /* JD1_EINT */
585#define WM8993_FLL_LOCK_EINT 0x0100 /* FLL_LOCK_EINT */
586#define WM8993_FLL_LOCK_EINT_MASK 0x0100 /* FLL_LOCK_EINT */
587#define WM8993_FLL_LOCK_EINT_SHIFT 8 /* FLL_LOCK_EINT */
588#define WM8993_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
589#define WM8993_GPI8_EINT 0x0080 /* GPI8_EINT */
590#define WM8993_GPI8_EINT_MASK 0x0080 /* GPI8_EINT */
591#define WM8993_GPI8_EINT_SHIFT 7 /* GPI8_EINT */
592#define WM8993_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
593#define WM8993_GPI7_EINT 0x0040 /* GPI7_EINT */
594#define WM8993_GPI7_EINT_MASK 0x0040 /* GPI7_EINT */
595#define WM8993_GPI7_EINT_SHIFT 6 /* GPI7_EINT */
596#define WM8993_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
597#define WM8993_GPIO1_EINT 0x0001 /* GPIO1_EINT */
598#define WM8993_GPIO1_EINT_MASK 0x0001 /* GPIO1_EINT */
599#define WM8993_GPIO1_EINT_SHIFT 0 /* GPIO1_EINT */
600#define WM8993_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
601
602/*
603 * R19 (0x13) - GPIO1
604 */
605#define WM8993_GPIO1_PU 0x0020 /* GPIO1_PU */
606#define WM8993_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
607#define WM8993_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
608#define WM8993_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
609#define WM8993_GPIO1_PD 0x0010 /* GPIO1_PD */
610#define WM8993_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
611#define WM8993_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
612#define WM8993_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
613#define WM8993_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
614#define WM8993_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
615#define WM8993_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
616
617/*
618 * R20 (0x14) - IRQ_DEBOUNCE
619 */
620#define WM8993_JD2_SC_DB 0x8000 /* JD2_SC_DB */
621#define WM8993_JD2_SC_DB_MASK 0x8000 /* JD2_SC_DB */
622#define WM8993_JD2_SC_DB_SHIFT 15 /* JD2_SC_DB */
623#define WM8993_JD2_SC_DB_WIDTH 1 /* JD2_SC_DB */
624#define WM8993_JD2_DB 0x4000 /* JD2_DB */
625#define WM8993_JD2_DB_MASK 0x4000 /* JD2_DB */
626#define WM8993_JD2_DB_SHIFT 14 /* JD2_DB */
627#define WM8993_JD2_DB_WIDTH 1 /* JD2_DB */
628#define WM8993_WSEQ_DB 0x2000 /* WSEQ_DB */
629#define WM8993_WSEQ_DB_MASK 0x2000 /* WSEQ_DB */
630#define WM8993_WSEQ_DB_SHIFT 13 /* WSEQ_DB */
631#define WM8993_WSEQ_DB_WIDTH 1 /* WSEQ_DB */
632#define WM8993_TEMPOK_DB 0x0800 /* TEMPOK_DB */
633#define WM8993_TEMPOK_DB_MASK 0x0800 /* TEMPOK_DB */
634#define WM8993_TEMPOK_DB_SHIFT 11 /* TEMPOK_DB */
635#define WM8993_TEMPOK_DB_WIDTH 1 /* TEMPOK_DB */
636#define WM8993_JD1_SC_DB 0x0400 /* JD1_SC_DB */
637#define WM8993_JD1_SC_DB_MASK 0x0400 /* JD1_SC_DB */
638#define WM8993_JD1_SC_DB_SHIFT 10 /* JD1_SC_DB */
639#define WM8993_JD1_SC_DB_WIDTH 1 /* JD1_SC_DB */
640#define WM8993_JD1_DB 0x0200 /* JD1_DB */
641#define WM8993_JD1_DB_MASK 0x0200 /* JD1_DB */
642#define WM8993_JD1_DB_SHIFT 9 /* JD1_DB */
643#define WM8993_JD1_DB_WIDTH 1 /* JD1_DB */
644#define WM8993_FLL_LOCK_DB 0x0100 /* FLL_LOCK_DB */
645#define WM8993_FLL_LOCK_DB_MASK 0x0100 /* FLL_LOCK_DB */
646#define WM8993_FLL_LOCK_DB_SHIFT 8 /* FLL_LOCK_DB */
647#define WM8993_FLL_LOCK_DB_WIDTH 1 /* FLL_LOCK_DB */
648#define WM8993_GPI8_DB 0x0080 /* GPI8_DB */
649#define WM8993_GPI8_DB_MASK 0x0080 /* GPI8_DB */
650#define WM8993_GPI8_DB_SHIFT 7 /* GPI8_DB */
651#define WM8993_GPI8_DB_WIDTH 1 /* GPI8_DB */
652#define WM8993_GPI7_DB 0x0008 /* GPI7_DB */
653#define WM8993_GPI7_DB_MASK 0x0008 /* GPI7_DB */
654#define WM8993_GPI7_DB_SHIFT 3 /* GPI7_DB */
655#define WM8993_GPI7_DB_WIDTH 1 /* GPI7_DB */
656#define WM8993_GPIO1_DB 0x0001 /* GPIO1_DB */
657#define WM8993_GPIO1_DB_MASK 0x0001 /* GPIO1_DB */
658#define WM8993_GPIO1_DB_SHIFT 0 /* GPIO1_DB */
659#define WM8993_GPIO1_DB_WIDTH 1 /* GPIO1_DB */
660
661/*
662 * R22 (0x16) - GPIOCTRL 2
663 */
664#define WM8993_IM_JD2_EINT 0x2000 /* IM_JD2_EINT */
665#define WM8993_IM_JD2_EINT_MASK 0x2000 /* IM_JD2_EINT */
666#define WM8993_IM_JD2_EINT_SHIFT 13 /* IM_JD2_EINT */
667#define WM8993_IM_JD2_EINT_WIDTH 1 /* IM_JD2_EINT */
668#define WM8993_IM_JD2_SC_EINT 0x1000 /* IM_JD2_SC_EINT */
669#define WM8993_IM_JD2_SC_EINT_MASK 0x1000 /* IM_JD2_SC_EINT */
670#define WM8993_IM_JD2_SC_EINT_SHIFT 12 /* IM_JD2_SC_EINT */
671#define WM8993_IM_JD2_SC_EINT_WIDTH 1 /* IM_JD2_SC_EINT */
672#define WM8993_IM_TEMPOK_EINT 0x0800 /* IM_TEMPOK_EINT */
673#define WM8993_IM_TEMPOK_EINT_MASK 0x0800 /* IM_TEMPOK_EINT */
674#define WM8993_IM_TEMPOK_EINT_SHIFT 11 /* IM_TEMPOK_EINT */
675#define WM8993_IM_TEMPOK_EINT_WIDTH 1 /* IM_TEMPOK_EINT */
676#define WM8993_IM_JD1_SC_EINT 0x0400 /* IM_JD1_SC_EINT */
677#define WM8993_IM_JD1_SC_EINT_MASK 0x0400 /* IM_JD1_SC_EINT */
678#define WM8993_IM_JD1_SC_EINT_SHIFT 10 /* IM_JD1_SC_EINT */
679#define WM8993_IM_JD1_SC_EINT_WIDTH 1 /* IM_JD1_SC_EINT */
680#define WM8993_IM_JD1_EINT 0x0200 /* IM_JD1_EINT */
681#define WM8993_IM_JD1_EINT_MASK 0x0200 /* IM_JD1_EINT */
682#define WM8993_IM_JD1_EINT_SHIFT 9 /* IM_JD1_EINT */
683#define WM8993_IM_JD1_EINT_WIDTH 1 /* IM_JD1_EINT */
684#define WM8993_IM_FLL_LOCK_EINT 0x0100 /* IM_FLL_LOCK_EINT */
685#define WM8993_IM_FLL_LOCK_EINT_MASK 0x0100 /* IM_FLL_LOCK_EINT */
686#define WM8993_IM_FLL_LOCK_EINT_SHIFT 8 /* IM_FLL_LOCK_EINT */
687#define WM8993_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
688#define WM8993_IM_GPI8_EINT 0x0040 /* IM_GPI8_EINT */
689#define WM8993_IM_GPI8_EINT_MASK 0x0040 /* IM_GPI8_EINT */
690#define WM8993_IM_GPI8_EINT_SHIFT 6 /* IM_GPI8_EINT */
691#define WM8993_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
692#define WM8993_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
693#define WM8993_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
694#define WM8993_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
695#define WM8993_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
696#define WM8993_GPI8_ENA 0x0010 /* GPI8_ENA */
697#define WM8993_GPI8_ENA_MASK 0x0010 /* GPI8_ENA */
698#define WM8993_GPI8_ENA_SHIFT 4 /* GPI8_ENA */
699#define WM8993_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
700#define WM8993_IM_GPI7_EINT 0x0004 /* IM_GPI7_EINT */
701#define WM8993_IM_GPI7_EINT_MASK 0x0004 /* IM_GPI7_EINT */
702#define WM8993_IM_GPI7_EINT_SHIFT 2 /* IM_GPI7_EINT */
703#define WM8993_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
704#define WM8993_IM_WSEQ_EINT 0x0002 /* IM_WSEQ_EINT */
705#define WM8993_IM_WSEQ_EINT_MASK 0x0002 /* IM_WSEQ_EINT */
706#define WM8993_IM_WSEQ_EINT_SHIFT 1 /* IM_WSEQ_EINT */
707#define WM8993_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
708#define WM8993_GPI7_ENA 0x0001 /* GPI7_ENA */
709#define WM8993_GPI7_ENA_MASK 0x0001 /* GPI7_ENA */
710#define WM8993_GPI7_ENA_SHIFT 0 /* GPI7_ENA */
711#define WM8993_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
712
713/*
714 * R23 (0x17) - GPIO_POL
715 */
716#define WM8993_JD2_SC_POL 0x8000 /* JD2_SC_POL */
717#define WM8993_JD2_SC_POL_MASK 0x8000 /* JD2_SC_POL */
718#define WM8993_JD2_SC_POL_SHIFT 15 /* JD2_SC_POL */
719#define WM8993_JD2_SC_POL_WIDTH 1 /* JD2_SC_POL */
720#define WM8993_JD2_POL 0x4000 /* JD2_POL */
721#define WM8993_JD2_POL_MASK 0x4000 /* JD2_POL */
722#define WM8993_JD2_POL_SHIFT 14 /* JD2_POL */
723#define WM8993_JD2_POL_WIDTH 1 /* JD2_POL */
724#define WM8993_WSEQ_POL 0x2000 /* WSEQ_POL */
725#define WM8993_WSEQ_POL_MASK 0x2000 /* WSEQ_POL */
726#define WM8993_WSEQ_POL_SHIFT 13 /* WSEQ_POL */
727#define WM8993_WSEQ_POL_WIDTH 1 /* WSEQ_POL */
728#define WM8993_IRQ_POL 0x1000 /* IRQ_POL */
729#define WM8993_IRQ_POL_MASK 0x1000 /* IRQ_POL */
730#define WM8993_IRQ_POL_SHIFT 12 /* IRQ_POL */
731#define WM8993_IRQ_POL_WIDTH 1 /* IRQ_POL */
732#define WM8993_TEMPOK_POL 0x0800 /* TEMPOK_POL */
733#define WM8993_TEMPOK_POL_MASK 0x0800 /* TEMPOK_POL */
734#define WM8993_TEMPOK_POL_SHIFT 11 /* TEMPOK_POL */
735#define WM8993_TEMPOK_POL_WIDTH 1 /* TEMPOK_POL */
736#define WM8993_JD1_SC_POL 0x0400 /* JD1_SC_POL */
737#define WM8993_JD1_SC_POL_MASK 0x0400 /* JD1_SC_POL */
738#define WM8993_JD1_SC_POL_SHIFT 10 /* JD1_SC_POL */
739#define WM8993_JD1_SC_POL_WIDTH 1 /* JD1_SC_POL */
740#define WM8993_JD1_POL 0x0200 /* JD1_POL */
741#define WM8993_JD1_POL_MASK 0x0200 /* JD1_POL */
742#define WM8993_JD1_POL_SHIFT 9 /* JD1_POL */
743#define WM8993_JD1_POL_WIDTH 1 /* JD1_POL */
744#define WM8993_FLL_LOCK_POL 0x0100 /* FLL_LOCK_POL */
745#define WM8993_FLL_LOCK_POL_MASK 0x0100 /* FLL_LOCK_POL */
746#define WM8993_FLL_LOCK_POL_SHIFT 8 /* FLL_LOCK_POL */
747#define WM8993_FLL_LOCK_POL_WIDTH 1 /* FLL_LOCK_POL */
748#define WM8993_GPI8_POL 0x0080 /* GPI8_POL */
749#define WM8993_GPI8_POL_MASK 0x0080 /* GPI8_POL */
750#define WM8993_GPI8_POL_SHIFT 7 /* GPI8_POL */
751#define WM8993_GPI8_POL_WIDTH 1 /* GPI8_POL */
752#define WM8993_GPI7_POL 0x0040 /* GPI7_POL */
753#define WM8993_GPI7_POL_MASK 0x0040 /* GPI7_POL */
754#define WM8993_GPI7_POL_SHIFT 6 /* GPI7_POL */
755#define WM8993_GPI7_POL_WIDTH 1 /* GPI7_POL */
756#define WM8993_GPIO1_POL 0x0001 /* GPIO1_POL */
757#define WM8993_GPIO1_POL_MASK 0x0001 /* GPIO1_POL */
758#define WM8993_GPIO1_POL_SHIFT 0 /* GPIO1_POL */
759#define WM8993_GPIO1_POL_WIDTH 1 /* GPIO1_POL */
760
761/*
762 * R24 (0x18) - Left Line Input 1&2 Volume
763 */
764#define WM8993_IN1_VU 0x0100 /* IN1_VU */
765#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
766#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
767#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
768#define WM8993_IN1L_MUTE 0x0080 /* IN1L_MUTE */
769#define WM8993_IN1L_MUTE_MASK 0x0080 /* IN1L_MUTE */
770#define WM8993_IN1L_MUTE_SHIFT 7 /* IN1L_MUTE */
771#define WM8993_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */
772#define WM8993_IN1L_ZC 0x0040 /* IN1L_ZC */
773#define WM8993_IN1L_ZC_MASK 0x0040 /* IN1L_ZC */
774#define WM8993_IN1L_ZC_SHIFT 6 /* IN1L_ZC */
775#define WM8993_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
776#define WM8993_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
777#define WM8993_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
778#define WM8993_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
779
780/*
781 * R25 (0x19) - Left Line Input 3&4 Volume
782 */
783#define WM8993_IN2_VU 0x0100 /* IN2_VU */
784#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
785#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
786#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
787#define WM8993_IN2L_MUTE 0x0080 /* IN2L_MUTE */
788#define WM8993_IN2L_MUTE_MASK 0x0080 /* IN2L_MUTE */
789#define WM8993_IN2L_MUTE_SHIFT 7 /* IN2L_MUTE */
790#define WM8993_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */
791#define WM8993_IN2L_ZC 0x0040 /* IN2L_ZC */
792#define WM8993_IN2L_ZC_MASK 0x0040 /* IN2L_ZC */
793#define WM8993_IN2L_ZC_SHIFT 6 /* IN2L_ZC */
794#define WM8993_IN2L_ZC_WIDTH 1 /* IN2L_ZC */
795#define WM8993_IN2L_VOL_MASK 0x001F /* IN2L_VOL - [4:0] */
796#define WM8993_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [4:0] */
797#define WM8993_IN2L_VOL_WIDTH 5 /* IN2L_VOL - [4:0] */
798
799/*
800 * R26 (0x1A) - Right Line Input 1&2 Volume
801 */
802#define WM8993_IN1_VU 0x0100 /* IN1_VU */
803#define WM8993_IN1_VU_MASK 0x0100 /* IN1_VU */
804#define WM8993_IN1_VU_SHIFT 8 /* IN1_VU */
805#define WM8993_IN1_VU_WIDTH 1 /* IN1_VU */
806#define WM8993_IN1R_MUTE 0x0080 /* IN1R_MUTE */
807#define WM8993_IN1R_MUTE_MASK 0x0080 /* IN1R_MUTE */
808#define WM8993_IN1R_MUTE_SHIFT 7 /* IN1R_MUTE */
809#define WM8993_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */
810#define WM8993_IN1R_ZC 0x0040 /* IN1R_ZC */
811#define WM8993_IN1R_ZC_MASK 0x0040 /* IN1R_ZC */
812#define WM8993_IN1R_ZC_SHIFT 6 /* IN1R_ZC */
813#define WM8993_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
814#define WM8993_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
815#define WM8993_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
816#define WM8993_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
817
818/*
819 * R27 (0x1B) - Right Line Input 3&4 Volume
820 */
821#define WM8993_IN2_VU 0x0100 /* IN2_VU */
822#define WM8993_IN2_VU_MASK 0x0100 /* IN2_VU */
823#define WM8993_IN2_VU_SHIFT 8 /* IN2_VU */
824#define WM8993_IN2_VU_WIDTH 1 /* IN2_VU */
825#define WM8993_IN2R_MUTE 0x0080 /* IN2R_MUTE */
826#define WM8993_IN2R_MUTE_MASK 0x0080 /* IN2R_MUTE */
827#define WM8993_IN2R_MUTE_SHIFT 7 /* IN2R_MUTE */
828#define WM8993_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */
829#define WM8993_IN2R_ZC 0x0040 /* IN2R_ZC */
830#define WM8993_IN2R_ZC_MASK 0x0040 /* IN2R_ZC */
831#define WM8993_IN2R_ZC_SHIFT 6 /* IN2R_ZC */
832#define WM8993_IN2R_ZC_WIDTH 1 /* IN2R_ZC */
833#define WM8993_IN2R_VOL_MASK 0x001F /* IN2R_VOL - [4:0] */
834#define WM8993_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [4:0] */
835#define WM8993_IN2R_VOL_WIDTH 5 /* IN2R_VOL - [4:0] */
836
837/*
838 * R28 (0x1C) - Left Output Volume
839 */
840#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
841#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
842#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
843#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
844#define WM8993_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */
845#define WM8993_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */
846#define WM8993_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */
847#define WM8993_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
848#define WM8993_HPOUT1L_MUTE_N 0x0040 /* HPOUT1L_MUTE_N */
849#define WM8993_HPOUT1L_MUTE_N_MASK 0x0040 /* HPOUT1L_MUTE_N */
850#define WM8993_HPOUT1L_MUTE_N_SHIFT 6 /* HPOUT1L_MUTE_N */
851#define WM8993_HPOUT1L_MUTE_N_WIDTH 1 /* HPOUT1L_MUTE_N */
852#define WM8993_HPOUT1L_VOL_MASK 0x003F /* HPOUT1L_VOL - [5:0] */
853#define WM8993_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [5:0] */
854#define WM8993_HPOUT1L_VOL_WIDTH 6 /* HPOUT1L_VOL - [5:0] */
855
856/*
857 * R29 (0x1D) - Right Output Volume
858 */
859#define WM8993_HPOUT1_VU 0x0100 /* HPOUT1_VU */
860#define WM8993_HPOUT1_VU_MASK 0x0100 /* HPOUT1_VU */
861#define WM8993_HPOUT1_VU_SHIFT 8 /* HPOUT1_VU */
862#define WM8993_HPOUT1_VU_WIDTH 1 /* HPOUT1_VU */
863#define WM8993_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */
864#define WM8993_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */
865#define WM8993_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */
866#define WM8993_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
867#define WM8993_HPOUT1R_MUTE_N 0x0040 /* HPOUT1R_MUTE_N */
868#define WM8993_HPOUT1R_MUTE_N_MASK 0x0040 /* HPOUT1R_MUTE_N */
869#define WM8993_HPOUT1R_MUTE_N_SHIFT 6 /* HPOUT1R_MUTE_N */
870#define WM8993_HPOUT1R_MUTE_N_WIDTH 1 /* HPOUT1R_MUTE_N */
871#define WM8993_HPOUT1R_VOL_MASK 0x003F /* HPOUT1R_VOL - [5:0] */
872#define WM8993_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [5:0] */
873#define WM8993_HPOUT1R_VOL_WIDTH 6 /* HPOUT1R_VOL - [5:0] */
874
875/*
876 * R30 (0x1E) - Line Outputs Volume
877 */
878#define WM8993_LINEOUT1N_MUTE 0x0040 /* LINEOUT1N_MUTE */
879#define WM8993_LINEOUT1N_MUTE_MASK 0x0040 /* LINEOUT1N_MUTE */
880#define WM8993_LINEOUT1N_MUTE_SHIFT 6 /* LINEOUT1N_MUTE */
881#define WM8993_LINEOUT1N_MUTE_WIDTH 1 /* LINEOUT1N_MUTE */
882#define WM8993_LINEOUT1P_MUTE 0x0020 /* LINEOUT1P_MUTE */
883#define WM8993_LINEOUT1P_MUTE_MASK 0x0020 /* LINEOUT1P_MUTE */
884#define WM8993_LINEOUT1P_MUTE_SHIFT 5 /* LINEOUT1P_MUTE */
885#define WM8993_LINEOUT1P_MUTE_WIDTH 1 /* LINEOUT1P_MUTE */
886#define WM8993_LINEOUT1_VOL 0x0010 /* LINEOUT1_VOL */
887#define WM8993_LINEOUT1_VOL_MASK 0x0010 /* LINEOUT1_VOL */
888#define WM8993_LINEOUT1_VOL_SHIFT 4 /* LINEOUT1_VOL */
889#define WM8993_LINEOUT1_VOL_WIDTH 1 /* LINEOUT1_VOL */
890#define WM8993_LINEOUT2N_MUTE 0x0004 /* LINEOUT2N_MUTE */
891#define WM8993_LINEOUT2N_MUTE_MASK 0x0004 /* LINEOUT2N_MUTE */
892#define WM8993_LINEOUT2N_MUTE_SHIFT 2 /* LINEOUT2N_MUTE */
893#define WM8993_LINEOUT2N_MUTE_WIDTH 1 /* LINEOUT2N_MUTE */
894#define WM8993_LINEOUT2P_MUTE 0x0002 /* LINEOUT2P_MUTE */
895#define WM8993_LINEOUT2P_MUTE_MASK 0x0002 /* LINEOUT2P_MUTE */
896#define WM8993_LINEOUT2P_MUTE_SHIFT 1 /* LINEOUT2P_MUTE */
897#define WM8993_LINEOUT2P_MUTE_WIDTH 1 /* LINEOUT2P_MUTE */
898#define WM8993_LINEOUT2_VOL 0x0001 /* LINEOUT2_VOL */
899#define WM8993_LINEOUT2_VOL_MASK 0x0001 /* LINEOUT2_VOL */
900#define WM8993_LINEOUT2_VOL_SHIFT 0 /* LINEOUT2_VOL */
901#define WM8993_LINEOUT2_VOL_WIDTH 1 /* LINEOUT2_VOL */
902
903/*
904 * R31 (0x1F) - HPOUT2 Volume
905 */
906#define WM8993_HPOUT2_MUTE 0x0020 /* HPOUT2_MUTE */
907#define WM8993_HPOUT2_MUTE_MASK 0x0020 /* HPOUT2_MUTE */
908#define WM8993_HPOUT2_MUTE_SHIFT 5 /* HPOUT2_MUTE */
909#define WM8993_HPOUT2_MUTE_WIDTH 1 /* HPOUT2_MUTE */
910#define WM8993_HPOUT2_VOL 0x0010 /* HPOUT2_VOL */
911#define WM8993_HPOUT2_VOL_MASK 0x0010 /* HPOUT2_VOL */
912#define WM8993_HPOUT2_VOL_SHIFT 4 /* HPOUT2_VOL */
913#define WM8993_HPOUT2_VOL_WIDTH 1 /* HPOUT2_VOL */
914
915/*
916 * R32 (0x20) - Left OPGA Volume
917 */
918#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
919#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
920#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
921#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
922#define WM8993_MIXOUTL_ZC 0x0080 /* MIXOUTL_ZC */
923#define WM8993_MIXOUTL_ZC_MASK 0x0080 /* MIXOUTL_ZC */
924#define WM8993_MIXOUTL_ZC_SHIFT 7 /* MIXOUTL_ZC */
925#define WM8993_MIXOUTL_ZC_WIDTH 1 /* MIXOUTL_ZC */
926#define WM8993_MIXOUTL_MUTE_N 0x0040 /* MIXOUTL_MUTE_N */
927#define WM8993_MIXOUTL_MUTE_N_MASK 0x0040 /* MIXOUTL_MUTE_N */
928#define WM8993_MIXOUTL_MUTE_N_SHIFT 6 /* MIXOUTL_MUTE_N */
929#define WM8993_MIXOUTL_MUTE_N_WIDTH 1 /* MIXOUTL_MUTE_N */
930#define WM8993_MIXOUTL_VOL_MASK 0x003F /* MIXOUTL_VOL - [5:0] */
931#define WM8993_MIXOUTL_VOL_SHIFT 0 /* MIXOUTL_VOL - [5:0] */
932#define WM8993_MIXOUTL_VOL_WIDTH 6 /* MIXOUTL_VOL - [5:0] */
933
934/*
935 * R33 (0x21) - Right OPGA Volume
936 */
937#define WM8993_MIXOUT_VU 0x0100 /* MIXOUT_VU */
938#define WM8993_MIXOUT_VU_MASK 0x0100 /* MIXOUT_VU */
939#define WM8993_MIXOUT_VU_SHIFT 8 /* MIXOUT_VU */
940#define WM8993_MIXOUT_VU_WIDTH 1 /* MIXOUT_VU */
941#define WM8993_MIXOUTR_ZC 0x0080 /* MIXOUTR_ZC */
942#define WM8993_MIXOUTR_ZC_MASK 0x0080 /* MIXOUTR_ZC */
943#define WM8993_MIXOUTR_ZC_SHIFT 7 /* MIXOUTR_ZC */
944#define WM8993_MIXOUTR_ZC_WIDTH 1 /* MIXOUTR_ZC */
945#define WM8993_MIXOUTR_MUTE_N 0x0040 /* MIXOUTR_MUTE_N */
946#define WM8993_MIXOUTR_MUTE_N_MASK 0x0040 /* MIXOUTR_MUTE_N */
947#define WM8993_MIXOUTR_MUTE_N_SHIFT 6 /* MIXOUTR_MUTE_N */
948#define WM8993_MIXOUTR_MUTE_N_WIDTH 1 /* MIXOUTR_MUTE_N */
949#define WM8993_MIXOUTR_VOL_MASK 0x003F /* MIXOUTR_VOL - [5:0] */
950#define WM8993_MIXOUTR_VOL_SHIFT 0 /* MIXOUTR_VOL - [5:0] */
951#define WM8993_MIXOUTR_VOL_WIDTH 6 /* MIXOUTR_VOL - [5:0] */
952
953/*
954 * R34 (0x22) - SPKMIXL Attenuation
955 */
956#define WM8993_MIXINL_SPKMIXL_VOL 0x0020 /* MIXINL_SPKMIXL_VOL */
957#define WM8993_MIXINL_SPKMIXL_VOL_MASK 0x0020 /* MIXINL_SPKMIXL_VOL */
958#define WM8993_MIXINL_SPKMIXL_VOL_SHIFT 5 /* MIXINL_SPKMIXL_VOL */
959#define WM8993_MIXINL_SPKMIXL_VOL_WIDTH 1 /* MIXINL_SPKMIXL_VOL */
960#define WM8993_IN1LP_SPKMIXL_VOL 0x0010 /* IN1LP_SPKMIXL_VOL */
961#define WM8993_IN1LP_SPKMIXL_VOL_MASK 0x0010 /* IN1LP_SPKMIXL_VOL */
962#define WM8993_IN1LP_SPKMIXL_VOL_SHIFT 4 /* IN1LP_SPKMIXL_VOL */
963#define WM8993_IN1LP_SPKMIXL_VOL_WIDTH 1 /* IN1LP_SPKMIXL_VOL */
964#define WM8993_MIXOUTL_SPKMIXL_VOL 0x0008 /* MIXOUTL_SPKMIXL_VOL */
965#define WM8993_MIXOUTL_SPKMIXL_VOL_MASK 0x0008 /* MIXOUTL_SPKMIXL_VOL */
966#define WM8993_MIXOUTL_SPKMIXL_VOL_SHIFT 3 /* MIXOUTL_SPKMIXL_VOL */
967#define WM8993_MIXOUTL_SPKMIXL_VOL_WIDTH 1 /* MIXOUTL_SPKMIXL_VOL */
968#define WM8993_DACL_SPKMIXL_VOL 0x0004 /* DACL_SPKMIXL_VOL */
969#define WM8993_DACL_SPKMIXL_VOL_MASK 0x0004 /* DACL_SPKMIXL_VOL */
970#define WM8993_DACL_SPKMIXL_VOL_SHIFT 2 /* DACL_SPKMIXL_VOL */
971#define WM8993_DACL_SPKMIXL_VOL_WIDTH 1 /* DACL_SPKMIXL_VOL */
972#define WM8993_SPKMIXL_VOL_MASK 0x0003 /* SPKMIXL_VOL - [1:0] */
973#define WM8993_SPKMIXL_VOL_SHIFT 0 /* SPKMIXL_VOL - [1:0] */
974#define WM8993_SPKMIXL_VOL_WIDTH 2 /* SPKMIXL_VOL - [1:0] */
975
976/*
977 * R35 (0x23) - SPKMIXR Attenuation
978 */
979#define WM8993_SPKOUT_CLASSAB_MODE 0x0100 /* SPKOUT_CLASSAB_MODE */
980#define WM8993_SPKOUT_CLASSAB_MODE_MASK 0x0100 /* SPKOUT_CLASSAB_MODE */
981#define WM8993_SPKOUT_CLASSAB_MODE_SHIFT 8 /* SPKOUT_CLASSAB_MODE */
982#define WM8993_SPKOUT_CLASSAB_MODE_WIDTH 1 /* SPKOUT_CLASSAB_MODE */
983#define WM8993_MIXINR_SPKMIXR_VOL 0x0020 /* MIXINR_SPKMIXR_VOL */
984#define WM8993_MIXINR_SPKMIXR_VOL_MASK 0x0020 /* MIXINR_SPKMIXR_VOL */
985#define WM8993_MIXINR_SPKMIXR_VOL_SHIFT 5 /* MIXINR_SPKMIXR_VOL */
986#define WM8993_MIXINR_SPKMIXR_VOL_WIDTH 1 /* MIXINR_SPKMIXR_VOL */
987#define WM8993_IN1RP_SPKMIXR_VOL 0x0010 /* IN1RP_SPKMIXR_VOL */
988#define WM8993_IN1RP_SPKMIXR_VOL_MASK 0x0010 /* IN1RP_SPKMIXR_VOL */
989#define WM8993_IN1RP_SPKMIXR_VOL_SHIFT 4 /* IN1RP_SPKMIXR_VOL */
990#define WM8993_IN1RP_SPKMIXR_VOL_WIDTH 1 /* IN1RP_SPKMIXR_VOL */
991#define WM8993_MIXOUTR_SPKMIXR_VOL 0x0008 /* MIXOUTR_SPKMIXR_VOL */
992#define WM8993_MIXOUTR_SPKMIXR_VOL_MASK 0x0008 /* MIXOUTR_SPKMIXR_VOL */
993#define WM8993_MIXOUTR_SPKMIXR_VOL_SHIFT 3 /* MIXOUTR_SPKMIXR_VOL */
994#define WM8993_MIXOUTR_SPKMIXR_VOL_WIDTH 1 /* MIXOUTR_SPKMIXR_VOL */
995#define WM8993_DACR_SPKMIXR_VOL 0x0004 /* DACR_SPKMIXR_VOL */
996#define WM8993_DACR_SPKMIXR_VOL_MASK 0x0004 /* DACR_SPKMIXR_VOL */
997#define WM8993_DACR_SPKMIXR_VOL_SHIFT 2 /* DACR_SPKMIXR_VOL */
998#define WM8993_DACR_SPKMIXR_VOL_WIDTH 1 /* DACR_SPKMIXR_VOL */
999#define WM8993_SPKMIXR_VOL_MASK 0x0003 /* SPKMIXR_VOL - [1:0] */
1000#define WM8993_SPKMIXR_VOL_SHIFT 0 /* SPKMIXR_VOL - [1:0] */
1001#define WM8993_SPKMIXR_VOL_WIDTH 2 /* SPKMIXR_VOL - [1:0] */
1002
1003/*
1004 * R36 (0x24) - SPKOUT Mixers
1005 */
1006#define WM8993_VRX_TO_SPKOUTL 0x0020 /* VRX_TO_SPKOUTL */
1007#define WM8993_VRX_TO_SPKOUTL_MASK 0x0020 /* VRX_TO_SPKOUTL */
1008#define WM8993_VRX_TO_SPKOUTL_SHIFT 5 /* VRX_TO_SPKOUTL */
1009#define WM8993_VRX_TO_SPKOUTL_WIDTH 1 /* VRX_TO_SPKOUTL */
1010#define WM8993_SPKMIXL_TO_SPKOUTL 0x0010 /* SPKMIXL_TO_SPKOUTL */
1011#define WM8993_SPKMIXL_TO_SPKOUTL_MASK 0x0010 /* SPKMIXL_TO_SPKOUTL */
1012#define WM8993_SPKMIXL_TO_SPKOUTL_SHIFT 4 /* SPKMIXL_TO_SPKOUTL */
1013#define WM8993_SPKMIXL_TO_SPKOUTL_WIDTH 1 /* SPKMIXL_TO_SPKOUTL */
1014#define WM8993_SPKMIXR_TO_SPKOUTL 0x0008 /* SPKMIXR_TO_SPKOUTL */
1015#define WM8993_SPKMIXR_TO_SPKOUTL_MASK 0x0008 /* SPKMIXR_TO_SPKOUTL */
1016#define WM8993_SPKMIXR_TO_SPKOUTL_SHIFT 3 /* SPKMIXR_TO_SPKOUTL */
1017#define WM8993_SPKMIXR_TO_SPKOUTL_WIDTH 1 /* SPKMIXR_TO_SPKOUTL */
1018#define WM8993_VRX_TO_SPKOUTR 0x0004 /* VRX_TO_SPKOUTR */
1019#define WM8993_VRX_TO_SPKOUTR_MASK 0x0004 /* VRX_TO_SPKOUTR */
1020#define WM8993_VRX_TO_SPKOUTR_SHIFT 2 /* VRX_TO_SPKOUTR */
1021#define WM8993_VRX_TO_SPKOUTR_WIDTH 1 /* VRX_TO_SPKOUTR */
1022#define WM8993_SPKMIXL_TO_SPKOUTR 0x0002 /* SPKMIXL_TO_SPKOUTR */
1023#define WM8993_SPKMIXL_TO_SPKOUTR_MASK 0x0002 /* SPKMIXL_TO_SPKOUTR */
1024#define WM8993_SPKMIXL_TO_SPKOUTR_SHIFT 1 /* SPKMIXL_TO_SPKOUTR */
1025#define WM8993_SPKMIXL_TO_SPKOUTR_WIDTH 1 /* SPKMIXL_TO_SPKOUTR */
1026#define WM8993_SPKMIXR_TO_SPKOUTR 0x0001 /* SPKMIXR_TO_SPKOUTR */
1027#define WM8993_SPKMIXR_TO_SPKOUTR_MASK 0x0001 /* SPKMIXR_TO_SPKOUTR */
1028#define WM8993_SPKMIXR_TO_SPKOUTR_SHIFT 0 /* SPKMIXR_TO_SPKOUTR */
1029#define WM8993_SPKMIXR_TO_SPKOUTR_WIDTH 1 /* SPKMIXR_TO_SPKOUTR */
1030
1031/*
1032 * R37 (0x25) - SPKOUT Boost
1033 */
1034#define WM8993_SPKOUTL_BOOST_MASK 0x0038 /* SPKOUTL_BOOST - [5:3] */
1035#define WM8993_SPKOUTL_BOOST_SHIFT 3 /* SPKOUTL_BOOST - [5:3] */
1036#define WM8993_SPKOUTL_BOOST_WIDTH 3 /* SPKOUTL_BOOST - [5:3] */
1037#define WM8993_SPKOUTR_BOOST_MASK 0x0007 /* SPKOUTR_BOOST - [2:0] */
1038#define WM8993_SPKOUTR_BOOST_SHIFT 0 /* SPKOUTR_BOOST - [2:0] */
1039#define WM8993_SPKOUTR_BOOST_WIDTH 3 /* SPKOUTR_BOOST - [2:0] */
1040
1041/*
1042 * R38 (0x26) - Speaker Volume Left
1043 */
1044#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1045#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1046#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1047#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1048#define WM8993_SPKOUTL_ZC 0x0080 /* SPKOUTL_ZC */
1049#define WM8993_SPKOUTL_ZC_MASK 0x0080 /* SPKOUTL_ZC */
1050#define WM8993_SPKOUTL_ZC_SHIFT 7 /* SPKOUTL_ZC */
1051#define WM8993_SPKOUTL_ZC_WIDTH 1 /* SPKOUTL_ZC */
1052#define WM8993_SPKOUTL_MUTE_N 0x0040 /* SPKOUTL_MUTE_N */
1053#define WM8993_SPKOUTL_MUTE_N_MASK 0x0040 /* SPKOUTL_MUTE_N */
1054#define WM8993_SPKOUTL_MUTE_N_SHIFT 6 /* SPKOUTL_MUTE_N */
1055#define WM8993_SPKOUTL_MUTE_N_WIDTH 1 /* SPKOUTL_MUTE_N */
1056#define WM8993_SPKOUTL_VOL_MASK 0x003F /* SPKOUTL_VOL - [5:0] */
1057#define WM8993_SPKOUTL_VOL_SHIFT 0 /* SPKOUTL_VOL - [5:0] */
1058#define WM8993_SPKOUTL_VOL_WIDTH 6 /* SPKOUTL_VOL - [5:0] */
1059
1060/*
1061 * R39 (0x27) - Speaker Volume Right
1062 */
1063#define WM8993_SPKOUT_VU 0x0100 /* SPKOUT_VU */
1064#define WM8993_SPKOUT_VU_MASK 0x0100 /* SPKOUT_VU */
1065#define WM8993_SPKOUT_VU_SHIFT 8 /* SPKOUT_VU */
1066#define WM8993_SPKOUT_VU_WIDTH 1 /* SPKOUT_VU */
1067#define WM8993_SPKOUTR_ZC 0x0080 /* SPKOUTR_ZC */
1068#define WM8993_SPKOUTR_ZC_MASK 0x0080 /* SPKOUTR_ZC */
1069#define WM8993_SPKOUTR_ZC_SHIFT 7 /* SPKOUTR_ZC */
1070#define WM8993_SPKOUTR_ZC_WIDTH 1 /* SPKOUTR_ZC */
1071#define WM8993_SPKOUTR_MUTE_N 0x0040 /* SPKOUTR_MUTE_N */
1072#define WM8993_SPKOUTR_MUTE_N_MASK 0x0040 /* SPKOUTR_MUTE_N */
1073#define WM8993_SPKOUTR_MUTE_N_SHIFT 6 /* SPKOUTR_MUTE_N */
1074#define WM8993_SPKOUTR_MUTE_N_WIDTH 1 /* SPKOUTR_MUTE_N */
1075#define WM8993_SPKOUTR_VOL_MASK 0x003F /* SPKOUTR_VOL - [5:0] */
1076#define WM8993_SPKOUTR_VOL_SHIFT 0 /* SPKOUTR_VOL - [5:0] */
1077#define WM8993_SPKOUTR_VOL_WIDTH 6 /* SPKOUTR_VOL - [5:0] */
1078
1079/*
1080 * R40 (0x28) - Input Mixer2
1081 */
1082#define WM8993_IN2LP_TO_IN2L 0x0080 /* IN2LP_TO_IN2L */
1083#define WM8993_IN2LP_TO_IN2L_MASK 0x0080 /* IN2LP_TO_IN2L */
1084#define WM8993_IN2LP_TO_IN2L_SHIFT 7 /* IN2LP_TO_IN2L */
1085#define WM8993_IN2LP_TO_IN2L_WIDTH 1 /* IN2LP_TO_IN2L */
1086#define WM8993_IN2LN_TO_IN2L 0x0040 /* IN2LN_TO_IN2L */
1087#define WM8993_IN2LN_TO_IN2L_MASK 0x0040 /* IN2LN_TO_IN2L */
1088#define WM8993_IN2LN_TO_IN2L_SHIFT 6 /* IN2LN_TO_IN2L */
1089#define WM8993_IN2LN_TO_IN2L_WIDTH 1 /* IN2LN_TO_IN2L */
1090#define WM8993_IN1LP_TO_IN1L 0x0020 /* IN1LP_TO_IN1L */
1091#define WM8993_IN1LP_TO_IN1L_MASK 0x0020 /* IN1LP_TO_IN1L */
1092#define WM8993_IN1LP_TO_IN1L_SHIFT 5 /* IN1LP_TO_IN1L */
1093#define WM8993_IN1LP_TO_IN1L_WIDTH 1 /* IN1LP_TO_IN1L */
1094#define WM8993_IN1LN_TO_IN1L 0x0010 /* IN1LN_TO_IN1L */
1095#define WM8993_IN1LN_TO_IN1L_MASK 0x0010 /* IN1LN_TO_IN1L */
1096#define WM8993_IN1LN_TO_IN1L_SHIFT 4 /* IN1LN_TO_IN1L */
1097#define WM8993_IN1LN_TO_IN1L_WIDTH 1 /* IN1LN_TO_IN1L */
1098#define WM8993_IN2RP_TO_IN2R 0x0008 /* IN2RP_TO_IN2R */
1099#define WM8993_IN2RP_TO_IN2R_MASK 0x0008 /* IN2RP_TO_IN2R */
1100#define WM8993_IN2RP_TO_IN2R_SHIFT 3 /* IN2RP_TO_IN2R */
1101#define WM8993_IN2RP_TO_IN2R_WIDTH 1 /* IN2RP_TO_IN2R */
1102#define WM8993_IN2RN_TO_IN2R 0x0004 /* IN2RN_TO_IN2R */
1103#define WM8993_IN2RN_TO_IN2R_MASK 0x0004 /* IN2RN_TO_IN2R */
1104#define WM8993_IN2RN_TO_IN2R_SHIFT 2 /* IN2RN_TO_IN2R */
1105#define WM8993_IN2RN_TO_IN2R_WIDTH 1 /* IN2RN_TO_IN2R */
1106#define WM8993_IN1RP_TO_IN1R 0x0002 /* IN1RP_TO_IN1R */
1107#define WM8993_IN1RP_TO_IN1R_MASK 0x0002 /* IN1RP_TO_IN1R */
1108#define WM8993_IN1RP_TO_IN1R_SHIFT 1 /* IN1RP_TO_IN1R */
1109#define WM8993_IN1RP_TO_IN1R_WIDTH 1 /* IN1RP_TO_IN1R */
1110#define WM8993_IN1RN_TO_IN1R 0x0001 /* IN1RN_TO_IN1R */
1111#define WM8993_IN1RN_TO_IN1R_MASK 0x0001 /* IN1RN_TO_IN1R */
1112#define WM8993_IN1RN_TO_IN1R_SHIFT 0 /* IN1RN_TO_IN1R */
1113#define WM8993_IN1RN_TO_IN1R_WIDTH 1 /* IN1RN_TO_IN1R */
1114
1115/*
1116 * R41 (0x29) - Input Mixer3
1117 */
1118#define WM8993_IN2L_TO_MIXINL 0x0100 /* IN2L_TO_MIXINL */
1119#define WM8993_IN2L_TO_MIXINL_MASK 0x0100 /* IN2L_TO_MIXINL */
1120#define WM8993_IN2L_TO_MIXINL_SHIFT 8 /* IN2L_TO_MIXINL */
1121#define WM8993_IN2L_TO_MIXINL_WIDTH 1 /* IN2L_TO_MIXINL */
1122#define WM8993_IN2L_MIXINL_VOL 0x0080 /* IN2L_MIXINL_VOL */
1123#define WM8993_IN2L_MIXINL_VOL_MASK 0x0080 /* IN2L_MIXINL_VOL */
1124#define WM8993_IN2L_MIXINL_VOL_SHIFT 7 /* IN2L_MIXINL_VOL */
1125#define WM8993_IN2L_MIXINL_VOL_WIDTH 1 /* IN2L_MIXINL_VOL */
1126#define WM8993_IN1L_TO_MIXINL 0x0020 /* IN1L_TO_MIXINL */
1127#define WM8993_IN1L_TO_MIXINL_MASK 0x0020 /* IN1L_TO_MIXINL */
1128#define WM8993_IN1L_TO_MIXINL_SHIFT 5 /* IN1L_TO_MIXINL */
1129#define WM8993_IN1L_TO_MIXINL_WIDTH 1 /* IN1L_TO_MIXINL */
1130#define WM8993_IN1L_MIXINL_VOL 0x0010 /* IN1L_MIXINL_VOL */
1131#define WM8993_IN1L_MIXINL_VOL_MASK 0x0010 /* IN1L_MIXINL_VOL */
1132#define WM8993_IN1L_MIXINL_VOL_SHIFT 4 /* IN1L_MIXINL_VOL */
1133#define WM8993_IN1L_MIXINL_VOL_WIDTH 1 /* IN1L_MIXINL_VOL */
1134#define WM8993_MIXOUTL_MIXINL_VOL_MASK 0x0007 /* MIXOUTL_MIXINL_VOL - [2:0] */
1135#define WM8993_MIXOUTL_MIXINL_VOL_SHIFT 0 /* MIXOUTL_MIXINL_VOL - [2:0] */
1136#define WM8993_MIXOUTL_MIXINL_VOL_WIDTH 3 /* MIXOUTL_MIXINL_VOL - [2:0] */
1137
1138/*
1139 * R42 (0x2A) - Input Mixer4
1140 */
1141#define WM8993_IN2R_TO_MIXINR 0x0100 /* IN2R_TO_MIXINR */
1142#define WM8993_IN2R_TO_MIXINR_MASK 0x0100 /* IN2R_TO_MIXINR */
1143#define WM8993_IN2R_TO_MIXINR_SHIFT 8 /* IN2R_TO_MIXINR */
1144#define WM8993_IN2R_TO_MIXINR_WIDTH 1 /* IN2R_TO_MIXINR */
1145#define WM8993_IN2R_MIXINR_VOL 0x0080 /* IN2R_MIXINR_VOL */
1146#define WM8993_IN2R_MIXINR_VOL_MASK 0x0080 /* IN2R_MIXINR_VOL */
1147#define WM8993_IN2R_MIXINR_VOL_SHIFT 7 /* IN2R_MIXINR_VOL */
1148#define WM8993_IN2R_MIXINR_VOL_WIDTH 1 /* IN2R_MIXINR_VOL */
1149#define WM8993_IN1R_TO_MIXINR 0x0020 /* IN1R_TO_MIXINR */
1150#define WM8993_IN1R_TO_MIXINR_MASK 0x0020 /* IN1R_TO_MIXINR */
1151#define WM8993_IN1R_TO_MIXINR_SHIFT 5 /* IN1R_TO_MIXINR */
1152#define WM8993_IN1R_TO_MIXINR_WIDTH 1 /* IN1R_TO_MIXINR */
1153#define WM8993_IN1R_MIXINR_VOL 0x0010 /* IN1R_MIXINR_VOL */
1154#define WM8993_IN1R_MIXINR_VOL_MASK 0x0010 /* IN1R_MIXINR_VOL */
1155#define WM8993_IN1R_MIXINR_VOL_SHIFT 4 /* IN1R_MIXINR_VOL */
1156#define WM8993_IN1R_MIXINR_VOL_WIDTH 1 /* IN1R_MIXINR_VOL */
1157#define WM8993_MIXOUTR_MIXINR_VOL_MASK 0x0007 /* MIXOUTR_MIXINR_VOL - [2:0] */
1158#define WM8993_MIXOUTR_MIXINR_VOL_SHIFT 0 /* MIXOUTR_MIXINR_VOL - [2:0] */
1159#define WM8993_MIXOUTR_MIXINR_VOL_WIDTH 3 /* MIXOUTR_MIXINR_VOL - [2:0] */
1160
1161/*
1162 * R43 (0x2B) - Input Mixer5
1163 */
1164#define WM8993_IN1LP_MIXINL_VOL_MASK 0x01C0 /* IN1LP_MIXINL_VOL - [8:6] */
1165#define WM8993_IN1LP_MIXINL_VOL_SHIFT 6 /* IN1LP_MIXINL_VOL - [8:6] */
1166#define WM8993_IN1LP_MIXINL_VOL_WIDTH 3 /* IN1LP_MIXINL_VOL - [8:6] */
1167#define WM8993_VRX_MIXINL_VOL_MASK 0x0007 /* VRX_MIXINL_VOL - [2:0] */
1168#define WM8993_VRX_MIXINL_VOL_SHIFT 0 /* VRX_MIXINL_VOL - [2:0] */
1169#define WM8993_VRX_MIXINL_VOL_WIDTH 3 /* VRX_MIXINL_VOL - [2:0] */
1170
1171/*
1172 * R44 (0x2C) - Input Mixer6
1173 */
1174#define WM8993_IN1RP_MIXINR_VOL_MASK 0x01C0 /* IN1RP_MIXINR_VOL - [8:6] */
1175#define WM8993_IN1RP_MIXINR_VOL_SHIFT 6 /* IN1RP_MIXINR_VOL - [8:6] */
1176#define WM8993_IN1RP_MIXINR_VOL_WIDTH 3 /* IN1RP_MIXINR_VOL - [8:6] */
1177#define WM8993_VRX_MIXINR_VOL_MASK 0x0007 /* VRX_MIXINR_VOL - [2:0] */
1178#define WM8993_VRX_MIXINR_VOL_SHIFT 0 /* VRX_MIXINR_VOL - [2:0] */
1179#define WM8993_VRX_MIXINR_VOL_WIDTH 3 /* VRX_MIXINR_VOL - [2:0] */
1180
1181/*
1182 * R45 (0x2D) - Output Mixer1
1183 */
1184#define WM8993_DACL_TO_HPOUT1L 0x0100 /* DACL_TO_HPOUT1L */
1185#define WM8993_DACL_TO_HPOUT1L_MASK 0x0100 /* DACL_TO_HPOUT1L */
1186#define WM8993_DACL_TO_HPOUT1L_SHIFT 8 /* DACL_TO_HPOUT1L */
1187#define WM8993_DACL_TO_HPOUT1L_WIDTH 1 /* DACL_TO_HPOUT1L */
1188#define WM8993_MIXINR_TO_MIXOUTL 0x0080 /* MIXINR_TO_MIXOUTL */
1189#define WM8993_MIXINR_TO_MIXOUTL_MASK 0x0080 /* MIXINR_TO_MIXOUTL */
1190#define WM8993_MIXINR_TO_MIXOUTL_SHIFT 7 /* MIXINR_TO_MIXOUTL */
1191#define WM8993_MIXINR_TO_MIXOUTL_WIDTH 1 /* MIXINR_TO_MIXOUTL */
1192#define WM8993_MIXINL_TO_MIXOUTL 0x0040 /* MIXINL_TO_MIXOUTL */
1193#define WM8993_MIXINL_TO_MIXOUTL_MASK 0x0040 /* MIXINL_TO_MIXOUTL */
1194#define WM8993_MIXINL_TO_MIXOUTL_SHIFT 6 /* MIXINL_TO_MIXOUTL */
1195#define WM8993_MIXINL_TO_MIXOUTL_WIDTH 1 /* MIXINL_TO_MIXOUTL */
1196#define WM8993_IN2RN_TO_MIXOUTL 0x0020 /* IN2RN_TO_MIXOUTL */
1197#define WM8993_IN2RN_TO_MIXOUTL_MASK 0x0020 /* IN2RN_TO_MIXOUTL */
1198#define WM8993_IN2RN_TO_MIXOUTL_SHIFT 5 /* IN2RN_TO_MIXOUTL */
1199#define WM8993_IN2RN_TO_MIXOUTL_WIDTH 1 /* IN2RN_TO_MIXOUTL */
1200#define WM8993_IN2LN_TO_MIXOUTL 0x0010 /* IN2LN_TO_MIXOUTL */
1201#define WM8993_IN2LN_TO_MIXOUTL_MASK 0x0010 /* IN2LN_TO_MIXOUTL */
1202#define WM8993_IN2LN_TO_MIXOUTL_SHIFT 4 /* IN2LN_TO_MIXOUTL */
1203#define WM8993_IN2LN_TO_MIXOUTL_WIDTH 1 /* IN2LN_TO_MIXOUTL */
1204#define WM8993_IN1R_TO_MIXOUTL 0x0008 /* IN1R_TO_MIXOUTL */
1205#define WM8993_IN1R_TO_MIXOUTL_MASK 0x0008 /* IN1R_TO_MIXOUTL */
1206#define WM8993_IN1R_TO_MIXOUTL_SHIFT 3 /* IN1R_TO_MIXOUTL */
1207#define WM8993_IN1R_TO_MIXOUTL_WIDTH 1 /* IN1R_TO_MIXOUTL */
1208#define WM8993_IN1L_TO_MIXOUTL 0x0004 /* IN1L_TO_MIXOUTL */
1209#define WM8993_IN1L_TO_MIXOUTL_MASK 0x0004 /* IN1L_TO_MIXOUTL */
1210#define WM8993_IN1L_TO_MIXOUTL_SHIFT 2 /* IN1L_TO_MIXOUTL */
1211#define WM8993_IN1L_TO_MIXOUTL_WIDTH 1 /* IN1L_TO_MIXOUTL */
1212#define WM8993_IN2LP_TO_MIXOUTL 0x0002 /* IN2LP_TO_MIXOUTL */
1213#define WM8993_IN2LP_TO_MIXOUTL_MASK 0x0002 /* IN2LP_TO_MIXOUTL */
1214#define WM8993_IN2LP_TO_MIXOUTL_SHIFT 1 /* IN2LP_TO_MIXOUTL */
1215#define WM8993_IN2LP_TO_MIXOUTL_WIDTH 1 /* IN2LP_TO_MIXOUTL */
1216#define WM8993_DACL_TO_MIXOUTL 0x0001 /* DACL_TO_MIXOUTL */
1217#define WM8993_DACL_TO_MIXOUTL_MASK 0x0001 /* DACL_TO_MIXOUTL */
1218#define WM8993_DACL_TO_MIXOUTL_SHIFT 0 /* DACL_TO_MIXOUTL */
1219#define WM8993_DACL_TO_MIXOUTL_WIDTH 1 /* DACL_TO_MIXOUTL */
1220
1221/*
1222 * R46 (0x2E) - Output Mixer2
1223 */
1224#define WM8993_DACR_TO_HPOUT1R 0x0100 /* DACR_TO_HPOUT1R */
1225#define WM8993_DACR_TO_HPOUT1R_MASK 0x0100 /* DACR_TO_HPOUT1R */
1226#define WM8993_DACR_TO_HPOUT1R_SHIFT 8 /* DACR_TO_HPOUT1R */
1227#define WM8993_DACR_TO_HPOUT1R_WIDTH 1 /* DACR_TO_HPOUT1R */
1228#define WM8993_MIXINL_TO_MIXOUTR 0x0080 /* MIXINL_TO_MIXOUTR */
1229#define WM8993_MIXINL_TO_MIXOUTR_MASK 0x0080 /* MIXINL_TO_MIXOUTR */
1230#define WM8993_MIXINL_TO_MIXOUTR_SHIFT 7 /* MIXINL_TO_MIXOUTR */
1231#define WM8993_MIXINL_TO_MIXOUTR_WIDTH 1 /* MIXINL_TO_MIXOUTR */
1232#define WM8993_MIXINR_TO_MIXOUTR 0x0040 /* MIXINR_TO_MIXOUTR */
1233#define WM8993_MIXINR_TO_MIXOUTR_MASK 0x0040 /* MIXINR_TO_MIXOUTR */
1234#define WM8993_MIXINR_TO_MIXOUTR_SHIFT 6 /* MIXINR_TO_MIXOUTR */
1235#define WM8993_MIXINR_TO_MIXOUTR_WIDTH 1 /* MIXINR_TO_MIXOUTR */
1236#define WM8993_IN2LN_TO_MIXOUTR 0x0020 /* IN2LN_TO_MIXOUTR */
1237#define WM8993_IN2LN_TO_MIXOUTR_MASK 0x0020 /* IN2LN_TO_MIXOUTR */
1238#define WM8993_IN2LN_TO_MIXOUTR_SHIFT 5 /* IN2LN_TO_MIXOUTR */
1239#define WM8993_IN2LN_TO_MIXOUTR_WIDTH 1 /* IN2LN_TO_MIXOUTR */
1240#define WM8993_IN2RN_TO_MIXOUTR 0x0010 /* IN2RN_TO_MIXOUTR */
1241#define WM8993_IN2RN_TO_MIXOUTR_MASK 0x0010 /* IN2RN_TO_MIXOUTR */
1242#define WM8993_IN2RN_TO_MIXOUTR_SHIFT 4 /* IN2RN_TO_MIXOUTR */
1243#define WM8993_IN2RN_TO_MIXOUTR_WIDTH 1 /* IN2RN_TO_MIXOUTR */
1244#define WM8993_IN1L_TO_MIXOUTR 0x0008 /* IN1L_TO_MIXOUTR */
1245#define WM8993_IN1L_TO_MIXOUTR_MASK 0x0008 /* IN1L_TO_MIXOUTR */
1246#define WM8993_IN1L_TO_MIXOUTR_SHIFT 3 /* IN1L_TO_MIXOUTR */
1247#define WM8993_IN1L_TO_MIXOUTR_WIDTH 1 /* IN1L_TO_MIXOUTR */
1248#define WM8993_IN1R_TO_MIXOUTR 0x0004 /* IN1R_TO_MIXOUTR */
1249#define WM8993_IN1R_TO_MIXOUTR_MASK 0x0004 /* IN1R_TO_MIXOUTR */
1250#define WM8993_IN1R_TO_MIXOUTR_SHIFT 2 /* IN1R_TO_MIXOUTR */
1251#define WM8993_IN1R_TO_MIXOUTR_WIDTH 1 /* IN1R_TO_MIXOUTR */
1252#define WM8993_IN2RP_TO_MIXOUTR 0x0002 /* IN2RP_TO_MIXOUTR */
1253#define WM8993_IN2RP_TO_MIXOUTR_MASK 0x0002 /* IN2RP_TO_MIXOUTR */
1254#define WM8993_IN2RP_TO_MIXOUTR_SHIFT 1 /* IN2RP_TO_MIXOUTR */
1255#define WM8993_IN2RP_TO_MIXOUTR_WIDTH 1 /* IN2RP_TO_MIXOUTR */
1256#define WM8993_DACR_TO_MIXOUTR 0x0001 /* DACR_TO_MIXOUTR */
1257#define WM8993_DACR_TO_MIXOUTR_MASK 0x0001 /* DACR_TO_MIXOUTR */
1258#define WM8993_DACR_TO_MIXOUTR_SHIFT 0 /* DACR_TO_MIXOUTR */
1259#define WM8993_DACR_TO_MIXOUTR_WIDTH 1 /* DACR_TO_MIXOUTR */
1260
1261/*
1262 * R47 (0x2F) - Output Mixer3
1263 */
1264#define WM8993_IN2LP_MIXOUTL_VOL_MASK 0x0E00 /* IN2LP_MIXOUTL_VOL - [11:9] */
1265#define WM8993_IN2LP_MIXOUTL_VOL_SHIFT 9 /* IN2LP_MIXOUTL_VOL - [11:9] */
1266#define WM8993_IN2LP_MIXOUTL_VOL_WIDTH 3 /* IN2LP_MIXOUTL_VOL - [11:9] */
1267#define WM8993_IN2LN_MIXOUTL_VOL_MASK 0x01C0 /* IN2LN_MIXOUTL_VOL - [8:6] */
1268#define WM8993_IN2LN_MIXOUTL_VOL_SHIFT 6 /* IN2LN_MIXOUTL_VOL - [8:6] */
1269#define WM8993_IN2LN_MIXOUTL_VOL_WIDTH 3 /* IN2LN_MIXOUTL_VOL - [8:6] */
1270#define WM8993_IN1R_MIXOUTL_VOL_MASK 0x0038 /* IN1R_MIXOUTL_VOL - [5:3] */
1271#define WM8993_IN1R_MIXOUTL_VOL_SHIFT 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1272#define WM8993_IN1R_MIXOUTL_VOL_WIDTH 3 /* IN1R_MIXOUTL_VOL - [5:3] */
1273#define WM8993_IN1L_MIXOUTL_VOL_MASK 0x0007 /* IN1L_MIXOUTL_VOL - [2:0] */
1274#define WM8993_IN1L_MIXOUTL_VOL_SHIFT 0 /* IN1L_MIXOUTL_VOL - [2:0] */
1275#define WM8993_IN1L_MIXOUTL_VOL_WIDTH 3 /* IN1L_MIXOUTL_VOL - [2:0] */
1276
1277/*
1278 * R48 (0x30) - Output Mixer4
1279 */
1280#define WM8993_IN2RP_MIXOUTR_VOL_MASK 0x0E00 /* IN2RP_MIXOUTR_VOL - [11:9] */
1281#define WM8993_IN2RP_MIXOUTR_VOL_SHIFT 9 /* IN2RP_MIXOUTR_VOL - [11:9] */
1282#define WM8993_IN2RP_MIXOUTR_VOL_WIDTH 3 /* IN2RP_MIXOUTR_VOL - [11:9] */
1283#define WM8993_IN2RN_MIXOUTR_VOL_MASK 0x01C0 /* IN2RN_MIXOUTR_VOL - [8:6] */
1284#define WM8993_IN2RN_MIXOUTR_VOL_SHIFT 6 /* IN2RN_MIXOUTR_VOL - [8:6] */
1285#define WM8993_IN2RN_MIXOUTR_VOL_WIDTH 3 /* IN2RN_MIXOUTR_VOL - [8:6] */
1286#define WM8993_IN1L_MIXOUTR_VOL_MASK 0x0038 /* IN1L_MIXOUTR_VOL - [5:3] */
1287#define WM8993_IN1L_MIXOUTR_VOL_SHIFT 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1288#define WM8993_IN1L_MIXOUTR_VOL_WIDTH 3 /* IN1L_MIXOUTR_VOL - [5:3] */
1289#define WM8993_IN1R_MIXOUTR_VOL_MASK 0x0007 /* IN1R_MIXOUTR_VOL - [2:0] */
1290#define WM8993_IN1R_MIXOUTR_VOL_SHIFT 0 /* IN1R_MIXOUTR_VOL - [2:0] */
1291#define WM8993_IN1R_MIXOUTR_VOL_WIDTH 3 /* IN1R_MIXOUTR_VOL - [2:0] */
1292
1293/*
1294 * R49 (0x31) - Output Mixer5
1295 */
1296#define WM8993_DACL_MIXOUTL_VOL_MASK 0x0E00 /* DACL_MIXOUTL_VOL - [11:9] */
1297#define WM8993_DACL_MIXOUTL_VOL_SHIFT 9 /* DACL_MIXOUTL_VOL - [11:9] */
1298#define WM8993_DACL_MIXOUTL_VOL_WIDTH 3 /* DACL_MIXOUTL_VOL - [11:9] */
1299#define WM8993_IN2RN_MIXOUTL_VOL_MASK 0x01C0 /* IN2RN_MIXOUTL_VOL - [8:6] */
1300#define WM8993_IN2RN_MIXOUTL_VOL_SHIFT 6 /* IN2RN_MIXOUTL_VOL - [8:6] */
1301#define WM8993_IN2RN_MIXOUTL_VOL_WIDTH 3 /* IN2RN_MIXOUTL_VOL - [8:6] */
1302#define WM8993_MIXINR_MIXOUTL_VOL_MASK 0x0038 /* MIXINR_MIXOUTL_VOL - [5:3] */
1303#define WM8993_MIXINR_MIXOUTL_VOL_SHIFT 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1304#define WM8993_MIXINR_MIXOUTL_VOL_WIDTH 3 /* MIXINR_MIXOUTL_VOL - [5:3] */
1305#define WM8993_MIXINL_MIXOUTL_VOL_MASK 0x0007 /* MIXINL_MIXOUTL_VOL - [2:0] */
1306#define WM8993_MIXINL_MIXOUTL_VOL_SHIFT 0 /* MIXINL_MIXOUTL_VOL - [2:0] */
1307#define WM8993_MIXINL_MIXOUTL_VOL_WIDTH 3 /* MIXINL_MIXOUTL_VOL - [2:0] */
1308
1309/*
1310 * R50 (0x32) - Output Mixer6
1311 */
1312#define WM8993_DACR_MIXOUTR_VOL_MASK 0x0E00 /* DACR_MIXOUTR_VOL - [11:9] */
1313#define WM8993_DACR_MIXOUTR_VOL_SHIFT 9 /* DACR_MIXOUTR_VOL - [11:9] */
1314#define WM8993_DACR_MIXOUTR_VOL_WIDTH 3 /* DACR_MIXOUTR_VOL - [11:9] */
1315#define WM8993_IN2LN_MIXOUTR_VOL_MASK 0x01C0 /* IN2LN_MIXOUTR_VOL - [8:6] */
1316#define WM8993_IN2LN_MIXOUTR_VOL_SHIFT 6 /* IN2LN_MIXOUTR_VOL - [8:6] */
1317#define WM8993_IN2LN_MIXOUTR_VOL_WIDTH 3 /* IN2LN_MIXOUTR_VOL - [8:6] */
1318#define WM8993_MIXINL_MIXOUTR_VOL_MASK 0x0038 /* MIXINL_MIXOUTR_VOL - [5:3] */
1319#define WM8993_MIXINL_MIXOUTR_VOL_SHIFT 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1320#define WM8993_MIXINL_MIXOUTR_VOL_WIDTH 3 /* MIXINL_MIXOUTR_VOL - [5:3] */
1321#define WM8993_MIXINR_MIXOUTR_VOL_MASK 0x0007 /* MIXINR_MIXOUTR_VOL - [2:0] */
1322#define WM8993_MIXINR_MIXOUTR_VOL_SHIFT 0 /* MIXINR_MIXOUTR_VOL - [2:0] */
1323#define WM8993_MIXINR_MIXOUTR_VOL_WIDTH 3 /* MIXINR_MIXOUTR_VOL - [2:0] */
1324
1325/*
1326 * R51 (0x33) - HPOUT2 Mixer
1327 */
1328#define WM8993_VRX_TO_HPOUT2 0x0020 /* VRX_TO_HPOUT2 */
1329#define WM8993_VRX_TO_HPOUT2_MASK 0x0020 /* VRX_TO_HPOUT2 */
1330#define WM8993_VRX_TO_HPOUT2_SHIFT 5 /* VRX_TO_HPOUT2 */
1331#define WM8993_VRX_TO_HPOUT2_WIDTH 1 /* VRX_TO_HPOUT2 */
1332#define WM8993_MIXOUTLVOL_TO_HPOUT2 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1333#define WM8993_MIXOUTLVOL_TO_HPOUT2_MASK 0x0010 /* MIXOUTLVOL_TO_HPOUT2 */
1334#define WM8993_MIXOUTLVOL_TO_HPOUT2_SHIFT 4 /* MIXOUTLVOL_TO_HPOUT2 */
1335#define WM8993_MIXOUTLVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTLVOL_TO_HPOUT2 */
1336#define WM8993_MIXOUTRVOL_TO_HPOUT2 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1337#define WM8993_MIXOUTRVOL_TO_HPOUT2_MASK 0x0008 /* MIXOUTRVOL_TO_HPOUT2 */
1338#define WM8993_MIXOUTRVOL_TO_HPOUT2_SHIFT 3 /* MIXOUTRVOL_TO_HPOUT2 */
1339#define WM8993_MIXOUTRVOL_TO_HPOUT2_WIDTH 1 /* MIXOUTRVOL_TO_HPOUT2 */
1340
1341/*
1342 * R52 (0x34) - Line Mixer1
1343 */
1344#define WM8993_MIXOUTL_TO_LINEOUT1N 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1345#define WM8993_MIXOUTL_TO_LINEOUT1N_MASK 0x0040 /* MIXOUTL_TO_LINEOUT1N */
1346#define WM8993_MIXOUTL_TO_LINEOUT1N_SHIFT 6 /* MIXOUTL_TO_LINEOUT1N */
1347#define WM8993_MIXOUTL_TO_LINEOUT1N_WIDTH 1 /* MIXOUTL_TO_LINEOUT1N */
1348#define WM8993_MIXOUTR_TO_LINEOUT1N 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1349#define WM8993_MIXOUTR_TO_LINEOUT1N_MASK 0x0020 /* MIXOUTR_TO_LINEOUT1N */
1350#define WM8993_MIXOUTR_TO_LINEOUT1N_SHIFT 5 /* MIXOUTR_TO_LINEOUT1N */
1351#define WM8993_MIXOUTR_TO_LINEOUT1N_WIDTH 1 /* MIXOUTR_TO_LINEOUT1N */
1352#define WM8993_LINEOUT1_MODE 0x0010 /* LINEOUT1_MODE */
1353#define WM8993_LINEOUT1_MODE_MASK 0x0010 /* LINEOUT1_MODE */
1354#define WM8993_LINEOUT1_MODE_SHIFT 4 /* LINEOUT1_MODE */
1355#define WM8993_LINEOUT1_MODE_WIDTH 1 /* LINEOUT1_MODE */
1356#define WM8993_IN1R_TO_LINEOUT1P 0x0004 /* IN1R_TO_LINEOUT1P */
1357#define WM8993_IN1R_TO_LINEOUT1P_MASK 0x0004 /* IN1R_TO_LINEOUT1P */
1358#define WM8993_IN1R_TO_LINEOUT1P_SHIFT 2 /* IN1R_TO_LINEOUT1P */
1359#define WM8993_IN1R_TO_LINEOUT1P_WIDTH 1 /* IN1R_TO_LINEOUT1P */
1360#define WM8993_IN1L_TO_LINEOUT1P 0x0002 /* IN1L_TO_LINEOUT1P */
1361#define WM8993_IN1L_TO_LINEOUT1P_MASK 0x0002 /* IN1L_TO_LINEOUT1P */
1362#define WM8993_IN1L_TO_LINEOUT1P_SHIFT 1 /* IN1L_TO_LINEOUT1P */
1363#define WM8993_IN1L_TO_LINEOUT1P_WIDTH 1 /* IN1L_TO_LINEOUT1P */
1364#define WM8993_MIXOUTL_TO_LINEOUT1P 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1365#define WM8993_MIXOUTL_TO_LINEOUT1P_MASK 0x0001 /* MIXOUTL_TO_LINEOUT1P */
1366#define WM8993_MIXOUTL_TO_LINEOUT1P_SHIFT 0 /* MIXOUTL_TO_LINEOUT1P */
1367#define WM8993_MIXOUTL_TO_LINEOUT1P_WIDTH 1 /* MIXOUTL_TO_LINEOUT1P */
1368
1369/*
1370 * R53 (0x35) - Line Mixer2
1371 */
1372#define WM8993_MIXOUTR_TO_LINEOUT2N 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1373#define WM8993_MIXOUTR_TO_LINEOUT2N_MASK 0x0040 /* MIXOUTR_TO_LINEOUT2N */
1374#define WM8993_MIXOUTR_TO_LINEOUT2N_SHIFT 6 /* MIXOUTR_TO_LINEOUT2N */
1375#define WM8993_MIXOUTR_TO_LINEOUT2N_WIDTH 1 /* MIXOUTR_TO_LINEOUT2N */
1376#define WM8993_MIXOUTL_TO_LINEOUT2N 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1377#define WM8993_MIXOUTL_TO_LINEOUT2N_MASK 0x0020 /* MIXOUTL_TO_LINEOUT2N */
1378#define WM8993_MIXOUTL_TO_LINEOUT2N_SHIFT 5 /* MIXOUTL_TO_LINEOUT2N */
1379#define WM8993_MIXOUTL_TO_LINEOUT2N_WIDTH 1 /* MIXOUTL_TO_LINEOUT2N */
1380#define WM8993_LINEOUT2_MODE 0x0010 /* LINEOUT2_MODE */
1381#define WM8993_LINEOUT2_MODE_MASK 0x0010 /* LINEOUT2_MODE */
1382#define WM8993_LINEOUT2_MODE_SHIFT 4 /* LINEOUT2_MODE */
1383#define WM8993_LINEOUT2_MODE_WIDTH 1 /* LINEOUT2_MODE */
1384#define WM8993_IN1L_TO_LINEOUT2P 0x0004 /* IN1L_TO_LINEOUT2P */
1385#define WM8993_IN1L_TO_LINEOUT2P_MASK 0x0004 /* IN1L_TO_LINEOUT2P */
1386#define WM8993_IN1L_TO_LINEOUT2P_SHIFT 2 /* IN1L_TO_LINEOUT2P */
1387#define WM8993_IN1L_TO_LINEOUT2P_WIDTH 1 /* IN1L_TO_LINEOUT2P */
1388#define WM8993_IN1R_TO_LINEOUT2P 0x0002 /* IN1R_TO_LINEOUT2P */
1389#define WM8993_IN1R_TO_LINEOUT2P_MASK 0x0002 /* IN1R_TO_LINEOUT2P */
1390#define WM8993_IN1R_TO_LINEOUT2P_SHIFT 1 /* IN1R_TO_LINEOUT2P */
1391#define WM8993_IN1R_TO_LINEOUT2P_WIDTH 1 /* IN1R_TO_LINEOUT2P */
1392#define WM8993_MIXOUTR_TO_LINEOUT2P 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1393#define WM8993_MIXOUTR_TO_LINEOUT2P_MASK 0x0001 /* MIXOUTR_TO_LINEOUT2P */
1394#define WM8993_MIXOUTR_TO_LINEOUT2P_SHIFT 0 /* MIXOUTR_TO_LINEOUT2P */
1395#define WM8993_MIXOUTR_TO_LINEOUT2P_WIDTH 1 /* MIXOUTR_TO_LINEOUT2P */
1396
1397/*
1398 * R54 (0x36) - Speaker Mixer
1399 */
1400#define WM8993_SPKAB_REF_SEL 0x0100 /* SPKAB_REF_SEL */
1401#define WM8993_SPKAB_REF_SEL_MASK 0x0100 /* SPKAB_REF_SEL */
1402#define WM8993_SPKAB_REF_SEL_SHIFT 8 /* SPKAB_REF_SEL */
1403#define WM8993_SPKAB_REF_SEL_WIDTH 1 /* SPKAB_REF_SEL */
1404#define WM8993_MIXINL_TO_SPKMIXL 0x0080 /* MIXINL_TO_SPKMIXL */
1405#define WM8993_MIXINL_TO_SPKMIXL_MASK 0x0080 /* MIXINL_TO_SPKMIXL */
1406#define WM8993_MIXINL_TO_SPKMIXL_SHIFT 7 /* MIXINL_TO_SPKMIXL */
1407#define WM8993_MIXINL_TO_SPKMIXL_WIDTH 1 /* MIXINL_TO_SPKMIXL */
1408#define WM8993_MIXINR_TO_SPKMIXR 0x0040 /* MIXINR_TO_SPKMIXR */
1409#define WM8993_MIXINR_TO_SPKMIXR_MASK 0x0040 /* MIXINR_TO_SPKMIXR */
1410#define WM8993_MIXINR_TO_SPKMIXR_SHIFT 6 /* MIXINR_TO_SPKMIXR */
1411#define WM8993_MIXINR_TO_SPKMIXR_WIDTH 1 /* MIXINR_TO_SPKMIXR */
1412#define WM8993_IN1LP_TO_SPKMIXL 0x0020 /* IN1LP_TO_SPKMIXL */
1413#define WM8993_IN1LP_TO_SPKMIXL_MASK 0x0020 /* IN1LP_TO_SPKMIXL */
1414#define WM8993_IN1LP_TO_SPKMIXL_SHIFT 5 /* IN1LP_TO_SPKMIXL */
1415#define WM8993_IN1LP_TO_SPKMIXL_WIDTH 1 /* IN1LP_TO_SPKMIXL */
1416#define WM8993_IN1RP_TO_SPKMIXR 0x0010 /* IN1RP_TO_SPKMIXR */
1417#define WM8993_IN1RP_TO_SPKMIXR_MASK 0x0010 /* IN1RP_TO_SPKMIXR */
1418#define WM8993_IN1RP_TO_SPKMIXR_SHIFT 4 /* IN1RP_TO_SPKMIXR */
1419#define WM8993_IN1RP_TO_SPKMIXR_WIDTH 1 /* IN1RP_TO_SPKMIXR */
1420#define WM8993_MIXOUTL_TO_SPKMIXL 0x0008 /* MIXOUTL_TO_SPKMIXL */
1421#define WM8993_MIXOUTL_TO_SPKMIXL_MASK 0x0008 /* MIXOUTL_TO_SPKMIXL */
1422#define WM8993_MIXOUTL_TO_SPKMIXL_SHIFT 3 /* MIXOUTL_TO_SPKMIXL */
1423#define WM8993_MIXOUTL_TO_SPKMIXL_WIDTH 1 /* MIXOUTL_TO_SPKMIXL */
1424#define WM8993_MIXOUTR_TO_SPKMIXR 0x0004 /* MIXOUTR_TO_SPKMIXR */
1425#define WM8993_MIXOUTR_TO_SPKMIXR_MASK 0x0004 /* MIXOUTR_TO_SPKMIXR */
1426#define WM8993_MIXOUTR_TO_SPKMIXR_SHIFT 2 /* MIXOUTR_TO_SPKMIXR */
1427#define WM8993_MIXOUTR_TO_SPKMIXR_WIDTH 1 /* MIXOUTR_TO_SPKMIXR */
1428#define WM8993_DACL_TO_SPKMIXL 0x0002 /* DACL_TO_SPKMIXL */
1429#define WM8993_DACL_TO_SPKMIXL_MASK 0x0002 /* DACL_TO_SPKMIXL */
1430#define WM8993_DACL_TO_SPKMIXL_SHIFT 1 /* DACL_TO_SPKMIXL */
1431#define WM8993_DACL_TO_SPKMIXL_WIDTH 1 /* DACL_TO_SPKMIXL */
1432#define WM8993_DACR_TO_SPKMIXR 0x0001 /* DACR_TO_SPKMIXR */
1433#define WM8993_DACR_TO_SPKMIXR_MASK 0x0001 /* DACR_TO_SPKMIXR */
1434#define WM8993_DACR_TO_SPKMIXR_SHIFT 0 /* DACR_TO_SPKMIXR */
1435#define WM8993_DACR_TO_SPKMIXR_WIDTH 1 /* DACR_TO_SPKMIXR */
1436
1437/*
1438 * R55 (0x37) - Additional Control
1439 */
1440#define WM8993_LINEOUT1_FB 0x0080 /* LINEOUT1_FB */
1441#define WM8993_LINEOUT1_FB_MASK 0x0080 /* LINEOUT1_FB */
1442#define WM8993_LINEOUT1_FB_SHIFT 7 /* LINEOUT1_FB */
1443#define WM8993_LINEOUT1_FB_WIDTH 1 /* LINEOUT1_FB */
1444#define WM8993_LINEOUT2_FB 0x0040 /* LINEOUT2_FB */
1445#define WM8993_LINEOUT2_FB_MASK 0x0040 /* LINEOUT2_FB */
1446#define WM8993_LINEOUT2_FB_SHIFT 6 /* LINEOUT2_FB */
1447#define WM8993_LINEOUT2_FB_WIDTH 1 /* LINEOUT2_FB */
1448#define WM8993_VROI 0x0001 /* VROI */
1449#define WM8993_VROI_MASK 0x0001 /* VROI */
1450#define WM8993_VROI_SHIFT 0 /* VROI */
1451#define WM8993_VROI_WIDTH 1 /* VROI */
1452
1453/*
1454 * R56 (0x38) - AntiPOP1
1455 */
1456#define WM8993_LINEOUT_VMID_BUF_ENA 0x0080 /* LINEOUT_VMID_BUF_ENA */
1457#define WM8993_LINEOUT_VMID_BUF_ENA_MASK 0x0080 /* LINEOUT_VMID_BUF_ENA */
1458#define WM8993_LINEOUT_VMID_BUF_ENA_SHIFT 7 /* LINEOUT_VMID_BUF_ENA */
1459#define WM8993_LINEOUT_VMID_BUF_ENA_WIDTH 1 /* LINEOUT_VMID_BUF_ENA */
1460#define WM8993_HPOUT2_IN_ENA 0x0040 /* HPOUT2_IN_ENA */
1461#define WM8993_HPOUT2_IN_ENA_MASK 0x0040 /* HPOUT2_IN_ENA */
1462#define WM8993_HPOUT2_IN_ENA_SHIFT 6 /* HPOUT2_IN_ENA */
1463#define WM8993_HPOUT2_IN_ENA_WIDTH 1 /* HPOUT2_IN_ENA */
1464#define WM8993_LINEOUT1_DISCH 0x0020 /* LINEOUT1_DISCH */
1465#define WM8993_LINEOUT1_DISCH_MASK 0x0020 /* LINEOUT1_DISCH */
1466#define WM8993_LINEOUT1_DISCH_SHIFT 5 /* LINEOUT1_DISCH */
1467#define WM8993_LINEOUT1_DISCH_WIDTH 1 /* LINEOUT1_DISCH */
1468#define WM8993_LINEOUT2_DISCH 0x0010 /* LINEOUT2_DISCH */
1469#define WM8993_LINEOUT2_DISCH_MASK 0x0010 /* LINEOUT2_DISCH */
1470#define WM8993_LINEOUT2_DISCH_SHIFT 4 /* LINEOUT2_DISCH */
1471#define WM8993_LINEOUT2_DISCH_WIDTH 1 /* LINEOUT2_DISCH */
1472
1473/*
1474 * R57 (0x39) - AntiPOP2
1475 */
1476#define WM8993_VMID_RAMP_MASK 0x0060 /* VMID_RAMP - [6:5] */
1477#define WM8993_VMID_RAMP_SHIFT 5 /* VMID_RAMP - [6:5] */
1478#define WM8993_VMID_RAMP_WIDTH 2 /* VMID_RAMP - [6:5] */
1479#define WM8993_VMID_BUF_ENA 0x0008 /* VMID_BUF_ENA */
1480#define WM8993_VMID_BUF_ENA_MASK 0x0008 /* VMID_BUF_ENA */
1481#define WM8993_VMID_BUF_ENA_SHIFT 3 /* VMID_BUF_ENA */
1482#define WM8993_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
1483#define WM8993_STARTUP_BIAS_ENA 0x0004 /* STARTUP_BIAS_ENA */
1484#define WM8993_STARTUP_BIAS_ENA_MASK 0x0004 /* STARTUP_BIAS_ENA */
1485#define WM8993_STARTUP_BIAS_ENA_SHIFT 2 /* STARTUP_BIAS_ENA */
1486#define WM8993_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
1487#define WM8993_BIAS_SRC 0x0002 /* BIAS_SRC */
1488#define WM8993_BIAS_SRC_MASK 0x0002 /* BIAS_SRC */
1489#define WM8993_BIAS_SRC_SHIFT 1 /* BIAS_SRC */
1490#define WM8993_BIAS_SRC_WIDTH 1 /* BIAS_SRC */
1491#define WM8993_VMID_DISCH 0x0001 /* VMID_DISCH */
1492#define WM8993_VMID_DISCH_MASK 0x0001 /* VMID_DISCH */
1493#define WM8993_VMID_DISCH_SHIFT 0 /* VMID_DISCH */
1494#define WM8993_VMID_DISCH_WIDTH 1 /* VMID_DISCH */
1495
1496/*
1497 * R58 (0x3A) - MICBIAS
1498 */
1499#define WM8993_JD_SCTHR_MASK 0x00C0 /* JD_SCTHR - [7:6] */
1500#define WM8993_JD_SCTHR_SHIFT 6 /* JD_SCTHR - [7:6] */
1501#define WM8993_JD_SCTHR_WIDTH 2 /* JD_SCTHR - [7:6] */
1502#define WM8993_JD_THR_MASK 0x0030 /* JD_THR - [5:4] */
1503#define WM8993_JD_THR_SHIFT 4 /* JD_THR - [5:4] */
1504#define WM8993_JD_THR_WIDTH 2 /* JD_THR - [5:4] */
1505#define WM8993_JD_ENA 0x0004 /* JD_ENA */
1506#define WM8993_JD_ENA_MASK 0x0004 /* JD_ENA */
1507#define WM8993_JD_ENA_SHIFT 2 /* JD_ENA */
1508#define WM8993_JD_ENA_WIDTH 1 /* JD_ENA */
1509#define WM8993_MICB2_LVL 0x0002 /* MICB2_LVL */
1510#define WM8993_MICB2_LVL_MASK 0x0002 /* MICB2_LVL */
1511#define WM8993_MICB2_LVL_SHIFT 1 /* MICB2_LVL */
1512#define WM8993_MICB2_LVL_WIDTH 1 /* MICB2_LVL */
1513#define WM8993_MICB1_LVL 0x0001 /* MICB1_LVL */
1514#define WM8993_MICB1_LVL_MASK 0x0001 /* MICB1_LVL */
1515#define WM8993_MICB1_LVL_SHIFT 0 /* MICB1_LVL */
1516#define WM8993_MICB1_LVL_WIDTH 1 /* MICB1_LVL */
1517
1518/*
1519 * R60 (0x3C) - FLL Control 1
1520 */
1521#define WM8993_FLL_FRAC 0x0004 /* FLL_FRAC */
1522#define WM8993_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */
1523#define WM8993_FLL_FRAC_SHIFT 2 /* FLL_FRAC */
1524#define WM8993_FLL_FRAC_WIDTH 1 /* FLL_FRAC */
1525#define WM8993_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1526#define WM8993_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1527#define WM8993_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1528#define WM8993_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1529#define WM8993_FLL_ENA 0x0001 /* FLL_ENA */
1530#define WM8993_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1531#define WM8993_FLL_ENA_SHIFT 0 /* FLL_ENA */
1532#define WM8993_FLL_ENA_WIDTH 1 /* FLL_ENA */
1533
1534/*
1535 * R61 (0x3D) - FLL Control 2
1536 */
1537#define WM8993_FLL_OUTDIV_MASK 0x0700 /* FLL_OUTDIV - [10:8] */
1538#define WM8993_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [10:8] */
1539#define WM8993_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [10:8] */
1540#define WM8993_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1541#define WM8993_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1542#define WM8993_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1543#define WM8993_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1544#define WM8993_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1545#define WM8993_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1546
1547/*
1548 * R62 (0x3E) - FLL Control 3
1549 */
1550#define WM8993_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1551#define WM8993_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1552#define WM8993_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1553
1554/*
1555 * R63 (0x3F) - FLL Control 4
1556 */
1557#define WM8993_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1558#define WM8993_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1559#define WM8993_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1560#define WM8993_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1561#define WM8993_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1562#define WM8993_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1563
1564/*
1565 * R64 (0x40) - FLL Control 5
1566 */
1567#define WM8993_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */
1568#define WM8993_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */
1569#define WM8993_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */
1570#define WM8993_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */
1571#define WM8993_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */
1572#define WM8993_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */
1573#define WM8993_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1574#define WM8993_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1575#define WM8993_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1576#define WM8993_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1577#define WM8993_FLL_CLK_SRC_MASK 0x0003 /* FLL_CLK_SRC - [1:0] */
1578#define WM8993_FLL_CLK_SRC_SHIFT 0 /* FLL_CLK_SRC - [1:0] */
1579#define WM8993_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [1:0] */
1580
1581/*
1582 * R65 (0x41) - Clocking 3
1583 */
1584#define WM8993_CLK_DCS_DIV_MASK 0x3C00 /* CLK_DCS_DIV - [13:10] */
1585#define WM8993_CLK_DCS_DIV_SHIFT 10 /* CLK_DCS_DIV - [13:10] */
1586#define WM8993_CLK_DCS_DIV_WIDTH 4 /* CLK_DCS_DIV - [13:10] */
1587#define WM8993_SAMPLE_RATE_MASK 0x0380 /* SAMPLE_RATE - [9:7] */
1588#define WM8993_SAMPLE_RATE_SHIFT 7 /* SAMPLE_RATE - [9:7] */
1589#define WM8993_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [9:7] */
1590#define WM8993_CLK_SYS_RATE_MASK 0x001E /* CLK_SYS_RATE - [4:1] */
1591#define WM8993_CLK_SYS_RATE_SHIFT 1 /* CLK_SYS_RATE - [4:1] */
1592#define WM8993_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [4:1] */
1593#define WM8993_CLK_DSP_ENA 0x0001 /* CLK_DSP_ENA */
1594#define WM8993_CLK_DSP_ENA_MASK 0x0001 /* CLK_DSP_ENA */
1595#define WM8993_CLK_DSP_ENA_SHIFT 0 /* CLK_DSP_ENA */
1596#define WM8993_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
1597
1598/*
1599 * R66 (0x42) - Clocking 4
1600 */
1601#define WM8993_DAC_DIV4 0x0200 /* DAC_DIV4 */
1602#define WM8993_DAC_DIV4_MASK 0x0200 /* DAC_DIV4 */
1603#define WM8993_DAC_DIV4_SHIFT 9 /* DAC_DIV4 */
1604#define WM8993_DAC_DIV4_WIDTH 1 /* DAC_DIV4 */
1605#define WM8993_CLK_256K_DIV_MASK 0x007E /* CLK_256K_DIV - [6:1] */
1606#define WM8993_CLK_256K_DIV_SHIFT 1 /* CLK_256K_DIV - [6:1] */
1607#define WM8993_CLK_256K_DIV_WIDTH 6 /* CLK_256K_DIV - [6:1] */
1608#define WM8993_SR_MODE 0x0001 /* SR_MODE */
1609#define WM8993_SR_MODE_MASK 0x0001 /* SR_MODE */
1610#define WM8993_SR_MODE_SHIFT 0 /* SR_MODE */
1611#define WM8993_SR_MODE_WIDTH 1 /* SR_MODE */
1612
1613/*
1614 * R67 (0x43) - MW Slave Control
1615 */
1616#define WM8993_MASK_WRITE_ENA 0x0001 /* MASK_WRITE_ENA */
1617#define WM8993_MASK_WRITE_ENA_MASK 0x0001 /* MASK_WRITE_ENA */
1618#define WM8993_MASK_WRITE_ENA_SHIFT 0 /* MASK_WRITE_ENA */
1619#define WM8993_MASK_WRITE_ENA_WIDTH 1 /* MASK_WRITE_ENA */
1620
1621/*
1622 * R69 (0x45) - Bus Control 1
1623 */
1624#define WM8993_CLK_SYS_ENA 0x0002 /* CLK_SYS_ENA */
1625#define WM8993_CLK_SYS_ENA_MASK 0x0002 /* CLK_SYS_ENA */
1626#define WM8993_CLK_SYS_ENA_SHIFT 1 /* CLK_SYS_ENA */
1627#define WM8993_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
1628
1629/*
1630 * R70 (0x46) - Write Sequencer 0
1631 */
1632#define WM8993_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1633#define WM8993_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1634#define WM8993_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1635#define WM8993_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1636#define WM8993_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1637#define WM8993_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1638#define WM8993_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1639
1640/*
1641 * R71 (0x47) - Write Sequencer 1
1642 */
1643#define WM8993_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1644#define WM8993_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1645#define WM8993_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1646#define WM8993_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1647#define WM8993_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1648#define WM8993_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1649#define WM8993_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1650#define WM8993_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1651#define WM8993_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1652
1653/*
1654 * R72 (0x48) - Write Sequencer 2
1655 */
1656#define WM8993_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1657#define WM8993_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1658#define WM8993_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1659#define WM8993_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1660#define WM8993_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1661#define WM8993_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1662#define WM8993_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1663#define WM8993_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1664#define WM8993_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1665#define WM8993_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1666
1667/*
1668 * R73 (0x49) - Write Sequencer 3
1669 */
1670#define WM8993_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1671#define WM8993_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1672#define WM8993_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1673#define WM8993_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1674#define WM8993_WSEQ_START 0x0100 /* WSEQ_START */
1675#define WM8993_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1676#define WM8993_WSEQ_START_SHIFT 8 /* WSEQ_START */
1677#define WM8993_WSEQ_START_WIDTH 1 /* WSEQ_START */
1678#define WM8993_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1679#define WM8993_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1680#define WM8993_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1681
1682/*
1683 * R74 (0x4A) - Write Sequencer 4
1684 */
1685#define WM8993_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1686#define WM8993_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1687#define WM8993_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1688#define WM8993_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1689
1690/*
1691 * R75 (0x4B) - Write Sequencer 5
1692 */
1693#define WM8993_WSEQ_CURRENT_INDEX_MASK 0x003F /* WSEQ_CURRENT_INDEX - [5:0] */
1694#define WM8993_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [5:0] */
1695#define WM8993_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [5:0] */
1696
1697/*
1698 * R76 (0x4C) - Charge Pump 1
1699 */
1700#define WM8993_CP_ENA 0x8000 /* CP_ENA */
1701#define WM8993_CP_ENA_MASK 0x8000 /* CP_ENA */
1702#define WM8993_CP_ENA_SHIFT 15 /* CP_ENA */
1703#define WM8993_CP_ENA_WIDTH 1 /* CP_ENA */
1704
1705/*
1706 * R81 (0x51) - Class W 0
1707 */
1708#define WM8993_CP_DYN_FREQ 0x0002 /* CP_DYN_FREQ */
1709#define WM8993_CP_DYN_FREQ_MASK 0x0002 /* CP_DYN_FREQ */
1710#define WM8993_CP_DYN_FREQ_SHIFT 1 /* CP_DYN_FREQ */
1711#define WM8993_CP_DYN_FREQ_WIDTH 1 /* CP_DYN_FREQ */
1712#define WM8993_CP_DYN_V 0x0001 /* CP_DYN_V */
1713#define WM8993_CP_DYN_V_MASK 0x0001 /* CP_DYN_V */
1714#define WM8993_CP_DYN_V_SHIFT 0 /* CP_DYN_V */
1715#define WM8993_CP_DYN_V_WIDTH 1 /* CP_DYN_V */
1716
1717/*
1718 * R84 (0x54) - DC Servo 0
1719 */
1720#define WM8993_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1721#define WM8993_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1722#define WM8993_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1723#define WM8993_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1724#define WM8993_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1725#define WM8993_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1726#define WM8993_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1727#define WM8993_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1728#define WM8993_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1729#define WM8993_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1730#define WM8993_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1731#define WM8993_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1732#define WM8993_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1733#define WM8993_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1734#define WM8993_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1735#define WM8993_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1736#define WM8993_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1737#define WM8993_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1738#define WM8993_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1739#define WM8993_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1740#define WM8993_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1741#define WM8993_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1742#define WM8993_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1743#define WM8993_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1744#define WM8993_DCS_TRIG_DAC_WR_1 0x0008 /* DCS_TRIG_DAC_WR_1 */
1745#define WM8993_DCS_TRIG_DAC_WR_1_MASK 0x0008 /* DCS_TRIG_DAC_WR_1 */
1746#define WM8993_DCS_TRIG_DAC_WR_1_SHIFT 3 /* DCS_TRIG_DAC_WR_1 */
1747#define WM8993_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1748#define WM8993_DCS_TRIG_DAC_WR_0 0x0004 /* DCS_TRIG_DAC_WR_0 */
1749#define WM8993_DCS_TRIG_DAC_WR_0_MASK 0x0004 /* DCS_TRIG_DAC_WR_0 */
1750#define WM8993_DCS_TRIG_DAC_WR_0_SHIFT 2 /* DCS_TRIG_DAC_WR_0 */
1751#define WM8993_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1752#define WM8993_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1753#define WM8993_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1754#define WM8993_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1755#define WM8993_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1756#define WM8993_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1757#define WM8993_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1758#define WM8993_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1759#define WM8993_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1760
1761/*
1762 * R85 (0x55) - DC Servo 1
1763 */
1764#define WM8993_DCS_SERIES_NO_01_MASK 0x0FE0 /* DCS_SERIES_NO_01 - [11:5] */
1765#define WM8993_DCS_SERIES_NO_01_SHIFT 5 /* DCS_SERIES_NO_01 - [11:5] */
1766#define WM8993_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [11:5] */
1767#define WM8993_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1768#define WM8993_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1769#define WM8993_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1770
1771/*
1772 * R87 (0x57) - DC Servo 3
1773 */
1774#define WM8993_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1775#define WM8993_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1776#define WM8993_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1777#define WM8993_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1778#define WM8993_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1779#define WM8993_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1780
1781/*
1782 * R88 (0x58) - DC Servo Readback 0
1783 */
1784#define WM8993_DCS_DATAPATH_BUSY 0x4000 /* DCS_DATAPATH_BUSY */
1785#define WM8993_DCS_DATAPATH_BUSY_MASK 0x4000 /* DCS_DATAPATH_BUSY */
1786#define WM8993_DCS_DATAPATH_BUSY_SHIFT 14 /* DCS_DATAPATH_BUSY */
1787#define WM8993_DCS_DATAPATH_BUSY_WIDTH 1 /* DCS_DATAPATH_BUSY */
1788#define WM8993_DCS_CHANNEL_MASK 0x3000 /* DCS_CHANNEL - [13:12] */
1789#define WM8993_DCS_CHANNEL_SHIFT 12 /* DCS_CHANNEL - [13:12] */
1790#define WM8993_DCS_CHANNEL_WIDTH 2 /* DCS_CHANNEL - [13:12] */
1791#define WM8993_DCS_CAL_COMPLETE_MASK 0x0300 /* DCS_CAL_COMPLETE - [9:8] */
1792#define WM8993_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [9:8] */
1793#define WM8993_DCS_CAL_COMPLETE_WIDTH 2 /* DCS_CAL_COMPLETE - [9:8] */
1794#define WM8993_DCS_DAC_WR_COMPLETE_MASK 0x0030 /* DCS_DAC_WR_COMPLETE - [5:4] */
1795#define WM8993_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [5:4] */
1796#define WM8993_DCS_DAC_WR_COMPLETE_WIDTH 2 /* DCS_DAC_WR_COMPLETE - [5:4] */
1797#define WM8993_DCS_STARTUP_COMPLETE_MASK 0x0003 /* DCS_STARTUP_COMPLETE - [1:0] */
1798#define WM8993_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [1:0] */
1799#define WM8993_DCS_STARTUP_COMPLETE_WIDTH 2 /* DCS_STARTUP_COMPLETE - [1:0] */
1800
1801/*
1802 * R89 (0x59) - DC Servo Readback 1
1803 */
1804#define WM8993_DCS_INTEG_CHAN_1_MASK 0x00FF /* DCS_INTEG_CHAN_1 - [7:0] */
1805#define WM8993_DCS_INTEG_CHAN_1_SHIFT 0 /* DCS_INTEG_CHAN_1 - [7:0] */
1806#define WM8993_DCS_INTEG_CHAN_1_WIDTH 8 /* DCS_INTEG_CHAN_1 - [7:0] */
1807
1808/*
1809 * R90 (0x5A) - DC Servo Readback 2
1810 */
1811#define WM8993_DCS_INTEG_CHAN_0_MASK 0x00FF /* DCS_INTEG_CHAN_0 - [7:0] */
1812#define WM8993_DCS_INTEG_CHAN_0_SHIFT 0 /* DCS_INTEG_CHAN_0 - [7:0] */
1813#define WM8993_DCS_INTEG_CHAN_0_WIDTH 8 /* DCS_INTEG_CHAN_0 - [7:0] */
1814
1815/*
1816 * R96 (0x60) - Analogue HP 0
1817 */
1818#define WM8993_HPOUT1_AUTO_PU 0x0100 /* HPOUT1_AUTO_PU */
1819#define WM8993_HPOUT1_AUTO_PU_MASK 0x0100 /* HPOUT1_AUTO_PU */
1820#define WM8993_HPOUT1_AUTO_PU_SHIFT 8 /* HPOUT1_AUTO_PU */
1821#define WM8993_HPOUT1_AUTO_PU_WIDTH 1 /* HPOUT1_AUTO_PU */
1822#define WM8993_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1823#define WM8993_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1824#define WM8993_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1825#define WM8993_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1826#define WM8993_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1827#define WM8993_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1828#define WM8993_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1829#define WM8993_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1830#define WM8993_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1831#define WM8993_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1832#define WM8993_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1833#define WM8993_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1834#define WM8993_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1835#define WM8993_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1836#define WM8993_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1837#define WM8993_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1838#define WM8993_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1839#define WM8993_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1840#define WM8993_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1841#define WM8993_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1842#define WM8993_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1843#define WM8993_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1844#define WM8993_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1845#define WM8993_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1846
1847/*
1848 * R98 (0x62) - EQ1
1849 */
1850#define WM8993_EQ_ENA 0x0001 /* EQ_ENA */
1851#define WM8993_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1852#define WM8993_EQ_ENA_SHIFT 0 /* EQ_ENA */
1853#define WM8993_EQ_ENA_WIDTH 1 /* EQ_ENA */
1854
1855/*
1856 * R99 (0x63) - EQ2
1857 */
1858#define WM8993_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1859#define WM8993_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1860#define WM8993_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1861
1862/*
1863 * R100 (0x64) - EQ3
1864 */
1865#define WM8993_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1866#define WM8993_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1867#define WM8993_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1868
1869/*
1870 * R101 (0x65) - EQ4
1871 */
1872#define WM8993_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1873#define WM8993_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1874#define WM8993_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1875
1876/*
1877 * R102 (0x66) - EQ5
1878 */
1879#define WM8993_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1880#define WM8993_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1881#define WM8993_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1882
1883/*
1884 * R103 (0x67) - EQ6
1885 */
1886#define WM8993_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1887#define WM8993_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1888#define WM8993_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1889
1890/*
1891 * R104 (0x68) - EQ7
1892 */
1893#define WM8993_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1894#define WM8993_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1895#define WM8993_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1896
1897/*
1898 * R105 (0x69) - EQ8
1899 */
1900#define WM8993_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1901#define WM8993_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1902#define WM8993_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1903
1904/*
1905 * R106 (0x6A) - EQ9
1906 */
1907#define WM8993_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1908#define WM8993_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1909#define WM8993_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1910
1911/*
1912 * R107 (0x6B) - EQ10
1913 */
1914#define WM8993_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1915#define WM8993_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1916#define WM8993_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1917
1918/*
1919 * R108 (0x6C) - EQ11
1920 */
1921#define WM8993_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1922#define WM8993_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1923#define WM8993_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1924
1925/*
1926 * R109 (0x6D) - EQ12
1927 */
1928#define WM8993_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1929#define WM8993_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1930#define WM8993_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1931
1932/*
1933 * R110 (0x6E) - EQ13
1934 */
1935#define WM8993_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1936#define WM8993_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1937#define WM8993_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1938
1939/*
1940 * R111 (0x6F) - EQ14
1941 */
1942#define WM8993_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1943#define WM8993_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1944#define WM8993_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1945
1946/*
1947 * R112 (0x70) - EQ15
1948 */
1949#define WM8993_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1950#define WM8993_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1951#define WM8993_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1952
1953/*
1954 * R113 (0x71) - EQ16
1955 */
1956#define WM8993_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1957#define WM8993_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1958#define WM8993_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1959
1960/*
1961 * R114 (0x72) - EQ17
1962 */
1963#define WM8993_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1964#define WM8993_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1965#define WM8993_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1966
1967/*
1968 * R115 (0x73) - EQ18
1969 */
1970#define WM8993_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1971#define WM8993_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1972#define WM8993_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1973
1974/*
1975 * R116 (0x74) - EQ19
1976 */
1977#define WM8993_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1978#define WM8993_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1979#define WM8993_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1980
1981/*
1982 * R117 (0x75) - EQ20
1983 */
1984#define WM8993_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1985#define WM8993_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1986#define WM8993_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1987
1988/*
1989 * R118 (0x76) - EQ21
1990 */
1991#define WM8993_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1992#define WM8993_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1993#define WM8993_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1994
1995/*
1996 * R119 (0x77) - EQ22
1997 */
1998#define WM8993_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1999#define WM8993_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
2000#define WM8993_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
2001
2002/*
2003 * R120 (0x78) - EQ23
2004 */
2005#define WM8993_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
2006#define WM8993_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
2007#define WM8993_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
2008
2009/*
2010 * R121 (0x79) - EQ24
2011 */
2012#define WM8993_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
2013#define WM8993_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
2014#define WM8993_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
2015
2016/*
2017 * R122 (0x7A) - Digital Pulls
2018 */
2019#define WM8993_MCLK_PU 0x0080 /* MCLK_PU */
2020#define WM8993_MCLK_PU_MASK 0x0080 /* MCLK_PU */
2021#define WM8993_MCLK_PU_SHIFT 7 /* MCLK_PU */
2022#define WM8993_MCLK_PU_WIDTH 1 /* MCLK_PU */
2023#define WM8993_MCLK_PD 0x0040 /* MCLK_PD */
2024#define WM8993_MCLK_PD_MASK 0x0040 /* MCLK_PD */
2025#define WM8993_MCLK_PD_SHIFT 6 /* MCLK_PD */
2026#define WM8993_MCLK_PD_WIDTH 1 /* MCLK_PD */
2027#define WM8993_DACDAT_PU 0x0020 /* DACDAT_PU */
2028#define WM8993_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
2029#define WM8993_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
2030#define WM8993_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
2031#define WM8993_DACDAT_PD 0x0010 /* DACDAT_PD */
2032#define WM8993_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
2033#define WM8993_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
2034#define WM8993_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
2035#define WM8993_LRCLK_PU 0x0008 /* LRCLK_PU */
2036#define WM8993_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
2037#define WM8993_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
2038#define WM8993_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
2039#define WM8993_LRCLK_PD 0x0004 /* LRCLK_PD */
2040#define WM8993_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
2041#define WM8993_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
2042#define WM8993_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
2043#define WM8993_BCLK_PU 0x0002 /* BCLK_PU */
2044#define WM8993_BCLK_PU_MASK 0x0002 /* BCLK_PU */
2045#define WM8993_BCLK_PU_SHIFT 1 /* BCLK_PU */
2046#define WM8993_BCLK_PU_WIDTH 1 /* BCLK_PU */
2047#define WM8993_BCLK_PD 0x0001 /* BCLK_PD */
2048#define WM8993_BCLK_PD_MASK 0x0001 /* BCLK_PD */
2049#define WM8993_BCLK_PD_SHIFT 0 /* BCLK_PD */
2050#define WM8993_BCLK_PD_WIDTH 1 /* BCLK_PD */
2051
2052/*
2053 * R123 (0x7B) - DRC Control 1
2054 */
2055#define WM8993_DRC_ENA 0x8000 /* DRC_ENA */
2056#define WM8993_DRC_ENA_MASK 0x8000 /* DRC_ENA */
2057#define WM8993_DRC_ENA_SHIFT 15 /* DRC_ENA */
2058#define WM8993_DRC_ENA_WIDTH 1 /* DRC_ENA */
2059#define WM8993_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
2060#define WM8993_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
2061#define WM8993_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
2062#define WM8993_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
2063#define WM8993_DRC_SMOOTH_ENA 0x0800 /* DRC_SMOOTH_ENA */
2064#define WM8993_DRC_SMOOTH_ENA_MASK 0x0800 /* DRC_SMOOTH_ENA */
2065#define WM8993_DRC_SMOOTH_ENA_SHIFT 11 /* DRC_SMOOTH_ENA */
2066#define WM8993_DRC_SMOOTH_ENA_WIDTH 1 /* DRC_SMOOTH_ENA */
2067#define WM8993_DRC_QR_ENA 0x0400 /* DRC_QR_ENA */
2068#define WM8993_DRC_QR_ENA_MASK 0x0400 /* DRC_QR_ENA */
2069#define WM8993_DRC_QR_ENA_SHIFT 10 /* DRC_QR_ENA */
2070#define WM8993_DRC_QR_ENA_WIDTH 1 /* DRC_QR_ENA */
2071#define WM8993_DRC_ANTICLIP_ENA 0x0200 /* DRC_ANTICLIP_ENA */
2072#define WM8993_DRC_ANTICLIP_ENA_MASK 0x0200 /* DRC_ANTICLIP_ENA */
2073#define WM8993_DRC_ANTICLIP_ENA_SHIFT 9 /* DRC_ANTICLIP_ENA */
2074#define WM8993_DRC_ANTICLIP_ENA_WIDTH 1 /* DRC_ANTICLIP_ENA */
2075#define WM8993_DRC_HYST_ENA 0x0100 /* DRC_HYST_ENA */
2076#define WM8993_DRC_HYST_ENA_MASK 0x0100 /* DRC_HYST_ENA */
2077#define WM8993_DRC_HYST_ENA_SHIFT 8 /* DRC_HYST_ENA */
2078#define WM8993_DRC_HYST_ENA_WIDTH 1 /* DRC_HYST_ENA */
2079#define WM8993_DRC_THRESH_HYST_MASK 0x0030 /* DRC_THRESH_HYST - [5:4] */
2080#define WM8993_DRC_THRESH_HYST_SHIFT 4 /* DRC_THRESH_HYST - [5:4] */
2081#define WM8993_DRC_THRESH_HYST_WIDTH 2 /* DRC_THRESH_HYST - [5:4] */
2082#define WM8993_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
2083#define WM8993_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
2084#define WM8993_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
2085#define WM8993_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
2086#define WM8993_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
2087#define WM8993_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
2088
2089/*
2090 * R124 (0x7C) - DRC Control 2
2091 */
2092#define WM8993_DRC_ATTACK_RATE_MASK 0xF000 /* DRC_ATTACK_RATE - [15:12] */
2093#define WM8993_DRC_ATTACK_RATE_SHIFT 12 /* DRC_ATTACK_RATE - [15:12] */
2094#define WM8993_DRC_ATTACK_RATE_WIDTH 4 /* DRC_ATTACK_RATE - [15:12] */
2095#define WM8993_DRC_DECAY_RATE_MASK 0x0F00 /* DRC_DECAY_RATE - [11:8] */
2096#define WM8993_DRC_DECAY_RATE_SHIFT 8 /* DRC_DECAY_RATE - [11:8] */
2097#define WM8993_DRC_DECAY_RATE_WIDTH 4 /* DRC_DECAY_RATE - [11:8] */
2098#define WM8993_DRC_THRESH_COMP_MASK 0x00FC /* DRC_THRESH_COMP - [7:2] */
2099#define WM8993_DRC_THRESH_COMP_SHIFT 2 /* DRC_THRESH_COMP - [7:2] */
2100#define WM8993_DRC_THRESH_COMP_WIDTH 6 /* DRC_THRESH_COMP - [7:2] */
2101
2102/*
2103 * R125 (0x7D) - DRC Control 3
2104 */
2105#define WM8993_DRC_AMP_COMP_MASK 0xF800 /* DRC_AMP_COMP - [15:11] */
2106#define WM8993_DRC_AMP_COMP_SHIFT 11 /* DRC_AMP_COMP - [15:11] */
2107#define WM8993_DRC_AMP_COMP_WIDTH 5 /* DRC_AMP_COMP - [15:11] */
2108#define WM8993_DRC_R0_SLOPE_COMP_MASK 0x0700 /* DRC_R0_SLOPE_COMP - [10:8] */
2109#define WM8993_DRC_R0_SLOPE_COMP_SHIFT 8 /* DRC_R0_SLOPE_COMP - [10:8] */
2110#define WM8993_DRC_R0_SLOPE_COMP_WIDTH 3 /* DRC_R0_SLOPE_COMP - [10:8] */
2111#define WM8993_DRC_FF_DELAY 0x0080 /* DRC_FF_DELAY */
2112#define WM8993_DRC_FF_DELAY_MASK 0x0080 /* DRC_FF_DELAY */
2113#define WM8993_DRC_FF_DELAY_SHIFT 7 /* DRC_FF_DELAY */
2114#define WM8993_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
2115#define WM8993_DRC_THRESH_QR_MASK 0x000C /* DRC_THRESH_QR - [3:2] */
2116#define WM8993_DRC_THRESH_QR_SHIFT 2 /* DRC_THRESH_QR - [3:2] */
2117#define WM8993_DRC_THRESH_QR_WIDTH 2 /* DRC_THRESH_QR - [3:2] */
2118#define WM8993_DRC_RATE_QR_MASK 0x0003 /* DRC_RATE_QR - [1:0] */
2119#define WM8993_DRC_RATE_QR_SHIFT 0 /* DRC_RATE_QR - [1:0] */
2120#define WM8993_DRC_RATE_QR_WIDTH 2 /* DRC_RATE_QR - [1:0] */
2121
2122/*
2123 * R126 (0x7E) - DRC Control 4
2124 */
2125#define WM8993_DRC_R1_SLOPE_COMP_MASK 0xE000 /* DRC_R1_SLOPE_COMP - [15:13] */
2126#define WM8993_DRC_R1_SLOPE_COMP_SHIFT 13 /* DRC_R1_SLOPE_COMP - [15:13] */
2127#define WM8993_DRC_R1_SLOPE_COMP_WIDTH 3 /* DRC_R1_SLOPE_COMP - [15:13] */
2128#define WM8993_DRC_STARTUP_GAIN_MASK 0x1F00 /* DRC_STARTUP_GAIN - [12:8] */
2129#define WM8993_DRC_STARTUP_GAIN_SHIFT 8 /* DRC_STARTUP_GAIN - [12:8] */
2130#define WM8993_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [12:8] */
2131
2132#endif
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 86fc57e25f97..c64e55aa63b6 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -165,87 +165,23 @@ struct wm9081_priv {
165 int master; 165 int master;
166 int fll_fref; 166 int fll_fref;
167 int fll_fout; 167 int fll_fout;
168 int tdm_width;
168 struct wm9081_retune_mobile_config *retune; 169 struct wm9081_retune_mobile_config *retune;
169}; 170};
170 171
171static int wm9081_reg_is_volatile(int reg) 172static int wm9081_volatile_register(unsigned int reg)
172{ 173{
173 switch (reg) { 174 switch (reg) {
175 case WM9081_SOFTWARE_RESET:
176 return 1;
174 default: 177 default:
175 return 0; 178 return 0;
176 } 179 }
177} 180}
178 181
179static unsigned int wm9081_read_reg_cache(struct snd_soc_codec *codec,
180 unsigned int reg)
181{
182 u16 *cache = codec->reg_cache;
183 BUG_ON(reg > WM9081_MAX_REGISTER);
184 return cache[reg];
185}
186
187static unsigned int wm9081_read_hw(struct snd_soc_codec *codec, u8 reg)
188{
189 struct i2c_msg xfer[2];
190 u16 data;
191 int ret;
192 struct i2c_client *client = codec->control_data;
193
194 BUG_ON(reg > WM9081_MAX_REGISTER);
195
196 /* Write register */
197 xfer[0].addr = client->addr;
198 xfer[0].flags = 0;
199 xfer[0].len = 1;
200 xfer[0].buf = &reg;
201
202 /* Read data */
203 xfer[1].addr = client->addr;
204 xfer[1].flags = I2C_M_RD;
205 xfer[1].len = 2;
206 xfer[1].buf = (u8 *)&data;
207
208 ret = i2c_transfer(client->adapter, xfer, 2);
209 if (ret != 2) {
210 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
211 return 0;
212 }
213
214 return (data >> 8) | ((data & 0xff) << 8);
215}
216
217static unsigned int wm9081_read(struct snd_soc_codec *codec, unsigned int reg)
218{
219 if (wm9081_reg_is_volatile(reg))
220 return wm9081_read_hw(codec, reg);
221 else
222 return wm9081_read_reg_cache(codec, reg);
223}
224
225static int wm9081_write(struct snd_soc_codec *codec, unsigned int reg,
226 unsigned int value)
227{
228 u16 *cache = codec->reg_cache;
229 u8 data[3];
230
231 BUG_ON(reg > WM9081_MAX_REGISTER);
232
233 if (!wm9081_reg_is_volatile(reg))
234 cache[reg] = value;
235
236 data[0] = reg;
237 data[1] = value >> 8;
238 data[2] = value & 0x00ff;
239
240 if (codec->hw_write(codec->control_data, data, 3) == 3)
241 return 0;
242 else
243 return -EIO;
244}
245
246static int wm9081_reset(struct snd_soc_codec *codec) 182static int wm9081_reset(struct snd_soc_codec *codec)
247{ 183{
248 return wm9081_write(codec, WM9081_SOFTWARE_RESET, 0); 184 return snd_soc_write(codec, WM9081_SOFTWARE_RESET, 0);
249} 185}
250 186
251static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); 187static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0);
@@ -356,7 +292,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol,
356 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 292 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
357 unsigned int reg; 293 unsigned int reg;
358 294
359 reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); 295 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
360 if (reg & WM9081_SPK_MODE) 296 if (reg & WM9081_SPK_MODE)
361 ucontrol->value.integer.value[0] = 1; 297 ucontrol->value.integer.value[0] = 1;
362 else 298 else
@@ -375,8 +311,8 @@ static int speaker_mode_put(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol) 311 struct snd_ctl_elem_value *ucontrol)
376{ 312{
377 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 313 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
378 unsigned int reg_pwr = wm9081_read(codec, WM9081_POWER_MANAGEMENT); 314 unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
379 unsigned int reg2 = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); 315 unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2);
380 316
381 /* Are we changing anything? */ 317 /* Are we changing anything? */
382 if (ucontrol->value.integer.value[0] == 318 if (ucontrol->value.integer.value[0] ==
@@ -397,7 +333,7 @@ static int speaker_mode_put(struct snd_kcontrol *kcontrol,
397 reg2 &= ~WM9081_SPK_MODE; 333 reg2 &= ~WM9081_SPK_MODE;
398 } 334 }
399 335
400 wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2); 336 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2);
401 337
402 return 0; 338 return 0;
403} 339}
@@ -456,7 +392,7 @@ static int speaker_event(struct snd_soc_dapm_widget *w,
456 struct snd_kcontrol *kcontrol, int event) 392 struct snd_kcontrol *kcontrol, int event)
457{ 393{
458 struct snd_soc_codec *codec = w->codec; 394 struct snd_soc_codec *codec = w->codec;
459 unsigned int reg = wm9081_read(codec, WM9081_POWER_MANAGEMENT); 395 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
460 396
461 switch (event) { 397 switch (event) {
462 case SND_SOC_DAPM_POST_PMU: 398 case SND_SOC_DAPM_POST_PMU:
@@ -468,7 +404,7 @@ static int speaker_event(struct snd_soc_dapm_widget *w,
468 break; 404 break;
469 } 405 }
470 406
471 wm9081_write(codec, WM9081_POWER_MANAGEMENT, reg); 407 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
472 408
473 return 0; 409 return 0;
474} 410}
@@ -607,7 +543,7 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
607 if (ret != 0) 543 if (ret != 0)
608 return ret; 544 return ret;
609 545
610 reg5 = wm9081_read(codec, WM9081_FLL_CONTROL_5); 546 reg5 = snd_soc_read(codec, WM9081_FLL_CONTROL_5);
611 reg5 &= ~WM9081_FLL_CLK_SRC_MASK; 547 reg5 &= ~WM9081_FLL_CLK_SRC_MASK;
612 548
613 switch (fll_id) { 549 switch (fll_id) {
@@ -621,44 +557,44 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
621 } 557 }
622 558
623 /* Disable CLK_SYS while we reconfigure */ 559 /* Disable CLK_SYS while we reconfigure */
624 clk_sys_reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); 560 clk_sys_reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
625 if (clk_sys_reg & WM9081_CLK_SYS_ENA) 561 if (clk_sys_reg & WM9081_CLK_SYS_ENA)
626 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, 562 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3,
627 clk_sys_reg & ~WM9081_CLK_SYS_ENA); 563 clk_sys_reg & ~WM9081_CLK_SYS_ENA);
628 564
629 /* Any FLL configuration change requires that the FLL be 565 /* Any FLL configuration change requires that the FLL be
630 * disabled first. */ 566 * disabled first. */
631 reg1 = wm9081_read(codec, WM9081_FLL_CONTROL_1); 567 reg1 = snd_soc_read(codec, WM9081_FLL_CONTROL_1);
632 reg1 &= ~WM9081_FLL_ENA; 568 reg1 &= ~WM9081_FLL_ENA;
633 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); 569 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
634 570
635 /* Apply the configuration */ 571 /* Apply the configuration */
636 if (fll_div.k) 572 if (fll_div.k)
637 reg1 |= WM9081_FLL_FRAC_MASK; 573 reg1 |= WM9081_FLL_FRAC_MASK;
638 else 574 else
639 reg1 &= ~WM9081_FLL_FRAC_MASK; 575 reg1 &= ~WM9081_FLL_FRAC_MASK;
640 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); 576 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1);
641 577
642 wm9081_write(codec, WM9081_FLL_CONTROL_2, 578 snd_soc_write(codec, WM9081_FLL_CONTROL_2,
643 (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) | 579 (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) |
644 (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT)); 580 (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT));
645 wm9081_write(codec, WM9081_FLL_CONTROL_3, fll_div.k); 581 snd_soc_write(codec, WM9081_FLL_CONTROL_3, fll_div.k);
646 582
647 reg4 = wm9081_read(codec, WM9081_FLL_CONTROL_4); 583 reg4 = snd_soc_read(codec, WM9081_FLL_CONTROL_4);
648 reg4 &= ~WM9081_FLL_N_MASK; 584 reg4 &= ~WM9081_FLL_N_MASK;
649 reg4 |= fll_div.n << WM9081_FLL_N_SHIFT; 585 reg4 |= fll_div.n << WM9081_FLL_N_SHIFT;
650 wm9081_write(codec, WM9081_FLL_CONTROL_4, reg4); 586 snd_soc_write(codec, WM9081_FLL_CONTROL_4, reg4);
651 587
652 reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK; 588 reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK;
653 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; 589 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
654 wm9081_write(codec, WM9081_FLL_CONTROL_5, reg5); 590 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
655 591
656 /* Enable the FLL */ 592 /* Enable the FLL */
657 wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); 593 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
658 594
659 /* Then bring CLK_SYS up again if it was disabled */ 595 /* Then bring CLK_SYS up again if it was disabled */
660 if (clk_sys_reg & WM9081_CLK_SYS_ENA) 596 if (clk_sys_reg & WM9081_CLK_SYS_ENA)
661 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg); 597 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg);
662 598
663 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 599 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
664 600
@@ -707,6 +643,10 @@ static int configure_clock(struct snd_soc_codec *codec)
707 target > 3000000) 643 target > 3000000)
708 break; 644 break;
709 } 645 }
646
647 if (i == ARRAY_SIZE(clk_sys_rates))
648 return -EINVAL;
649
710 } else if (wm9081->fs) { 650 } else if (wm9081->fs) {
711 for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { 651 for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) {
712 new_sysclk = clk_sys_rates[i].ratio 652 new_sysclk = clk_sys_rates[i].ratio
@@ -714,6 +654,10 @@ static int configure_clock(struct snd_soc_codec *codec)
714 if (new_sysclk > 3000000) 654 if (new_sysclk > 3000000)
715 break; 655 break;
716 } 656 }
657
658 if (i == ARRAY_SIZE(clk_sys_rates))
659 return -EINVAL;
660
717 } else { 661 } else {
718 new_sysclk = 12288000; 662 new_sysclk = 12288000;
719 } 663 }
@@ -734,19 +678,19 @@ static int configure_clock(struct snd_soc_codec *codec)
734 return -EINVAL; 678 return -EINVAL;
735 } 679 }
736 680
737 reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_1); 681 reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_1);
738 if (mclkdiv) 682 if (mclkdiv)
739 reg |= WM9081_MCLKDIV2; 683 reg |= WM9081_MCLKDIV2;
740 else 684 else
741 reg &= ~WM9081_MCLKDIV2; 685 reg &= ~WM9081_MCLKDIV2;
742 wm9081_write(codec, WM9081_CLOCK_CONTROL_1, reg); 686 snd_soc_write(codec, WM9081_CLOCK_CONTROL_1, reg);
743 687
744 reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); 688 reg = snd_soc_read(codec, WM9081_CLOCK_CONTROL_3);
745 if (fll) 689 if (fll)
746 reg |= WM9081_CLK_SRC_SEL; 690 reg |= WM9081_CLK_SRC_SEL;
747 else 691 else
748 reg &= ~WM9081_CLK_SRC_SEL; 692 reg &= ~WM9081_CLK_SRC_SEL;
749 wm9081_write(codec, WM9081_CLOCK_CONTROL_3, reg); 693 snd_soc_write(codec, WM9081_CLOCK_CONTROL_3, reg);
750 694
751 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate); 695 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate);
752 696
@@ -846,76 +790,76 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
846 790
847 case SND_SOC_BIAS_PREPARE: 791 case SND_SOC_BIAS_PREPARE:
848 /* VMID=2*40k */ 792 /* VMID=2*40k */
849 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 793 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
850 reg &= ~WM9081_VMID_SEL_MASK; 794 reg &= ~WM9081_VMID_SEL_MASK;
851 reg |= 0x2; 795 reg |= 0x2;
852 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 796 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
853 797
854 /* Normal bias current */ 798 /* Normal bias current */
855 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 799 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
856 reg &= ~WM9081_STBY_BIAS_ENA; 800 reg &= ~WM9081_STBY_BIAS_ENA;
857 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 801 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
858 break; 802 break;
859 803
860 case SND_SOC_BIAS_STANDBY: 804 case SND_SOC_BIAS_STANDBY:
861 /* Initial cold start */ 805 /* Initial cold start */
862 if (codec->bias_level == SND_SOC_BIAS_OFF) { 806 if (codec->bias_level == SND_SOC_BIAS_OFF) {
863 /* Disable LINEOUT discharge */ 807 /* Disable LINEOUT discharge */
864 reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); 808 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
865 reg &= ~WM9081_LINEOUT_DISCH; 809 reg &= ~WM9081_LINEOUT_DISCH;
866 wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); 810 snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
867 811
868 /* Select startup bias source */ 812 /* Select startup bias source */
869 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 813 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
870 reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA; 814 reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA;
871 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 815 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
872 816
873 /* VMID 2*4k; Soft VMID ramp enable */ 817 /* VMID 2*4k; Soft VMID ramp enable */
874 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 818 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
875 reg |= WM9081_VMID_RAMP | 0x6; 819 reg |= WM9081_VMID_RAMP | 0x6;
876 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 820 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
877 821
878 mdelay(100); 822 mdelay(100);
879 823
880 /* Normal bias enable & soft start off */ 824 /* Normal bias enable & soft start off */
881 reg |= WM9081_BIAS_ENA; 825 reg |= WM9081_BIAS_ENA;
882 reg &= ~WM9081_VMID_RAMP; 826 reg &= ~WM9081_VMID_RAMP;
883 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 827 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
884 828
885 /* Standard bias source */ 829 /* Standard bias source */
886 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 830 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
887 reg &= ~WM9081_BIAS_SRC; 831 reg &= ~WM9081_BIAS_SRC;
888 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 832 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
889 } 833 }
890 834
891 /* VMID 2*240k */ 835 /* VMID 2*240k */
892 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 836 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
893 reg &= ~WM9081_VMID_SEL_MASK; 837 reg &= ~WM9081_VMID_SEL_MASK;
894 reg |= 0x40; 838 reg |= 0x40;
895 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 839 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
896 840
897 /* Standby bias current on */ 841 /* Standby bias current on */
898 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 842 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
899 reg |= WM9081_STBY_BIAS_ENA; 843 reg |= WM9081_STBY_BIAS_ENA;
900 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 844 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
901 break; 845 break;
902 846
903 case SND_SOC_BIAS_OFF: 847 case SND_SOC_BIAS_OFF:
904 /* Startup bias source */ 848 /* Startup bias source */
905 reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); 849 reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1);
906 reg |= WM9081_BIAS_SRC; 850 reg |= WM9081_BIAS_SRC;
907 wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); 851 snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg);
908 852
909 /* Disable VMID and biases with soft ramping */ 853 /* Disable VMID and biases with soft ramping */
910 reg = wm9081_read(codec, WM9081_VMID_CONTROL); 854 reg = snd_soc_read(codec, WM9081_VMID_CONTROL);
911 reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); 855 reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA);
912 reg |= WM9081_VMID_RAMP; 856 reg |= WM9081_VMID_RAMP;
913 wm9081_write(codec, WM9081_VMID_CONTROL, reg); 857 snd_soc_write(codec, WM9081_VMID_CONTROL, reg);
914 858
915 /* Actively discharge LINEOUT */ 859 /* Actively discharge LINEOUT */
916 reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); 860 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
917 reg |= WM9081_LINEOUT_DISCH; 861 reg |= WM9081_LINEOUT_DISCH;
918 wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); 862 snd_soc_write(codec, WM9081_ANTI_POP_CONTROL, reg);
919 break; 863 break;
920 } 864 }
921 865
@@ -929,7 +873,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
929{ 873{
930 struct snd_soc_codec *codec = dai->codec; 874 struct snd_soc_codec *codec = dai->codec;
931 struct wm9081_priv *wm9081 = codec->private_data; 875 struct wm9081_priv *wm9081 = codec->private_data;
932 unsigned int aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); 876 unsigned int aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
933 877
934 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | 878 aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV |
935 WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK); 879 WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK);
@@ -1010,7 +954,7 @@ static int wm9081_set_dai_fmt(struct snd_soc_dai *dai,
1010 return -EINVAL; 954 return -EINVAL;
1011 } 955 }
1012 956
1013 wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); 957 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
1014 958
1015 return 0; 959 return 0;
1016} 960}
@@ -1024,47 +968,51 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1024 int ret, i, best, best_val, cur_val; 968 int ret, i, best, best_val, cur_val;
1025 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; 969 unsigned int clk_ctrl2, aif1, aif2, aif3, aif4;
1026 970
1027 clk_ctrl2 = wm9081_read(codec, WM9081_CLOCK_CONTROL_2); 971 clk_ctrl2 = snd_soc_read(codec, WM9081_CLOCK_CONTROL_2);
1028 clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK); 972 clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK);
1029 973
1030 aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); 974 aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1031 975
1032 aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); 976 aif2 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_2);
1033 aif2 &= ~WM9081_AIF_WL_MASK; 977 aif2 &= ~WM9081_AIF_WL_MASK;
1034 978
1035 aif3 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_3); 979 aif3 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_3);
1036 aif3 &= ~WM9081_BCLK_DIV_MASK; 980 aif3 &= ~WM9081_BCLK_DIV_MASK;
1037 981
1038 aif4 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_4); 982 aif4 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_4);
1039 aif4 &= ~WM9081_LRCLK_RATE_MASK; 983 aif4 &= ~WM9081_LRCLK_RATE_MASK;
1040 984
1041 /* What BCLK do we need? */
1042 wm9081->fs = params_rate(params); 985 wm9081->fs = params_rate(params);
1043 wm9081->bclk = 2 * wm9081->fs;
1044 switch (params_format(params)) {
1045 case SNDRV_PCM_FORMAT_S16_LE:
1046 wm9081->bclk *= 16;
1047 break;
1048 case SNDRV_PCM_FORMAT_S20_3LE:
1049 wm9081->bclk *= 20;
1050 aif2 |= 0x4;
1051 break;
1052 case SNDRV_PCM_FORMAT_S24_LE:
1053 wm9081->bclk *= 24;
1054 aif2 |= 0x8;
1055 break;
1056 case SNDRV_PCM_FORMAT_S32_LE:
1057 wm9081->bclk *= 32;
1058 aif2 |= 0xc;
1059 break;
1060 default:
1061 return -EINVAL;
1062 }
1063 986
1064 if (aif1 & WM9081_AIFDAC_TDM_MODE_MASK) { 987 if (wm9081->tdm_width) {
988 /* If TDM is set up then that fixes our BCLK. */
1065 int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> 989 int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >>
1066 WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; 990 WM9081_AIFDAC_TDM_MODE_SHIFT) + 1;
1067 wm9081->bclk *= slots; 991
992 wm9081->bclk = wm9081->fs * wm9081->tdm_width * slots;
993 } else {
994 /* Otherwise work out a BCLK from the sample size */
995 wm9081->bclk = 2 * wm9081->fs;
996
997 switch (params_format(params)) {
998 case SNDRV_PCM_FORMAT_S16_LE:
999 wm9081->bclk *= 16;
1000 break;
1001 case SNDRV_PCM_FORMAT_S20_3LE:
1002 wm9081->bclk *= 20;
1003 aif2 |= 0x4;
1004 break;
1005 case SNDRV_PCM_FORMAT_S24_LE:
1006 wm9081->bclk *= 24;
1007 aif2 |= 0x8;
1008 break;
1009 case SNDRV_PCM_FORMAT_S32_LE:
1010 wm9081->bclk *= 32;
1011 aif2 |= 0xc;
1012 break;
1013 default:
1014 return -EINVAL;
1015 }
1068 } 1016 }
1069 1017
1070 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk); 1018 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk);
@@ -1149,22 +1097,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1149 s->name, s->rate); 1097 s->name, s->rate);
1150 1098
1151 /* If the EQ is enabled then disable it while we write out */ 1099 /* If the EQ is enabled then disable it while we write out */
1152 eq1 = wm9081_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA; 1100 eq1 = snd_soc_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA;
1153 if (eq1 & WM9081_EQ_ENA) 1101 if (eq1 & WM9081_EQ_ENA)
1154 wm9081_write(codec, WM9081_EQ_1, 0); 1102 snd_soc_write(codec, WM9081_EQ_1, 0);
1155 1103
1156 /* Write out the other values */ 1104 /* Write out the other values */
1157 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1105 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1158 wm9081_write(codec, WM9081_EQ_1 + i, s->config[i]); 1106 snd_soc_write(codec, WM9081_EQ_1 + i, s->config[i]);
1159 1107
1160 eq1 |= (s->config[0] & ~WM9081_EQ_ENA); 1108 eq1 |= (s->config[0] & ~WM9081_EQ_ENA);
1161 wm9081_write(codec, WM9081_EQ_1, eq1); 1109 snd_soc_write(codec, WM9081_EQ_1, eq1);
1162 } 1110 }
1163 1111
1164 wm9081_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2); 1112 snd_soc_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2);
1165 wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); 1113 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_2, aif2);
1166 wm9081_write(codec, WM9081_AUDIO_INTERFACE_3, aif3); 1114 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_3, aif3);
1167 wm9081_write(codec, WM9081_AUDIO_INTERFACE_4, aif4); 1115 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_4, aif4);
1168 1116
1169 return 0; 1117 return 0;
1170} 1118}
@@ -1174,14 +1122,14 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1174 struct snd_soc_codec *codec = codec_dai->codec; 1122 struct snd_soc_codec *codec = codec_dai->codec;
1175 unsigned int reg; 1123 unsigned int reg;
1176 1124
1177 reg = wm9081_read(codec, WM9081_DAC_DIGITAL_2); 1125 reg = snd_soc_read(codec, WM9081_DAC_DIGITAL_2);
1178 1126
1179 if (mute) 1127 if (mute)
1180 reg |= WM9081_DAC_MUTE; 1128 reg |= WM9081_DAC_MUTE;
1181 else 1129 else
1182 reg &= ~WM9081_DAC_MUTE; 1130 reg &= ~WM9081_DAC_MUTE;
1183 1131
1184 wm9081_write(codec, WM9081_DAC_DIGITAL_2, reg); 1132 snd_soc_write(codec, WM9081_DAC_DIGITAL_2, reg);
1185 1133
1186 return 0; 1134 return 0;
1187} 1135}
@@ -1207,19 +1155,25 @@ static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai,
1207} 1155}
1208 1156
1209static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, 1157static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1210 unsigned int mask, int slots) 1158 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
1211{ 1159{
1212 struct snd_soc_codec *codec = dai->codec; 1160 struct snd_soc_codec *codec = dai->codec;
1213 unsigned int aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); 1161 struct wm9081_priv *wm9081 = codec->private_data;
1162 unsigned int aif1 = snd_soc_read(codec, WM9081_AUDIO_INTERFACE_1);
1214 1163
1215 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); 1164 aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK);
1216 1165
1217 if (slots < 1 || slots > 4) 1166 if (slots < 0 || slots > 4)
1218 return -EINVAL; 1167 return -EINVAL;
1219 1168
1169 wm9081->tdm_width = slot_width;
1170
1171 if (slots == 0)
1172 slots = 1;
1173
1220 aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; 1174 aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT;
1221 1175
1222 switch (mask) { 1176 switch (rx_mask) {
1223 case 1: 1177 case 1:
1224 break; 1178 break;
1225 case 2: 1179 case 2:
@@ -1235,7 +1189,7 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1235 return -EINVAL; 1189 return -EINVAL;
1236 } 1190 }
1237 1191
1238 wm9081_write(codec, WM9081_AUDIO_INTERFACE_1, aif1); 1192 snd_soc_write(codec, WM9081_AUDIO_INTERFACE_1, aif1);
1239 1193
1240 return 0; 1194 return 0;
1241} 1195}
@@ -1357,7 +1311,7 @@ static int wm9081_resume(struct platform_device *pdev)
1357 if (i == WM9081_SOFTWARE_RESET) 1311 if (i == WM9081_SOFTWARE_RESET)
1358 continue; 1312 continue;
1359 1313
1360 wm9081_write(codec, i, reg_cache[i]); 1314 snd_soc_write(codec, i, reg_cache[i]);
1361 } 1315 }
1362 1316
1363 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1317 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
@@ -1377,7 +1331,8 @@ struct snd_soc_codec_device soc_codec_dev_wm9081 = {
1377}; 1331};
1378EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081); 1332EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081);
1379 1333
1380static int wm9081_register(struct wm9081_priv *wm9081) 1334static int wm9081_register(struct wm9081_priv *wm9081,
1335 enum snd_soc_control_type control)
1381{ 1336{
1382 struct snd_soc_codec *codec = &wm9081->codec; 1337 struct snd_soc_codec *codec = &wm9081->codec;
1383 int ret; 1338 int ret;
@@ -1396,19 +1351,24 @@ static int wm9081_register(struct wm9081_priv *wm9081)
1396 codec->private_data = wm9081; 1351 codec->private_data = wm9081;
1397 codec->name = "WM9081"; 1352 codec->name = "WM9081";
1398 codec->owner = THIS_MODULE; 1353 codec->owner = THIS_MODULE;
1399 codec->read = wm9081_read;
1400 codec->write = wm9081_write;
1401 codec->dai = &wm9081_dai; 1354 codec->dai = &wm9081_dai;
1402 codec->num_dai = 1; 1355 codec->num_dai = 1;
1403 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache); 1356 codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache);
1404 codec->reg_cache = &wm9081->reg_cache; 1357 codec->reg_cache = &wm9081->reg_cache;
1405 codec->bias_level = SND_SOC_BIAS_OFF; 1358 codec->bias_level = SND_SOC_BIAS_OFF;
1406 codec->set_bias_level = wm9081_set_bias_level; 1359 codec->set_bias_level = wm9081_set_bias_level;
1360 codec->volatile_register = wm9081_volatile_register;
1407 1361
1408 memcpy(codec->reg_cache, wm9081_reg_defaults, 1362 memcpy(codec->reg_cache, wm9081_reg_defaults,
1409 sizeof(wm9081_reg_defaults)); 1363 sizeof(wm9081_reg_defaults));
1410 1364
1411 reg = wm9081_read_hw(codec, WM9081_SOFTWARE_RESET); 1365 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
1366 if (ret != 0) {
1367 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1368 return ret;
1369 }
1370
1371 reg = snd_soc_read(codec, WM9081_SOFTWARE_RESET);
1412 if (reg != 0x9081) { 1372 if (reg != 0x9081) {
1413 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); 1373 dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg);
1414 ret = -EINVAL; 1374 ret = -EINVAL;
@@ -1424,10 +1384,10 @@ static int wm9081_register(struct wm9081_priv *wm9081)
1424 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1384 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1425 1385
1426 /* Enable zero cross by default */ 1386 /* Enable zero cross by default */
1427 reg = wm9081_read(codec, WM9081_ANALOGUE_LINEOUT); 1387 reg = snd_soc_read(codec, WM9081_ANALOGUE_LINEOUT);
1428 wm9081_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); 1388 snd_soc_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC);
1429 reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); 1389 reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_PGA);
1430 wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, 1390 snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA,
1431 reg | WM9081_SPKPGAZC); 1391 reg | WM9081_SPKPGAZC);
1432 1392
1433 wm9081_dai.dev = codec->dev; 1393 wm9081_dai.dev = codec->dev;
@@ -1482,7 +1442,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1482 1442
1483 codec->dev = &i2c->dev; 1443 codec->dev = &i2c->dev;
1484 1444
1485 return wm9081_register(wm9081); 1445 return wm9081_register(wm9081, SND_SOC_I2C);
1486} 1446}
1487 1447
1488static __devexit int wm9081_i2c_remove(struct i2c_client *client) 1448static __devexit int wm9081_i2c_remove(struct i2c_client *client)
@@ -1492,6 +1452,21 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1492 return 0; 1452 return 0;
1493} 1453}
1494 1454
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1495static const struct i2c_device_id wm9081_i2c_id[] = { 1470static const struct i2c_device_id wm9081_i2c_id[] = {
1496 { "wm9081", 0 }, 1471 { "wm9081", 0 },
1497 { } 1472 { }
@@ -1505,6 +1480,8 @@ static struct i2c_driver wm9081_i2c_driver = {
1505 }, 1480 },
1506 .probe = wm9081_i2c_probe, 1481 .probe = wm9081_i2c_probe,
1507 .remove = __devexit_p(wm9081_i2c_remove), 1482 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1508 .id_table = wm9081_i2c_id, 1485 .id_table = wm9081_i2c_id,
1509}; 1486};
1510 1487
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index fa88b463e71f..e7d2840d9e59 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -406,7 +406,7 @@ static int wm9705_soc_probe(struct platform_device *pdev)
406 ret = snd_soc_init_card(socdev); 406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) { 407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n"); 408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto pcm_err; 409 goto reset_err;
410 } 410 }
411 411
412 return 0; 412 return 0;
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
new file mode 100644
index 000000000000..e542027eea89
--- /dev/null
+++ b/sound/soc/codecs/wm_hubs.c
@@ -0,0 +1,743 @@
1/*
2 * wm_hubs.c -- WM8993/4 common code
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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/moduleparam.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/pm.h>
19#include <linux/i2c.h>
20#include <linux/platform_device.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8993.h"
30#include "wm_hubs.h"
31
32const DECLARE_TLV_DB_SCALE(wm_hubs_spkmix_tlv, -300, 300, 0);
33EXPORT_SYMBOL_GPL(wm_hubs_spkmix_tlv);
34
35static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1650, 150, 0);
36static const DECLARE_TLV_DB_SCALE(inmix_sw_tlv, 0, 3000, 0);
37static const DECLARE_TLV_DB_SCALE(inmix_tlv, -1500, 300, 1);
38static const DECLARE_TLV_DB_SCALE(earpiece_tlv, -600, 600, 0);
39static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0);
40static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1);
41static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0);
42static const unsigned int spkboost_tlv[] = {
43 TLV_DB_RANGE_HEAD(7),
44 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0),
45 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0),
46};
47static const DECLARE_TLV_DB_SCALE(line_tlv, -600, 600, 0);
48
49static const char *speaker_ref_text[] = {
50 "SPKVDD/2",
51 "VMID",
52};
53
54static const struct soc_enum speaker_ref =
55 SOC_ENUM_SINGLE(WM8993_SPEAKER_MIXER, 8, 2, speaker_ref_text);
56
57static const char *speaker_mode_text[] = {
58 "Class D",
59 "Class AB",
60};
61
62static const struct soc_enum speaker_mode =
63 SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
64
65static void wait_for_dc_servo(struct snd_soc_codec *codec)
66{
67 unsigned int reg;
68 int count = 0;
69
70 dev_dbg(codec->dev, "Waiting for DC servo...\n");
71 do {
72 count++;
73 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK)
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82}
83
84/*
85 * Update the DC servo calibration on gain changes
86 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol)
89{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
91 int ret;
92
93 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
94
95 /* Only need to do this if the outputs are active */
96 if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
97 & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
98 snd_soc_update_bits(codec,
99 WM8993_DC_SERVO_0,
100 WM8993_DCS_TRIG_SINGLE_0 |
101 WM8993_DCS_TRIG_SINGLE_1,
102 WM8993_DCS_TRIG_SINGLE_0 |
103 WM8993_DCS_TRIG_SINGLE_1);
104
105 return ret;
106}
107
108static const struct snd_kcontrol_new analogue_snd_controls[] = {
109SOC_SINGLE_TLV("IN1L Volume", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
110 inpga_tlv),
111SOC_SINGLE("IN1L Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
112SOC_SINGLE("IN1L ZC Switch", WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
113
114SOC_SINGLE_TLV("IN1R Volume", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 0, 31, 0,
115 inpga_tlv),
116SOC_SINGLE("IN1R Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 1),
117SOC_SINGLE("IN1R ZC Switch", WM8993_RIGHT_LINE_INPUT_1_2_VOLUME, 7, 1, 0),
118
119
120SOC_SINGLE_TLV("IN2L Volume", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
121 inpga_tlv),
122SOC_SINGLE("IN2L Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
123SOC_SINGLE("IN2L ZC Switch", WM8993_LEFT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
124
125SOC_SINGLE_TLV("IN2R Volume", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 0, 31, 0,
126 inpga_tlv),
127SOC_SINGLE("IN2R Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 1),
128SOC_SINGLE("IN2R ZC Switch", WM8993_RIGHT_LINE_INPUT_3_4_VOLUME, 7, 1, 0),
129
130SOC_SINGLE_TLV("MIXINL IN2L Volume", WM8993_INPUT_MIXER3, 7, 1, 0,
131 inmix_sw_tlv),
132SOC_SINGLE_TLV("MIXINL IN1L Volume", WM8993_INPUT_MIXER3, 4, 1, 0,
133 inmix_sw_tlv),
134SOC_SINGLE_TLV("MIXINL Output Record Volume", WM8993_INPUT_MIXER3, 0, 7, 0,
135 inmix_tlv),
136SOC_SINGLE_TLV("MIXINL IN1LP Volume", WM8993_INPUT_MIXER5, 6, 7, 0, inmix_tlv),
137SOC_SINGLE_TLV("MIXINL Direct Voice Volume", WM8993_INPUT_MIXER5, 0, 6, 0,
138 inmix_tlv),
139
140SOC_SINGLE_TLV("MIXINR IN2R Volume", WM8993_INPUT_MIXER4, 7, 1, 0,
141 inmix_sw_tlv),
142SOC_SINGLE_TLV("MIXINR IN1R Volume", WM8993_INPUT_MIXER4, 4, 1, 0,
143 inmix_sw_tlv),
144SOC_SINGLE_TLV("MIXINR Output Record Volume", WM8993_INPUT_MIXER4, 0, 7, 0,
145 inmix_tlv),
146SOC_SINGLE_TLV("MIXINR IN1RP Volume", WM8993_INPUT_MIXER6, 6, 7, 0, inmix_tlv),
147SOC_SINGLE_TLV("MIXINR Direct Voice Volume", WM8993_INPUT_MIXER6, 0, 6, 0,
148 inmix_tlv),
149
150SOC_SINGLE_TLV("Left Output Mixer IN2RN Volume", WM8993_OUTPUT_MIXER5, 6, 7, 1,
151 outmix_tlv),
152SOC_SINGLE_TLV("Left Output Mixer IN2LN Volume", WM8993_OUTPUT_MIXER3, 6, 7, 1,
153 outmix_tlv),
154SOC_SINGLE_TLV("Left Output Mixer IN2LP Volume", WM8993_OUTPUT_MIXER3, 9, 7, 1,
155 outmix_tlv),
156SOC_SINGLE_TLV("Left Output Mixer IN1L Volume", WM8993_OUTPUT_MIXER3, 0, 7, 1,
157 outmix_tlv),
158SOC_SINGLE_TLV("Left Output Mixer IN1R Volume", WM8993_OUTPUT_MIXER3, 3, 7, 1,
159 outmix_tlv),
160SOC_SINGLE_TLV("Left Output Mixer Right Input Volume",
161 WM8993_OUTPUT_MIXER5, 3, 7, 1, outmix_tlv),
162SOC_SINGLE_TLV("Left Output Mixer Left Input Volume",
163 WM8993_OUTPUT_MIXER5, 0, 7, 1, outmix_tlv),
164SOC_SINGLE_TLV("Left Output Mixer DAC Volume", WM8993_OUTPUT_MIXER5, 9, 7, 1,
165 outmix_tlv),
166
167SOC_SINGLE_TLV("Right Output Mixer IN2LN Volume",
168 WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
169SOC_SINGLE_TLV("Right Output Mixer IN2RN Volume",
170 WM8993_OUTPUT_MIXER4, 6, 7, 1, outmix_tlv),
171SOC_SINGLE_TLV("Right Output Mixer IN1L Volume",
172 WM8993_OUTPUT_MIXER4, 3, 7, 1, outmix_tlv),
173SOC_SINGLE_TLV("Right Output Mixer IN1R Volume",
174 WM8993_OUTPUT_MIXER4, 0, 7, 1, outmix_tlv),
175SOC_SINGLE_TLV("Right Output Mixer IN2RP Volume",
176 WM8993_OUTPUT_MIXER4, 9, 7, 1, outmix_tlv),
177SOC_SINGLE_TLV("Right Output Mixer Left Input Volume",
178 WM8993_OUTPUT_MIXER6, 3, 7, 1, outmix_tlv),
179SOC_SINGLE_TLV("Right Output Mixer Right Input Volume",
180 WM8993_OUTPUT_MIXER6, 6, 7, 1, outmix_tlv),
181SOC_SINGLE_TLV("Right Output Mixer DAC Volume",
182 WM8993_OUTPUT_MIXER6, 9, 7, 1, outmix_tlv),
183
184SOC_DOUBLE_R_TLV("Output Volume", WM8993_LEFT_OPGA_VOLUME,
185 WM8993_RIGHT_OPGA_VOLUME, 0, 63, 0, outpga_tlv),
186SOC_DOUBLE_R("Output Switch", WM8993_LEFT_OPGA_VOLUME,
187 WM8993_RIGHT_OPGA_VOLUME, 6, 1, 0),
188SOC_DOUBLE_R("Output ZC Switch", WM8993_LEFT_OPGA_VOLUME,
189 WM8993_RIGHT_OPGA_VOLUME, 7, 1, 0),
190
191SOC_SINGLE("Earpiece Switch", WM8993_HPOUT2_VOLUME, 5, 1, 1),
192SOC_SINGLE_TLV("Earpiece Volume", WM8993_HPOUT2_VOLUME, 4, 1, 1, earpiece_tlv),
193
194SOC_SINGLE_TLV("SPKL Input Volume", WM8993_SPKMIXL_ATTENUATION,
195 5, 1, 1, wm_hubs_spkmix_tlv),
196SOC_SINGLE_TLV("SPKL IN1LP Volume", WM8993_SPKMIXL_ATTENUATION,
197 4, 1, 1, wm_hubs_spkmix_tlv),
198SOC_SINGLE_TLV("SPKL Output Volume", WM8993_SPKMIXL_ATTENUATION,
199 3, 1, 1, wm_hubs_spkmix_tlv),
200
201SOC_SINGLE_TLV("SPKR Input Volume", WM8993_SPKMIXR_ATTENUATION,
202 5, 1, 1, wm_hubs_spkmix_tlv),
203SOC_SINGLE_TLV("SPKR IN1RP Volume", WM8993_SPKMIXR_ATTENUATION,
204 4, 1, 1, wm_hubs_spkmix_tlv),
205SOC_SINGLE_TLV("SPKR Output Volume", WM8993_SPKMIXR_ATTENUATION,
206 3, 1, 1, wm_hubs_spkmix_tlv),
207
208SOC_DOUBLE_R_TLV("Speaker Mixer Volume",
209 WM8993_SPKMIXL_ATTENUATION, WM8993_SPKMIXR_ATTENUATION,
210 0, 3, 1, spkmixout_tlv),
211SOC_DOUBLE_R_TLV("Speaker Volume",
212 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
213 0, 63, 0, outpga_tlv),
214SOC_DOUBLE_R("Speaker Switch",
215 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
216 6, 1, 0),
217SOC_DOUBLE_R("Speaker ZC Switch",
218 WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT,
219 7, 1, 0),
220SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0,
221 spkboost_tlv),
222SOC_ENUM("Speaker Reference", speaker_ref),
223SOC_ENUM("Speaker Mode", speaker_mode),
224
225{
226 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Headphone Volume",
227 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |
228 SNDRV_CTL_ELEM_ACCESS_READWRITE,
229 .tlv.p = outpga_tlv,
230 .info = snd_soc_info_volsw_2r,
231 .get = snd_soc_get_volsw_2r, .put = wm8993_put_dc_servo,
232 .private_value = (unsigned long)&(struct soc_mixer_control) {
233 .reg = WM8993_LEFT_OUTPUT_VOLUME,
234 .rreg = WM8993_RIGHT_OUTPUT_VOLUME,
235 .shift = 0, .max = 63
236 },
237},
238SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME,
239 WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0),
240SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME,
241 WM8993_RIGHT_OUTPUT_VOLUME, 7, 1, 0),
242
243SOC_SINGLE("LINEOUT1N Switch", WM8993_LINE_OUTPUTS_VOLUME, 6, 1, 1),
244SOC_SINGLE("LINEOUT1P Switch", WM8993_LINE_OUTPUTS_VOLUME, 5, 1, 1),
245SOC_SINGLE_TLV("LINEOUT1 Volume", WM8993_LINE_OUTPUTS_VOLUME, 4, 1, 1,
246 line_tlv),
247
248SOC_SINGLE("LINEOUT2N Switch", WM8993_LINE_OUTPUTS_VOLUME, 2, 1, 1),
249SOC_SINGLE("LINEOUT2P Switch", WM8993_LINE_OUTPUTS_VOLUME, 1, 1, 1),
250SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv),
252};
253
254static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event)
256{
257 struct snd_soc_codec *codec = w->codec;
258 unsigned int reg = snd_soc_read(codec, WM8993_ANALOGUE_HP_0);
259
260 switch (event) {
261 case SND_SOC_DAPM_POST_PMU:
262 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
263 WM8993_CP_ENA, WM8993_CP_ENA);
264
265 msleep(5);
266
267 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
268 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
269 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA);
270
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273
274 /* Start the DC servo */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
276 0xFFFF,
277 WM8993_DCS_ENA_CHAN_0 |
278 WM8993_DCS_ENA_CHAN_1 |
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
285 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
286 break;
287
288 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT |
290 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP |
292 WM8993_HPOUT1R_RMV_SHORT |
293 WM8993_HPOUT1R_DLY |
294 WM8993_HPOUT1R_OUTP);
295
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
297 0xffff, 0);
298
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break;
307 }
308
309 return 0;
310}
311
312static int earpiece_event(struct snd_soc_dapm_widget *w,
313 struct snd_kcontrol *control, int event)
314{
315 struct snd_soc_codec *codec = w->codec;
316 u16 reg = snd_soc_read(codec, WM8993_ANTIPOP1) & ~WM8993_HPOUT2_IN_ENA;
317
318 switch (event) {
319 case SND_SOC_DAPM_PRE_PMU:
320 reg |= WM8993_HPOUT2_IN_ENA;
321 snd_soc_write(codec, WM8993_ANTIPOP1, reg);
322 udelay(50);
323 break;
324
325 case SND_SOC_DAPM_POST_PMD:
326 snd_soc_write(codec, WM8993_ANTIPOP1, reg);
327 break;
328
329 default:
330 BUG();
331 break;
332 }
333
334 return 0;
335}
336
337static const struct snd_kcontrol_new in1l_pga[] = {
338SOC_DAPM_SINGLE("IN1LP Switch", WM8993_INPUT_MIXER2, 5, 1, 0),
339SOC_DAPM_SINGLE("IN1LN Switch", WM8993_INPUT_MIXER2, 4, 1, 0),
340};
341
342static const struct snd_kcontrol_new in1r_pga[] = {
343SOC_DAPM_SINGLE("IN1RP Switch", WM8993_INPUT_MIXER2, 1, 1, 0),
344SOC_DAPM_SINGLE("IN1RN Switch", WM8993_INPUT_MIXER2, 0, 1, 0),
345};
346
347static const struct snd_kcontrol_new in2l_pga[] = {
348SOC_DAPM_SINGLE("IN2LP Switch", WM8993_INPUT_MIXER2, 7, 1, 0),
349SOC_DAPM_SINGLE("IN2LN Switch", WM8993_INPUT_MIXER2, 6, 1, 0),
350};
351
352static const struct snd_kcontrol_new in2r_pga[] = {
353SOC_DAPM_SINGLE("IN2RP Switch", WM8993_INPUT_MIXER2, 3, 1, 0),
354SOC_DAPM_SINGLE("IN2RN Switch", WM8993_INPUT_MIXER2, 2, 1, 0),
355};
356
357static const struct snd_kcontrol_new mixinl[] = {
358SOC_DAPM_SINGLE("IN2L Switch", WM8993_INPUT_MIXER3, 8, 1, 0),
359SOC_DAPM_SINGLE("IN1L Switch", WM8993_INPUT_MIXER3, 5, 1, 0),
360};
361
362static const struct snd_kcontrol_new mixinr[] = {
363SOC_DAPM_SINGLE("IN2R Switch", WM8993_INPUT_MIXER4, 8, 1, 0),
364SOC_DAPM_SINGLE("IN1R Switch", WM8993_INPUT_MIXER4, 5, 1, 0),
365};
366
367static const struct snd_kcontrol_new left_output_mixer[] = {
368SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER1, 7, 1, 0),
369SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER1, 6, 1, 0),
370SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER1, 5, 1, 0),
371SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER1, 4, 1, 0),
372SOC_DAPM_SINGLE("IN2LP Switch", WM8993_OUTPUT_MIXER1, 1, 1, 0),
373SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER1, 3, 1, 0),
374SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER1, 2, 1, 0),
375SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER1, 0, 1, 0),
376};
377
378static const struct snd_kcontrol_new right_output_mixer[] = {
379SOC_DAPM_SINGLE("Left Input Switch", WM8993_OUTPUT_MIXER2, 7, 1, 0),
380SOC_DAPM_SINGLE("Right Input Switch", WM8993_OUTPUT_MIXER2, 6, 1, 0),
381SOC_DAPM_SINGLE("IN2LN Switch", WM8993_OUTPUT_MIXER2, 5, 1, 0),
382SOC_DAPM_SINGLE("IN2RN Switch", WM8993_OUTPUT_MIXER2, 4, 1, 0),
383SOC_DAPM_SINGLE("IN1L Switch", WM8993_OUTPUT_MIXER2, 3, 1, 0),
384SOC_DAPM_SINGLE("IN1R Switch", WM8993_OUTPUT_MIXER2, 2, 1, 0),
385SOC_DAPM_SINGLE("IN2RP Switch", WM8993_OUTPUT_MIXER2, 1, 1, 0),
386SOC_DAPM_SINGLE("DAC Switch", WM8993_OUTPUT_MIXER2, 0, 1, 0),
387};
388
389static const struct snd_kcontrol_new earpiece_mixer[] = {
390SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_HPOUT2_MIXER, 5, 1, 0),
391SOC_DAPM_SINGLE("Left Output Switch", WM8993_HPOUT2_MIXER, 4, 1, 0),
392SOC_DAPM_SINGLE("Right Output Switch", WM8993_HPOUT2_MIXER, 3, 1, 0),
393};
394
395static const struct snd_kcontrol_new left_speaker_boost[] = {
396SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 5, 1, 0),
397SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 4, 1, 0),
398SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 3, 1, 0),
399};
400
401static const struct snd_kcontrol_new right_speaker_boost[] = {
402SOC_DAPM_SINGLE("Direct Voice Switch", WM8993_SPKOUT_MIXERS, 2, 1, 0),
403SOC_DAPM_SINGLE("SPKL Switch", WM8993_SPKOUT_MIXERS, 1, 1, 0),
404SOC_DAPM_SINGLE("SPKR Switch", WM8993_SPKOUT_MIXERS, 0, 1, 0),
405};
406
407static const struct snd_kcontrol_new line1_mix[] = {
408SOC_DAPM_SINGLE("IN1R Switch", WM8993_LINE_MIXER1, 2, 1, 0),
409SOC_DAPM_SINGLE("IN1L Switch", WM8993_LINE_MIXER1, 1, 1, 0),
410SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
411};
412
413static const struct snd_kcontrol_new line1n_mix[] = {
414SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 6, 1, 0),
415SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER1, 5, 1, 0),
416};
417
418static const struct snd_kcontrol_new line1p_mix[] = {
419SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER1, 0, 1, 0),
420};
421
422static const struct snd_kcontrol_new line2_mix[] = {
423SOC_DAPM_SINGLE("IN2R Switch", WM8993_LINE_MIXER2, 2, 1, 0),
424SOC_DAPM_SINGLE("IN2L Switch", WM8993_LINE_MIXER2, 1, 1, 0),
425SOC_DAPM_SINGLE("Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
426};
427
428static const struct snd_kcontrol_new line2n_mix[] = {
429SOC_DAPM_SINGLE("Left Output Switch", WM8993_LINE_MIXER2, 6, 1, 0),
430SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 5, 1, 0),
431};
432
433static const struct snd_kcontrol_new line2p_mix[] = {
434SOC_DAPM_SINGLE("Right Output Switch", WM8993_LINE_MIXER2, 0, 1, 0),
435};
436
437static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
438SND_SOC_DAPM_INPUT("IN1LN"),
439SND_SOC_DAPM_INPUT("IN1LP"),
440SND_SOC_DAPM_INPUT("IN2LN"),
441SND_SOC_DAPM_INPUT("IN2LP/VXRN"),
442SND_SOC_DAPM_INPUT("IN1RN"),
443SND_SOC_DAPM_INPUT("IN1RP"),
444SND_SOC_DAPM_INPUT("IN2RN"),
445SND_SOC_DAPM_INPUT("IN2RP/VXRP"),
446
447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
449
450SND_SOC_DAPM_MIXER("IN1L PGA", WM8993_POWER_MANAGEMENT_2, 6, 0,
451 in1l_pga, ARRAY_SIZE(in1l_pga)),
452SND_SOC_DAPM_MIXER("IN1R PGA", WM8993_POWER_MANAGEMENT_2, 4, 0,
453 in1r_pga, ARRAY_SIZE(in1r_pga)),
454
455SND_SOC_DAPM_MIXER("IN2L PGA", WM8993_POWER_MANAGEMENT_2, 7, 0,
456 in2l_pga, ARRAY_SIZE(in2l_pga)),
457SND_SOC_DAPM_MIXER("IN2R PGA", WM8993_POWER_MANAGEMENT_2, 5, 0,
458 in2r_pga, ARRAY_SIZE(in2r_pga)),
459
460/* Dummy widgets to represent differential paths */
461SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0),
462
463SND_SOC_DAPM_MIXER("MIXINL", WM8993_POWER_MANAGEMENT_2, 9, 0,
464 mixinl, ARRAY_SIZE(mixinl)),
465SND_SOC_DAPM_MIXER("MIXINR", WM8993_POWER_MANAGEMENT_2, 8, 0,
466 mixinr, ARRAY_SIZE(mixinr)),
467
468SND_SOC_DAPM_MIXER("Left Output Mixer", WM8993_POWER_MANAGEMENT_3, 5, 0,
469 left_output_mixer, ARRAY_SIZE(left_output_mixer)),
470SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
471 right_output_mixer, ARRAY_SIZE(right_output_mixer)),
472
473SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0),
474SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
479
480SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
481 earpiece_mixer, ARRAY_SIZE(earpiece_mixer)),
482SND_SOC_DAPM_PGA_E("Earpiece Driver", WM8993_POWER_MANAGEMENT_1, 11, 0,
483 NULL, 0, earpiece_event,
484 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
485
486SND_SOC_DAPM_MIXER("SPKL Boost", SND_SOC_NOPM, 0, 0,
487 left_speaker_boost, ARRAY_SIZE(left_speaker_boost)),
488SND_SOC_DAPM_MIXER("SPKR Boost", SND_SOC_NOPM, 0, 0,
489 right_speaker_boost, ARRAY_SIZE(right_speaker_boost)),
490
491SND_SOC_DAPM_PGA("SPKL Driver", WM8993_POWER_MANAGEMENT_1, 12, 0,
492 NULL, 0),
493SND_SOC_DAPM_PGA("SPKR Driver", WM8993_POWER_MANAGEMENT_1, 13, 0,
494 NULL, 0),
495
496SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
497 line1_mix, ARRAY_SIZE(line1_mix)),
498SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0,
499 line2_mix, ARRAY_SIZE(line2_mix)),
500
501SND_SOC_DAPM_MIXER("LINEOUT1N Mixer", SND_SOC_NOPM, 0, 0,
502 line1n_mix, ARRAY_SIZE(line1n_mix)),
503SND_SOC_DAPM_MIXER("LINEOUT1P Mixer", SND_SOC_NOPM, 0, 0,
504 line1p_mix, ARRAY_SIZE(line1p_mix)),
505SND_SOC_DAPM_MIXER("LINEOUT2N Mixer", SND_SOC_NOPM, 0, 0,
506 line2n_mix, ARRAY_SIZE(line2n_mix)),
507SND_SOC_DAPM_MIXER("LINEOUT2P Mixer", SND_SOC_NOPM, 0, 0,
508 line2p_mix, ARRAY_SIZE(line2p_mix)),
509
510SND_SOC_DAPM_PGA("LINEOUT1N Driver", WM8993_POWER_MANAGEMENT_3, 13, 0,
511 NULL, 0),
512SND_SOC_DAPM_PGA("LINEOUT1P Driver", WM8993_POWER_MANAGEMENT_3, 12, 0,
513 NULL, 0),
514SND_SOC_DAPM_PGA("LINEOUT2N Driver", WM8993_POWER_MANAGEMENT_3, 11, 0,
515 NULL, 0),
516SND_SOC_DAPM_PGA("LINEOUT2P Driver", WM8993_POWER_MANAGEMENT_3, 10, 0,
517 NULL, 0),
518
519SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
520SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
521SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
522SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
523SND_SOC_DAPM_OUTPUT("HPOUT1L"),
524SND_SOC_DAPM_OUTPUT("HPOUT1R"),
525SND_SOC_DAPM_OUTPUT("HPOUT2P"),
526SND_SOC_DAPM_OUTPUT("HPOUT2N"),
527SND_SOC_DAPM_OUTPUT("LINEOUT1P"),
528SND_SOC_DAPM_OUTPUT("LINEOUT1N"),
529SND_SOC_DAPM_OUTPUT("LINEOUT2P"),
530SND_SOC_DAPM_OUTPUT("LINEOUT2N"),
531};
532
533static const struct snd_soc_dapm_route analogue_routes[] = {
534 { "IN1L PGA", "IN1LP Switch", "IN1LP" },
535 { "IN1L PGA", "IN1LN Switch", "IN1LN" },
536
537 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
538 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
539
540 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" },
541 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
542
543 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" },
544 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
545
546 { "Direct Voice", NULL, "IN2LP/VXRN" },
547 { "Direct Voice", NULL, "IN2RP/VXRP" },
548
549 { "MIXINL", "IN1L Switch", "IN1L PGA" },
550 { "MIXINL", "IN2L Switch", "IN2L PGA" },
551 { "MIXINL", NULL, "Direct Voice" },
552 { "MIXINL", NULL, "IN1LP" },
553 { "MIXINL", NULL, "Left Output Mixer" },
554
555 { "MIXINR", "IN1R Switch", "IN1R PGA" },
556 { "MIXINR", "IN2R Switch", "IN2R PGA" },
557 { "MIXINR", NULL, "Direct Voice" },
558 { "MIXINR", NULL, "IN1RP" },
559 { "MIXINR", NULL, "Right Output Mixer" },
560
561 { "ADCL", NULL, "MIXINL" },
562 { "ADCR", NULL, "MIXINR" },
563
564 { "Left Output Mixer", "Left Input Switch", "MIXINL" },
565 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
568 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" },
569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
571
572 { "Right Output Mixer", "Left Input Switch", "MIXINL" },
573 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
576 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" },
577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
579
580 { "Left Output PGA", NULL, "Left Output Mixer" },
581 { "Left Output PGA", NULL, "TOCLK" },
582
583 { "Right Output PGA", NULL, "Right Output Mixer" },
584 { "Right Output PGA", NULL, "TOCLK" },
585
586 { "Earpiece Mixer", "Direct Voice Switch", "Direct Voice" },
587 { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" },
588 { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" },
589
590 { "Earpiece Driver", NULL, "Earpiece Mixer" },
591 { "HPOUT2N", NULL, "Earpiece Driver" },
592 { "HPOUT2P", NULL, "Earpiece Driver" },
593
594 { "SPKL", "Input Switch", "MIXINL" },
595 { "SPKL", "IN1LP Switch", "IN1LP" },
596 { "SPKL", "Output Switch", "Left Output Mixer" },
597 { "SPKL", NULL, "TOCLK" },
598
599 { "SPKR", "Input Switch", "MIXINR" },
600 { "SPKR", "IN1RP Switch", "IN1RP" },
601 { "SPKR", "Output Switch", "Right Output Mixer" },
602 { "SPKR", NULL, "TOCLK" },
603
604 { "SPKL Boost", "Direct Voice Switch", "Direct Voice" },
605 { "SPKL Boost", "SPKL Switch", "SPKL" },
606 { "SPKL Boost", "SPKR Switch", "SPKR" },
607
608 { "SPKR Boost", "Direct Voice Switch", "Direct Voice" },
609 { "SPKR Boost", "SPKR Switch", "SPKR" },
610 { "SPKR Boost", "SPKL Switch", "SPKL" },
611
612 { "SPKL Driver", NULL, "SPKL Boost" },
613 { "SPKL Driver", NULL, "CLK_SYS" },
614
615 { "SPKR Driver", NULL, "SPKR Boost" },
616 { "SPKR Driver", NULL, "CLK_SYS" },
617
618 { "SPKOUTLP", NULL, "SPKL Driver" },
619 { "SPKOUTLN", NULL, "SPKL Driver" },
620 { "SPKOUTRP", NULL, "SPKR Driver" },
621 { "SPKOUTRN", NULL, "SPKR Driver" },
622
623 { "Left Headphone Mux", "Mixer", "Left Output Mixer" },
624 { "Right Headphone Mux", "Mixer", "Right Output Mixer" },
625
626 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" },
629
630 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" },
632
633 { "LINEOUT1N", NULL, "LINEOUT1N Driver" },
634 { "LINEOUT1P", NULL, "LINEOUT1P Driver" },
635 { "LINEOUT2N", NULL, "LINEOUT2N Driver" },
636 { "LINEOUT2P", NULL, "LINEOUT2P Driver" },
637};
638
639static const struct snd_soc_dapm_route lineout1_diff_routes[] = {
640 { "LINEOUT1 Mixer", "IN1L Switch", "IN1L PGA" },
641 { "LINEOUT1 Mixer", "IN1R Switch", "IN1R PGA" },
642 { "LINEOUT1 Mixer", "Output Switch", "Left Output Mixer" },
643
644 { "LINEOUT1N Driver", NULL, "LINEOUT1 Mixer" },
645 { "LINEOUT1P Driver", NULL, "LINEOUT1 Mixer" },
646};
647
648static const struct snd_soc_dapm_route lineout1_se_routes[] = {
649 { "LINEOUT1N Mixer", "Left Output Switch", "Left Output Mixer" },
650 { "LINEOUT1N Mixer", "Right Output Switch", "Left Output Mixer" },
651
652 { "LINEOUT1P Mixer", "Left Output Switch", "Left Output Mixer" },
653
654 { "LINEOUT1N Driver", NULL, "LINEOUT1N Mixer" },
655 { "LINEOUT1P Driver", NULL, "LINEOUT1P Mixer" },
656};
657
658static const struct snd_soc_dapm_route lineout2_diff_routes[] = {
659 { "LINEOUT2 Mixer", "IN2L Switch", "IN2L PGA" },
660 { "LINEOUT2 Mixer", "IN2R Switch", "IN2R PGA" },
661 { "LINEOUT2 Mixer", "Output Switch", "Right Output Mixer" },
662
663 { "LINEOUT2N Driver", NULL, "LINEOUT2 Mixer" },
664 { "LINEOUT2P Driver", NULL, "LINEOUT2 Mixer" },
665};
666
667static const struct snd_soc_dapm_route lineout2_se_routes[] = {
668 { "LINEOUT2N Mixer", "Left Output Switch", "Left Output Mixer" },
669 { "LINEOUT2N Mixer", "Right Output Switch", "Left Output Mixer" },
670
671 { "LINEOUT2P Mixer", "Right Output Switch", "Right Output Mixer" },
672
673 { "LINEOUT2N Driver", NULL, "LINEOUT2N Mixer" },
674 { "LINEOUT2P Driver", NULL, "LINEOUT2P Mixer" },
675};
676
677int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
678{
679 /* Latch volume update bits & default ZC on */
680 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
681 WM8993_IN1_VU, WM8993_IN1_VU);
682 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_1_2_VOLUME,
683 WM8993_IN1_VU, WM8993_IN1_VU);
684 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_3_4_VOLUME,
685 WM8993_IN2_VU, WM8993_IN2_VU);
686 snd_soc_update_bits(codec, WM8993_RIGHT_LINE_INPUT_3_4_VOLUME,
687 WM8993_IN2_VU, WM8993_IN2_VU);
688
689 snd_soc_update_bits(codec, WM8993_SPEAKER_VOLUME_RIGHT,
690 WM8993_SPKOUT_VU, WM8993_SPKOUT_VU);
691
692 snd_soc_update_bits(codec, WM8993_LEFT_OUTPUT_VOLUME,
693 WM8993_HPOUT1L_ZC, WM8993_HPOUT1L_ZC);
694 snd_soc_update_bits(codec, WM8993_RIGHT_OUTPUT_VOLUME,
695 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC,
696 WM8993_HPOUT1_VU | WM8993_HPOUT1R_ZC);
697
698 snd_soc_update_bits(codec, WM8993_LEFT_OPGA_VOLUME,
699 WM8993_MIXOUTL_ZC, WM8993_MIXOUTL_ZC);
700 snd_soc_update_bits(codec, WM8993_RIGHT_OPGA_VOLUME,
701 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU,
702 WM8993_MIXOUTR_ZC | WM8993_MIXOUT_VU);
703
704 snd_soc_add_controls(codec, analogue_snd_controls,
705 ARRAY_SIZE(analogue_snd_controls));
706
707 snd_soc_dapm_new_controls(codec, analogue_dapm_widgets,
708 ARRAY_SIZE(analogue_dapm_widgets));
709 return 0;
710}
711EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
712
713int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
714 int lineout1_diff, int lineout2_diff)
715{
716 snd_soc_dapm_add_routes(codec, analogue_routes,
717 ARRAY_SIZE(analogue_routes));
718
719 if (lineout1_diff)
720 snd_soc_dapm_add_routes(codec,
721 lineout1_diff_routes,
722 ARRAY_SIZE(lineout1_diff_routes));
723 else
724 snd_soc_dapm_add_routes(codec,
725 lineout1_se_routes,
726 ARRAY_SIZE(lineout1_se_routes));
727
728 if (lineout2_diff)
729 snd_soc_dapm_add_routes(codec,
730 lineout2_diff_routes,
731 ARRAY_SIZE(lineout2_diff_routes));
732 else
733 snd_soc_dapm_add_routes(codec,
734 lineout2_se_routes,
735 ARRAY_SIZE(lineout2_se_routes));
736
737 return 0;
738}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
new file mode 100644
index 000000000000..ec09cb6a2939
--- /dev/null
+++ b/sound/soc/codecs/wm_hubs.h
@@ -0,0 +1,24 @@
1/*
2 * wm_hubs.h -- WM899x common code
3 *
4 * Copyright 2009 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
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#ifndef _WM_HUBS_H
15#define _WM_HUBS_H
16
17struct snd_soc_codec;
18
19extern const unsigned int wm_hubs_spkmix_tlv[];
20
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23
24#endif
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 411a710be660..4dfd4ad9d90e 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -9,6 +9,9 @@ config SND_DAVINCI_SOC
9config SND_DAVINCI_SOC_I2S 9config SND_DAVINCI_SOC_I2S
10 tristate 10 tristate
11 11
12config SND_DAVINCI_SOC_MCASP
13 tristate
14
12config SND_DAVINCI_SOC_EVM 15config SND_DAVINCI_SOC_EVM
13 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM" 16 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM"
14 depends on SND_DAVINCI_SOC 17 depends on SND_DAVINCI_SOC
@@ -19,6 +22,16 @@ config SND_DAVINCI_SOC_EVM
19 Say Y if you want to add support for SoC audio on TI 22 Say Y if you want to add support for SoC audio on TI
20 DaVinci DM6446 or DM355 EVM platforms. 23 DaVinci DM6446 or DM355 EVM platforms.
21 24
25config SND_DM6467_SOC_EVM
26 tristate "SoC Audio support for DaVinci DM6467 EVM"
27 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM
28 select SND_DAVINCI_SOC_MCASP
29 select SND_SOC_TLV320AIC3X
30 select SND_SOC_SPDIF
31
32 help
33 Say Y if you want to add support for SoC audio on TI
34
22config SND_DAVINCI_SOC_SFFSDR 35config SND_DAVINCI_SOC_SFFSDR
23 tristate "SoC Audio support for SFFSDR" 36 tristate "SoC Audio support for SFFSDR"
24 depends on SND_DAVINCI_SOC && MACH_SFFSDR 37 depends on SND_DAVINCI_SOC && MACH_SFFSDR
@@ -28,3 +41,23 @@ config SND_DAVINCI_SOC_SFFSDR
28 help 41 help
29 Say Y if you want to add support for SoC audio on 42 Say Y if you want to add support for SoC audio on
30 Lyrtech SFFSDR board. 43 Lyrtech SFFSDR board.
44
45config SND_DA830_SOC_EVM
46 tristate "SoC Audio support for DA830/OMAP-L137 EVM"
47 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM
48 select SND_DAVINCI_SOC_MCASP
49 select SND_SOC_TLV320AIC3X
50
51 help
52 Say Y if you want to add support for SoC audio on TI
53 DA830/OMAP-L137 EVM
54
55config SND_DA850_SOC_EVM
56 tristate "SoC Audio support for DA850/OMAP-L138 EVM"
57 depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM
58 select SND_DAVINCI_SOC_MCASP
59 select SND_SOC_TLV320AIC3X
60 help
61 Say Y if you want to add support for SoC audio on TI
62 DA850/OMAP-L138 EVM
63
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca8bae1fc3f6..a6939d71b988 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -1,13 +1,18 @@
1# DAVINCI Platform Support 1# DAVINCI Platform Support
2snd-soc-davinci-objs := davinci-pcm.o 2snd-soc-davinci-objs := davinci-pcm.o
3snd-soc-davinci-i2s-objs := davinci-i2s.o 3snd-soc-davinci-i2s-objs := davinci-i2s.o
4snd-soc-davinci-mcasp-objs:= davinci-mcasp.o
4 5
5obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o 6obj-$(CONFIG_SND_DAVINCI_SOC) += snd-soc-davinci.o
6obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o 7obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
8obj-$(CONFIG_SND_DAVINCI_SOC_MCASP) += snd-soc-davinci-mcasp.o
7 9
8# DAVINCI Machine Support 10# DAVINCI Machine Support
9snd-soc-evm-objs := davinci-evm.o 11snd-soc-evm-objs := davinci-evm.o
10snd-soc-sffsdr-objs := davinci-sffsdr.o 12snd-soc-sffsdr-objs := davinci-sffsdr.o
11 13
12obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 14obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
15obj-$(CONFIG_SND_DM6467_SOC_EVM) += snd-soc-evm.o
16obj-$(CONFIG_SND_DA830_SOC_EVM) += snd-soc-evm.o
17obj-$(CONFIG_SND_DA850_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o 18obj-$(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 58fd1cbedd88..67414f659405 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -14,6 +14,7 @@
14#include <linux/timer.h> 14#include <linux/timer.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/i2c.h>
17#include <sound/core.h> 18#include <sound/core.h>
18#include <sound/pcm.h> 19#include <sound/pcm.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
@@ -27,9 +28,10 @@
27#include <mach/mux.h> 28#include <mach/mux.h>
28 29
29#include "../codecs/tlv320aic3x.h" 30#include "../codecs/tlv320aic3x.h"
31#include "../codecs/spdif_transciever.h"
30#include "davinci-pcm.h" 32#include "davinci-pcm.h"
31#include "davinci-i2s.h" 33#include "davinci-i2s.h"
32 34#include "davinci-mcasp.h"
33 35
34#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \ 36#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
35 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF) 37 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
@@ -43,7 +45,7 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
43 unsigned sysclk; 45 unsigned sysclk;
44 46
45 /* ASP1 on DM355 EVM is clocked by an external oscillator */ 47 /* ASP1 on DM355 EVM is clocked by an external oscillator */
46 if (machine_is_davinci_dm355_evm()) 48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm())
47 sysclk = 27000000; 49 sysclk = 27000000;
48 50
49 /* ASP0 in DM6446 EVM is clocked by U55, as configured by 51 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -53,6 +55,10 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
53 else if (machine_is_davinci_evm()) 55 else if (machine_is_davinci_evm())
54 sysclk = 12288000; 56 sysclk = 12288000;
55 57
58 else if (machine_is_davinci_da830_evm() ||
59 machine_is_davinci_da850_evm())
60 sysclk = 24576000;
61
56 else 62 else
57 return -EINVAL; 63 return -EINVAL;
58 64
@@ -144,6 +150,32 @@ static struct snd_soc_dai_link evm_dai = {
144 .ops = &evm_ops, 150 .ops = &evm_ops,
145}; 151};
146 152
153static struct snd_soc_dai_link dm6467_evm_dai[] = {
154 {
155 .name = "TLV320AIC3X",
156 .stream_name = "AIC3X",
157 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI],
158 .codec_dai = &aic3x_dai,
159 .init = evm_aic3x_init,
160 .ops = &evm_ops,
161 },
162 {
163 .name = "McASP",
164 .stream_name = "spdif",
165 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_DIT_DAI],
166 .codec_dai = &dit_stub_dai,
167 .ops = &evm_ops,
168 },
169};
170static struct snd_soc_dai_link da8xx_evm_dai = {
171 .name = "TLV320AIC3X",
172 .stream_name = "AIC3X",
173 .cpu_dai = &davinci_mcasp_dai[DAVINCI_MCASP_I2S_DAI],
174 .codec_dai = &aic3x_dai,
175 .init = evm_aic3x_init,
176 .ops = &evm_ops,
177};
178
147/* davinci-evm audio machine driver */ 179/* davinci-evm audio machine driver */
148static struct snd_soc_card snd_soc_card_evm = { 180static struct snd_soc_card snd_soc_card_evm = {
149 .name = "DaVinci EVM", 181 .name = "DaVinci EVM",
@@ -152,73 +184,80 @@ static struct snd_soc_card snd_soc_card_evm = {
152 .num_links = 1, 184 .num_links = 1,
153}; 185};
154 186
155/* evm audio private data */ 187/* davinci dm6467 evm audio machine driver */
156static struct aic3x_setup_data evm_aic3x_setup = { 188static struct snd_soc_card dm6467_snd_soc_card_evm = {
157 .i2c_bus = 1, 189 .name = "DaVinci DM6467 EVM",
158 .i2c_address = 0x1b, 190 .platform = &davinci_soc_platform,
191 .dai_link = dm6467_evm_dai,
192 .num_links = ARRAY_SIZE(dm6467_evm_dai),
159}; 193};
160 194
195static struct snd_soc_card da830_snd_soc_card = {
196 .name = "DA830/OMAP-L137 EVM",
197 .dai_link = &da8xx_evm_dai,
198 .platform = &davinci_soc_platform,
199 .num_links = 1,
200};
201
202static struct snd_soc_card da850_snd_soc_card = {
203 .name = "DA850/OMAP-L138 EVM",
204 .dai_link = &da8xx_evm_dai,
205 .platform = &davinci_soc_platform,
206 .num_links = 1,
207};
208
209static struct aic3x_setup_data aic3x_setup;
210
161/* evm audio subsystem */ 211/* evm audio subsystem */
162static struct snd_soc_device evm_snd_devdata = { 212static struct snd_soc_device evm_snd_devdata = {
163 .card = &snd_soc_card_evm, 213 .card = &snd_soc_card_evm,
164 .codec_dev = &soc_codec_dev_aic3x, 214 .codec_dev = &soc_codec_dev_aic3x,
165 .codec_data = &evm_aic3x_setup, 215 .codec_data = &aic3x_setup,
166};
167
168/* DM6446 EVM uses ASP0; line-out is a pair of RCA jacks */
169static struct resource evm_snd_resources[] = {
170 {
171 .start = DAVINCI_ASP0_BASE,
172 .end = DAVINCI_ASP0_BASE + SZ_8K - 1,
173 .flags = IORESOURCE_MEM,
174 },
175}; 216};
176 217
177static struct evm_snd_platform_data evm_snd_data = { 218/* evm audio subsystem */
178 .tx_dma_ch = DAVINCI_DMA_ASP0_TX, 219static struct snd_soc_device dm6467_evm_snd_devdata = {
179 .rx_dma_ch = DAVINCI_DMA_ASP0_RX, 220 .card = &dm6467_snd_soc_card_evm,
221 .codec_dev = &soc_codec_dev_aic3x,
222 .codec_data = &aic3x_setup,
180}; 223};
181 224
182/* DM335 EVM uses ASP1; line-out is a stereo mini-jack */ 225/* evm audio subsystem */
183static struct resource dm335evm_snd_resources[] = { 226static struct snd_soc_device da830_evm_snd_devdata = {
184 { 227 .card = &da830_snd_soc_card,
185 .start = DAVINCI_ASP1_BASE, 228 .codec_dev = &soc_codec_dev_aic3x,
186 .end = DAVINCI_ASP1_BASE + SZ_8K - 1, 229 .codec_data = &aic3x_setup,
187 .flags = IORESOURCE_MEM,
188 },
189}; 230};
190 231
191static struct evm_snd_platform_data dm335evm_snd_data = { 232static struct snd_soc_device da850_evm_snd_devdata = {
192 .tx_dma_ch = DAVINCI_DMA_ASP1_TX, 233 .card = &da850_snd_soc_card,
193 .rx_dma_ch = DAVINCI_DMA_ASP1_RX, 234 .codec_dev = &soc_codec_dev_aic3x,
235 .codec_data = &aic3x_setup,
194}; 236};
195 237
196static struct platform_device *evm_snd_device; 238static struct platform_device *evm_snd_device;
197 239
198static int __init evm_init(void) 240static int __init evm_init(void)
199{ 241{
200 struct resource *resources; 242 struct snd_soc_device *evm_snd_dev_data;
201 unsigned num_resources;
202 struct evm_snd_platform_data *data;
203 int index; 243 int index;
204 int ret; 244 int ret;
205 245
206 if (machine_is_davinci_evm()) { 246 if (machine_is_davinci_evm()) {
207 davinci_cfg_reg(DM644X_MCBSP); 247 evm_snd_dev_data = &evm_snd_devdata;
208
209 resources = evm_snd_resources;
210 num_resources = ARRAY_SIZE(evm_snd_resources);
211 data = &evm_snd_data;
212 index = 0; 248 index = 0;
213 } else if (machine_is_davinci_dm355_evm()) { 249 } else if (machine_is_davinci_dm355_evm()) {
214 /* we don't use ASP1 IRQs, or we'd need to mux them ... */ 250 evm_snd_dev_data = &evm_snd_devdata;
215 davinci_cfg_reg(DM355_EVT8_ASP1_TX); 251 index = 1;
216 davinci_cfg_reg(DM355_EVT9_ASP1_RX); 252 } else if (machine_is_davinci_dm6467_evm()) {
217 253 evm_snd_dev_data = &dm6467_evm_snd_devdata;
218 resources = dm335evm_snd_resources; 254 index = 0;
219 num_resources = ARRAY_SIZE(dm335evm_snd_resources); 255 } else if (machine_is_davinci_da830_evm()) {
220 data = &dm335evm_snd_data; 256 evm_snd_dev_data = &da830_evm_snd_devdata;
221 index = 1; 257 index = 1;
258 } else if (machine_is_davinci_da850_evm()) {
259 evm_snd_dev_data = &da850_evm_snd_devdata;
260 index = 0;
222 } else 261 } else
223 return -EINVAL; 262 return -EINVAL;
224 263
@@ -226,17 +265,8 @@ static int __init evm_init(void)
226 if (!evm_snd_device) 265 if (!evm_snd_device)
227 return -ENOMEM; 266 return -ENOMEM;
228 267
229 platform_set_drvdata(evm_snd_device, &evm_snd_devdata); 268 platform_set_drvdata(evm_snd_device, evm_snd_dev_data);
230 evm_snd_devdata.dev = &evm_snd_device->dev; 269 evm_snd_dev_data->dev = &evm_snd_device->dev;
231 platform_device_add_data(evm_snd_device, data, sizeof(*data));
232
233 ret = platform_device_add_resources(evm_snd_device, resources,
234 num_resources);
235 if (ret) {
236 platform_device_put(evm_snd_device);
237 return ret;
238 }
239
240 ret = platform_device_add(evm_snd_device); 270 ret = platform_device_add(evm_snd_device);
241 if (ret) 271 if (ret)
242 platform_device_put(evm_snd_device); 272 platform_device_put(evm_snd_device);
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index b1ea52fc83c7..12a6c549ee6e 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -22,6 +22,8 @@
22#include <sound/initval.h> 22#include <sound/initval.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24 24
25#include <mach/asp.h>
26
25#include "davinci-pcm.h" 27#include "davinci-pcm.h"
26 28
27 29
@@ -63,6 +65,7 @@
63#define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5) 65#define DAVINCI_MCBSP_RCR_RWDLEN1(v) ((v) << 5)
64#define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8) 66#define DAVINCI_MCBSP_RCR_RFRLEN1(v) ((v) << 8)
65#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16) 67#define DAVINCI_MCBSP_RCR_RDATDLY(v) ((v) << 16)
68#define DAVINCI_MCBSP_RCR_RFIG (1 << 18)
66#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21) 69#define DAVINCI_MCBSP_RCR_RWDLEN2(v) ((v) << 21)
67 70
68#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5) 71#define DAVINCI_MCBSP_XCR_XWDLEN1(v) ((v) << 5)
@@ -85,14 +88,6 @@
85#define DAVINCI_MCBSP_PCR_FSRM (1 << 10) 88#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
86#define DAVINCI_MCBSP_PCR_FSXM (1 << 11) 89#define DAVINCI_MCBSP_PCR_FSXM (1 << 11)
87 90
88#define MOD_REG_BIT(val, mask, set) do { \
89 if (set) { \
90 val |= mask; \
91 } else { \
92 val &= ~mask; \
93 } \
94} while (0)
95
96enum { 91enum {
97 DAVINCI_MCBSP_WORD_8 = 0, 92 DAVINCI_MCBSP_WORD_8 = 0,
98 DAVINCI_MCBSP_WORD_12, 93 DAVINCI_MCBSP_WORD_12,
@@ -112,6 +107,10 @@ static struct davinci_pcm_dma_params davinci_i2s_pcm_in = {
112 107
113struct davinci_mcbsp_dev { 108struct davinci_mcbsp_dev {
114 void __iomem *base; 109 void __iomem *base;
110#define MOD_DSP_A 0
111#define MOD_DSP_B 1
112 int mode;
113 u32 pcr;
115 struct clk *clk; 114 struct clk *clk;
116 struct davinci_pcm_dma_params *dma_params[2]; 115 struct davinci_pcm_dma_params *dma_params[2];
117}; 116};
@@ -127,96 +126,100 @@ static inline u32 davinci_mcbsp_read_reg(struct davinci_mcbsp_dev *dev, int reg)
127 return __raw_readl(dev->base + reg); 126 return __raw_readl(dev->base + reg);
128} 127}
129 128
130static void davinci_mcbsp_start(struct snd_pcm_substream *substream) 129static void toggle_clock(struct davinci_mcbsp_dev *dev, int playback)
130{
131 u32 m = playback ? DAVINCI_MCBSP_PCR_CLKXP : DAVINCI_MCBSP_PCR_CLKRP;
132 /* The clock needs to toggle to complete reset.
133 * So, fake it by toggling the clk polarity.
134 */
135 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m);
136 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr);
137}
138
139static void davinci_mcbsp_start(struct davinci_mcbsp_dev *dev,
140 struct snd_pcm_substream *substream)
131{ 141{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data; 142 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
134 struct snd_soc_device *socdev = rtd->socdev; 143 struct snd_soc_device *socdev = rtd->socdev;
135 struct snd_soc_platform *platform = socdev->card->platform; 144 struct snd_soc_platform *platform = socdev->card->platform;
136 u32 w; 145 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
137 int ret; 146 u32 spcr;
138 147 u32 mask = playback ? DAVINCI_MCBSP_SPCR_XRST : DAVINCI_MCBSP_SPCR_RRST;
139 /* Start the sample generator and enable transmitter/receiver */ 148 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
140 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 149 if (spcr & mask) {
141 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1); 150 /* start off disabled */
142 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 151 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
152 spcr & ~mask);
153 toggle_clock(dev, playback);
154 }
155 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM |
156 DAVINCI_MCBSP_PCR_CLKXM | DAVINCI_MCBSP_PCR_CLKRM)) {
157 /* Start the sample generator */
158 spcr |= DAVINCI_MCBSP_SPCR_GRST;
159 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
160 }
143 161
144 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 162 if (playback) {
145 /* Stop the DMA to avoid data loss */ 163 /* Stop the DMA to avoid data loss */
146 /* while the transmitter is out of reset to handle XSYNCERR */ 164 /* while the transmitter is out of reset to handle XSYNCERR */
147 if (platform->pcm_ops->trigger) { 165 if (platform->pcm_ops->trigger) {
148 ret = platform->pcm_ops->trigger(substream, 166 int ret = platform->pcm_ops->trigger(substream,
149 SNDRV_PCM_TRIGGER_STOP); 167 SNDRV_PCM_TRIGGER_STOP);
150 if (ret < 0) 168 if (ret < 0)
151 printk(KERN_DEBUG "Playback DMA stop failed\n"); 169 printk(KERN_DEBUG "Playback DMA stop failed\n");
152 } 170 }
153 171
154 /* Enable the transmitter */ 172 /* Enable the transmitter */
155 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 173 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
156 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1); 174 spcr |= DAVINCI_MCBSP_SPCR_XRST;
157 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 175 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
158 176
159 /* wait for any unexpected frame sync error to occur */ 177 /* wait for any unexpected frame sync error to occur */
160 udelay(100); 178 udelay(100);
161 179
162 /* Disable the transmitter to clear any outstanding XSYNCERR */ 180 /* Disable the transmitter to clear any outstanding XSYNCERR */
163 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 181 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
164 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0); 182 spcr &= ~DAVINCI_MCBSP_SPCR_XRST;
165 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 183 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
184 toggle_clock(dev, playback);
166 185
167 /* Restart the DMA */ 186 /* Restart the DMA */
168 if (platform->pcm_ops->trigger) { 187 if (platform->pcm_ops->trigger) {
169 ret = platform->pcm_ops->trigger(substream, 188 int ret = platform->pcm_ops->trigger(substream,
170 SNDRV_PCM_TRIGGER_START); 189 SNDRV_PCM_TRIGGER_START);
171 if (ret < 0) 190 if (ret < 0)
172 printk(KERN_DEBUG "Playback DMA start failed\n"); 191 printk(KERN_DEBUG "Playback DMA start failed\n");
173 } 192 }
174 /* Enable the transmitter */
175 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
176 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
177 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
178
179 } else {
180
181 /* Enable the reciever */
182 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
183 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
184 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
185 } 193 }
186 194
195 /* Enable transmitter or receiver */
196 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
197 spcr |= mask;
187 198
188 /* Start frame sync */ 199 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) {
189 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 200 /* Start frame sync */
190 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_FRST, 1); 201 spcr |= DAVINCI_MCBSP_SPCR_FRST;
191 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 202 }
203 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
192} 204}
193 205
194static void davinci_mcbsp_stop(struct snd_pcm_substream *substream) 206static void davinci_mcbsp_stop(struct davinci_mcbsp_dev *dev, int playback)
195{ 207{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data; 208 u32 spcr;
197 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
198 u32 w;
199 209
200 /* Reset transmitter/receiver and sample rate/frame sync generators */ 210 /* Reset transmitter/receiver and sample rate/frame sync generators */
201 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 211 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
202 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST | 212 spcr &= ~(DAVINCI_MCBSP_SPCR_GRST | DAVINCI_MCBSP_SPCR_FRST);
203 DAVINCI_MCBSP_SPCR_FRST, 0); 213 spcr &= playback ? ~DAVINCI_MCBSP_SPCR_XRST : ~DAVINCI_MCBSP_SPCR_RRST;
204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 214 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
205 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0); 215 toggle_clock(dev, playback);
206 else
207 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 0);
208 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
209} 216}
210 217
211static int davinci_i2s_startup(struct snd_pcm_substream *substream, 218static int davinci_i2s_startup(struct snd_pcm_substream *substream,
212 struct snd_soc_dai *dai) 219 struct snd_soc_dai *cpu_dai)
213{ 220{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 221 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
215 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
216 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
217
218 cpu_dai->dma_data = dev->dma_params[substream->stream]; 222 cpu_dai->dma_data = dev->dma_params[substream->stream];
219
220 return 0; 223 return 0;
221} 224}
222 225
@@ -228,12 +231,11 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
228 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 231 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
229 unsigned int pcr; 232 unsigned int pcr;
230 unsigned int srgr; 233 unsigned int srgr;
231 unsigned int rcr;
232 unsigned int xcr;
233 srgr = DAVINCI_MCBSP_SRGR_FSGM | 234 srgr = DAVINCI_MCBSP_SRGR_FSGM |
234 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | 235 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
235 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); 236 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
236 237
238 /* set master/slave audio interface */
237 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 239 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
238 case SND_SOC_DAIFMT_CBS_CFS: 240 case SND_SOC_DAIFMT_CBS_CFS:
239 /* cpu is master */ 241 /* cpu is master */
@@ -258,11 +260,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
258 return -EINVAL; 260 return -EINVAL;
259 } 261 }
260 262
261 rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1); 263 /* interface format */
262 xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1);
263 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 264 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
264 case SND_SOC_DAIFMT_DSP_B:
265 break;
266 case SND_SOC_DAIFMT_I2S: 265 case SND_SOC_DAIFMT_I2S:
267 /* Davinci doesn't support TRUE I2S, but some codecs will have 266 /* Davinci doesn't support TRUE I2S, but some codecs will have
268 * the left and right channels contiguous. This allows 267 * the left and right channels contiguous. This allows
@@ -282,8 +281,10 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
282 */ 281 */
283 fmt ^= SND_SOC_DAIFMT_NB_IF; 282 fmt ^= SND_SOC_DAIFMT_NB_IF;
284 case SND_SOC_DAIFMT_DSP_A: 283 case SND_SOC_DAIFMT_DSP_A:
285 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1); 284 dev->mode = MOD_DSP_A;
286 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); 285 break;
286 case SND_SOC_DAIFMT_DSP_B:
287 dev->mode = MOD_DSP_B;
287 break; 288 break;
288 default: 289 default:
289 printk(KERN_ERR "%s:bad format\n", __func__); 290 printk(KERN_ERR "%s:bad format\n", __func__);
@@ -343,9 +344,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
343 return -EINVAL; 344 return -EINVAL;
344 } 345 }
345 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); 346 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
347 dev->pcr = pcr;
346 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); 348 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
347 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
348 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
349 return 0; 349 return 0;
350} 350}
351 351
@@ -353,31 +353,40 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
353 struct snd_pcm_hw_params *params, 353 struct snd_pcm_hw_params *params,
354 struct snd_soc_dai *dai) 354 struct snd_soc_dai *dai)
355{ 355{
356 struct snd_soc_pcm_runtime *rtd = substream->private_data; 356 struct davinci_pcm_dma_params *dma_params = dai->dma_data;
357 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 357 struct davinci_mcbsp_dev *dev = dai->private_data;
358 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
359 struct snd_interval *i = NULL; 358 struct snd_interval *i = NULL;
360 int mcbsp_word_length; 359 int mcbsp_word_length;
361 u32 w; 360 unsigned int rcr, xcr, srgr;
361 u32 spcr;
362 362
363 /* general line settings */ 363 /* general line settings */
364 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 364 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
365 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 365 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
366 w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE; 366 spcr |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
367 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 367 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
368 } else { 368 } else {
369 w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE; 369 spcr |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
370 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 370 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, spcr);
371 } 371 }
372 372
373 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 373 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
374 w = DAVINCI_MCBSP_SRGR_FSGM; 374 srgr = DAVINCI_MCBSP_SRGR_FSGM;
375 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1); 375 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1);
376 376
377 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 377 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
378 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1); 378 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1);
379 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w); 379 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
380 380
381 rcr = DAVINCI_MCBSP_RCR_RFIG;
382 xcr = DAVINCI_MCBSP_XCR_XFIG;
383 if (dev->mode == MOD_DSP_B) {
384 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(0);
385 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(0);
386 } else {
387 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
388 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
389 }
381 /* Determine xfer data type */ 390 /* Determine xfer data type */
382 switch (params_format(params)) { 391 switch (params_format(params)) {
383 case SNDRV_PCM_FORMAT_S8: 392 case SNDRV_PCM_FORMAT_S8:
@@ -397,18 +406,31 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
397 return -EINVAL; 406 return -EINVAL;
398 } 407 }
399 408
400 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { 409 dma_params->acnt = dma_params->data_type;
401 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); 410 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1);
402 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 411 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1);
403 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
404 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
405 412
406 } else { 413 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
407 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); 414 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
408 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | 415 xcr |= DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
409 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1); 416 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length);
410 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
411 417
418 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
419 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
420 else
421 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
422 return 0;
423}
424
425static int davinci_i2s_prepare(struct snd_pcm_substream *substream,
426 struct snd_soc_dai *dai)
427{
428 struct davinci_mcbsp_dev *dev = dai->private_data;
429 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
430 davinci_mcbsp_stop(dev, playback);
431 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0) {
432 /* codec is master */
433 davinci_mcbsp_start(dev, substream);
412 } 434 }
413 return 0; 435 return 0;
414} 436}
@@ -416,35 +438,72 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
416static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 438static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
417 struct snd_soc_dai *dai) 439 struct snd_soc_dai *dai)
418{ 440{
441 struct davinci_mcbsp_dev *dev = dai->private_data;
419 int ret = 0; 442 int ret = 0;
443 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
444 if ((dev->pcr & DAVINCI_MCBSP_PCR_FSXM) == 0)
445 return 0; /* return if codec is master */
420 446
421 switch (cmd) { 447 switch (cmd) {
422 case SNDRV_PCM_TRIGGER_START: 448 case SNDRV_PCM_TRIGGER_START:
423 case SNDRV_PCM_TRIGGER_RESUME: 449 case SNDRV_PCM_TRIGGER_RESUME:
424 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 450 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
425 davinci_mcbsp_start(substream); 451 davinci_mcbsp_start(dev, substream);
426 break; 452 break;
427 case SNDRV_PCM_TRIGGER_STOP: 453 case SNDRV_PCM_TRIGGER_STOP:
428 case SNDRV_PCM_TRIGGER_SUSPEND: 454 case SNDRV_PCM_TRIGGER_SUSPEND:
429 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 455 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
430 davinci_mcbsp_stop(substream); 456 davinci_mcbsp_stop(dev, playback);
431 break; 457 break;
432 default: 458 default:
433 ret = -EINVAL; 459 ret = -EINVAL;
434 } 460 }
435
436 return ret; 461 return ret;
437} 462}
438 463
439static int davinci_i2s_probe(struct platform_device *pdev, 464static void davinci_i2s_shutdown(struct snd_pcm_substream *substream,
440 struct snd_soc_dai *dai) 465 struct snd_soc_dai *dai)
466{
467 struct davinci_mcbsp_dev *dev = dai->private_data;
468 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
469 davinci_mcbsp_stop(dev, playback);
470}
471
472#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000
473
474static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
475 .startup = davinci_i2s_startup,
476 .shutdown = davinci_i2s_shutdown,
477 .prepare = davinci_i2s_prepare,
478 .trigger = davinci_i2s_trigger,
479 .hw_params = davinci_i2s_hw_params,
480 .set_fmt = davinci_i2s_set_dai_fmt,
481
482};
483
484struct snd_soc_dai davinci_i2s_dai = {
485 .name = "davinci-i2s",
486 .id = 0,
487 .playback = {
488 .channels_min = 2,
489 .channels_max = 2,
490 .rates = DAVINCI_I2S_RATES,
491 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
492 .capture = {
493 .channels_min = 2,
494 .channels_max = 2,
495 .rates = DAVINCI_I2S_RATES,
496 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
497 .ops = &davinci_i2s_dai_ops,
498
499};
500EXPORT_SYMBOL_GPL(davinci_i2s_dai);
501
502static int davinci_i2s_probe(struct platform_device *pdev)
441{ 503{
442 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 504 struct snd_platform_data *pdata = pdev->dev.platform_data;
443 struct snd_soc_card *card = socdev->card;
444 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
445 struct davinci_mcbsp_dev *dev; 505 struct davinci_mcbsp_dev *dev;
446 struct resource *mem, *ioarea; 506 struct resource *mem, *ioarea, *res;
447 struct evm_snd_platform_data *pdata;
448 int ret; 507 int ret;
449 508
450 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 509 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -466,8 +525,6 @@ static int davinci_i2s_probe(struct platform_device *pdev,
466 goto err_release_region; 525 goto err_release_region;
467 } 526 }
468 527
469 cpu_dai->private_data = dev;
470
471 dev->clk = clk_get(&pdev->dev, NULL); 528 dev->clk = clk_get(&pdev->dev, NULL);
472 if (IS_ERR(dev->clk)) { 529 if (IS_ERR(dev->clk)) {
473 ret = -ENODEV; 530 ret = -ENODEV;
@@ -476,18 +533,37 @@ static int davinci_i2s_probe(struct platform_device *pdev,
476 clk_enable(dev->clk); 533 clk_enable(dev->clk);
477 534
478 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 535 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
479 pdata = pdev->dev.platform_data;
480 536
481 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out; 537 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &davinci_i2s_pcm_out;
482 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = pdata->tx_dma_ch;
483 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr = 538 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->dma_addr =
484 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG); 539 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DXR_REG);
485 540
486 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in; 541 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &davinci_i2s_pcm_in;
487 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = pdata->rx_dma_ch;
488 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr = 542 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->dma_addr =
489 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG); 543 (dma_addr_t)(io_v2p(dev->base) + DAVINCI_MCBSP_DRR_REG);
490 544
545 /* first TX, then RX */
546 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
547 if (!res) {
548 dev_err(&pdev->dev, "no DMA resource\n");
549 ret = -ENXIO;
550 goto err_free_mem;
551 }
552 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK]->channel = res->start;
553
554 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
555 if (!res) {
556 dev_err(&pdev->dev, "no DMA resource\n");
557 ret = -ENXIO;
558 goto err_free_mem;
559 }
560 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE]->channel = res->start;
561
562 davinci_i2s_dai.private_data = dev;
563 ret = snd_soc_register_dai(&davinci_i2s_dai);
564 if (ret != 0)
565 goto err_free_mem;
566
491 return 0; 567 return 0;
492 568
493err_free_mem: 569err_free_mem:
@@ -498,62 +574,40 @@ err_release_region:
498 return ret; 574 return ret;
499} 575}
500 576
501static void davinci_i2s_remove(struct platform_device *pdev, 577static int davinci_i2s_remove(struct platform_device *pdev)
502 struct snd_soc_dai *dai)
503{ 578{
504 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 579 struct davinci_mcbsp_dev *dev = davinci_i2s_dai.private_data;
505 struct snd_soc_card *card = socdev->card;
506 struct snd_soc_dai *cpu_dai = card->dai_link->cpu_dai;
507 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
508 struct resource *mem; 580 struct resource *mem;
509 581
582 snd_soc_unregister_dai(&davinci_i2s_dai);
510 clk_disable(dev->clk); 583 clk_disable(dev->clk);
511 clk_put(dev->clk); 584 clk_put(dev->clk);
512 dev->clk = NULL; 585 dev->clk = NULL;
513
514 kfree(dev); 586 kfree(dev);
515
516 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 587 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
517 release_mem_region(mem->start, (mem->end - mem->start) + 1); 588 release_mem_region(mem->start, (mem->end - mem->start) + 1);
518}
519 589
520#define DAVINCI_I2S_RATES SNDRV_PCM_RATE_8000_96000 590 return 0;
521 591}
522static struct snd_soc_dai_ops davinci_i2s_dai_ops = {
523 .startup = davinci_i2s_startup,
524 .trigger = davinci_i2s_trigger,
525 .hw_params = davinci_i2s_hw_params,
526 .set_fmt = davinci_i2s_set_dai_fmt,
527};
528 592
529struct snd_soc_dai davinci_i2s_dai = { 593static struct platform_driver davinci_mcbsp_driver = {
530 .name = "davinci-i2s", 594 .probe = davinci_i2s_probe,
531 .id = 0, 595 .remove = davinci_i2s_remove,
532 .probe = davinci_i2s_probe, 596 .driver = {
533 .remove = davinci_i2s_remove, 597 .name = "davinci-asp",
534 .playback = { 598 .owner = THIS_MODULE,
535 .channels_min = 2, 599 },
536 .channels_max = 2,
537 .rates = DAVINCI_I2S_RATES,
538 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
539 .capture = {
540 .channels_min = 2,
541 .channels_max = 2,
542 .rates = DAVINCI_I2S_RATES,
543 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
544 .ops = &davinci_i2s_dai_ops,
545}; 600};
546EXPORT_SYMBOL_GPL(davinci_i2s_dai);
547 601
548static int __init davinci_i2s_init(void) 602static int __init davinci_i2s_init(void)
549{ 603{
550 return snd_soc_register_dai(&davinci_i2s_dai); 604 return platform_driver_register(&davinci_mcbsp_driver);
551} 605}
552module_init(davinci_i2s_init); 606module_init(davinci_i2s_init);
553 607
554static void __exit davinci_i2s_exit(void) 608static void __exit davinci_i2s_exit(void)
555{ 609{
556 snd_soc_unregister_dai(&davinci_i2s_dai); 610 platform_driver_unregister(&davinci_mcbsp_driver);
557} 611}
558module_exit(davinci_i2s_exit); 612module_exit(davinci_i2s_exit);
559 613
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
new file mode 100644
index 000000000000..eca22d7829d2
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -0,0 +1,973 @@
1/*
2 * ALSA SoC McASP Audio Layer for TI DAVINCI processor
3 *
4 * Multi-channel Audio Serial Port Driver
5 *
6 * Author: Nirmal Pandey <n-pandey@ti.com>,
7 * Suresh Rajashekara <suresh.r@ti.com>
8 * Steve Chen <schen@.mvista.com>
9 *
10 * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
11 * Copyright: (C) 2009 Texas Instruments, India
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 version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/io.h>
23#include <linux/clk.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 "davinci-pcm.h"
32#include "davinci-mcasp.h"
33
34/*
35 * McASP register definitions
36 */
37#define DAVINCI_MCASP_PID_REG 0x00
38#define DAVINCI_MCASP_PWREMUMGT_REG 0x04
39
40#define DAVINCI_MCASP_PFUNC_REG 0x10
41#define DAVINCI_MCASP_PDIR_REG 0x14
42#define DAVINCI_MCASP_PDOUT_REG 0x18
43#define DAVINCI_MCASP_PDSET_REG 0x1c
44
45#define DAVINCI_MCASP_PDCLR_REG 0x20
46
47#define DAVINCI_MCASP_TLGC_REG 0x30
48#define DAVINCI_MCASP_TLMR_REG 0x34
49
50#define DAVINCI_MCASP_GBLCTL_REG 0x44
51#define DAVINCI_MCASP_AMUTE_REG 0x48
52#define DAVINCI_MCASP_LBCTL_REG 0x4c
53
54#define DAVINCI_MCASP_TXDITCTL_REG 0x50
55
56#define DAVINCI_MCASP_GBLCTLR_REG 0x60
57#define DAVINCI_MCASP_RXMASK_REG 0x64
58#define DAVINCI_MCASP_RXFMT_REG 0x68
59#define DAVINCI_MCASP_RXFMCTL_REG 0x6c
60
61#define DAVINCI_MCASP_ACLKRCTL_REG 0x70
62#define DAVINCI_MCASP_AHCLKRCTL_REG 0x74
63#define DAVINCI_MCASP_RXTDM_REG 0x78
64#define DAVINCI_MCASP_EVTCTLR_REG 0x7c
65
66#define DAVINCI_MCASP_RXSTAT_REG 0x80
67#define DAVINCI_MCASP_RXTDMSLOT_REG 0x84
68#define DAVINCI_MCASP_RXCLKCHK_REG 0x88
69#define DAVINCI_MCASP_REVTCTL_REG 0x8c
70
71#define DAVINCI_MCASP_GBLCTLX_REG 0xa0
72#define DAVINCI_MCASP_TXMASK_REG 0xa4
73#define DAVINCI_MCASP_TXFMT_REG 0xa8
74#define DAVINCI_MCASP_TXFMCTL_REG 0xac
75
76#define DAVINCI_MCASP_ACLKXCTL_REG 0xb0
77#define DAVINCI_MCASP_AHCLKXCTL_REG 0xb4
78#define DAVINCI_MCASP_TXTDM_REG 0xb8
79#define DAVINCI_MCASP_EVTCTLX_REG 0xbc
80
81#define DAVINCI_MCASP_TXSTAT_REG 0xc0
82#define DAVINCI_MCASP_TXTDMSLOT_REG 0xc4
83#define DAVINCI_MCASP_TXCLKCHK_REG 0xc8
84#define DAVINCI_MCASP_XEVTCTL_REG 0xcc
85
86/* Left(even TDM Slot) Channel Status Register File */
87#define DAVINCI_MCASP_DITCSRA_REG 0x100
88/* Right(odd TDM slot) Channel Status Register File */
89#define DAVINCI_MCASP_DITCSRB_REG 0x118
90/* Left(even TDM slot) User Data Register File */
91#define DAVINCI_MCASP_DITUDRA_REG 0x130
92/* Right(odd TDM Slot) User Data Register File */
93#define DAVINCI_MCASP_DITUDRB_REG 0x148
94
95/* Serializer n Control Register */
96#define DAVINCI_MCASP_XRSRCTL_BASE_REG 0x180
97#define DAVINCI_MCASP_XRSRCTL_REG(n) (DAVINCI_MCASP_XRSRCTL_BASE_REG + \
98 (n << 2))
99
100/* Transmit Buffer for Serializer n */
101#define DAVINCI_MCASP_TXBUF_REG 0x200
102/* Receive Buffer for Serializer n */
103#define DAVINCI_MCASP_RXBUF_REG 0x280
104
105/* McASP FIFO Registers */
106#define DAVINCI_MCASP_WFIFOCTL (0x1010)
107#define DAVINCI_MCASP_WFIFOSTS (0x1014)
108#define DAVINCI_MCASP_RFIFOCTL (0x1018)
109#define DAVINCI_MCASP_RFIFOSTS (0x101C)
110
111/*
112 * DAVINCI_MCASP_PWREMUMGT_REG - Power Down and Emulation Management
113 * Register Bits
114 */
115#define MCASP_FREE BIT(0)
116#define MCASP_SOFT BIT(1)
117
118/*
119 * DAVINCI_MCASP_PFUNC_REG - Pin Function / GPIO Enable Register Bits
120 */
121#define AXR(n) (1<<n)
122#define PFUNC_AMUTE BIT(25)
123#define ACLKX BIT(26)
124#define AHCLKX BIT(27)
125#define AFSX BIT(28)
126#define ACLKR BIT(29)
127#define AHCLKR BIT(30)
128#define AFSR BIT(31)
129
130/*
131 * DAVINCI_MCASP_PDIR_REG - Pin Direction Register Bits
132 */
133#define AXR(n) (1<<n)
134#define PDIR_AMUTE BIT(25)
135#define ACLKX BIT(26)
136#define AHCLKX BIT(27)
137#define AFSX BIT(28)
138#define ACLKR BIT(29)
139#define AHCLKR BIT(30)
140#define AFSR BIT(31)
141
142/*
143 * DAVINCI_MCASP_TXDITCTL_REG - Transmit DIT Control Register Bits
144 */
145#define DITEN BIT(0) /* Transmit DIT mode enable/disable */
146#define VA BIT(2)
147#define VB BIT(3)
148
149/*
150 * DAVINCI_MCASP_TXFMT_REG - Transmit Bitstream Format Register Bits
151 */
152#define TXROT(val) (val)
153#define TXSEL BIT(3)
154#define TXSSZ(val) (val<<4)
155#define TXPBIT(val) (val<<8)
156#define TXPAD(val) (val<<13)
157#define TXORD BIT(15)
158#define FSXDLY(val) (val<<16)
159
160/*
161 * DAVINCI_MCASP_RXFMT_REG - Receive Bitstream Format Register Bits
162 */
163#define RXROT(val) (val)
164#define RXSEL BIT(3)
165#define RXSSZ(val) (val<<4)
166#define RXPBIT(val) (val<<8)
167#define RXPAD(val) (val<<13)
168#define RXORD BIT(15)
169#define FSRDLY(val) (val<<16)
170
171/*
172 * DAVINCI_MCASP_TXFMCTL_REG - Transmit Frame Control Register Bits
173 */
174#define FSXPOL BIT(0)
175#define AFSXE BIT(1)
176#define FSXDUR BIT(4)
177#define FSXMOD(val) (val<<7)
178
179/*
180 * DAVINCI_MCASP_RXFMCTL_REG - Receive Frame Control Register Bits
181 */
182#define FSRPOL BIT(0)
183#define AFSRE BIT(1)
184#define FSRDUR BIT(4)
185#define FSRMOD(val) (val<<7)
186
187/*
188 * DAVINCI_MCASP_ACLKXCTL_REG - Transmit Clock Control Register Bits
189 */
190#define ACLKXDIV(val) (val)
191#define ACLKXE BIT(5)
192#define TX_ASYNC BIT(6)
193#define ACLKXPOL BIT(7)
194
195/*
196 * DAVINCI_MCASP_ACLKRCTL_REG Receive Clock Control Register Bits
197 */
198#define ACLKRDIV(val) (val)
199#define ACLKRE BIT(5)
200#define RX_ASYNC BIT(6)
201#define ACLKRPOL BIT(7)
202
203/*
204 * DAVINCI_MCASP_AHCLKXCTL_REG - High Frequency Transmit Clock Control
205 * Register Bits
206 */
207#define AHCLKXDIV(val) (val)
208#define AHCLKXPOL BIT(14)
209#define AHCLKXE BIT(15)
210
211/*
212 * DAVINCI_MCASP_AHCLKRCTL_REG - High Frequency Receive Clock Control
213 * Register Bits
214 */
215#define AHCLKRDIV(val) (val)
216#define AHCLKRPOL BIT(14)
217#define AHCLKRE BIT(15)
218
219/*
220 * DAVINCI_MCASP_XRSRCTL_BASE_REG - Serializer Control Register Bits
221 */
222#define MODE(val) (val)
223#define DISMOD (val)(val<<2)
224#define TXSTATE BIT(4)
225#define RXSTATE BIT(5)
226
227/*
228 * DAVINCI_MCASP_LBCTL_REG - Loop Back Control Register Bits
229 */
230#define LBEN BIT(0)
231#define LBORD BIT(1)
232#define LBGENMODE(val) (val<<2)
233
234/*
235 * DAVINCI_MCASP_TXTDMSLOT_REG - Transmit TDM Slot Register configuration
236 */
237#define TXTDMS(n) (1<<n)
238
239/*
240 * DAVINCI_MCASP_RXTDMSLOT_REG - Receive TDM Slot Register configuration
241 */
242#define RXTDMS(n) (1<<n)
243
244/*
245 * DAVINCI_MCASP_GBLCTL_REG - Global Control Register Bits
246 */
247#define RXCLKRST BIT(0) /* Receiver Clock Divider Reset */
248#define RXHCLKRST BIT(1) /* Receiver High Frequency Clock Divider */
249#define RXSERCLR BIT(2) /* Receiver Serializer Clear */
250#define RXSMRST BIT(3) /* Receiver State Machine Reset */
251#define RXFSRST BIT(4) /* Frame Sync Generator Reset */
252#define TXCLKRST BIT(8) /* Transmitter Clock Divider Reset */
253#define TXHCLKRST BIT(9) /* Transmitter High Frequency Clock Divider*/
254#define TXSERCLR BIT(10) /* Transmit Serializer Clear */
255#define TXSMRST BIT(11) /* Transmitter State Machine Reset */
256#define TXFSRST BIT(12) /* Frame Sync Generator Reset */
257
258/*
259 * DAVINCI_MCASP_AMUTE_REG - Mute Control Register Bits
260 */
261#define MUTENA(val) (val)
262#define MUTEINPOL BIT(2)
263#define MUTEINENA BIT(3)
264#define MUTEIN BIT(4)
265#define MUTER BIT(5)
266#define MUTEX BIT(6)
267#define MUTEFSR BIT(7)
268#define MUTEFSX BIT(8)
269#define MUTEBADCLKR BIT(9)
270#define MUTEBADCLKX BIT(10)
271#define MUTERXDMAERR BIT(11)
272#define MUTETXDMAERR BIT(12)
273
274/*
275 * DAVINCI_MCASP_REVTCTL_REG - Receiver DMA Event Control Register bits
276 */
277#define RXDATADMADIS BIT(0)
278
279/*
280 * DAVINCI_MCASP_XEVTCTL_REG - Transmitter DMA Event Control Register bits
281 */
282#define TXDATADMADIS BIT(0)
283
284/*
285 * DAVINCI_MCASP_W[R]FIFOCTL - Write/Read FIFO Control Register bits
286 */
287#define FIFO_ENABLE BIT(16)
288#define NUMEVT_MASK (0xFF << 8)
289#define NUMDMA_MASK (0xFF)
290
291#define DAVINCI_MCASP_NUM_SERIALIZER 16
292
293static inline void mcasp_set_bits(void __iomem *reg, u32 val)
294{
295 __raw_writel(__raw_readl(reg) | val, reg);
296}
297
298static inline void mcasp_clr_bits(void __iomem *reg, u32 val)
299{
300 __raw_writel((__raw_readl(reg) & ~(val)), reg);
301}
302
303static inline void mcasp_mod_bits(void __iomem *reg, u32 val, u32 mask)
304{
305 __raw_writel((__raw_readl(reg) & ~mask) | val, reg);
306}
307
308static inline void mcasp_set_reg(void __iomem *reg, u32 val)
309{
310 __raw_writel(val, reg);
311}
312
313static inline u32 mcasp_get_reg(void __iomem *reg)
314{
315 return (unsigned int)__raw_readl(reg);
316}
317
318static inline void mcasp_set_ctl_reg(void __iomem *regs, u32 val)
319{
320 int i = 0;
321
322 mcasp_set_bits(regs, val);
323
324 /* programming GBLCTL needs to read back from GBLCTL and verfiy */
325 /* loop count is to avoid the lock-up */
326 for (i = 0; i < 1000; i++) {
327 if ((mcasp_get_reg(regs) & val) == val)
328 break;
329 }
330
331 if (i == 1000 && ((mcasp_get_reg(regs) & val) != val))
332 printk(KERN_ERR "GBLCTL write error\n");
333}
334
335static int davinci_mcasp_startup(struct snd_pcm_substream *substream,
336 struct snd_soc_dai *cpu_dai)
337{
338 struct davinci_audio_dev *dev = cpu_dai->private_data;
339 cpu_dai->dma_data = dev->dma_params[substream->stream];
340 return 0;
341}
342
343static void mcasp_start_rx(struct davinci_audio_dev *dev)
344{
345 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXHCLKRST);
346 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXCLKRST);
347 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSERCLR);
348 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
349
350 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
351 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
352 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXBUF_REG, 0);
353
354 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXSMRST);
355 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, RXFSRST);
356}
357
358static void mcasp_start_tx(struct davinci_audio_dev *dev)
359{
360 u8 offset = 0, i;
361 u32 cnt;
362
363 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXHCLKRST);
364 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXCLKRST);
365 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSERCLR);
366 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
367
368 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXSMRST);
369 mcasp_set_ctl_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, TXFSRST);
370 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
371 for (i = 0; i < dev->num_serializer; i++) {
372 if (dev->serial_dir[i] == TX_MODE) {
373 offset = i;
374 break;
375 }
376 }
377
378 /* wait for TX ready */
379 cnt = 0;
380 while (!(mcasp_get_reg(dev->base + DAVINCI_MCASP_XRSRCTL_REG(offset)) &
381 TXSTATE) && (cnt < 100000))
382 cnt++;
383
384 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXBUF_REG, 0);
385}
386
387static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream)
388{
389 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
390 mcasp_start_tx(dev);
391 else
392 mcasp_start_rx(dev);
393
394 /* enable FIFO */
395 if (dev->txnumevt)
396 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
397
398 if (dev->rxnumevt)
399 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
400}
401
402static void mcasp_stop_rx(struct davinci_audio_dev *dev)
403{
404 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLR_REG, 0);
405 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
406}
407
408static void mcasp_stop_tx(struct davinci_audio_dev *dev)
409{
410 mcasp_set_reg(dev->base + DAVINCI_MCASP_GBLCTLX_REG, 0);
411 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
412}
413
414static void davinci_mcasp_stop(struct davinci_audio_dev *dev, int stream)
415{
416 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
417 mcasp_stop_tx(dev);
418 else
419 mcasp_stop_rx(dev);
420
421 /* disable FIFO */
422 if (dev->txnumevt)
423 mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
424
425 if (dev->rxnumevt)
426 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
427}
428
429static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
430 unsigned int fmt)
431{
432 struct davinci_audio_dev *dev = cpu_dai->private_data;
433 void __iomem *base = dev->base;
434
435 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
436 case SND_SOC_DAIFMT_CBS_CFS:
437 /* codec is clock and frame slave */
438 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
439 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
440
441 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
442 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
443
444 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x7 << 26));
445 break;
446 case SND_SOC_DAIFMT_CBM_CFS:
447 /* codec is clock master and frame slave */
448 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
449 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
450
451 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
452 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
453
454 mcasp_set_bits(base + DAVINCI_MCASP_PDIR_REG, (0x2d << 26));
455 break;
456 case SND_SOC_DAIFMT_CBM_CFM:
457 /* codec is clock and frame master */
458 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXE);
459 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, AFSXE);
460
461 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRE);
462 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, AFSRE);
463
464 mcasp_clr_bits(base + DAVINCI_MCASP_PDIR_REG, (0x3f << 26));
465 break;
466
467 default:
468 return -EINVAL;
469 }
470
471 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
472 case SND_SOC_DAIFMT_IB_NF:
473 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
474 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
475
476 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
477 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
478 break;
479
480 case SND_SOC_DAIFMT_NB_IF:
481 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
482 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
483
484 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
485 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
486 break;
487
488 case SND_SOC_DAIFMT_IB_IF:
489 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
490 mcasp_set_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
491
492 mcasp_set_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
493 mcasp_set_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
494 break;
495
496 case SND_SOC_DAIFMT_NB_NF:
497 mcasp_set_bits(base + DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL);
498 mcasp_clr_bits(base + DAVINCI_MCASP_TXFMCTL_REG, FSXPOL);
499
500 mcasp_clr_bits(base + DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL);
501 mcasp_clr_bits(base + DAVINCI_MCASP_RXFMCTL_REG, FSRPOL);
502 break;
503
504 default:
505 return -EINVAL;
506 }
507
508 return 0;
509}
510
511static int davinci_config_channel_size(struct davinci_audio_dev *dev,
512 int channel_size)
513{
514 u32 fmt = 0;
515
516 switch (channel_size) {
517 case DAVINCI_AUDIO_WORD_8:
518 fmt = 0x03;
519 break;
520
521 case DAVINCI_AUDIO_WORD_12:
522 fmt = 0x05;
523 break;
524
525 case DAVINCI_AUDIO_WORD_16:
526 fmt = 0x07;
527 break;
528
529 case DAVINCI_AUDIO_WORD_20:
530 fmt = 0x09;
531 break;
532
533 case DAVINCI_AUDIO_WORD_24:
534 fmt = 0x0B;
535 break;
536
537 case DAVINCI_AUDIO_WORD_28:
538 fmt = 0x0D;
539 break;
540
541 case DAVINCI_AUDIO_WORD_32:
542 fmt = 0x0F;
543 break;
544
545 default:
546 return -EINVAL;
547 }
548
549 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMT_REG,
550 RXSSZ(fmt), RXSSZ(0x0F));
551 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
552 TXSSZ(fmt), TXSSZ(0x0F));
553 return 0;
554}
555
556static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream)
557{
558 int i;
559 u8 tx_ser = 0;
560 u8 rx_ser = 0;
561
562 /* Default configuration */
563 mcasp_set_bits(dev->base + DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT);
564
565 /* All PINS as McASP */
566 mcasp_set_reg(dev->base + DAVINCI_MCASP_PFUNC_REG, 0x00000000);
567
568 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
569 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXSTAT_REG, 0xFFFFFFFF);
570 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG,
571 TXDATADMADIS);
572 } else {
573 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXSTAT_REG, 0xFFFFFFFF);
574 mcasp_clr_bits(dev->base + DAVINCI_MCASP_REVTCTL_REG,
575 RXDATADMADIS);
576 }
577
578 for (i = 0; i < dev->num_serializer; i++) {
579 mcasp_set_bits(dev->base + DAVINCI_MCASP_XRSRCTL_REG(i),
580 dev->serial_dir[i]);
581 if (dev->serial_dir[i] == TX_MODE) {
582 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
583 AXR(i));
584 tx_ser++;
585 } else if (dev->serial_dir[i] == RX_MODE) {
586 mcasp_clr_bits(dev->base + DAVINCI_MCASP_PDIR_REG,
587 AXR(i));
588 rx_ser++;
589 }
590 }
591
592 if (dev->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) {
593 if (dev->txnumevt * tx_ser > 64)
594 dev->txnumevt = 1;
595
596 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, tx_ser,
597 NUMDMA_MASK);
598 mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL,
599 ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK);
600 mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE);
601 }
602
603 if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) {
604 if (dev->rxnumevt * rx_ser > 64)
605 dev->rxnumevt = 1;
606
607 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, rx_ser,
608 NUMDMA_MASK);
609 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL,
610 ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK);
611 mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE);
612 }
613}
614
615static void davinci_hw_param(struct davinci_audio_dev *dev, int stream)
616{
617 int i, active_slots;
618 u32 mask = 0;
619
620 active_slots = (dev->tdm_slots > 31) ? 32 : dev->tdm_slots;
621 for (i = 0; i < active_slots; i++)
622 mask |= (1 << i);
623
624 mcasp_clr_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG, TX_ASYNC);
625
626 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
627 /* bit stream is MSB first with no delay */
628 /* DSP_B mode */
629 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG,
630 AHCLKXE);
631 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, mask);
632 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG, TXORD);
633
634 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
635 mcasp_mod_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
636 FSXMOD(dev->tdm_slots), FSXMOD(0x1FF));
637 else
638 printk(KERN_ERR "playback tdm slot %d not supported\n",
639 dev->tdm_slots);
640
641 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0xFFFFFFFF);
642 mcasp_clr_bits(dev->base + DAVINCI_MCASP_TXFMCTL_REG, FSXDUR);
643 } else {
644 /* bit stream is MSB first with no delay */
645 /* DSP_B mode */
646 mcasp_set_bits(dev->base + DAVINCI_MCASP_RXFMT_REG, RXORD);
647 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKRCTL_REG,
648 AHCLKRE);
649 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXTDM_REG, mask);
650
651 if ((dev->tdm_slots >= 2) || (dev->tdm_slots <= 32))
652 mcasp_mod_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG,
653 FSRMOD(dev->tdm_slots), FSRMOD(0x1FF));
654 else
655 printk(KERN_ERR "capture tdm slot %d not supported\n",
656 dev->tdm_slots);
657
658 mcasp_set_reg(dev->base + DAVINCI_MCASP_RXMASK_REG, 0xFFFFFFFF);
659 mcasp_clr_bits(dev->base + DAVINCI_MCASP_RXFMCTL_REG, FSRDUR);
660 }
661}
662
663/* S/PDIF */
664static void davinci_hw_dit_param(struct davinci_audio_dev *dev)
665{
666 /* Set the PDIR for Serialiser as output */
667 mcasp_set_bits(dev->base + DAVINCI_MCASP_PDIR_REG, AFSX);
668
669 /* TXMASK for 24 bits */
670 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXMASK_REG, 0x00FFFFFF);
671
672 /* Set the TX format : 24 bit right rotation, 32 bit slot, Pad 0
673 and LSB first */
674 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXFMT_REG,
675 TXROT(6) | TXSSZ(15));
676
677 /* Set TX frame synch : DIT Mode, 1 bit width, internal, rising edge */
678 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXFMCTL_REG,
679 AFSXE | FSXMOD(0x180));
680
681 /* Set the TX tdm : for all the slots */
682 mcasp_set_reg(dev->base + DAVINCI_MCASP_TXTDM_REG, 0xFFFFFFFF);
683
684 /* Set the TX clock controls : div = 1 and internal */
685 mcasp_set_bits(dev->base + DAVINCI_MCASP_ACLKXCTL_REG,
686 ACLKXE | TX_ASYNC);
687
688 mcasp_clr_bits(dev->base + DAVINCI_MCASP_XEVTCTL_REG, TXDATADMADIS);
689
690 /* Only 44100 and 48000 are valid, both have the same setting */
691 mcasp_set_bits(dev->base + DAVINCI_MCASP_AHCLKXCTL_REG, AHCLKXDIV(3));
692
693 /* Enable the DIT */
694 mcasp_set_bits(dev->base + DAVINCI_MCASP_TXDITCTL_REG, DITEN);
695}
696
697static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
698 struct snd_pcm_hw_params *params,
699 struct snd_soc_dai *cpu_dai)
700{
701 struct davinci_audio_dev *dev = cpu_dai->private_data;
702 struct davinci_pcm_dma_params *dma_params =
703 dev->dma_params[substream->stream];
704 int word_length;
705 u8 numevt;
706
707 davinci_hw_common_param(dev, substream->stream);
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 numevt = dev->txnumevt;
710 else
711 numevt = dev->rxnumevt;
712
713 if (!numevt)
714 numevt = 1;
715
716 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
717 davinci_hw_dit_param(dev);
718 else
719 davinci_hw_param(dev, substream->stream);
720
721 switch (params_format(params)) {
722 case SNDRV_PCM_FORMAT_S8:
723 dma_params->data_type = 1;
724 word_length = DAVINCI_AUDIO_WORD_8;
725 break;
726
727 case SNDRV_PCM_FORMAT_S16_LE:
728 dma_params->data_type = 2;
729 word_length = DAVINCI_AUDIO_WORD_16;
730 break;
731
732 case SNDRV_PCM_FORMAT_S32_LE:
733 dma_params->data_type = 4;
734 word_length = DAVINCI_AUDIO_WORD_32;
735 break;
736
737 default:
738 printk(KERN_WARNING "davinci-mcasp: unsupported PCM format");
739 return -EINVAL;
740 }
741
742 if (dev->version == MCASP_VERSION_2) {
743 dma_params->data_type *= numevt;
744 dma_params->acnt = 4 * numevt;
745 } else
746 dma_params->acnt = dma_params->data_type;
747
748 davinci_config_channel_size(dev, word_length);
749
750 return 0;
751}
752
753static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
754 int cmd, struct snd_soc_dai *cpu_dai)
755{
756 struct snd_soc_pcm_runtime *rtd = substream->private_data;
757 struct davinci_audio_dev *dev = rtd->dai->cpu_dai->private_data;
758 int ret = 0;
759
760 switch (cmd) {
761 case SNDRV_PCM_TRIGGER_START:
762 case SNDRV_PCM_TRIGGER_RESUME:
763 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
764 davinci_mcasp_start(dev, substream->stream);
765 break;
766
767 case SNDRV_PCM_TRIGGER_STOP:
768 case SNDRV_PCM_TRIGGER_SUSPEND:
769 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
770 davinci_mcasp_stop(dev, substream->stream);
771 break;
772
773 default:
774 ret = -EINVAL;
775 }
776
777 return ret;
778}
779
780static struct snd_soc_dai_ops davinci_mcasp_dai_ops = {
781 .startup = davinci_mcasp_startup,
782 .trigger = davinci_mcasp_trigger,
783 .hw_params = davinci_mcasp_hw_params,
784 .set_fmt = davinci_mcasp_set_dai_fmt,
785
786};
787
788struct snd_soc_dai davinci_mcasp_dai[] = {
789 {
790 .name = "davinci-i2s",
791 .id = 0,
792 .playback = {
793 .channels_min = 2,
794 .channels_max = 2,
795 .rates = DAVINCI_MCASP_RATES,
796 .formats = SNDRV_PCM_FMTBIT_S8 |
797 SNDRV_PCM_FMTBIT_S16_LE |
798 SNDRV_PCM_FMTBIT_S32_LE,
799 },
800 .capture = {
801 .channels_min = 2,
802 .channels_max = 2,
803 .rates = DAVINCI_MCASP_RATES,
804 .formats = SNDRV_PCM_FMTBIT_S8 |
805 SNDRV_PCM_FMTBIT_S16_LE |
806 SNDRV_PCM_FMTBIT_S32_LE,
807 },
808 .ops = &davinci_mcasp_dai_ops,
809
810 },
811 {
812 .name = "davinci-dit",
813 .id = 1,
814 .playback = {
815 .channels_min = 1,
816 .channels_max = 384,
817 .rates = DAVINCI_MCASP_RATES,
818 .formats = SNDRV_PCM_FMTBIT_S16_LE,
819 },
820 .ops = &davinci_mcasp_dai_ops,
821 },
822
823};
824EXPORT_SYMBOL_GPL(davinci_mcasp_dai);
825
826static int davinci_mcasp_probe(struct platform_device *pdev)
827{
828 struct davinci_pcm_dma_params *dma_data;
829 struct resource *mem, *ioarea, *res;
830 struct snd_platform_data *pdata;
831 struct davinci_audio_dev *dev;
832 int count = 0;
833 int ret = 0;
834
835 dev = kzalloc(sizeof(struct davinci_audio_dev), GFP_KERNEL);
836 if (!dev)
837 return -ENOMEM;
838
839 dma_data = kzalloc(sizeof(struct davinci_pcm_dma_params) * 2,
840 GFP_KERNEL);
841 if (!dma_data) {
842 ret = -ENOMEM;
843 goto err_release_dev;
844 }
845
846 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
847 if (!mem) {
848 dev_err(&pdev->dev, "no mem resource?\n");
849 ret = -ENODEV;
850 goto err_release_data;
851 }
852
853 ioarea = request_mem_region(mem->start,
854 (mem->end - mem->start) + 1, pdev->name);
855 if (!ioarea) {
856 dev_err(&pdev->dev, "Audio region already claimed\n");
857 ret = -EBUSY;
858 goto err_release_data;
859 }
860
861 pdata = pdev->dev.platform_data;
862 dev->clk = clk_get(&pdev->dev, NULL);
863 if (IS_ERR(dev->clk)) {
864 ret = -ENODEV;
865 goto err_release_region;
866 }
867
868 clk_enable(dev->clk);
869
870 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
871 dev->op_mode = pdata->op_mode;
872 dev->tdm_slots = pdata->tdm_slots;
873 dev->num_serializer = pdata->num_serializer;
874 dev->serial_dir = pdata->serial_dir;
875 dev->codec_fmt = pdata->codec_fmt;
876 dev->version = pdata->version;
877 dev->txnumevt = pdata->txnumevt;
878 dev->rxnumevt = pdata->rxnumevt;
879
880 dma_data[count].name = "I2S PCM Stereo out";
881 dma_data[count].eventq_no = pdata->eventq_no;
882 dma_data[count].dma_addr = (dma_addr_t) (pdata->tx_dma_offset +
883 io_v2p(dev->base));
884 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK] = &dma_data[count];
885
886 /* first TX, then RX */
887 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
888 if (!res) {
889 dev_err(&pdev->dev, "no DMA resource\n");
890 goto err_release_region;
891 }
892
893 dma_data[count].channel = res->start;
894 count++;
895 dma_data[count].name = "I2S PCM Stereo in";
896 dma_data[count].eventq_no = pdata->eventq_no;
897 dma_data[count].dma_addr = (dma_addr_t)(pdata->rx_dma_offset +
898 io_v2p(dev->base));
899 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE] = &dma_data[count];
900
901 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
902 if (!res) {
903 dev_err(&pdev->dev, "no DMA resource\n");
904 goto err_release_region;
905 }
906
907 dma_data[count].channel = res->start;
908 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
909 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
910 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
911
912 if (ret != 0)
913 goto err_release_region;
914 return 0;
915
916err_release_region:
917 release_mem_region(mem->start, (mem->end - mem->start) + 1);
918err_release_data:
919 kfree(dma_data);
920err_release_dev:
921 kfree(dev);
922
923 return ret;
924}
925
926static int davinci_mcasp_remove(struct platform_device *pdev)
927{
928 struct snd_platform_data *pdata = pdev->dev.platform_data;
929 struct davinci_pcm_dma_params *dma_data;
930 struct davinci_audio_dev *dev;
931 struct resource *mem;
932
933 snd_soc_unregister_dai(&davinci_mcasp_dai[pdata->op_mode]);
934 dev = davinci_mcasp_dai[pdata->op_mode].private_data;
935 clk_disable(dev->clk);
936 clk_put(dev->clk);
937 dev->clk = NULL;
938
939 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
940 release_mem_region(mem->start, (mem->end - mem->start) + 1);
941
942 dma_data = dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK];
943 kfree(dma_data);
944 kfree(dev);
945
946 return 0;
947}
948
949static struct platform_driver davinci_mcasp_driver = {
950 .probe = davinci_mcasp_probe,
951 .remove = davinci_mcasp_remove,
952 .driver = {
953 .name = "davinci-mcasp",
954 .owner = THIS_MODULE,
955 },
956};
957
958static int __init davinci_mcasp_init(void)
959{
960 return platform_driver_register(&davinci_mcasp_driver);
961}
962module_init(davinci_mcasp_init);
963
964static void __exit davinci_mcasp_exit(void)
965{
966 platform_driver_unregister(&davinci_mcasp_driver);
967}
968module_exit(davinci_mcasp_exit);
969
970MODULE_AUTHOR("Steve Chen");
971MODULE_DESCRIPTION("TI DAVINCI McASP SoC Interface");
972MODULE_LICENSE("GPL");
973
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
new file mode 100644
index 000000000000..554354c1cc2f
--- /dev/null
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -0,0 +1,60 @@
1/*
2 * ALSA SoC McASP Audio Layer for TI DAVINCI processor
3 *
4 * MCASP related definitions
5 *
6 * Author: Nirmal Pandey <n-pandey@ti.com>,
7 * Suresh Rajashekara <suresh.r@ti.com>
8 * Steve Chen <schen@.mvista.com>
9 *
10 * Copyright: (C) 2009 MontaVista Software, Inc., <source@mvista.com>
11 * Copyright: (C) 2009 Texas Instruments, India
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 version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#ifndef DAVINCI_MCASP_H
19#define DAVINCI_MCASP_H
20
21#include <linux/io.h>
22#include <mach/asp.h>
23#include "davinci-pcm.h"
24
25extern struct snd_soc_dai davinci_mcasp_dai[];
26
27#define DAVINCI_MCASP_RATES SNDRV_PCM_RATE_8000_96000
28#define DAVINCI_MCASP_I2S_DAI 0
29#define DAVINCI_MCASP_DIT_DAI 1
30
31enum {
32 DAVINCI_AUDIO_WORD_8 = 0,
33 DAVINCI_AUDIO_WORD_12,
34 DAVINCI_AUDIO_WORD_16,
35 DAVINCI_AUDIO_WORD_20,
36 DAVINCI_AUDIO_WORD_24,
37 DAVINCI_AUDIO_WORD_32,
38 DAVINCI_AUDIO_WORD_28, /* This is only valid for McASP */
39};
40
41struct davinci_audio_dev {
42 void __iomem *base;
43 int sample_rate;
44 struct clk *clk;
45 struct davinci_pcm_dma_params *dma_params[2];
46 unsigned int codec_fmt;
47
48 /* McASP specific data */
49 int tdm_slots;
50 u8 op_mode;
51 u8 num_serializer;
52 u8 *serial_dir;
53 u8 version;
54
55 /* McASP FIFO related */
56 u8 txnumevt;
57 u8 rxnumevt;
58};
59
60#endif /* DAVINCI_MCASP_H */
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index a05996588489..091dacb78b4d 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -67,6 +67,7 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
67 dma_addr_t src, dst; 67 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 68 unsigned short src_bidx, dst_bidx;
69 unsigned int data_type; 69 unsigned int data_type;
70 unsigned short acnt;
70 unsigned int count; 71 unsigned int count;
71 72
72 period_size = snd_pcm_lib_period_bytes(substream); 73 period_size = snd_pcm_lib_period_bytes(substream);
@@ -91,11 +92,12 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
91 dst_bidx = data_type; 92 dst_bidx = data_type;
92 } 93 }
93 94
95 acnt = prtd->params->acnt;
94 edma_set_src(lch, src, INCR, W8BIT); 96 edma_set_src(lch, src, INCR, W8BIT);
95 edma_set_dest(lch, dst, INCR, W8BIT); 97 edma_set_dest(lch, dst, INCR, W8BIT);
96 edma_set_src_index(lch, src_bidx, 0); 98 edma_set_src_index(lch, src_bidx, 0);
97 edma_set_dest_index(lch, dst_bidx, 0); 99 edma_set_dest_index(lch, dst_bidx, 0);
98 edma_set_transfer_params(lch, data_type, count, 1, 0, ASYNC); 100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC);
99 101
100 prtd->period++; 102 prtd->period++;
101 if (unlikely(prtd->period >= runtime->periods)) 103 if (unlikely(prtd->period >= runtime->periods))
@@ -206,6 +208,7 @@ static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
206 /* Copy self-linked parameter RAM entry into master channel */ 208 /* Copy self-linked parameter RAM entry into master channel */
207 edma_read_slot(prtd->slave_lch, &temp); 209 edma_read_slot(prtd->slave_lch, &temp);
208 edma_write_slot(prtd->master_lch, &temp); 210 edma_write_slot(prtd->master_lch, &temp);
211 davinci_pcm_enqueue_dma(substream);
209 212
210 return 0; 213 return 0;
211} 214}
@@ -243,6 +246,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
243 int ret = 0; 246 int ret = 0;
244 247
245 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); 248 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware);
249 /* ensure that buffer size is a multiple of period size */
250 ret = snd_pcm_hw_constraint_integer(runtime,
251 SNDRV_PCM_HW_PARAM_PERIODS);
252 if (ret < 0)
253 return ret;
246 254
247 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL); 255 prtd = kzalloc(sizeof(struct davinci_runtime_data), GFP_KERNEL);
248 if (prtd == NULL) 256 if (prtd == NULL)
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 62cb4eb07e34..63d96253c73a 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -12,17 +12,20 @@
12#ifndef _DAVINCI_PCM_H 12#ifndef _DAVINCI_PCM_H
13#define _DAVINCI_PCM_H 13#define _DAVINCI_PCM_H
14 14
15#include <mach/edma.h>
16#include <mach/asp.h>
17
18
15struct davinci_pcm_dma_params { 19struct davinci_pcm_dma_params {
16 char *name; /* stream identifier */ 20 char *name; /* stream identifier */
17 int channel; /* sync dma channel ID */ 21 int channel; /* sync dma channel ID */
18 dma_addr_t dma_addr; /* device physical address for DMA */ 22 unsigned short acnt;
19 unsigned int data_type; /* xfer data type */ 23 dma_addr_t dma_addr; /* device physical address for DMA */
24 enum dma_event_q eventq_no; /* event queue number */
25 unsigned char data_type; /* xfer data type */
26 unsigned char convert_mono_stereo;
20}; 27};
21 28
22struct evm_snd_platform_data {
23 int tx_dma_ch;
24 int rx_dma_ch;
25};
26 29
27extern struct snd_soc_platform davinci_soc_platform; 30extern struct snd_soc_platform davinci_soc_platform;
28 31
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index f0a2d4071998..9ff62e3a9b1d 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -69,6 +69,23 @@ static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
69 69
70static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s) 70static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s)
71{ 71{
72 if (s->appl_ptr > s->runtime->control->appl_ptr) {
73 /*
74 * In this case s->runtime->control->appl_ptr has wrapped around.
75 * Play the data to the end of the boundary, then wrap our own
76 * appl_ptr back around.
77 */
78 while (s->appl_ptr < s->runtime->boundary) {
79 if (bcom_queue_full(s->bcom_task))
80 return;
81
82 s->appl_ptr += s->period_size;
83
84 psc_dma_bcom_enqueue_next_buffer(s);
85 }
86 s->appl_ptr -= s->runtime->boundary;
87 }
88
72 while (s->appl_ptr < s->runtime->control->appl_ptr) { 89 while (s->appl_ptr < s->runtime->control->appl_ptr) {
73 90
74 if (bcom_queue_full(s->bcom_task)) 91 if (bcom_queue_full(s->bcom_task))
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 7eb549985d49..c4ae3e096bb9 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -12,6 +12,7 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of_device.h> 13#include <linux/of_device.h>
14#include <linux/of_platform.h> 14#include <linux/of_platform.h>
15#include <linux/delay.h>
15 16
16#include <sound/pcm.h> 17#include <sound/pcm.h>
17#include <sound/pcm_params.h> 18#include <sound/pcm_params.h>
@@ -112,7 +113,7 @@ static void psc_ac97_cold_reset(struct snd_ac97 *ac97)
112 out_8(&regs->op1, MPC52xx_PSC_OP_RES); 113 out_8(&regs->op1, MPC52xx_PSC_OP_RES);
113 udelay(10); 114 udelay(10);
114 out_8(&regs->op0, MPC52xx_PSC_OP_RES); 115 out_8(&regs->op0, MPC52xx_PSC_OP_RES);
115 udelay(50); 116 msleep(1);
116 psc_ac97_warm_reset(ac97); 117 psc_ac97_warm_reset(ac97);
117} 118}
118 119
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
new file mode 100644
index 000000000000..a700562e8692
--- /dev/null
+++ b/sound/soc/imx/Kconfig
@@ -0,0 +1,21 @@
1config SND_MX1_MX2_SOC
2 tristate "SoC Audio for Freecale i.MX1x i.MX2x CPUs"
3 depends on ARCH_MX2 || ARCH_MX1
4 select SND_PCM
5 help
6 Say Y or M if you want to add support for codecs attached to
7 the MX1 or MX2 SSI interface.
8
9config SND_MXC_SOC_SSI
10 tristate
11
12config SND_SOC_MX27VIS_WM8974
13 tristate "SoC Audio support for MX27 - WM8974 Visstrim_sm10 board"
14 depends on SND_MX1_MX2_SOC && MACH_MX27 && MACH_IMX27_VISSTRIM_M10
15 select SND_MXC_SOC_SSI
16 select SND_SOC_WM8974
17 help
18 Say Y if you want to add support for SoC audio on Visstrim SM10
19 board with WM8974.
20
21
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
new file mode 100644
index 000000000000..c2ffd2c8df5a
--- /dev/null
+++ b/sound/soc/imx/Makefile
@@ -0,0 +1,10 @@
1# i.MX Platform Support
2snd-soc-mx1_mx2-objs := mx1_mx2-pcm.o
3snd-soc-mxc-ssi-objs := mxc-ssi.o
4
5obj-$(CONFIG_SND_MX1_MX2_SOC) += snd-soc-mx1_mx2.o
6obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-mxc-ssi.o
7
8# i.MX Machine Support
9snd-soc-mx27vis-wm8974-objs := mx27vis_wm8974.o
10obj-$(CONFIG_SND_SOC_MX27VIS_WM8974) += snd-soc-mx27vis-wm8974.o
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
new file mode 100644
index 000000000000..b83866529397
--- /dev/null
+++ b/sound/soc/imx/mx1_mx2-pcm.c
@@ -0,0 +1,488 @@
1/*
2 * mx1_mx2-pcm.c -- ALSA SoC interface for Freescale i.MX1x, i.MX2x CPUs
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * javier.martin@vista-silicon.com
7 *
8 * Based on mxc-pcm.c by Liam Girdwood.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 *
15 */
16
17#include <linux/module.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/slab.h>
21#include <linux/dma-mapping.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <asm/dma.h>
27#include <mach/hardware.h>
28#include <mach/dma-mx1-mx2.h>
29
30#include "mx1_mx2-pcm.h"
31
32
33static const struct snd_pcm_hardware mx1_mx2_pcm_hardware = {
34 .info = (SNDRV_PCM_INFO_INTERLEAVED |
35 SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP |
37 SNDRV_PCM_INFO_MMAP_VALID),
38 .formats = SNDRV_PCM_FMTBIT_S16_LE,
39 .buffer_bytes_max = 32 * 1024,
40 .period_bytes_min = 64,
41 .period_bytes_max = 8 * 1024,
42 .periods_min = 2,
43 .periods_max = 255,
44 .fifo_size = 0,
45};
46
47struct mx1_mx2_runtime_data {
48 int dma_ch;
49 int active;
50 unsigned int period;
51 unsigned int periods;
52 int tx_spin;
53 spinlock_t dma_lock;
54 struct mx1_mx2_pcm_dma_params *dma_params;
55};
56
57
58/**
59 * This function stops the current dma transfer for playback
60 * and clears the dma pointers.
61 *
62 * @param substream pointer to the structure of the current stream.
63 *
64 */
65static int audio_stop_dma(struct snd_pcm_substream *substream)
66{
67 struct snd_pcm_runtime *runtime = substream->runtime;
68 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
69 unsigned long flags;
70
71 spin_lock_irqsave(&prtd->dma_lock, flags);
72
73 pr_debug("%s\n", __func__);
74
75 prtd->active = 0;
76 prtd->period = 0;
77 prtd->periods = 0;
78
79 /* this stops the dma channel and clears the buffer ptrs */
80
81 imx_dma_disable(prtd->dma_ch);
82
83 spin_unlock_irqrestore(&prtd->dma_lock, flags);
84
85 return 0;
86}
87
88/**
89 * This function is called whenever a new audio block needs to be
90 * transferred to the codec. The function receives the address and the size
91 * of the new block and start a new DMA transfer.
92 *
93 * @param substream pointer to the structure of the current stream.
94 *
95 */
96static int dma_new_period(struct snd_pcm_substream *substream)
97{
98 struct snd_pcm_runtime *runtime = substream->runtime;
99 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
100 unsigned int dma_size;
101 unsigned int offset;
102 int ret = 0;
103 dma_addr_t mem_addr;
104 unsigned int dev_addr;
105
106 if (prtd->active) {
107 dma_size = frames_to_bytes(runtime, runtime->period_size);
108 offset = dma_size * prtd->period;
109
110 pr_debug("%s: period (%d) out of (%d)\n", __func__,
111 prtd->period,
112 runtime->periods);
113 pr_debug("period_size %d frames\n offset %d bytes\n",
114 (unsigned int)runtime->period_size,
115 offset);
116 pr_debug("dma_size %d bytes\n", dma_size);
117
118 snd_BUG_ON(dma_size > mx1_mx2_pcm_hardware.period_bytes_max);
119
120 mem_addr = (dma_addr_t)(runtime->dma_addr + offset);
121 dev_addr = prtd->dma_params->per_address;
122 pr_debug("%s: mem_addr is %x\n dev_addr is %x\n",
123 __func__, mem_addr, dev_addr);
124
125 ret = imx_dma_setup_single(prtd->dma_ch, mem_addr,
126 dma_size, dev_addr,
127 prtd->dma_params->transfer_type);
128 if (ret < 0) {
129 printk(KERN_ERR "Error %d configuring DMA\n", ret);
130 return ret;
131 }
132 imx_dma_enable(prtd->dma_ch);
133
134 pr_debug("%s: transfer enabled\nmem_addr = %x\n",
135 __func__, (unsigned int) mem_addr);
136 pr_debug("dev_addr = %x\ndma_size = %d\n",
137 (unsigned int) dev_addr, dma_size);
138
139 prtd->tx_spin = 1; /* FGA little trick to retrieve DMA pos */
140 prtd->period++;
141 prtd->period %= runtime->periods;
142 }
143 return ret;
144}
145
146
147/**
148 * This is a callback which will be called
149 * when a TX transfer finishes. The call occurs
150 * in interrupt context.
151 *
152 * @param dat pointer to the structure of the current stream.
153 *
154 */
155static void audio_dma_irq(int channel, void *data)
156{
157 struct snd_pcm_substream *substream;
158 struct snd_pcm_runtime *runtime;
159 struct mx1_mx2_runtime_data *prtd;
160 unsigned int dma_size;
161 unsigned int previous_period;
162 unsigned int offset;
163
164 substream = data;
165 runtime = substream->runtime;
166 prtd = runtime->private_data;
167 previous_period = prtd->periods;
168 dma_size = frames_to_bytes(runtime, runtime->period_size);
169 offset = dma_size * previous_period;
170
171 prtd->tx_spin = 0;
172 prtd->periods++;
173 prtd->periods %= runtime->periods;
174
175 pr_debug("%s: irq per %d offset %x\n", __func__, prtd->periods, offset);
176
177 /*
178 * If we are getting a callback for an active stream then we inform
179 * the PCM middle layer we've finished a period
180 */
181 if (prtd->active)
182 snd_pcm_period_elapsed(substream);
183
184 /*
185 * Trig next DMA transfer
186 */
187 dma_new_period(substream);
188}
189
190/**
191 * This function configures the hardware to allow audio
192 * playback operations. It is called by ALSA framework.
193 *
194 * @param substream pointer to the structure of the current stream.
195 *
196 * @return 0 on success, -1 otherwise.
197 */
198static int
199snd_mx1_mx2_prepare(struct snd_pcm_substream *substream)
200{
201 struct snd_pcm_runtime *runtime = substream->runtime;
202 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
203
204 prtd->period = 0;
205 prtd->periods = 0;
206
207 return 0;
208}
209
210static int mx1_mx2_pcm_hw_params(struct snd_pcm_substream *substream,
211 struct snd_pcm_hw_params *hw_params)
212{
213 struct snd_pcm_runtime *runtime = substream->runtime;
214 int ret;
215
216 ret = snd_pcm_lib_malloc_pages(substream,
217 params_buffer_bytes(hw_params));
218 if (ret < 0) {
219 printk(KERN_ERR "%s: Error %d failed to malloc pcm pages \n",
220 __func__, ret);
221 return ret;
222 }
223
224 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_addr 0x(%x)\n",
225 __func__, (unsigned int)runtime->dma_addr);
226 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_area 0x(%x)\n",
227 __func__, (unsigned int)runtime->dma_area);
228 pr_debug("%s: snd_imx1_mx2_audio_hw_params runtime->dma_bytes 0x(%x)\n",
229 __func__, (unsigned int)runtime->dma_bytes);
230
231 return ret;
232}
233
234static int mx1_mx2_pcm_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_pcm_runtime *runtime = substream->runtime;
237 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
238
239 imx_dma_free(prtd->dma_ch);
240
241 snd_pcm_lib_free_pages(substream);
242
243 return 0;
244}
245
246static int mx1_mx2_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
247{
248 struct mx1_mx2_runtime_data *prtd = substream->runtime->private_data;
249 int ret = 0;
250
251 switch (cmd) {
252 case SNDRV_PCM_TRIGGER_START:
253 prtd->tx_spin = 0;
254 /* requested stream startup */
255 prtd->active = 1;
256 pr_debug("%s: starting dma_new_period\n", __func__);
257 ret = dma_new_period(substream);
258 break;
259 case SNDRV_PCM_TRIGGER_STOP:
260 /* requested stream shutdown */
261 pr_debug("%s: stopping dma transfer\n", __func__);
262 ret = audio_stop_dma(substream);
263 break;
264 default:
265 ret = -EINVAL;
266 break;
267 }
268
269 return ret;
270}
271
272static snd_pcm_uframes_t
273mx1_mx2_pcm_pointer(struct snd_pcm_substream *substream)
274{
275 struct snd_pcm_runtime *runtime = substream->runtime;
276 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
277 unsigned int offset = 0;
278
279 /* tx_spin value is used here to check if a transfer is active */
280 if (prtd->tx_spin) {
281 offset = (runtime->period_size * (prtd->periods)) +
282 (runtime->period_size >> 1);
283 if (offset >= runtime->buffer_size)
284 offset = runtime->period_size >> 1;
285 } else {
286 offset = (runtime->period_size * (prtd->periods));
287 if (offset >= runtime->buffer_size)
288 offset = 0;
289 }
290 pr_debug("%s: pointer offset %x\n", __func__, offset);
291
292 return offset;
293}
294
295static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
296{
297 struct snd_pcm_runtime *runtime = substream->runtime;
298 struct mx1_mx2_runtime_data *prtd;
299 struct snd_soc_pcm_runtime *rtd = substream->private_data;
300 struct mx1_mx2_pcm_dma_params *dma_data = rtd->dai->cpu_dai->dma_data;
301 int ret;
302
303 snd_soc_set_runtime_hwparams(substream, &mx1_mx2_pcm_hardware);
304
305 ret = snd_pcm_hw_constraint_integer(runtime,
306 SNDRV_PCM_HW_PARAM_PERIODS);
307 if (ret < 0)
308 return ret;
309
310 prtd = kzalloc(sizeof(struct mx1_mx2_runtime_data), GFP_KERNEL);
311 if (prtd == NULL) {
312 ret = -ENOMEM;
313 goto out;
314 }
315
316 runtime->private_data = prtd;
317
318 if (!dma_data)
319 return -ENODEV;
320
321 prtd->dma_params = dma_data;
322
323 pr_debug("%s: Requesting dma channel (%s)\n", __func__,
324 prtd->dma_params->name);
325 prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name,
326 DMA_PRIO_HIGH);
327 if (prtd->dma_ch < 0) {
328 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
329 return ret;
330 }
331 imx_dma_config_burstlen(prtd->dma_ch,
332 prtd->dma_params->watermark_level);
333
334 ret = imx_dma_config_channel(prtd->dma_ch,
335 prtd->dma_params->per_config,
336 prtd->dma_params->mem_config,
337 prtd->dma_params->event_id, 0);
338
339 if (ret) {
340 pr_debug(KERN_ERR "Error %d configuring dma channel %d\n",
341 ret, prtd->dma_ch);
342 return ret;
343 }
344
345 pr_debug("%s: Setting tx dma callback function\n", __func__);
346 ret = imx_dma_setup_handlers(prtd->dma_ch,
347 audio_dma_irq, NULL,
348 (void *)substream);
349 if (ret < 0) {
350 printk(KERN_ERR "Error %d setting dma callback function\n", ret);
351 return ret;
352 }
353 return 0;
354
355 out:
356 return ret;
357}
358
359static int mx1_mx2_pcm_close(struct snd_pcm_substream *substream)
360{
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 struct mx1_mx2_runtime_data *prtd = runtime->private_data;
363
364 kfree(prtd);
365
366 return 0;
367}
368
369static int mx1_mx2_pcm_mmap(struct snd_pcm_substream *substream,
370 struct vm_area_struct *vma)
371{
372 struct snd_pcm_runtime *runtime = substream->runtime;
373 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
374 runtime->dma_area,
375 runtime->dma_addr,
376 runtime->dma_bytes);
377}
378
379static struct snd_pcm_ops mx1_mx2_pcm_ops = {
380 .open = mx1_mx2_pcm_open,
381 .close = mx1_mx2_pcm_close,
382 .ioctl = snd_pcm_lib_ioctl,
383 .hw_params = mx1_mx2_pcm_hw_params,
384 .hw_free = mx1_mx2_pcm_hw_free,
385 .prepare = snd_mx1_mx2_prepare,
386 .trigger = mx1_mx2_pcm_trigger,
387 .pointer = mx1_mx2_pcm_pointer,
388 .mmap = mx1_mx2_pcm_mmap,
389};
390
391static u64 mx1_mx2_pcm_dmamask = 0xffffffff;
392
393static int mx1_mx2_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
394{
395 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
396 struct snd_dma_buffer *buf = &substream->dma_buffer;
397 size_t size = mx1_mx2_pcm_hardware.buffer_bytes_max;
398 buf->dev.type = SNDRV_DMA_TYPE_DEV;
399 buf->dev.dev = pcm->card->dev;
400 buf->private_data = NULL;
401
402 /* Reserve uncached-buffered memory area for DMA */
403 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
404 &buf->addr, GFP_KERNEL);
405
406 pr_debug("%s: preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
407 __func__, (void *) buf->area, (void *) buf->addr, size);
408
409 if (!buf->area)
410 return -ENOMEM;
411
412 buf->bytes = size;
413 return 0;
414}
415
416static void mx1_mx2_pcm_free_dma_buffers(struct snd_pcm *pcm)
417{
418 struct snd_pcm_substream *substream;
419 struct snd_dma_buffer *buf;
420 int stream;
421
422 for (stream = 0; stream < 2; stream++) {
423 substream = pcm->streams[stream].substream;
424 if (!substream)
425 continue;
426
427 buf = &substream->dma_buffer;
428 if (!buf->area)
429 continue;
430
431 dma_free_writecombine(pcm->card->dev, buf->bytes,
432 buf->area, buf->addr);
433 buf->area = NULL;
434 }
435}
436
437static int mx1_mx2_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
438 struct snd_pcm *pcm)
439{
440 int ret = 0;
441
442 if (!card->dev->dma_mask)
443 card->dev->dma_mask = &mx1_mx2_pcm_dmamask;
444 if (!card->dev->coherent_dma_mask)
445 card->dev->coherent_dma_mask = 0xffffffff;
446
447 if (dai->playback.channels_min) {
448 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
449 SNDRV_PCM_STREAM_PLAYBACK);
450 pr_debug("%s: preallocate playback buffer\n", __func__);
451 if (ret)
452 goto out;
453 }
454
455 if (dai->capture.channels_min) {
456 ret = mx1_mx2_pcm_preallocate_dma_buffer(pcm,
457 SNDRV_PCM_STREAM_CAPTURE);
458 pr_debug("%s: preallocate capture buffer\n", __func__);
459 if (ret)
460 goto out;
461 }
462 out:
463 return ret;
464}
465
466struct snd_soc_platform mx1_mx2_soc_platform = {
467 .name = "mx1_mx2-audio",
468 .pcm_ops = &mx1_mx2_pcm_ops,
469 .pcm_new = mx1_mx2_pcm_new,
470 .pcm_free = mx1_mx2_pcm_free_dma_buffers,
471};
472EXPORT_SYMBOL_GPL(mx1_mx2_soc_platform);
473
474static int __init mx1_mx2_soc_platform_init(void)
475{
476 return snd_soc_register_platform(&mx1_mx2_soc_platform);
477}
478module_init(mx1_mx2_soc_platform_init);
479
480static void __exit mx1_mx2_soc_platform_exit(void)
481{
482 snd_soc_unregister_platform(&mx1_mx2_soc_platform);
483}
484module_exit(mx1_mx2_soc_platform_exit);
485
486MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
487MODULE_DESCRIPTION("Freescale i.MX2x, i.MX1x PCM DMA module");
488MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mx1_mx2-pcm.h b/sound/soc/imx/mx1_mx2-pcm.h
new file mode 100644
index 000000000000..2e528106570b
--- /dev/null
+++ b/sound/soc/imx/mx1_mx2-pcm.h
@@ -0,0 +1,26 @@
1/*
2 * mx1_mx2-pcm.h :- ASoC platform header for Freescale i.MX1x, i.MX2x
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 _MX1_MX2_PCM_H
10#define _MX1_MX2_PCM_H
11
12/* DMA information for mx1_mx2 platforms */
13struct mx1_mx2_pcm_dma_params {
14 char *name; /* stream identifier */
15 unsigned int transfer_type; /* READ or WRITE DMA transfer */
16 dma_addr_t per_address; /* physical address of SSI fifo */
17 int event_id; /* fixed DMA number for SSI fifo */
18 int watermark_level; /* SSI fifo watermark level */
19 int per_config; /* DMA Config flags for peripheral */
20 int mem_config; /* DMA Config flags for RAM */
21 };
22
23/* platform data */
24extern struct snd_soc_platform mx1_mx2_soc_platform;
25
26#endif
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
new file mode 100644
index 000000000000..e4dcb539108a
--- /dev/null
+++ b/sound/soc/imx/mx27vis_wm8974.c
@@ -0,0 +1,317 @@
1/*
2 * mx27vis_wm8974.c -- SoC audio for mx27vis
3 *
4 * Copyright 2009 Vista Silicon S.L.
5 * Author: Javier Martin
6 * javier.martin@vista-silicon.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/device.h>
18#include <linux/i2c.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24
25#include "../codecs/wm8974.h"
26#include "mx1_mx2-pcm.h"
27#include "mxc-ssi.h"
28#include <mach/gpio.h>
29#include <mach/iomux.h>
30
31#define IGNORED_ARG 0
32
33
34static struct snd_soc_card mx27vis;
35
36/**
37 * This function connects SSI1 (HPCR1) as slave to
38 * SSI1 external signals (PPCR1)
39 * As slave, HPCR1 must set TFSDIR and TCLKDIR as inputs from
40 * port 4
41 */
42void audmux_connect_1_4(void)
43{
44 pr_debug("AUDMUX: normal operation mode\n");
45 /* Reset HPCR1 and PPCR1 */
46
47 DAM_HPCR1 = 0x00000000;
48 DAM_PPCR1 = 0x00000000;
49
50 /* set to synchronous */
51 DAM_HPCR1 |= AUDMUX_HPCR_SYN;
52 DAM_PPCR1 |= AUDMUX_PPCR_SYN;
53
54
55 /* set Rx sources 1 <--> 4 */
56 DAM_HPCR1 |= AUDMUX_HPCR_RXDSEL(3); /* port 4 */
57 DAM_PPCR1 |= AUDMUX_PPCR_RXDSEL(0); /* port 1 */
58
59 /* set Tx frame and Clock direction and source 4 --> 1 output */
60 DAM_HPCR1 |= AUDMUX_HPCR_TFSDIR | AUDMUX_HPCR_TCLKDIR;
61 DAM_HPCR1 |= AUDMUX_HPCR_TFCSEL(3); /* TxDS and TxCclk from port 4 */
62
63 return;
64}
65
66static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
67 struct snd_pcm_hw_params *params)
68{
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
71 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
72 unsigned int pll_out = 0, bclk = 0, fmt = 0, mclk = 0;
73 int ret = 0;
74
75 /*
76 * The WM8974 is better at generating accurate audio clocks than the
77 * MX27 SSI controller, so we will use it as master when we can.
78 */
79 switch (params_rate(params)) {
80 case 8000:
81 fmt = SND_SOC_DAIFMT_CBM_CFM;
82 mclk = WM8974_MCLKDIV_12;
83 pll_out = 24576000;
84 break;
85 case 16000:
86 fmt = SND_SOC_DAIFMT_CBM_CFM;
87 pll_out = 12288000;
88 break;
89 case 48000:
90 fmt = SND_SOC_DAIFMT_CBM_CFM;
91 bclk = WM8974_BCLKDIV_4;
92 pll_out = 12288000;
93 break;
94 case 96000:
95 fmt = SND_SOC_DAIFMT_CBM_CFM;
96 bclk = WM8974_BCLKDIV_2;
97 pll_out = 12288000;
98 break;
99 case 11025:
100 fmt = SND_SOC_DAIFMT_CBM_CFM;
101 bclk = WM8974_BCLKDIV_16;
102 pll_out = 11289600;
103 break;
104 case 22050:
105 fmt = SND_SOC_DAIFMT_CBM_CFM;
106 bclk = WM8974_BCLKDIV_8;
107 pll_out = 11289600;
108 break;
109 case 44100:
110 fmt = SND_SOC_DAIFMT_CBM_CFM;
111 bclk = WM8974_BCLKDIV_4;
112 mclk = WM8974_MCLKDIV_2;
113 pll_out = 11289600;
114 break;
115 case 88200:
116 fmt = SND_SOC_DAIFMT_CBM_CFM;
117 bclk = WM8974_BCLKDIV_2;
118 pll_out = 11289600;
119 break;
120 }
121
122 /* set codec DAI configuration */
123 ret = codec_dai->ops->set_fmt(codec_dai,
124 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF |
125 SND_SOC_DAIFMT_SYNC | fmt);
126 if (ret < 0) {
127 printk(KERN_ERR "Error from codec DAI configuration\n");
128 return ret;
129 }
130
131 /* set cpu DAI configuration */
132 ret = cpu_dai->ops->set_fmt(cpu_dai,
133 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
134 SND_SOC_DAIFMT_SYNC | fmt);
135 if (ret < 0) {
136 printk(KERN_ERR "Error from cpu DAI configuration\n");
137 return ret;
138 }
139
140 /* Put DC field of STCCR to 1 (not zero) */
141 ret = cpu_dai->ops->set_tdm_slot(cpu_dai, 0, 2);
142
143 /* set the SSI system clock as input */
144 ret = cpu_dai->ops->set_sysclk(cpu_dai, IMX_SSP_SYS_CLK, 0,
145 SND_SOC_CLOCK_IN);
146 if (ret < 0) {
147 printk(KERN_ERR "Error when setting system SSI clk\n");
148 return ret;
149 }
150
151 /* set codec BCLK division for sample rate */
152 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_BCLKDIV, bclk);
153 if (ret < 0) {
154 printk(KERN_ERR "Error when setting BCLK division\n");
155 return ret;
156 }
157
158
159 /* codec PLL input is 25 MHz */
160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG,
161 25000000, pll_out);
162 if (ret < 0) {
163 printk(KERN_ERR "Error when setting PLL input\n");
164 return ret;
165 }
166
167 /*set codec MCLK division for sample rate */
168 ret = codec_dai->ops->set_clkdiv(codec_dai, WM8974_MCLKDIV, mclk);
169 if (ret < 0) {
170 printk(KERN_ERR "Error when setting MCLK division\n");
171 return ret;
172 }
173
174 return 0;
175}
176
177static int mx27vis_hifi_hw_free(struct snd_pcm_substream *substream)
178{
179 struct snd_soc_pcm_runtime *rtd = substream->private_data;
180 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
181
182 /* disable the PLL */
183 return codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 0, 0);
184}
185
186/*
187 * mx27vis WM8974 HiFi DAI opserations.
188 */
189static struct snd_soc_ops mx27vis_hifi_ops = {
190 .hw_params = mx27vis_hifi_hw_params,
191 .hw_free = mx27vis_hifi_hw_free,
192};
193
194
195static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
196{
197 return 0;
198}
199
200static int mx27vis_resume(struct platform_device *pdev)
201{
202 return 0;
203}
204
205static int mx27vis_probe(struct platform_device *pdev)
206{
207 int ret = 0;
208
209 ret = get_ssi_clk(0, &pdev->dev);
210
211 if (ret < 0) {
212 printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
213 return ret;
214 }
215
216
217 return 0;
218}
219
220static int mx27vis_remove(struct platform_device *pdev)
221{
222 put_ssi_clk(0);
223 return 0;
224}
225
226static struct snd_soc_dai_link mx27vis_dai[] = {
227{ /* Hifi Playback*/
228 .name = "WM8974",
229 .stream_name = "WM8974 HiFi",
230 .cpu_dai = &imx_ssi_pcm_dai[0],
231 .codec_dai = &wm8974_dai,
232 .ops = &mx27vis_hifi_ops,
233},
234};
235
236static struct snd_soc_card mx27vis = {
237 .name = "mx27vis",
238 .platform = &mx1_mx2_soc_platform,
239 .probe = mx27vis_probe,
240 .remove = mx27vis_remove,
241 .suspend_pre = mx27vis_suspend,
242 .resume_post = mx27vis_resume,
243 .dai_link = mx27vis_dai,
244 .num_links = ARRAY_SIZE(mx27vis_dai),
245};
246
247static struct snd_soc_device mx27vis_snd_devdata = {
248 .card = &mx27vis,
249 .codec_dev = &soc_codec_dev_wm8974,
250};
251
252static struct platform_device *mx27vis_snd_device;
253
254/* Temporal definition of board specific behaviour */
255void gpio_ssi_active(int ssi_num)
256{
257 int ret = 0;
258
259 unsigned int ssi1_pins[] = {
260 PC20_PF_SSI1_FS,
261 PC21_PF_SSI1_RXD,
262 PC22_PF_SSI1_TXD,
263 PC23_PF_SSI1_CLK,
264 };
265 unsigned int ssi2_pins[] = {
266 PC24_PF_SSI2_FS,
267 PC25_PF_SSI2_RXD,
268 PC26_PF_SSI2_TXD,
269 PC27_PF_SSI2_CLK,
270 };
271 if (ssi_num == 0)
272 ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
273 ARRAY_SIZE(ssi1_pins), "USB OTG");
274 else
275 ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
276 ARRAY_SIZE(ssi2_pins), "USB OTG");
277 if (ret)
278 printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
279}
280
281
282static int __init mx27vis_init(void)
283{
284 int ret;
285
286 mx27vis_snd_device = platform_device_alloc("soc-audio", -1);
287 if (!mx27vis_snd_device)
288 return -ENOMEM;
289
290 platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
291 mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
292 ret = platform_device_add(mx27vis_snd_device);
293
294 if (ret) {
295 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
296 platform_device_put(mx27vis_snd_device);
297 }
298
299 /* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
300 gpio_ssi_active(0);
301 audmux_connect_1_4();
302
303 return ret;
304}
305
306static void __exit mx27vis_exit(void)
307{
308 /* We should call some "ssi_gpio_inactive()" properly */
309}
310
311module_init(mx27vis_init);
312module_exit(mx27vis_exit);
313
314
315MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
316MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
317MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
new file mode 100644
index 000000000000..3806ff2c0cd4
--- /dev/null
+++ b/sound/soc/imx/mxc-ssi.c
@@ -0,0 +1,868 @@
1/*
2 * mxc-ssi.c -- SSI driver for Freescale IMX
3 *
4 * Copyright 2006 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * Based on mxc-alsa-mc13783 (C) 2006 Freescale.
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 * TODO:
16 * Need to rework SSI register defs when new defs go into mainline.
17 * Add support for TDM and FIFO 1.
18 * Add support for i.mx3x DMA interface.
19 *
20 */
21
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/platform_device.h>
26#include <linux/slab.h>
27#include <linux/dma-mapping.h>
28#include <linux/clk.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/soc.h>
33#include <mach/dma-mx1-mx2.h>
34#include <asm/mach-types.h>
35
36#include "mxc-ssi.h"
37#include "mx1_mx2-pcm.h"
38
39#define SSI1_PORT 0
40#define SSI2_PORT 1
41
42static int ssi_active[2] = {0, 0};
43
44/* DMA information for mx1_mx2 platforms */
45static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out0 = {
46 .name = "SSI1 PCM Stereo out 0",
47 .transfer_type = DMA_MODE_WRITE,
48 .per_address = SSI1_BASE_ADDR + STX0,
49 .event_id = DMA_REQ_SSI1_TX0,
50 .watermark_level = TXFIFO_WATERMARK,
51 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
52 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
53};
54
55static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_out1 = {
56 .name = "SSI1 PCM Stereo out 1",
57 .transfer_type = DMA_MODE_WRITE,
58 .per_address = SSI1_BASE_ADDR + STX1,
59 .event_id = DMA_REQ_SSI1_TX1,
60 .watermark_level = TXFIFO_WATERMARK,
61 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
62 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
63};
64
65static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in0 = {
66 .name = "SSI1 PCM Stereo in 0",
67 .transfer_type = DMA_MODE_READ,
68 .per_address = SSI1_BASE_ADDR + SRX0,
69 .event_id = DMA_REQ_SSI1_RX0,
70 .watermark_level = RXFIFO_WATERMARK,
71 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
72 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
73};
74
75static struct mx1_mx2_pcm_dma_params imx_ssi1_pcm_stereo_in1 = {
76 .name = "SSI1 PCM Stereo in 1",
77 .transfer_type = DMA_MODE_READ,
78 .per_address = SSI1_BASE_ADDR + SRX1,
79 .event_id = DMA_REQ_SSI1_RX1,
80 .watermark_level = RXFIFO_WATERMARK,
81 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
82 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
83};
84
85static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out0 = {
86 .name = "SSI2 PCM Stereo out 0",
87 .transfer_type = DMA_MODE_WRITE,
88 .per_address = SSI2_BASE_ADDR + STX0,
89 .event_id = DMA_REQ_SSI2_TX0,
90 .watermark_level = TXFIFO_WATERMARK,
91 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
92 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
93};
94
95static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_out1 = {
96 .name = "SSI2 PCM Stereo out 1",
97 .transfer_type = DMA_MODE_WRITE,
98 .per_address = SSI2_BASE_ADDR + STX1,
99 .event_id = DMA_REQ_SSI2_TX1,
100 .watermark_level = TXFIFO_WATERMARK,
101 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
102 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
103};
104
105static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in0 = {
106 .name = "SSI2 PCM Stereo in 0",
107 .transfer_type = DMA_MODE_READ,
108 .per_address = SSI2_BASE_ADDR + SRX0,
109 .event_id = DMA_REQ_SSI2_RX0,
110 .watermark_level = RXFIFO_WATERMARK,
111 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113};
114
115static struct mx1_mx2_pcm_dma_params imx_ssi2_pcm_stereo_in1 = {
116 .name = "SSI2 PCM Stereo in 1",
117 .transfer_type = DMA_MODE_READ,
118 .per_address = SSI2_BASE_ADDR + SRX1,
119 .event_id = DMA_REQ_SSI2_RX1,
120 .watermark_level = RXFIFO_WATERMARK,
121 .per_config = IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
122 .mem_config = IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
123};
124
125static struct clk *ssi_clk0, *ssi_clk1;
126
127int get_ssi_clk(int ssi, struct device *dev)
128{
129 switch (ssi) {
130 case 0:
131 ssi_clk0 = clk_get(dev, "ssi1");
132 if (IS_ERR(ssi_clk0))
133 return PTR_ERR(ssi_clk0);
134 return 0;
135 case 1:
136 ssi_clk1 = clk_get(dev, "ssi2");
137 if (IS_ERR(ssi_clk1))
138 return PTR_ERR(ssi_clk1);
139 return 0;
140 default:
141 return -EINVAL;
142 }
143}
144EXPORT_SYMBOL(get_ssi_clk);
145
146void put_ssi_clk(int ssi)
147{
148 switch (ssi) {
149 case 0:
150 clk_put(ssi_clk0);
151 ssi_clk0 = NULL;
152 break;
153 case 1:
154 clk_put(ssi_clk1);
155 ssi_clk1 = NULL;
156 break;
157 }
158}
159EXPORT_SYMBOL(put_ssi_clk);
160
161/*
162 * SSI system clock configuration.
163 * Should only be called when port is inactive (i.e. SSIEN = 0).
164 */
165static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
166 int clk_id, unsigned int freq, int dir)
167{
168 u32 scr;
169
170 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
171 scr = SSI1_SCR;
172 pr_debug("%s: SCR for SSI1 is %x\n", __func__, scr);
173 } else {
174 scr = SSI2_SCR;
175 pr_debug("%s: SCR for SSI2 is %x\n", __func__, scr);
176 }
177
178 if (scr & SSI_SCR_SSIEN) {
179 printk(KERN_WARNING "Warning ssi already enabled\n");
180 return 0;
181 }
182
183 switch (clk_id) {
184 case IMX_SSP_SYS_CLK:
185 if (dir == SND_SOC_CLOCK_OUT) {
186 scr |= SSI_SCR_SYS_CLK_EN;
187 pr_debug("%s: clk of is output\n", __func__);
188 } else {
189 scr &= ~SSI_SCR_SYS_CLK_EN;
190 pr_debug("%s: clk of is input\n", __func__);
191 }
192 break;
193 default:
194 return -EINVAL;
195 }
196
197 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
198 pr_debug("%s: writeback of SSI1_SCR\n", __func__);
199 SSI1_SCR = scr;
200 } else {
201 pr_debug("%s: writeback of SSI2_SCR\n", __func__);
202 SSI2_SCR = scr;
203 }
204
205 return 0;
206}
207
208/*
209 * SSI Clock dividers
210 * Should only be called when port is inactive (i.e. SSIEN = 0).
211 */
212static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
213 int div_id, int div)
214{
215 u32 stccr, srccr;
216
217 pr_debug("%s\n", __func__);
218 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
219 if (SSI1_SCR & SSI_SCR_SSIEN)
220 return 0;
221 srccr = SSI1_STCCR;
222 stccr = SSI1_STCCR;
223 } else {
224 if (SSI2_SCR & SSI_SCR_SSIEN)
225 return 0;
226 srccr = SSI2_STCCR;
227 stccr = SSI2_STCCR;
228 }
229
230 switch (div_id) {
231 case IMX_SSI_TX_DIV_2:
232 stccr &= ~SSI_STCCR_DIV2;
233 stccr |= div;
234 break;
235 case IMX_SSI_TX_DIV_PSR:
236 stccr &= ~SSI_STCCR_PSR;
237 stccr |= div;
238 break;
239 case IMX_SSI_TX_DIV_PM:
240 stccr &= ~0xff;
241 stccr |= SSI_STCCR_PM(div);
242 break;
243 case IMX_SSI_RX_DIV_2:
244 stccr &= ~SSI_STCCR_DIV2;
245 stccr |= div;
246 break;
247 case IMX_SSI_RX_DIV_PSR:
248 stccr &= ~SSI_STCCR_PSR;
249 stccr |= div;
250 break;
251 case IMX_SSI_RX_DIV_PM:
252 stccr &= ~0xff;
253 stccr |= SSI_STCCR_PM(div);
254 break;
255 default:
256 return -EINVAL;
257 }
258
259 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
260 SSI1_STCCR = stccr;
261 SSI1_SRCCR = srccr;
262 } else {
263 SSI2_STCCR = stccr;
264 SSI2_SRCCR = srccr;
265 }
266 return 0;
267}
268
269/*
270 * SSI Network Mode or TDM slots configuration.
271 * Should only be called when port is inactive (i.e. SSIEN = 0).
272 */
273static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
274 unsigned int mask, int slots)
275{
276 u32 stmsk, srmsk, stccr;
277
278 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
279 if (SSI1_SCR & SSI_SCR_SSIEN) {
280 printk(KERN_WARNING "Warning ssi already enabled\n");
281 return 0;
282 }
283 stccr = SSI1_STCCR;
284 } else {
285 if (SSI2_SCR & SSI_SCR_SSIEN) {
286 printk(KERN_WARNING "Warning ssi already enabled\n");
287 return 0;
288 }
289 stccr = SSI2_STCCR;
290 }
291
292 stmsk = srmsk = mask;
293 stccr &= ~SSI_STCCR_DC_MASK;
294 stccr |= SSI_STCCR_DC(slots - 1);
295
296 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
297 SSI1_STMSK = stmsk;
298 SSI1_SRMSK = srmsk;
299 SSI1_SRCCR = SSI1_STCCR = stccr;
300 } else {
301 SSI2_STMSK = stmsk;
302 SSI2_SRMSK = srmsk;
303 SSI2_SRCCR = SSI2_STCCR = stccr;
304 }
305
306 return 0;
307}
308
309/*
310 * SSI DAI format configuration.
311 * Should only be called when port is inactive (i.e. SSIEN = 0).
312 * Note: We don't use the I2S modes but instead manually configure the
313 * SSI for I2S.
314 */
315static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai,
316 unsigned int fmt)
317{
318 u32 stcr = 0, srcr = 0, scr;
319
320 /*
321 * This is done to avoid this function to modify
322 * previous set values in stcr
323 */
324 stcr = SSI1_STCR;
325
326 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
327 scr = SSI1_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
328 else
329 scr = SSI2_SCR & ~(SSI_SCR_SYN | SSI_SCR_NET);
330
331 if (scr & SSI_SCR_SSIEN) {
332 printk(KERN_WARNING "Warning ssi already enabled\n");
333 return 0;
334 }
335
336 /* DAI mode */
337 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
338 case SND_SOC_DAIFMT_I2S:
339 /* data on rising edge of bclk, frame low 1clk before data */
340 stcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
341 srcr |= SSI_SRCR_RFSI | SSI_SRCR_REFS | SSI_SRCR_RXBIT0;
342 break;
343 case SND_SOC_DAIFMT_LEFT_J:
344 /* data on rising edge of bclk, frame high with data */
345 stcr |= SSI_STCR_TXBIT0;
346 srcr |= SSI_SRCR_RXBIT0;
347 break;
348 case SND_SOC_DAIFMT_DSP_B:
349 /* data on rising edge of bclk, frame high with data */
350 stcr |= SSI_STCR_TFSL;
351 srcr |= SSI_SRCR_RFSL;
352 break;
353 case SND_SOC_DAIFMT_DSP_A:
354 /* data on rising edge of bclk, frame high 1clk before data */
355 stcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
356 srcr |= SSI_SRCR_RFSL | SSI_SRCR_REFS;
357 break;
358 }
359
360 /* DAI clock inversion */
361 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
362 case SND_SOC_DAIFMT_IB_IF:
363 stcr |= SSI_STCR_TFSI;
364 stcr &= ~SSI_STCR_TSCKP;
365 srcr |= SSI_SRCR_RFSI;
366 srcr &= ~SSI_SRCR_RSCKP;
367 break;
368 case SND_SOC_DAIFMT_IB_NF:
369 stcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
370 srcr &= ~(SSI_SRCR_RSCKP | SSI_SRCR_RFSI);
371 break;
372 case SND_SOC_DAIFMT_NB_IF:
373 stcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
374 srcr |= SSI_SRCR_RFSI | SSI_SRCR_RSCKP;
375 break;
376 case SND_SOC_DAIFMT_NB_NF:
377 stcr &= ~SSI_STCR_TFSI;
378 stcr |= SSI_STCR_TSCKP;
379 srcr &= ~SSI_SRCR_RFSI;
380 srcr |= SSI_SRCR_RSCKP;
381 break;
382 }
383
384 /* DAI clock master masks */
385 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
386 case SND_SOC_DAIFMT_CBS_CFS:
387 stcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR;
388 srcr |= SSI_SRCR_RFDIR | SSI_SRCR_RXDIR;
389 break;
390 case SND_SOC_DAIFMT_CBM_CFS:
391 stcr |= SSI_STCR_TFDIR;
392 srcr |= SSI_SRCR_RFDIR;
393 break;
394 case SND_SOC_DAIFMT_CBS_CFM:
395 stcr |= SSI_STCR_TXDIR;
396 srcr |= SSI_SRCR_RXDIR;
397 break;
398 }
399
400 /* sync */
401 if (!(fmt & SND_SOC_DAIFMT_ASYNC))
402 scr |= SSI_SCR_SYN;
403
404 /* tdm - only for stereo atm */
405 if (fmt & SND_SOC_DAIFMT_TDM)
406 scr |= SSI_SCR_NET;
407
408 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
409 SSI1_STCR = stcr;
410 SSI1_SRCR = srcr;
411 SSI1_SCR = scr;
412 } else {
413 SSI2_STCR = stcr;
414 SSI2_SRCR = srcr;
415 SSI2_SCR = scr;
416 }
417
418 return 0;
419}
420
421static int imx_ssi_startup(struct snd_pcm_substream *substream,
422 struct snd_soc_dai *dai)
423{
424 struct snd_soc_pcm_runtime *rtd = substream->private_data;
425 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
426
427 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
428 /* set up TX DMA params */
429 switch (cpu_dai->id) {
430 case IMX_DAI_SSI0:
431 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out0;
432 break;
433 case IMX_DAI_SSI1:
434 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out1;
435 break;
436 case IMX_DAI_SSI2:
437 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out0;
438 break;
439 case IMX_DAI_SSI3:
440 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out1;
441 }
442 pr_debug("%s: (playback)\n", __func__);
443 } else {
444 /* set up RX DMA params */
445 switch (cpu_dai->id) {
446 case IMX_DAI_SSI0:
447 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in0;
448 break;
449 case IMX_DAI_SSI1:
450 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in1;
451 break;
452 case IMX_DAI_SSI2:
453 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in0;
454 break;
455 case IMX_DAI_SSI3:
456 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in1;
457 }
458 pr_debug("%s: (capture)\n", __func__);
459 }
460
461 /*
462 * we cant really change any SSI values after SSI is enabled
463 * need to fix in software for max flexibility - lrg
464 */
465 if (cpu_dai->active) {
466 printk(KERN_WARNING "Warning ssi already enabled\n");
467 return 0;
468 }
469
470 /* reset the SSI port - Sect 45.4.4 */
471 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
472
473 if (!ssi_clk0)
474 return -EINVAL;
475
476 if (ssi_active[SSI1_PORT]++) {
477 pr_debug("%s: exit before reset\n", __func__);
478 return 0;
479 }
480
481 /* SSI1 Reset */
482 SSI1_SCR = 0;
483
484 SSI1_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
485 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
486 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
487 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
488 } else {
489
490 if (!ssi_clk1)
491 return -EINVAL;
492
493 if (ssi_active[SSI2_PORT]++) {
494 pr_debug("%s: exit before reset\n", __func__);
495 return 0;
496 }
497
498 /* SSI2 Reset */
499 SSI2_SCR = 0;
500
501 SSI2_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
502 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
503 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
504 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
505 }
506
507 return 0;
508}
509
510int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream,
511 struct snd_pcm_hw_params *params)
512{
513 struct snd_soc_pcm_runtime *rtd = substream->private_data;
514 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
515 u32 stccr, stcr, sier;
516
517 pr_debug("%s\n", __func__);
518
519 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
520 stccr = SSI1_STCCR & ~SSI_STCCR_WL_MASK;
521 stcr = SSI1_STCR;
522 sier = SSI1_SIER;
523 } else {
524 stccr = SSI2_STCCR & ~SSI_STCCR_WL_MASK;
525 stcr = SSI2_STCR;
526 sier = SSI2_SIER;
527 }
528
529 /* DAI data (word) size */
530 switch (params_format(params)) {
531 case SNDRV_PCM_FORMAT_S16_LE:
532 stccr |= SSI_STCCR_WL(16);
533 break;
534 case SNDRV_PCM_FORMAT_S20_3LE:
535 stccr |= SSI_STCCR_WL(20);
536 break;
537 case SNDRV_PCM_FORMAT_S24_LE:
538 stccr |= SSI_STCCR_WL(24);
539 break;
540 }
541
542 /* enable interrupts */
543 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
544 stcr |= SSI_STCR_TFEN0;
545 else
546 stcr |= SSI_STCR_TFEN1;
547 sier |= SSI_SIER_TDMAE;
548
549 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
550 SSI1_STCR = stcr;
551 SSI1_STCCR = stccr;
552 SSI1_SIER = sier;
553 } else {
554 SSI2_STCR = stcr;
555 SSI2_STCCR = stccr;
556 SSI2_SIER = sier;
557 }
558
559 return 0;
560}
561
562int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
563 struct snd_pcm_hw_params *params)
564{
565 struct snd_soc_pcm_runtime *rtd = substream->private_data;
566 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
567 u32 srccr, srcr, sier;
568
569 pr_debug("%s\n", __func__);
570
571 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
572 srccr = SSI1_SRCCR & ~SSI_SRCCR_WL_MASK;
573 srcr = SSI1_SRCR;
574 sier = SSI1_SIER;
575 } else {
576 srccr = SSI2_SRCCR & ~SSI_SRCCR_WL_MASK;
577 srcr = SSI2_SRCR;
578 sier = SSI2_SIER;
579 }
580
581 /* DAI data (word) size */
582 switch (params_format(params)) {
583 case SNDRV_PCM_FORMAT_S16_LE:
584 srccr |= SSI_SRCCR_WL(16);
585 break;
586 case SNDRV_PCM_FORMAT_S20_3LE:
587 srccr |= SSI_SRCCR_WL(20);
588 break;
589 case SNDRV_PCM_FORMAT_S24_LE:
590 srccr |= SSI_SRCCR_WL(24);
591 break;
592 }
593
594 /* enable interrupts */
595 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
596 srcr |= SSI_SRCR_RFEN0;
597 else
598 srcr |= SSI_SRCR_RFEN1;
599 sier |= SSI_SIER_RDMAE;
600
601 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
602 SSI1_SRCR = srcr;
603 SSI1_SRCCR = srccr;
604 SSI1_SIER = sier;
605 } else {
606 SSI2_SRCR = srcr;
607 SSI2_SRCCR = srccr;
608 SSI2_SIER = sier;
609 }
610
611 return 0;
612}
613
614/*
615 * Should only be called when port is inactive (i.e. SSIEN = 0),
616 * although can be called multiple times by upper layers.
617 */
618int imx_ssi_hw_params(struct snd_pcm_substream *substream,
619 struct snd_pcm_hw_params *params,
620 struct snd_soc_dai *dai)
621{
622 struct snd_soc_pcm_runtime *rtd = substream->private_data;
623 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
624
625 int ret;
626
627 /* cant change any parameters when SSI is running */
628 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
629 if (SSI1_SCR & SSI_SCR_SSIEN) {
630 printk(KERN_WARNING "Warning ssi already enabled\n");
631 return 0;
632 }
633 } else {
634 if (SSI2_SCR & SSI_SCR_SSIEN) {
635 printk(KERN_WARNING "Warning ssi already enabled\n");
636 return 0;
637 }
638 }
639
640 /*
641 * Configure both tx and rx params with the same settings. This is
642 * really a harware restriction because SSI must be disabled until
643 * we can change those values. If there is an active audio stream in
644 * one direction, enabling the other direction with different
645 * settings would mean disturbing the running one.
646 */
647 ret = imx_ssi_hw_tx_params(substream, params);
648 if (ret < 0)
649 return ret;
650 return imx_ssi_hw_rx_params(substream, params);
651}
652
653int imx_ssi_prepare(struct snd_pcm_substream *substream,
654 struct snd_soc_dai *dai)
655{
656 struct snd_soc_pcm_runtime *rtd = substream->private_data;
657 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
658 int ret;
659
660 pr_debug("%s\n", __func__);
661
662 /* Enable clks here to follow SSI recommended init sequence */
663 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
664 ret = clk_enable(ssi_clk0);
665 if (ret < 0)
666 printk(KERN_ERR "Unable to enable ssi_clk0\n");
667 } else {
668 ret = clk_enable(ssi_clk1);
669 if (ret < 0)
670 printk(KERN_ERR "Unable to enable ssi_clk1\n");
671 }
672
673 return 0;
674}
675
676static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
677 struct snd_soc_dai *dai)
678{
679 struct snd_soc_pcm_runtime *rtd = substream->private_data;
680 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
681 u32 scr;
682
683 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
684 scr = SSI1_SCR;
685 else
686 scr = SSI2_SCR;
687
688 switch (cmd) {
689 case SNDRV_PCM_TRIGGER_START:
690 case SNDRV_PCM_TRIGGER_RESUME:
691 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
692 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
693 scr |= SSI_SCR_TE | SSI_SCR_SSIEN;
694 else
695 scr |= SSI_SCR_RE | SSI_SCR_SSIEN;
696 break;
697 case SNDRV_PCM_TRIGGER_SUSPEND:
698 case SNDRV_PCM_TRIGGER_STOP:
699 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
700 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
701 scr &= ~SSI_SCR_TE;
702 else
703 scr &= ~SSI_SCR_RE;
704 break;
705 default:
706 return -EINVAL;
707 }
708
709 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
710 SSI1_SCR = scr;
711 else
712 SSI2_SCR = scr;
713
714 return 0;
715}
716
717static void imx_ssi_shutdown(struct snd_pcm_substream *substream,
718 struct snd_soc_dai *dai)
719{
720 struct snd_soc_pcm_runtime *rtd = substream->private_data;
721 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
722
723 /* shutdown SSI if neither Tx or Rx is active */
724 if (!cpu_dai->active) {
725
726 if (cpu_dai->id == IMX_DAI_SSI0 ||
727 cpu_dai->id == IMX_DAI_SSI2) {
728
729 if (--ssi_active[SSI1_PORT] > 1)
730 return;
731
732 SSI1_SCR = 0;
733 clk_disable(ssi_clk0);
734 } else {
735 if (--ssi_active[SSI2_PORT])
736 return;
737 SSI2_SCR = 0;
738 clk_disable(ssi_clk1);
739 }
740 }
741}
742
743#ifdef CONFIG_PM
744static int imx_ssi_suspend(struct platform_device *dev,
745 struct snd_soc_dai *dai)
746{
747 return 0;
748}
749
750static int imx_ssi_resume(struct platform_device *pdev,
751 struct snd_soc_dai *dai)
752{
753 return 0;
754}
755
756#else
757#define imx_ssi_suspend NULL
758#define imx_ssi_resume NULL
759#endif
760
761#define IMX_SSI_RATES \
762 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
763 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
764 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
765 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
766 SNDRV_PCM_RATE_96000)
767
768#define IMX_SSI_BITS \
769 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
770 SNDRV_PCM_FMTBIT_S24_LE)
771
772static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
773 .startup = imx_ssi_startup,
774 .shutdown = imx_ssi_shutdown,
775 .trigger = imx_ssi_trigger,
776 .prepare = imx_ssi_prepare,
777 .hw_params = imx_ssi_hw_params,
778 .set_sysclk = imx_ssi_set_dai_sysclk,
779 .set_clkdiv = imx_ssi_set_dai_clkdiv,
780 .set_fmt = imx_ssi_set_dai_fmt,
781 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
782};
783
784struct snd_soc_dai imx_ssi_pcm_dai[] = {
785{
786 .name = "imx-i2s-1-0",
787 .id = IMX_DAI_SSI0,
788 .suspend = imx_ssi_suspend,
789 .resume = imx_ssi_resume,
790 .playback = {
791 .channels_min = 1,
792 .channels_max = 2,
793 .formats = IMX_SSI_BITS,
794 .rates = IMX_SSI_RATES,},
795 .capture = {
796 .channels_min = 1,
797 .channels_max = 2,
798 .formats = IMX_SSI_BITS,
799 .rates = IMX_SSI_RATES,},
800 .ops = &imx_ssi_pcm_dai_ops,
801},
802{
803 .name = "imx-i2s-2-0",
804 .id = IMX_DAI_SSI1,
805 .playback = {
806 .channels_min = 1,
807 .channels_max = 2,
808 .formats = IMX_SSI_BITS,
809 .rates = IMX_SSI_RATES,},
810 .capture = {
811 .channels_min = 1,
812 .channels_max = 2,
813 .formats = IMX_SSI_BITS,
814 .rates = IMX_SSI_RATES,},
815 .ops = &imx_ssi_pcm_dai_ops,
816},
817{
818 .name = "imx-i2s-1-1",
819 .id = IMX_DAI_SSI2,
820 .suspend = imx_ssi_suspend,
821 .resume = imx_ssi_resume,
822 .playback = {
823 .channels_min = 1,
824 .channels_max = 2,
825 .formats = IMX_SSI_BITS,
826 .rates = IMX_SSI_RATES,},
827 .capture = {
828 .channels_min = 1,
829 .channels_max = 2,
830 .formats = IMX_SSI_BITS,
831 .rates = IMX_SSI_RATES,},
832 .ops = &imx_ssi_pcm_dai_ops,
833},
834{
835 .name = "imx-i2s-2-1",
836 .id = IMX_DAI_SSI3,
837 .playback = {
838 .channels_min = 1,
839 .channels_max = 2,
840 .formats = IMX_SSI_BITS,
841 .rates = IMX_SSI_RATES,},
842 .capture = {
843 .channels_min = 1,
844 .channels_max = 2,
845 .formats = IMX_SSI_BITS,
846 .rates = IMX_SSI_RATES,},
847 .ops = &imx_ssi_pcm_dai_ops,
848},
849};
850EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
851
852static int __init imx_ssi_init(void)
853{
854 return snd_soc_register_dais(imx_ssi_pcm_dai,
855 ARRAY_SIZE(imx_ssi_pcm_dai));
856}
857
858static void __exit imx_ssi_exit(void)
859{
860 snd_soc_unregister_dais(imx_ssi_pcm_dai,
861 ARRAY_SIZE(imx_ssi_pcm_dai));
862}
863
864module_init(imx_ssi_init);
865module_exit(imx_ssi_exit);
866MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com");
867MODULE_DESCRIPTION("i.MX ASoC I2S driver");
868MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.h b/sound/soc/imx/mxc-ssi.h
new file mode 100644
index 000000000000..12bbdc9c7ecd
--- /dev/null
+++ b/sound/soc/imx/mxc-ssi.h
@@ -0,0 +1,238 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License version 2 as
4 * published by the Free Software Foundation.
5 */
6
7#ifndef _IMX_SSI_H
8#define _IMX_SSI_H
9
10#include <mach/hardware.h>
11
12/* SSI regs definition - MOVE to /arch/arm/plat-mxc/include/mach/ when stable */
13#define SSI1_IO_BASE_ADDR IO_ADDRESS(SSI1_BASE_ADDR)
14#define SSI2_IO_BASE_ADDR IO_ADDRESS(SSI2_BASE_ADDR)
15
16#define STX0 0x00
17#define STX1 0x04
18#define SRX0 0x08
19#define SRX1 0x0c
20#define SCR 0x10
21#define SISR 0x14
22#define SIER 0x18
23#define STCR 0x1c
24#define SRCR 0x20
25#define STCCR 0x24
26#define SRCCR 0x28
27#define SFCSR 0x2c
28#define STR 0x30
29#define SOR 0x34
30#define SACNT 0x38
31#define SACADD 0x3c
32#define SACDAT 0x40
33#define SATAG 0x44
34#define STMSK 0x48
35#define SRMSK 0x4c
36
37#define SSI1_STX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX0)))
38#define SSI1_STX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STX1)))
39#define SSI1_SRX0 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX0)))
40#define SSI1_SRX1 (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRX1)))
41#define SSI1_SCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SCR)))
42#define SSI1_SISR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SISR)))
43#define SSI1_SIER (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SIER)))
44#define SSI1_STCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCR)))
45#define SSI1_SRCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCR)))
46#define SSI1_STCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STCCR)))
47#define SSI1_SRCCR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRCCR)))
48#define SSI1_SFCSR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SFCSR)))
49#define SSI1_STR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STR)))
50#define SSI1_SOR (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SOR)))
51#define SSI1_SACNT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACNT)))
52#define SSI1_SACADD (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACADD)))
53#define SSI1_SACDAT (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SACDAT)))
54#define SSI1_SATAG (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SATAG)))
55#define SSI1_STMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + STMSK)))
56#define SSI1_SRMSK (*((volatile u32 *)(SSI1_IO_BASE_ADDR + SRMSK)))
57
58
59#define SSI2_STX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX0)))
60#define SSI2_STX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STX1)))
61#define SSI2_SRX0 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX0)))
62#define SSI2_SRX1 (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRX1)))
63#define SSI2_SCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SCR)))
64#define SSI2_SISR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SISR)))
65#define SSI2_SIER (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SIER)))
66#define SSI2_STCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCR)))
67#define SSI2_SRCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCR)))
68#define SSI2_STCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STCCR)))
69#define SSI2_SRCCR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRCCR)))
70#define SSI2_SFCSR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SFCSR)))
71#define SSI2_STR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STR)))
72#define SSI2_SOR (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SOR)))
73#define SSI2_SACNT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACNT)))
74#define SSI2_SACADD (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACADD)))
75#define SSI2_SACDAT (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SACDAT)))
76#define SSI2_SATAG (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SATAG)))
77#define SSI2_STMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + STMSK)))
78#define SSI2_SRMSK (*((volatile u32 *)(SSI2_IO_BASE_ADDR + SRMSK)))
79
80#define SSI_SCR_CLK_IST (1 << 9)
81#define SSI_SCR_TCH_EN (1 << 8)
82#define SSI_SCR_SYS_CLK_EN (1 << 7)
83#define SSI_SCR_I2S_MODE_NORM (0 << 5)
84#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
85#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
86#define SSI_SCR_SYN (1 << 4)
87#define SSI_SCR_NET (1 << 3)
88#define SSI_SCR_RE (1 << 2)
89#define SSI_SCR_TE (1 << 1)
90#define SSI_SCR_SSIEN (1 << 0)
91
92#define SSI_SISR_CMDAU (1 << 18)
93#define SSI_SISR_CMDDU (1 << 17)
94#define SSI_SISR_RXT (1 << 16)
95#define SSI_SISR_RDR1 (1 << 15)
96#define SSI_SISR_RDR0 (1 << 14)
97#define SSI_SISR_TDE1 (1 << 13)
98#define SSI_SISR_TDE0 (1 << 12)
99#define SSI_SISR_ROE1 (1 << 11)
100#define SSI_SISR_ROE0 (1 << 10)
101#define SSI_SISR_TUE1 (1 << 9)
102#define SSI_SISR_TUE0 (1 << 8)
103#define SSI_SISR_TFS (1 << 7)
104#define SSI_SISR_RFS (1 << 6)
105#define SSI_SISR_TLS (1 << 5)
106#define SSI_SISR_RLS (1 << 4)
107#define SSI_SISR_RFF1 (1 << 3)
108#define SSI_SISR_RFF0 (1 << 2)
109#define SSI_SISR_TFE1 (1 << 1)
110#define SSI_SISR_TFE0 (1 << 0)
111
112#define SSI_SIER_RDMAE (1 << 22)
113#define SSI_SIER_RIE (1 << 21)
114#define SSI_SIER_TDMAE (1 << 20)
115#define SSI_SIER_TIE (1 << 19)
116#define SSI_SIER_CMDAU_EN (1 << 18)
117#define SSI_SIER_CMDDU_EN (1 << 17)
118#define SSI_SIER_RXT_EN (1 << 16)
119#define SSI_SIER_RDR1_EN (1 << 15)
120#define SSI_SIER_RDR0_EN (1 << 14)
121#define SSI_SIER_TDE1_EN (1 << 13)
122#define SSI_SIER_TDE0_EN (1 << 12)
123#define SSI_SIER_ROE1_EN (1 << 11)
124#define SSI_SIER_ROE0_EN (1 << 10)
125#define SSI_SIER_TUE1_EN (1 << 9)
126#define SSI_SIER_TUE0_EN (1 << 8)
127#define SSI_SIER_TFS_EN (1 << 7)
128#define SSI_SIER_RFS_EN (1 << 6)
129#define SSI_SIER_TLS_EN (1 << 5)
130#define SSI_SIER_RLS_EN (1 << 4)
131#define SSI_SIER_RFF1_EN (1 << 3)
132#define SSI_SIER_RFF0_EN (1 << 2)
133#define SSI_SIER_TFE1_EN (1 << 1)
134#define SSI_SIER_TFE0_EN (1 << 0)
135
136#define SSI_STCR_TXBIT0 (1 << 9)
137#define SSI_STCR_TFEN1 (1 << 8)
138#define SSI_STCR_TFEN0 (1 << 7)
139#define SSI_STCR_TFDIR (1 << 6)
140#define SSI_STCR_TXDIR (1 << 5)
141#define SSI_STCR_TSHFD (1 << 4)
142#define SSI_STCR_TSCKP (1 << 3)
143#define SSI_STCR_TFSI (1 << 2)
144#define SSI_STCR_TFSL (1 << 1)
145#define SSI_STCR_TEFS (1 << 0)
146
147#define SSI_SRCR_RXBIT0 (1 << 9)
148#define SSI_SRCR_RFEN1 (1 << 8)
149#define SSI_SRCR_RFEN0 (1 << 7)
150#define SSI_SRCR_RFDIR (1 << 6)
151#define SSI_SRCR_RXDIR (1 << 5)
152#define SSI_SRCR_RSHFD (1 << 4)
153#define SSI_SRCR_RSCKP (1 << 3)
154#define SSI_SRCR_RFSI (1 << 2)
155#define SSI_SRCR_RFSL (1 << 1)
156#define SSI_SRCR_REFS (1 << 0)
157
158#define SSI_STCCR_DIV2 (1 << 18)
159#define SSI_STCCR_PSR (1 << 15)
160#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
161#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
162#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
163#define SSI_STCCR_WL_MASK (0xf << 13)
164#define SSI_STCCR_DC_MASK (0x1f << 8)
165#define SSI_STCCR_PM_MASK (0xff << 0)
166
167#define SSI_SRCCR_DIV2 (1 << 18)
168#define SSI_SRCCR_PSR (1 << 15)
169#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
170#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
171#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
172#define SSI_SRCCR_WL_MASK (0xf << 13)
173#define SSI_SRCCR_DC_MASK (0x1f << 8)
174#define SSI_SRCCR_PM_MASK (0xff << 0)
175
176
177#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
178#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
179#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
180#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
181#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
182#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
183#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
184#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
185
186#define SSI_STR_TEST (1 << 15)
187#define SSI_STR_RCK2TCK (1 << 14)
188#define SSI_STR_RFS2TFS (1 << 13)
189#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
190#define SSI_STR_TXD2RXD (1 << 7)
191#define SSI_STR_TCK2RCK (1 << 6)
192#define SSI_STR_TFS2RFS (1 << 5)
193#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
194
195#define SSI_SOR_CLKOFF (1 << 6)
196#define SSI_SOR_RX_CLR (1 << 5)
197#define SSI_SOR_TX_CLR (1 << 4)
198#define SSI_SOR_INIT (1 << 3)
199#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
200#define SSI_SOR_SYNRST (1 << 0)
201
202#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
203#define SSI_SACNT_WR (x << 4)
204#define SSI_SACNT_RD (x << 3)
205#define SSI_SACNT_TIF (x << 2)
206#define SSI_SACNT_FV (x << 1)
207#define SSI_SACNT_AC97EN (x << 0)
208
209/* Watermarks for FIFO's */
210#define TXFIFO_WATERMARK 0x4
211#define RXFIFO_WATERMARK 0x4
212
213/* i.MX DAI SSP ID's */
214#define IMX_DAI_SSI0 0 /* SSI1 FIFO 0 */
215#define IMX_DAI_SSI1 1 /* SSI1 FIFO 1 */
216#define IMX_DAI_SSI2 2 /* SSI2 FIFO 0 */
217#define IMX_DAI_SSI3 3 /* SSI2 FIFO 1 */
218
219/* SSI clock sources */
220#define IMX_SSP_SYS_CLK 0
221
222/* SSI audio dividers */
223#define IMX_SSI_TX_DIV_2 0
224#define IMX_SSI_TX_DIV_PSR 1
225#define IMX_SSI_TX_DIV_PM 2
226#define IMX_SSI_RX_DIV_2 3
227#define IMX_SSI_RX_DIV_PSR 4
228#define IMX_SSI_RX_DIV_PM 5
229
230
231/* SSI Div 2 */
232#define IMX_SSI_DIV_2_OFF (~SSI_STCCR_DIV2)
233#define IMX_SSI_DIV_2_ON SSI_STCCR_DIV2
234
235extern struct snd_soc_dai imx_ssi_pcm_dai[4];
236extern int get_ssi_clk(int ssi, struct device *dev);
237extern void put_ssi_clk(int ssi);
238#endif
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index b771238662b6..2dee9839be86 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -15,6 +15,14 @@ config SND_OMAP_SOC_N810
15 help 15 help
16 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 17
18config SND_OMAP_SOC_AMS_DELTA
19 tristate "SoC Audio support for Amstrad E3 (Delta) videophone"
20 depends on SND_OMAP_SOC && MACH_AMS_DELTA
21 select SND_OMAP_SOC_MCBSP
22 select SND_SOC_CX20442
23 help
24 Say Y if you want to add support for SoC audio on Amstrad Delta.
25
18config SND_OMAP_SOC_OSK5912 26config SND_OMAP_SOC_OSK5912
19 tristate "SoC Audio support for omap osk5912" 27 tristate "SoC Audio support for omap osk5912"
20 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C 28 depends on SND_OMAP_SOC && MACH_OMAP_OSK && I2C
@@ -72,4 +80,11 @@ config SND_OMAP_SOC_OMAP3_BEAGLE
72 help 80 help
73 Say Y if you want to add support for SoC audio on the Beagleboard. 81 Say Y if you want to add support for SoC audio on the Beagleboard.
74 82
83config SND_OMAP_SOC_ZOOM2
84 tristate "SoC Audio support for Zoom2"
85 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_ZOOM2
86 select SND_OMAP_SOC_MCBSP
87 select SND_SOC_TWL4030
88 help
89 Say Y if you want to add support for Soc audio on Zoom2 board.
75 90
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index a37f49862389..02d69471dcb5 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -7,6 +7,7 @@ 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-ams-delta-objs := ams-delta.o
10snd-soc-osk5912-objs := osk5912.o 11snd-soc-osk5912-objs := osk5912.o
11snd-soc-overo-objs := overo.o 12snd-soc-overo-objs := overo.o
12snd-soc-omap2evm-objs := omap2evm.o 13snd-soc-omap2evm-objs := omap2evm.o
@@ -14,8 +15,10 @@ snd-soc-omap3evm-objs := omap3evm.o
14snd-soc-sdp3430-objs := sdp3430.o 15snd-soc-sdp3430-objs := sdp3430.o
15snd-soc-omap3pandora-objs := omap3pandora.o 16snd-soc-omap3pandora-objs := omap3pandora.o
16snd-soc-omap3beagle-objs := omap3beagle.o 17snd-soc-omap3beagle-objs := omap3beagle.o
18snd-soc-zoom2-objs := zoom2.o
17 19
18obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 20obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
21obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
19obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 22obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
20obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 23obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
21obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o 24obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
@@ -23,3 +26,4 @@ obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o
23obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 26obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
24obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 27obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
25obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 28obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
29obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
new file mode 100644
index 000000000000..5a5166ac7279
--- /dev/null
+++ b/sound/soc/omap/ams-delta.c
@@ -0,0 +1,646 @@
1/*
2 * ams-delta.c -- SoC audio for Amstrad E3 (Delta) videophone
3 *
4 * Copyright (C) 2009 Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>
5 *
6 * Initially based on sound/soc/omap/osk5912.x
7 * Copyright (C) 2008 Mistral Solutions
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/gpio.h>
26#include <linux/spinlock.h>
27#include <linux/tty.h>
28
29#include <sound/soc-dapm.h>
30#include <sound/jack.h>
31
32#include <asm/mach-types.h>
33
34#include <mach/board-ams-delta.h>
35#include <mach/mcbsp.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39#include "../codecs/cx20442.h"
40
41
42/* Board specific DAPM widgets */
43 const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
44 /* Handset */
45 SND_SOC_DAPM_MIC("Mouthpiece", NULL),
46 SND_SOC_DAPM_HP("Earpiece", NULL),
47 /* Handsfree/Speakerphone */
48 SND_SOC_DAPM_MIC("Microphone", NULL),
49 SND_SOC_DAPM_SPK("Speaker", NULL),
50};
51
52/* How they are connected to codec pins */
53static const struct snd_soc_dapm_route ams_delta_audio_map[] = {
54 {"TELIN", NULL, "Mouthpiece"},
55 {"Earpiece", NULL, "TELOUT"},
56
57 {"MIC", NULL, "Microphone"},
58 {"Speaker", NULL, "SPKOUT"},
59};
60
61/*
62 * Controls, functional after the modem line discipline is activated.
63 */
64
65/* Virtual switch: audio input/output constellations */
66static const char *ams_delta_audio_mode[] =
67 {"Mixed", "Handset", "Handsfree", "Speakerphone"};
68
69/* Selection <-> pin translation */
70#define AMS_DELTA_MOUTHPIECE 0
71#define AMS_DELTA_EARPIECE 1
72#define AMS_DELTA_MICROPHONE 2
73#define AMS_DELTA_SPEAKER 3
74#define AMS_DELTA_AGC 4
75
76#define AMS_DELTA_MIXED ((1 << AMS_DELTA_EARPIECE) | \
77 (1 << AMS_DELTA_MICROPHONE))
78#define AMS_DELTA_HANDSET ((1 << AMS_DELTA_MOUTHPIECE) | \
79 (1 << AMS_DELTA_EARPIECE))
80#define AMS_DELTA_HANDSFREE ((1 << AMS_DELTA_MICROPHONE) | \
81 (1 << AMS_DELTA_SPEAKER))
82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
83
84unsigned short ams_delta_audio_mode_pins[] = {
85 AMS_DELTA_MIXED,
86 AMS_DELTA_HANDSET,
87 AMS_DELTA_HANDSFREE,
88 AMS_DELTA_SPEAKERPHONE,
89};
90
91static unsigned short ams_delta_audio_agc;
92
93static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
94 struct snd_ctl_elem_value *ucontrol)
95{
96 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
97 struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
98 unsigned short pins;
99 int pin, changed = 0;
100
101 /* Refuse any mode changes if we are not able to control the codec. */
102 if (!codec->control_data)
103 return -EUNATCH;
104
105 if (ucontrol->value.enumerated.item[0] >= control->max)
106 return -EINVAL;
107
108 mutex_lock(&codec->mutex);
109
110 /* Translate selection to bitmap */
111 pins = ams_delta_audio_mode_pins[ucontrol->value.enumerated.item[0]];
112
113 /* Setup pins after corresponding bits if changed */
114 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
115 if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) {
116 changed = 1;
117 if (pin)
118 snd_soc_dapm_enable_pin(codec, "Mouthpiece");
119 else
120 snd_soc_dapm_disable_pin(codec, "Mouthpiece");
121 }
122 pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
123 if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) {
124 changed = 1;
125 if (pin)
126 snd_soc_dapm_enable_pin(codec, "Earpiece");
127 else
128 snd_soc_dapm_disable_pin(codec, "Earpiece");
129 }
130 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
131 if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) {
132 changed = 1;
133 if (pin)
134 snd_soc_dapm_enable_pin(codec, "Microphone");
135 else
136 snd_soc_dapm_disable_pin(codec, "Microphone");
137 }
138 pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
139 if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) {
140 changed = 1;
141 if (pin)
142 snd_soc_dapm_enable_pin(codec, "Speaker");
143 else
144 snd_soc_dapm_disable_pin(codec, "Speaker");
145 }
146 pin = !!(pins & (1 << AMS_DELTA_AGC));
147 if (pin != ams_delta_audio_agc) {
148 ams_delta_audio_agc = pin;
149 changed = 1;
150 if (pin)
151 snd_soc_dapm_enable_pin(codec, "AGCIN");
152 else
153 snd_soc_dapm_disable_pin(codec, "AGCIN");
154 }
155 if (changed)
156 snd_soc_dapm_sync(codec);
157
158 mutex_unlock(&codec->mutex);
159
160 return changed;
161}
162
163static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
164 struct snd_ctl_elem_value *ucontrol)
165{
166 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
167 unsigned short pins, mode;
168
169 pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") <<
170 AMS_DELTA_MOUTHPIECE) |
171 (snd_soc_dapm_get_pin_status(codec, "Earpiece") <<
172 AMS_DELTA_EARPIECE));
173 if (pins)
174 pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") <<
175 AMS_DELTA_MICROPHONE);
176 else
177 pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") <<
178 AMS_DELTA_MICROPHONE) |
179 (snd_soc_dapm_get_pin_status(codec, "Speaker") <<
180 AMS_DELTA_SPEAKER) |
181 (ams_delta_audio_agc << AMS_DELTA_AGC));
182
183 for (mode = 0; mode < ARRAY_SIZE(ams_delta_audio_mode); mode++)
184 if (pins == ams_delta_audio_mode_pins[mode])
185 break;
186
187 if (mode >= ARRAY_SIZE(ams_delta_audio_mode))
188 return -EINVAL;
189
190 ucontrol->value.enumerated.item[0] = mode;
191
192 return 0;
193}
194
195static const struct soc_enum ams_delta_audio_enum[] = {
196 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ams_delta_audio_mode),
197 ams_delta_audio_mode),
198};
199
200static const struct snd_kcontrol_new ams_delta_audio_controls[] = {
201 SOC_ENUM_EXT("Audio Mode", ams_delta_audio_enum[0],
202 ams_delta_get_audio_mode, ams_delta_set_audio_mode),
203};
204
205/* Hook switch */
206static struct snd_soc_jack ams_delta_hook_switch;
207static struct snd_soc_jack_gpio ams_delta_hook_switch_gpios[] = {
208 {
209 .gpio = 4,
210 .name = "hook_switch",
211 .report = SND_JACK_HEADSET,
212 .invert = 1,
213 .debounce_time = 150,
214 }
215};
216
217/* After we are able to control the codec over the modem,
218 * the hook switch can be used for dynamic DAPM reconfiguration. */
219static struct snd_soc_jack_pin ams_delta_hook_switch_pins[] = {
220 /* Handset */
221 {
222 .pin = "Mouthpiece",
223 .mask = SND_JACK_MICROPHONE,
224 },
225 {
226 .pin = "Earpiece",
227 .mask = SND_JACK_HEADPHONE,
228 },
229 /* Handsfree */
230 {
231 .pin = "Microphone",
232 .mask = SND_JACK_MICROPHONE,
233 .invert = 1,
234 },
235 {
236 .pin = "Speaker",
237 .mask = SND_JACK_HEADPHONE,
238 .invert = 1,
239 },
240};
241
242
243/*
244 * Modem line discipline, required for making above controls functional.
245 * Activated from userspace with ldattach, possibly invoked from udev rule.
246 */
247
248/* To actually apply any modem controlled configuration changes to the codec,
249 * we must connect codec DAI pins to the modem for a moment. Be carefull not
250 * to interfere with our digital mute function that shares the same hardware. */
251static struct timer_list cx81801_timer;
252static bool cx81801_cmd_pending;
253static bool ams_delta_muted;
254static DEFINE_SPINLOCK(ams_delta_lock);
255
256static void cx81801_timeout(unsigned long data)
257{
258 int muted;
259
260 spin_lock(&ams_delta_lock);
261 cx81801_cmd_pending = 0;
262 muted = ams_delta_muted;
263 spin_unlock(&ams_delta_lock);
264
265 /* Reconnect the codec DAI back from the modem to the CPU DAI
266 * only if digital mute still off */
267 if (!muted)
268 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0);
269}
270
271/* Line discipline .open() */
272static int cx81801_open(struct tty_struct *tty)
273{
274 return v253_ops.open(tty);
275}
276
277/* Line discipline .close() */
278static void cx81801_close(struct tty_struct *tty)
279{
280 struct snd_soc_codec *codec = tty->disc_data;
281
282 del_timer_sync(&cx81801_timer);
283
284 v253_ops.close(tty);
285
286 /* Prevent the hook switch from further changing the DAPM pins */
287 INIT_LIST_HEAD(&ams_delta_hook_switch.pins);
288
289 /* Revert back to default audio input/output constellation */
290 snd_soc_dapm_disable_pin(codec, "Mouthpiece");
291 snd_soc_dapm_enable_pin(codec, "Earpiece");
292 snd_soc_dapm_enable_pin(codec, "Microphone");
293 snd_soc_dapm_disable_pin(codec, "Speaker");
294 snd_soc_dapm_disable_pin(codec, "AGCIN");
295 snd_soc_dapm_sync(codec);
296}
297
298/* Line discipline .hangup() */
299static int cx81801_hangup(struct tty_struct *tty)
300{
301 cx81801_close(tty);
302 return 0;
303}
304
305/* Line discipline .recieve_buf() */
306static void cx81801_receive(struct tty_struct *tty,
307 const unsigned char *cp, char *fp, int count)
308{
309 struct snd_soc_codec *codec = tty->disc_data;
310 const unsigned char *c;
311 int apply, ret;
312
313 if (!codec->control_data) {
314 /* First modem response, complete setup procedure */
315
316 /* Initialize timer used for config pulse generation */
317 setup_timer(&cx81801_timer, cx81801_timeout, 0);
318
319 v253_ops.receive_buf(tty, cp, fp, count);
320
321 /* Link hook switch to DAPM pins */
322 ret = snd_soc_jack_add_pins(&ams_delta_hook_switch,
323 ARRAY_SIZE(ams_delta_hook_switch_pins),
324 ams_delta_hook_switch_pins);
325 if (ret)
326 dev_warn(codec->socdev->card->dev,
327 "Failed to link hook switch to DAPM pins, "
328 "will continue with hook switch unlinked.\n");
329
330 return;
331 }
332
333 v253_ops.receive_buf(tty, cp, fp, count);
334
335 for (c = &cp[count - 1]; c >= cp; c--) {
336 if (*c != '\r')
337 continue;
338 /* Complete modem response received, apply config to codec */
339
340 spin_lock_bh(&ams_delta_lock);
341 mod_timer(&cx81801_timer, jiffies + msecs_to_jiffies(150));
342 apply = !ams_delta_muted && !cx81801_cmd_pending;
343 cx81801_cmd_pending = 1;
344 spin_unlock_bh(&ams_delta_lock);
345
346 /* Apply config pulse by connecting the codec to the modem
347 * if not already done */
348 if (apply)
349 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
350 AMS_DELTA_LATCH2_MODEM_CODEC);
351 break;
352 }
353}
354
355/* Line discipline .write_wakeup() */
356static void cx81801_wakeup(struct tty_struct *tty)
357{
358 v253_ops.write_wakeup(tty);
359}
360
361static struct tty_ldisc_ops cx81801_ops = {
362 .magic = TTY_LDISC_MAGIC,
363 .name = "cx81801",
364 .owner = THIS_MODULE,
365 .open = cx81801_open,
366 .close = cx81801_close,
367 .hangup = cx81801_hangup,
368 .receive_buf = cx81801_receive,
369 .write_wakeup = cx81801_wakeup,
370};
371
372
373/*
374 * Even if not very usefull, the sound card can still work without any of the
375 * above functonality activated. You can still control its audio input/output
376 * constellation and speakerphone gain from userspace by issueing AT commands
377 * over the modem port.
378 */
379
380static int ams_delta_hw_params(struct snd_pcm_substream *substream,
381 struct snd_pcm_hw_params *params)
382{
383 struct snd_soc_pcm_runtime *rtd = substream->private_data;
384
385 /* Set cpu DAI configuration */
386 return snd_soc_dai_set_fmt(rtd->dai->cpu_dai,
387 SND_SOC_DAIFMT_DSP_A |
388 SND_SOC_DAIFMT_NB_NF |
389 SND_SOC_DAIFMT_CBM_CFM);
390}
391
392static struct snd_soc_ops ams_delta_ops = {
393 .hw_params = ams_delta_hw_params,
394};
395
396
397/* Board specific codec bias level control */
398static int ams_delta_set_bias_level(struct snd_soc_card *card,
399 enum snd_soc_bias_level level)
400{
401 struct snd_soc_codec *codec = card->codec;
402
403 switch (level) {
404 case SND_SOC_BIAS_ON:
405 case SND_SOC_BIAS_PREPARE:
406 case SND_SOC_BIAS_STANDBY:
407 if (codec->bias_level == SND_SOC_BIAS_OFF)
408 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
409 AMS_DELTA_LATCH2_MODEM_NRESET);
410 break;
411 case SND_SOC_BIAS_OFF:
412 if (codec->bias_level != SND_SOC_BIAS_OFF)
413 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
414 0);
415 }
416 codec->bias_level = level;
417
418 return 0;
419}
420
421/* Digital mute implemented using modem/CPU multiplexer.
422 * Shares hardware with codec config pulse generation */
423static bool ams_delta_muted = 1;
424
425static int ams_delta_digital_mute(struct snd_soc_dai *dai, int mute)
426{
427 int apply;
428
429 if (ams_delta_muted == mute)
430 return 0;
431
432 spin_lock_bh(&ams_delta_lock);
433 ams_delta_muted = mute;
434 apply = !cx81801_cmd_pending;
435 spin_unlock_bh(&ams_delta_lock);
436
437 if (apply)
438 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC,
439 mute ? AMS_DELTA_LATCH2_MODEM_CODEC : 0);
440 return 0;
441}
442
443/* Our codec DAI probably doesn't have its own .ops structure */
444static struct snd_soc_dai_ops ams_delta_dai_ops = {
445 .digital_mute = ams_delta_digital_mute,
446};
447
448/* Will be used if the codec ever has its own digital_mute function */
449static int ams_delta_startup(struct snd_pcm_substream *substream)
450{
451 return ams_delta_digital_mute(NULL, 0);
452}
453
454static void ams_delta_shutdown(struct snd_pcm_substream *substream)
455{
456 ams_delta_digital_mute(NULL, 1);
457}
458
459
460/*
461 * Card initialization
462 */
463
464static int ams_delta_cx20442_init(struct snd_soc_codec *codec)
465{
466 struct snd_soc_dai *codec_dai = codec->dai;
467 struct snd_soc_card *card = codec->socdev->card;
468 int ret;
469 /* Codec is ready, now add/activate board specific controls */
470
471 /* Set up digital mute if not provided by the codec */
472 if (!codec_dai->ops) {
473 codec_dai->ops = &ams_delta_dai_ops;
474 } else if (!codec_dai->ops->digital_mute) {
475 codec_dai->ops->digital_mute = ams_delta_digital_mute;
476 } else {
477 ams_delta_ops.startup = ams_delta_startup;
478 ams_delta_ops.shutdown = ams_delta_shutdown;
479 }
480
481 /* Set codec bias level */
482 ams_delta_set_bias_level(card, SND_SOC_BIAS_STANDBY);
483
484 /* Add hook switch - can be used to control the codec from userspace
485 * even if line discipline fails */
486 ret = snd_soc_jack_new(card, "hook_switch",
487 SND_JACK_HEADSET, &ams_delta_hook_switch);
488 if (ret)
489 dev_warn(card->dev,
490 "Failed to allocate resources for hook switch, "
491 "will continue without one.\n");
492 else {
493 ret = snd_soc_jack_add_gpios(&ams_delta_hook_switch,
494 ARRAY_SIZE(ams_delta_hook_switch_gpios),
495 ams_delta_hook_switch_gpios);
496 if (ret)
497 dev_warn(card->dev,
498 "Failed to set up hook switch GPIO line, "
499 "will continue with hook switch inactive.\n");
500 }
501
502 /* Register optional line discipline for over the modem control */
503 ret = tty_register_ldisc(N_V253, &cx81801_ops);
504 if (ret) {
505 dev_warn(card->dev,
506 "Failed to register line discipline, "
507 "will continue without any controls.\n");
508 return 0;
509 }
510
511 /* Add board specific DAPM widgets and routes */
512 ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets,
513 ARRAY_SIZE(ams_delta_dapm_widgets));
514 if (ret) {
515 dev_warn(card->dev,
516 "Failed to register DAPM controls, "
517 "will continue without any.\n");
518 return 0;
519 }
520
521 ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map,
522 ARRAY_SIZE(ams_delta_audio_map));
523 if (ret) {
524 dev_warn(card->dev,
525 "Failed to set up DAPM routes, "
526 "will continue with codec default map.\n");
527 return 0;
528 }
529
530 /* Set up initial pin constellation */
531 snd_soc_dapm_disable_pin(codec, "Mouthpiece");
532 snd_soc_dapm_enable_pin(codec, "Earpiece");
533 snd_soc_dapm_enable_pin(codec, "Microphone");
534 snd_soc_dapm_disable_pin(codec, "Speaker");
535 snd_soc_dapm_disable_pin(codec, "AGCIN");
536 snd_soc_dapm_disable_pin(codec, "AGCOUT");
537 snd_soc_dapm_sync(codec);
538
539 /* Add virtual switch */
540 ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
541 ARRAY_SIZE(ams_delta_audio_controls));
542 if (ret)
543 dev_warn(card->dev,
544 "Failed to register audio mode control, "
545 "will continue without it.\n");
546
547 return 0;
548}
549
550/* DAI glue - connects codec <--> CPU */
551static struct snd_soc_dai_link ams_delta_dai_link = {
552 .name = "CX20442",
553 .stream_name = "CX20442",
554 .cpu_dai = &omap_mcbsp_dai[0],
555 .codec_dai = &cx20442_dai,
556 .init = ams_delta_cx20442_init,
557 .ops = &ams_delta_ops,
558};
559
560/* Audio card driver */
561static struct snd_soc_card ams_delta_audio_card = {
562 .name = "AMS_DELTA",
563 .platform = &omap_soc_platform,
564 .dai_link = &ams_delta_dai_link,
565 .num_links = 1,
566 .set_bias_level = ams_delta_set_bias_level,
567};
568
569/* Audio subsystem */
570static struct snd_soc_device ams_delta_snd_soc_device = {
571 .card = &ams_delta_audio_card,
572 .codec_dev = &cx20442_codec_dev,
573};
574
575/* Module init/exit */
576static struct platform_device *ams_delta_audio_platform_device;
577static struct platform_device *cx20442_platform_device;
578
579static int __init ams_delta_module_init(void)
580{
581 int ret;
582
583 if (!(machine_is_ams_delta()))
584 return -ENODEV;
585
586 ams_delta_audio_platform_device =
587 platform_device_alloc("soc-audio", -1);
588 if (!ams_delta_audio_platform_device)
589 return -ENOMEM;
590
591 platform_set_drvdata(ams_delta_audio_platform_device,
592 &ams_delta_snd_soc_device);
593 ams_delta_snd_soc_device.dev = &ams_delta_audio_platform_device->dev;
594 *(unsigned int *)ams_delta_dai_link.cpu_dai->private_data = OMAP_MCBSP1;
595
596 ret = platform_device_add(ams_delta_audio_platform_device);
597 if (ret)
598 goto err;
599
600 /*
601 * Codec platform device could be registered from elsewhere (board?),
602 * but I do it here as it makes sense only if used with the card.
603 */
604 cx20442_platform_device = platform_device_register_simple("cx20442",
605 -1, NULL, 0);
606 return 0;
607err:
608 platform_device_put(ams_delta_audio_platform_device);
609 return ret;
610}
611module_init(ams_delta_module_init);
612
613static void __exit ams_delta_module_exit(void)
614{
615 struct snd_soc_codec *codec;
616 struct tty_struct *tty;
617
618 if (ams_delta_audio_card.codec) {
619 codec = ams_delta_audio_card.codec;
620
621 if (codec->control_data) {
622 tty = codec->control_data;
623
624 tty_hangup(tty);
625 }
626 }
627
628 if (tty_unregister_ldisc(N_V253) != 0)
629 dev_warn(&ams_delta_audio_platform_device->dev,
630 "failed to unregister V253 line discipline\n");
631
632 snd_soc_jack_free_gpios(&ams_delta_hook_switch,
633 ARRAY_SIZE(ams_delta_hook_switch_gpios),
634 ams_delta_hook_switch_gpios);
635
636 /* Keep modem power on */
637 ams_delta_set_bias_level(&ams_delta_audio_card, SND_SOC_BIAS_STANDBY);
638
639 platform_device_unregister(cx20442_platform_device);
640 platform_device_unregister(ams_delta_audio_platform_device);
641}
642module_exit(ams_delta_module_exit);
643
644MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
645MODULE_DESCRIPTION("ALSA SoC driver for Amstrad E3 (Delta) videophone");
646MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index b60b1dfbc435..0a505938e42b 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -22,6 +22,7 @@
22 */ 22 */
23 23
24#include <linux/clk.h> 24#include <linux/clk.h>
25#include <linux/i2c.h>
25#include <linux/platform_device.h> 26#include <linux/platform_device.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include <sound/pcm.h> 28#include <sound/pcm.h>
@@ -322,8 +323,6 @@ static struct snd_soc_card snd_soc_n810 = {
322 323
323/* Audio private data */ 324/* Audio private data */
324static struct aic3x_setup_data n810_aic33_setup = { 325static struct aic3x_setup_data n810_aic33_setup = {
325 .i2c_bus = 2,
326 .i2c_address = 0x18,
327 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED, 326 .gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
328 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT, 327 .gpio_func[1] = AIC3X_GPIO2_FUNC_DIGITAL_MIC_INPUT,
329}; 328};
@@ -337,6 +336,13 @@ static struct snd_soc_device n810_snd_devdata = {
337 336
338static struct platform_device *n810_snd_device; 337static struct platform_device *n810_snd_device;
339 338
339/* temporary i2c device creation until this can be moved into the machine
340 * support file.
341*/
342static struct i2c_board_info i2c_device[] = {
343 { I2C_BOARD_INFO("tlv320aic3x", 0x1b), }
344};
345
340static int __init n810_soc_init(void) 346static int __init n810_soc_init(void)
341{ 347{
342 int err; 348 int err;
@@ -345,6 +351,8 @@ static int __init n810_soc_init(void)
345 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax())) 351 if (!(machine_is_nokia_n810() || machine_is_nokia_n810_wimax()))
346 return -ENODEV; 352 return -ENODEV;
347 353
354 i2c_register_board_info(1, i2c_device, ARRAY_SIZE(i2c_device));
355
348 n810_snd_device = platform_device_alloc("soc-audio", -1); 356 n810_snd_device = platform_device_alloc("soc-audio", -1);
349 if (!n810_snd_device) 357 if (!n810_snd_device)
350 return -ENOMEM; 358 return -ENOMEM;
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index a5d46a7b196a..3341f49402ca 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -139,27 +139,67 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
139static const unsigned long omap34xx_mcbsp_port[][2] = {}; 139static const unsigned long omap34xx_mcbsp_port[][2] = {};
140#endif 140#endif
141 141
142static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
143{
144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
146 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
147 int dma_op_mode = omap_mcbsp_get_dma_op_mode(mcbsp_data->bus_id);
148 int samples;
149
150 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
151 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
152 samples = snd_pcm_lib_period_bytes(substream) >> 1;
153 else
154 samples = 1;
155
156 /* Configure McBSP internal buffer usage */
157 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
158 omap_mcbsp_set_tx_threshold(mcbsp_data->bus_id, samples - 1);
159 else
160 omap_mcbsp_set_rx_threshold(mcbsp_data->bus_id, samples - 1);
161}
162
142static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, 163static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
143 struct snd_soc_dai *dai) 164 struct snd_soc_dai *dai)
144{ 165{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 166 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 167 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
147 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 168 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
169 int bus_id = mcbsp_data->bus_id;
148 int err = 0; 170 int err = 0;
149 171
150 if (cpu_is_omap343x() && mcbsp_data->bus_id == 1) { 172 if (!cpu_dai->active)
173 err = omap_mcbsp_request(bus_id);
174
175 if (cpu_is_omap343x()) {
176 int dma_op_mode = omap_mcbsp_get_dma_op_mode(bus_id);
177 int max_period;
178
151 /* 179 /*
152 * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer. 180 * McBSP2 in OMAP3 has 1024 * 32-bit internal audio buffer.
153 * Set constraint for minimum buffer size to the same than FIFO 181 * Set constraint for minimum buffer size to the same than FIFO
154 * size in order to avoid underruns in playback startup because 182 * size in order to avoid underruns in playback startup because
155 * HW is keeping the DMA request active until FIFO is filled. 183 * HW is keeping the DMA request active until FIFO is filled.
156 */ 184 */
157 snd_pcm_hw_constraint_minmax(substream->runtime, 185 if (bus_id == 1)
158 SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4096, UINT_MAX); 186 snd_pcm_hw_constraint_minmax(substream->runtime,
159 } 187 SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
188 4096, UINT_MAX);
160 189
161 if (!cpu_dai->active) 190 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
162 err = omap_mcbsp_request(mcbsp_data->bus_id); 191 max_period = omap_mcbsp_get_max_tx_threshold(bus_id);
192 else
193 max_period = omap_mcbsp_get_max_rx_threshold(bus_id);
194
195 max_period++;
196 max_period <<= 1;
197
198 if (dma_op_mode == MCBSP_DMA_MODE_THRESHOLD)
199 snd_pcm_hw_constraint_minmax(substream->runtime,
200 SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
201 32, max_period);
202 }
163 203
164 return err; 204 return err;
165} 205}
@@ -183,21 +223,21 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
183 struct snd_soc_pcm_runtime *rtd = substream->private_data; 223 struct snd_soc_pcm_runtime *rtd = substream->private_data;
184 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 224 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
185 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 225 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
186 int err = 0; 226 int err = 0, play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
187 227
188 switch (cmd) { 228 switch (cmd) {
189 case SNDRV_PCM_TRIGGER_START: 229 case SNDRV_PCM_TRIGGER_START:
190 case SNDRV_PCM_TRIGGER_RESUME: 230 case SNDRV_PCM_TRIGGER_RESUME:
191 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 231 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
192 if (!mcbsp_data->active++) 232 mcbsp_data->active++;
193 omap_mcbsp_start(mcbsp_data->bus_id); 233 omap_mcbsp_start(mcbsp_data->bus_id, play, !play);
194 break; 234 break;
195 235
196 case SNDRV_PCM_TRIGGER_STOP: 236 case SNDRV_PCM_TRIGGER_STOP:
197 case SNDRV_PCM_TRIGGER_SUSPEND: 237 case SNDRV_PCM_TRIGGER_SUSPEND:
198 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 238 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
199 if (!--mcbsp_data->active) 239 omap_mcbsp_stop(mcbsp_data->bus_id, play, !play);
200 omap_mcbsp_stop(mcbsp_data->bus_id); 240 mcbsp_data->active--;
201 break; 241 break;
202 default: 242 default:
203 err = -EINVAL; 243 err = -EINVAL;
@@ -215,7 +255,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
215 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 255 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
216 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 256 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
217 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 257 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
218 int wlen, channels, wpf; 258 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
219 unsigned long port; 259 unsigned long port;
220 unsigned int format; 260 unsigned int format;
221 261
@@ -231,6 +271,12 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
231 } else if (cpu_is_omap343x()) { 271 } else if (cpu_is_omap343x()) {
232 dma = omap24xx_dma_reqs[bus_id][substream->stream]; 272 dma = omap24xx_dma_reqs[bus_id][substream->stream];
233 port = omap34xx_mcbsp_port[bus_id][substream->stream]; 273 port = omap34xx_mcbsp_port[bus_id][substream->stream];
274 omap_mcbsp_dai_dma_params[id][substream->stream].set_threshold =
275 omap_mcbsp_set_threshold;
276 /* TODO: Currently, MODE_ELEMENT == MODE_FRAME */
277 if (omap_mcbsp_get_dma_op_mode(bus_id) ==
278 MCBSP_DMA_MODE_THRESHOLD)
279 sync_mode = OMAP_DMA_SYNC_FRAME;
234 } else { 280 } else {
235 return -ENODEV; 281 return -ENODEV;
236 } 282 }
@@ -238,6 +284,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
238 substream->stream ? "Audio Capture" : "Audio Playback"; 284 substream->stream ? "Audio Capture" : "Audio Playback";
239 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 285 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
240 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 286 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
287 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
241 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 288 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
242 289
243 if (mcbsp_data->configured) { 290 if (mcbsp_data->configured) {
@@ -321,11 +368,14 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
321 /* Generic McBSP register settings */ 368 /* Generic McBSP register settings */
322 regs->spcr2 |= XINTM(3) | FREE; 369 regs->spcr2 |= XINTM(3) | FREE;
323 regs->spcr1 |= RINTM(3); 370 regs->spcr1 |= RINTM(3);
324 regs->rcr2 |= RFIG; 371 /* RFIG and XFIG are not defined in 34xx */
325 regs->xcr2 |= XFIG; 372 if (!cpu_is_omap34xx()) {
373 regs->rcr2 |= RFIG;
374 regs->xcr2 |= XFIG;
375 }
326 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 376 if (cpu_is_omap2430() || cpu_is_omap34xx()) {
327 regs->xccr = DXENDLY(1) | XDMAEN; 377 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
328 regs->rccr = RFULL_CYCLE | RDMAEN; 378 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
329 } 379 }
330 380
331 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 381 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
@@ -462,6 +512,40 @@ static int omap_mcbsp_dai_set_clks_src(struct omap_mcbsp_data *mcbsp_data,
462 return 0; 512 return 0;
463} 513}
464 514
515static int omap_mcbsp_dai_set_rcvr_src(struct omap_mcbsp_data *mcbsp_data,
516 int clk_id)
517{
518 int sel_bit, set = 0;
519 u16 reg = OMAP2_CONTROL_DEVCONF0;
520
521 if (cpu_class_is_omap1())
522 return -EINVAL; /* TODO: Can this be implemented for OMAP1? */
523 if (mcbsp_data->bus_id != 0)
524 return -EINVAL;
525
526 switch (clk_id) {
527 case OMAP_MCBSP_CLKR_SRC_CLKX:
528 set = 1;
529 case OMAP_MCBSP_CLKR_SRC_CLKR:
530 sel_bit = 3;
531 break;
532 case OMAP_MCBSP_FSR_SRC_FSX:
533 set = 1;
534 case OMAP_MCBSP_FSR_SRC_FSR:
535 sel_bit = 4;
536 break;
537 default:
538 return -EINVAL;
539 }
540
541 if (set)
542 omap_ctrl_writel(omap_ctrl_readl(reg) | (1 << sel_bit), reg);
543 else
544 omap_ctrl_writel(omap_ctrl_readl(reg) & ~(1 << sel_bit), reg);
545
546 return 0;
547}
548
465static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, 549static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
466 int clk_id, unsigned int freq, 550 int clk_id, unsigned int freq,
467 int dir) 551 int dir)
@@ -484,6 +568,13 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
484 case OMAP_MCBSP_SYSCLK_CLKR_EXT: 568 case OMAP_MCBSP_SYSCLK_CLKR_EXT:
485 regs->pcr0 |= SCLKME; 569 regs->pcr0 |= SCLKME;
486 break; 570 break;
571
572 case OMAP_MCBSP_CLKR_SRC_CLKR:
573 case OMAP_MCBSP_CLKR_SRC_CLKX:
574 case OMAP_MCBSP_FSR_SRC_FSR:
575 case OMAP_MCBSP_FSR_SRC_FSX:
576 err = omap_mcbsp_dai_set_rcvr_src(mcbsp_data, clk_id);
577 break;
487 default: 578 default:
488 err = -ENODEV; 579 err = -ENODEV;
489 } 580 }
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index c8147aace813..647d2f981ab0 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -32,6 +32,10 @@ enum omap_mcbsp_clksrg_clk {
32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */ 32 OMAP_MCBSP_SYSCLK_CLK, /* Internal ICLK */
33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */ 33 OMAP_MCBSP_SYSCLK_CLKX_EXT, /* External CLKX pin */
34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */ 34 OMAP_MCBSP_SYSCLK_CLKR_EXT, /* External CLKR pin */
35 OMAP_MCBSP_CLKR_SRC_CLKR, /* CLKR from CLKR pin */
36 OMAP_MCBSP_CLKR_SRC_CLKX, /* CLKR from CLKX pin */
37 OMAP_MCBSP_FSR_SRC_FSR, /* FSR from FSR pin */
38 OMAP_MCBSP_FSR_SRC_FSX, /* FSR from FSX pin */
35}; 39};
36 40
37/* McBSP dividers */ 41/* McBSP dividers */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 84a1950880eb..5735945788bf 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -59,16 +59,31 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
59 struct omap_runtime_data *prtd = runtime->private_data; 59 struct omap_runtime_data *prtd = runtime->private_data;
60 unsigned long flags; 60 unsigned long flags;
61 61
62 if (cpu_is_omap1510()) { 62 if ((cpu_is_omap1510()) &&
63 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
63 /* 64 /*
64 * OMAP1510 doesn't support DMA chaining so have to restart 65 * OMAP1510 doesn't fully support DMA progress counter
65 * the transfer after all periods are transferred 66 * and there is no software emulation implemented yet,
67 * so have to maintain our own playback progress counter
68 * that can be used by omap_pcm_pointer() instead.
66 */ 69 */
67 spin_lock_irqsave(&prtd->lock, flags); 70 spin_lock_irqsave(&prtd->lock, flags);
71 if ((stat == OMAP_DMA_LAST_IRQ) &&
72 (prtd->period_index == runtime->periods - 1)) {
73 /* we are in sync, do nothing */
74 spin_unlock_irqrestore(&prtd->lock, flags);
75 return;
76 }
68 if (prtd->period_index >= 0) { 77 if (prtd->period_index >= 0) {
69 if (++prtd->period_index == runtime->periods) { 78 if (stat & OMAP_DMA_BLOCK_IRQ) {
79 /* end of buffer reached, loop back */
80 prtd->period_index = 0;
81 } else if (stat & OMAP_DMA_LAST_IRQ) {
82 /* update the counter for the last period */
83 prtd->period_index = runtime->periods - 1;
84 } else if (++prtd->period_index >= runtime->periods) {
85 /* end of buffer missed? loop back */
70 prtd->period_index = 0; 86 prtd->period_index = 0;
71 omap_start_dma(prtd->dma_ch);
72 } 87 }
73 } 88 }
74 spin_unlock_irqrestore(&prtd->lock, flags); 89 spin_unlock_irqrestore(&prtd->lock, flags);
@@ -100,7 +115,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
100 prtd->dma_data = dma_data; 115 prtd->dma_data = dma_data;
101 err = omap_request_dma(dma_data->dma_req, dma_data->name, 116 err = omap_request_dma(dma_data->dma_req, dma_data->name,
102 omap_pcm_dma_irq, substream, &prtd->dma_ch); 117 omap_pcm_dma_irq, substream, &prtd->dma_ch);
103 if (!err && !cpu_is_omap1510()) { 118 if (!err) {
104 /* 119 /*
105 * Link channel with itself so DMA doesn't need any 120 * Link channel with itself so DMA doesn't need any
106 * reprogramming while looping the buffer 121 * reprogramming while looping the buffer
@@ -119,8 +134,7 @@ static int omap_pcm_hw_free(struct snd_pcm_substream *substream)
119 if (prtd->dma_data == NULL) 134 if (prtd->dma_data == NULL)
120 return 0; 135 return 0;
121 136
122 if (!cpu_is_omap1510()) 137 omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
123 omap_dma_unlink_lch(prtd->dma_ch, prtd->dma_ch);
124 omap_free_dma(prtd->dma_ch); 138 omap_free_dma(prtd->dma_ch);
125 prtd->dma_data = NULL; 139 prtd->dma_data = NULL;
126 140
@@ -148,7 +162,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
148 */ 162 */
149 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16; 163 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
150 dma_params.trigger = dma_data->dma_req; 164 dma_params.trigger = dma_data->dma_req;
151 dma_params.sync_mode = OMAP_DMA_SYNC_ELEMENT; 165 dma_params.sync_mode = dma_data->sync_mode;
152 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
153 dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; 167 dma_params.src_amode = OMAP_DMA_AMODE_POST_INC;
154 dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; 168 dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT;
@@ -174,7 +188,15 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
174 dma_params.frame_count = runtime->periods; 188 dma_params.frame_count = runtime->periods;
175 omap_set_dma_params(prtd->dma_ch, &dma_params); 189 omap_set_dma_params(prtd->dma_ch, &dma_params);
176 190
177 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 191 if ((cpu_is_omap1510()) &&
192 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
193 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
194 OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
195 else
196 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
197
198 omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
199 omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16);
178 200
179 return 0; 201 return 0;
180} 202}
@@ -183,6 +205,7 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
183{ 205{
184 struct snd_pcm_runtime *runtime = substream->runtime; 206 struct snd_pcm_runtime *runtime = substream->runtime;
185 struct omap_runtime_data *prtd = runtime->private_data; 207 struct omap_runtime_data *prtd = runtime->private_data;
208 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
186 unsigned long flags; 209 unsigned long flags;
187 int ret = 0; 210 int ret = 0;
188 211
@@ -192,6 +215,10 @@ static int omap_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
192 case SNDRV_PCM_TRIGGER_RESUME: 215 case SNDRV_PCM_TRIGGER_RESUME:
193 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 216 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
194 prtd->period_index = 0; 217 prtd->period_index = 0;
218 /* Configure McBSP internal buffer usage */
219 if (dma_data->set_threshold)
220 dma_data->set_threshold(substream);
221
195 omap_start_dma(prtd->dma_ch); 222 omap_start_dma(prtd->dma_ch);
196 break; 223 break;
197 224
@@ -288,7 +315,7 @@ static struct snd_pcm_ops omap_pcm_ops = {
288 .mmap = omap_pcm_mmap, 315 .mmap = omap_pcm_mmap,
289}; 316};
290 317
291static u64 omap_pcm_dmamask = DMA_BIT_MASK(32); 318static u64 omap_pcm_dmamask = DMA_BIT_MASK(64);
292 319
293static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, 320static int omap_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
294 int stream) 321 int stream)
@@ -330,7 +357,7 @@ static void omap_pcm_free_dma_buffers(struct snd_pcm *pcm)
330 } 357 }
331} 358}
332 359
333int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, 360static int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
334 struct snd_pcm *pcm) 361 struct snd_pcm *pcm)
335{ 362{
336 int ret = 0; 363 int ret = 0;
@@ -338,7 +365,7 @@ int omap_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
338 if (!card->dev->dma_mask) 365 if (!card->dev->dma_mask)
339 card->dev->dma_mask = &omap_pcm_dmamask; 366 card->dev->dma_mask = &omap_pcm_dmamask;
340 if (!card->dev->coherent_dma_mask) 367 if (!card->dev->coherent_dma_mask)
341 card->dev->coherent_dma_mask = DMA_BIT_MASK(32); 368 card->dev->coherent_dma_mask = DMA_BIT_MASK(64);
342 369
343 if (dai->playback.channels_min) { 370 if (dai->playback.channels_min) {
344 ret = omap_pcm_preallocate_dma_buffer(pcm, 371 ret = omap_pcm_preallocate_dma_buffer(pcm,
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index 8d9d26916b05..38a821dd4118 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -29,6 +29,8 @@ struct omap_pcm_dma_data {
29 char *name; /* stream identifier */ 29 char *name; /* stream identifier */
30 int dma_req; /* DMA request line */ 30 int dma_req; /* DMA request line */
31 unsigned long port_addr; /* transmit/receive register */ 31 unsigned long port_addr; /* transmit/receive register */
32 int sync_mode; /* DMA sync mode */
33 void (*set_threshold)(struct snd_pcm_substream *substream);
32}; 34};
33 35
34extern struct snd_soc_platform omap_soc_platform; 36extern struct snd_soc_platform omap_soc_platform;
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index b719e5db4f57..4a3f62d1f295 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/i2c/twl4030.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
@@ -39,6 +40,11 @@
39#include "omap-pcm.h" 40#include "omap-pcm.h"
40#include "../codecs/twl4030.h" 41#include "../codecs/twl4030.h"
41 42
43/* TWL4030 PMBR1 Register */
44#define TWL4030_INTBR_PMBR1 0x0D
45/* TWL4030 PMBR1 Register GPIO6 mux bit */
46#define TWL4030_GPIO6_PWM0_MUTE(value) (value << 2)
47
42static struct snd_soc_card snd_soc_sdp3430; 48static struct snd_soc_card snd_soc_sdp3430;
43 49
44static int sdp3430_hw_params(struct snd_pcm_substream *substream, 50static int sdp3430_hw_params(struct snd_pcm_substream *substream,
@@ -96,7 +102,7 @@ static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream,
96 ret = snd_soc_dai_set_fmt(codec_dai, 102 ret = snd_soc_dai_set_fmt(codec_dai,
97 SND_SOC_DAIFMT_DSP_A | 103 SND_SOC_DAIFMT_DSP_A |
98 SND_SOC_DAIFMT_IB_NF | 104 SND_SOC_DAIFMT_IB_NF |
99 SND_SOC_DAIFMT_CBS_CFM); 105 SND_SOC_DAIFMT_CBM_CFM);
100 if (ret) { 106 if (ret) {
101 printk(KERN_ERR "can't set codec DAI configuration\n"); 107 printk(KERN_ERR "can't set codec DAI configuration\n");
102 return ret; 108 return ret;
@@ -280,6 +286,7 @@ static struct snd_soc_card snd_soc_sdp3430 = {
280static struct twl4030_setup_data twl4030_setup = { 286static struct twl4030_setup_data twl4030_setup = {
281 .ramp_delay_value = 3, 287 .ramp_delay_value = 3,
282 .sysclk = 26000, 288 .sysclk = 26000,
289 .hs_extmute = 1,
283}; 290};
284 291
285/* Audio subsystem */ 292/* Audio subsystem */
@@ -294,6 +301,7 @@ static struct platform_device *sdp3430_snd_device;
294static int __init sdp3430_soc_init(void) 301static int __init sdp3430_soc_init(void)
295{ 302{
296 int ret; 303 int ret;
304 u8 pin_mux;
297 305
298 if (!machine_is_omap_3430sdp()) { 306 if (!machine_is_omap_3430sdp()) {
299 pr_debug("Not SDP3430!\n"); 307 pr_debug("Not SDP3430!\n");
@@ -312,6 +320,14 @@ static int __init sdp3430_soc_init(void)
312 *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */ 320 *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
313 *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ 321 *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
314 322
323 /* Set TWL4030 GPIO6 as EXTMUTE signal */
324 twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
325 TWL4030_INTBR_PMBR1);
326 pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
327 pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
328 twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
329 TWL4030_INTBR_PMBR1);
330
315 ret = platform_device_add(sdp3430_snd_device); 331 ret = platform_device_add(sdp3430_snd_device);
316 if (ret) 332 if (ret)
317 goto err1; 333 goto err1;
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
new file mode 100644
index 000000000000..f90b45f56220
--- /dev/null
+++ b/sound/soc/omap/zoom2.c
@@ -0,0 +1,314 @@
1/*
2 * zoom2.c -- SoC audio for Zoom2
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.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
38#define ZOOM2_HEADSET_MUX_GPIO (OMAP_MAX_GPIO_LINES + 15)
39#define ZOOM2_HEADSET_EXTMUTE_GPIO 153
40
41static int zoom2_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 zoom2_ops = {
81 .hw_params = zoom2_hw_params,
82};
83
84static int zoom2_hw_voice_params(struct snd_pcm_substream *substream,
85 struct snd_pcm_hw_params *params)
86{
87 struct snd_soc_pcm_runtime *rtd = substream->private_data;
88 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
89 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
90 int ret;
91
92 /* Set codec DAI configuration */
93 ret = snd_soc_dai_set_fmt(codec_dai,
94 SND_SOC_DAIFMT_DSP_A |
95 SND_SOC_DAIFMT_IB_NF |
96 SND_SOC_DAIFMT_CBM_CFM);
97 if (ret) {
98 printk(KERN_ERR "can't set codec DAI configuration\n");
99 return ret;
100 }
101
102 /* Set cpu DAI configuration */
103 ret = snd_soc_dai_set_fmt(cpu_dai,
104 SND_SOC_DAIFMT_DSP_A |
105 SND_SOC_DAIFMT_IB_NF |
106 SND_SOC_DAIFMT_CBM_CFM);
107 if (ret < 0) {
108 printk(KERN_ERR "can't set cpu DAI configuration\n");
109 return ret;
110 }
111
112 /* Set the codec system clock for DAC and ADC */
113 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
114 SND_SOC_CLOCK_IN);
115 if (ret < 0) {
116 printk(KERN_ERR "can't set codec system clock\n");
117 return ret;
118 }
119
120 return 0;
121}
122
123static struct snd_soc_ops zoom2_voice_ops = {
124 .hw_params = zoom2_hw_voice_params,
125};
126
127/* Zoom2 machine DAPM */
128static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = {
129 SND_SOC_DAPM_MIC("Ext Mic", NULL),
130 SND_SOC_DAPM_SPK("Ext Spk", NULL),
131 SND_SOC_DAPM_MIC("Headset Mic", NULL),
132 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
133 SND_SOC_DAPM_LINE("Aux In", NULL),
134};
135
136static const struct snd_soc_dapm_route audio_map[] = {
137 /* External Mics: MAINMIC, SUBMIC with bias*/
138 {"MAINMIC", NULL, "Mic Bias 1"},
139 {"SUBMIC", NULL, "Mic Bias 2"},
140 {"Mic Bias 1", NULL, "Ext Mic"},
141 {"Mic Bias 2", NULL, "Ext Mic"},
142
143 /* External Speakers: HFL, HFR */
144 {"Ext Spk", NULL, "HFL"},
145 {"Ext Spk", NULL, "HFR"},
146
147 /* Headset Stereophone: HSOL, HSOR */
148 {"Headset Stereophone", NULL, "HSOL"},
149 {"Headset Stereophone", NULL, "HSOR"},
150
151 /* Headset Mic: HSMIC with bias */
152 {"HSMIC", NULL, "Headset Mic Bias"},
153 {"Headset Mic Bias", NULL, "Headset Mic"},
154
155 /* Aux In: AUXL, AUXR */
156 {"Aux In", NULL, "AUXL"},
157 {"Aux In", NULL, "AUXR"},
158};
159
160static int zoom2_twl4030_init(struct snd_soc_codec *codec)
161{
162 int ret;
163
164 /* Add Zoom2 specific widgets */
165 ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets,
166 ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
167 if (ret)
168 return ret;
169
170 /* Set up Zoom2 specific audio path audio_map */
171 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
172
173 /* Zoom2 connected pins */
174 snd_soc_dapm_enable_pin(codec, "Ext Mic");
175 snd_soc_dapm_enable_pin(codec, "Ext Spk");
176 snd_soc_dapm_enable_pin(codec, "Headset Mic");
177 snd_soc_dapm_enable_pin(codec, "Headset Stereophone");
178 snd_soc_dapm_enable_pin(codec, "Aux In");
179
180 /* TWL4030 not connected pins */
181 snd_soc_dapm_nc_pin(codec, "CARKITMIC");
182 snd_soc_dapm_nc_pin(codec, "DIGIMIC0");
183 snd_soc_dapm_nc_pin(codec, "DIGIMIC1");
184
185 snd_soc_dapm_nc_pin(codec, "OUTL");
186 snd_soc_dapm_nc_pin(codec, "OUTR");
187 snd_soc_dapm_nc_pin(codec, "EARPIECE");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVEL");
189 snd_soc_dapm_nc_pin(codec, "PREDRIVER");
190 snd_soc_dapm_nc_pin(codec, "CARKITL");
191 snd_soc_dapm_nc_pin(codec, "CARKITR");
192
193 ret = snd_soc_dapm_sync(codec);
194
195 return ret;
196}
197
198static int zoom2_twl4030_voice_init(struct snd_soc_codec *codec)
199{
200 unsigned short reg;
201
202 /* Enable voice interface */
203 reg = codec->read(codec, TWL4030_REG_VOICE_IF);
204 reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN;
205 codec->write(codec, TWL4030_REG_VOICE_IF, reg);
206
207 return 0;
208}
209
210/* Digital audio interface glue - connects codec <--> CPU */
211static struct snd_soc_dai_link zoom2_dai[] = {
212 {
213 .name = "TWL4030 I2S",
214 .stream_name = "TWL4030 Audio",
215 .cpu_dai = &omap_mcbsp_dai[0],
216 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
217 .init = zoom2_twl4030_init,
218 .ops = &zoom2_ops,
219 },
220 {
221 .name = "TWL4030 PCM",
222 .stream_name = "TWL4030 Voice",
223 .cpu_dai = &omap_mcbsp_dai[1],
224 .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE],
225 .init = zoom2_twl4030_voice_init,
226 .ops = &zoom2_voice_ops,
227 },
228};
229
230/* Audio machine driver */
231static struct snd_soc_card snd_soc_zoom2 = {
232 .name = "Zoom2",
233 .platform = &omap_soc_platform,
234 .dai_link = zoom2_dai,
235 .num_links = ARRAY_SIZE(zoom2_dai),
236};
237
238/* EXTMUTE callback function */
239void zoom2_set_hs_extmute(int mute)
240{
241 gpio_set_value(ZOOM2_HEADSET_EXTMUTE_GPIO, mute);
242}
243
244/* twl4030 setup */
245static struct twl4030_setup_data twl4030_setup = {
246 .ramp_delay_value = 3, /* 161 ms */
247 .sysclk = 26000,
248 .hs_extmute = 1,
249 .set_hs_extmute = zoom2_set_hs_extmute,
250};
251
252/* Audio subsystem */
253static struct snd_soc_device zoom2_snd_devdata = {
254 .card = &snd_soc_zoom2,
255 .codec_dev = &soc_codec_dev_twl4030,
256 .codec_data = &twl4030_setup,
257};
258
259static struct platform_device *zoom2_snd_device;
260
261static int __init zoom2_soc_init(void)
262{
263 int ret;
264
265 if (!machine_is_omap_zoom2()) {
266 pr_debug("Not Zoom2!\n");
267 return -ENODEV;
268 }
269 printk(KERN_INFO "Zoom2 SoC init\n");
270
271 zoom2_snd_device = platform_device_alloc("soc-audio", -1);
272 if (!zoom2_snd_device) {
273 printk(KERN_ERR "Platform device allocation failed\n");
274 return -ENOMEM;
275 }
276
277 platform_set_drvdata(zoom2_snd_device, &zoom2_snd_devdata);
278 zoom2_snd_devdata.dev = &zoom2_snd_device->dev;
279 *(unsigned int *)zoom2_dai[0].cpu_dai->private_data = 1; /* McBSP2 */
280 *(unsigned int *)zoom2_dai[1].cpu_dai->private_data = 2; /* McBSP3 */
281
282 ret = platform_device_add(zoom2_snd_device);
283 if (ret)
284 goto err1;
285
286 BUG_ON(gpio_request(ZOOM2_HEADSET_MUX_GPIO, "hs_mux") < 0);
287 gpio_direction_output(ZOOM2_HEADSET_MUX_GPIO, 0);
288
289 BUG_ON(gpio_request(ZOOM2_HEADSET_EXTMUTE_GPIO, "ext_mute") < 0);
290 gpio_direction_output(ZOOM2_HEADSET_EXTMUTE_GPIO, 0);
291
292 return 0;
293
294err1:
295 printk(KERN_ERR "Unable to add platform device\n");
296 platform_device_put(zoom2_snd_device);
297
298 return ret;
299}
300module_init(zoom2_soc_init);
301
302static void __exit zoom2_soc_exit(void)
303{
304 gpio_free(ZOOM2_HEADSET_MUX_GPIO);
305 gpio_free(ZOOM2_HEADSET_EXTMUTE_GPIO);
306
307 platform_device_unregister(zoom2_snd_device);
308}
309module_exit(zoom2_soc_exit);
310
311MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
312MODULE_DESCRIPTION("ALSA SoC Zoom2");
313MODULE_LICENSE("GPL");
314
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 326955dea36c..9f7c61e23daf 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -20,12 +20,14 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <linux/i2c.h>
23 24
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
27#include <sound/soc.h> 28#include <sound/soc.h>
28#include <sound/soc-dapm.h> 29#include <sound/soc-dapm.h>
30#include <sound/uda1380.h>
29 31
30#include <mach/magician.h> 32#include <mach/magician.h>
31#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -188,7 +190,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
188 if (ret < 0) 190 if (ret < 0)
189 return ret; 191 return ret;
190 192
191 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 1); 193 ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 0, 1, width);
192 if (ret < 0) 194 if (ret < 0)
193 return ret; 195 return ret;
194 196
@@ -447,34 +449,47 @@ static struct snd_soc_card snd_soc_card_magician = {
447 .platform = &pxa2xx_soc_platform, 449 .platform = &pxa2xx_soc_platform,
448}; 450};
449 451
450/* magician audio private data */
451static struct uda1380_setup_data magician_uda1380_setup = {
452 .i2c_address = 0x18,
453 .dac_clk = UDA1380_DAC_CLK_WSPLL,
454};
455
456/* magician audio subsystem */ 452/* magician audio subsystem */
457static struct snd_soc_device magician_snd_devdata = { 453static struct snd_soc_device magician_snd_devdata = {
458 .card = &snd_soc_card_magician, 454 .card = &snd_soc_card_magician,
459 .codec_dev = &soc_codec_dev_uda1380, 455 .codec_dev = &soc_codec_dev_uda1380,
460 .codec_data = &magician_uda1380_setup,
461}; 456};
462 457
463static struct platform_device *magician_snd_device; 458static struct platform_device *magician_snd_device;
464 459
460/*
461 * FIXME: move into magician board file once merged into the pxa tree
462 */
463static struct uda1380_platform_data uda1380_info = {
464 .gpio_power = EGPIO_MAGICIAN_CODEC_POWER,
465 .gpio_reset = EGPIO_MAGICIAN_CODEC_RESET,
466 .dac_clk = UDA1380_DAC_CLK_WSPLL,
467};
468
469static struct i2c_board_info i2c_board_info[] = {
470 {
471 I2C_BOARD_INFO("uda1380", 0x18),
472 .platform_data = &uda1380_info,
473 },
474};
475
465static int __init magician_init(void) 476static int __init magician_init(void)
466{ 477{
467 int ret; 478 int ret;
479 struct i2c_adapter *adapter;
480 struct i2c_client *client;
468 481
469 if (!machine_is_magician()) 482 if (!machine_is_magician())
470 return -ENODEV; 483 return -ENODEV;
471 484
472 ret = gpio_request(EGPIO_MAGICIAN_CODEC_POWER, "CODEC_POWER"); 485 adapter = i2c_get_adapter(0);
473 if (ret) 486 if (!adapter)
474 goto err_request_power; 487 return -ENODEV;
475 ret = gpio_request(EGPIO_MAGICIAN_CODEC_RESET, "CODEC_RESET"); 488 client = i2c_new_device(adapter, i2c_board_info);
476 if (ret) 489 i2c_put_adapter(adapter);
477 goto err_request_reset; 490 if (!client)
491 return -ENODEV;
492
478 ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER"); 493 ret = gpio_request(EGPIO_MAGICIAN_SPK_POWER, "SPK_POWER");
479 if (ret) 494 if (ret)
480 goto err_request_spk; 495 goto err_request_spk;
@@ -491,14 +506,8 @@ static int __init magician_init(void)
491 if (ret) 506 if (ret)
492 goto err_request_in_sel1; 507 goto err_request_in_sel1;
493 508
494 gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 1);
495 gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0); 509 gpio_set_value(EGPIO_MAGICIAN_IN_SEL0, 0);
496 510
497 /* we may need to have the clock running here - pH5 */
498 gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 1);
499 udelay(5);
500 gpio_set_value(EGPIO_MAGICIAN_CODEC_RESET, 0);
501
502 magician_snd_device = platform_device_alloc("soc-audio", -1); 511 magician_snd_device = platform_device_alloc("soc-audio", -1);
503 if (!magician_snd_device) { 512 if (!magician_snd_device) {
504 ret = -ENOMEM; 513 ret = -ENOMEM;
@@ -526,10 +535,6 @@ err_request_mic:
526err_request_ep: 535err_request_ep:
527 gpio_free(EGPIO_MAGICIAN_SPK_POWER); 536 gpio_free(EGPIO_MAGICIAN_SPK_POWER);
528err_request_spk: 537err_request_spk:
529 gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
530err_request_reset:
531 gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
532err_request_power:
533 return ret; 538 return ret;
534} 539}
535 540
@@ -540,15 +545,12 @@ static void __exit magician_exit(void)
540 gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0); 545 gpio_set_value(EGPIO_MAGICIAN_SPK_POWER, 0);
541 gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0); 546 gpio_set_value(EGPIO_MAGICIAN_EP_POWER, 0);
542 gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0); 547 gpio_set_value(EGPIO_MAGICIAN_MIC_POWER, 0);
543 gpio_set_value(EGPIO_MAGICIAN_CODEC_POWER, 0);
544 548
545 gpio_free(EGPIO_MAGICIAN_IN_SEL1); 549 gpio_free(EGPIO_MAGICIAN_IN_SEL1);
546 gpio_free(EGPIO_MAGICIAN_IN_SEL0); 550 gpio_free(EGPIO_MAGICIAN_IN_SEL0);
547 gpio_free(EGPIO_MAGICIAN_MIC_POWER); 551 gpio_free(EGPIO_MAGICIAN_MIC_POWER);
548 gpio_free(EGPIO_MAGICIAN_EP_POWER); 552 gpio_free(EGPIO_MAGICIAN_EP_POWER);
549 gpio_free(EGPIO_MAGICIAN_SPK_POWER); 553 gpio_free(EGPIO_MAGICIAN_SPK_POWER);
550 gpio_free(EGPIO_MAGICIAN_CODEC_RESET);
551 gpio_free(EGPIO_MAGICIAN_CODEC_POWER);
552} 554}
553 555
554module_init(magician_init); 556module_init(magician_init);
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index e6102fda0a7f..1f96e3227be5 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -17,13 +17,12 @@
17#include <linux/moduleparam.h> 17#include <linux/moduleparam.h>
18#include <linux/device.h> 18#include <linux/device.h>
19#include <linux/gpio.h> 19#include <linux/gpio.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22 20
23#include <sound/core.h> 21#include <sound/core.h>
24#include <sound/pcm.h> 22#include <sound/pcm.h>
25#include <sound/soc.h> 23#include <sound/soc.h>
26#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25#include <sound/jack.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/audio.h> 28#include <mach/audio.h>
@@ -33,90 +32,31 @@
33#include "pxa2xx-pcm.h" 32#include "pxa2xx-pcm.h"
34#include "pxa2xx-ac97.h" 33#include "pxa2xx-ac97.h"
35 34
36static int palm27x_jack_func = 1; 35static struct snd_soc_jack hs_jack;
37static int palm27x_spk_func = 1;
38static int palm27x_ep_gpio = -1;
39 36
40static void palm27x_ext_control(struct snd_soc_codec *codec) 37/* Headphones jack detection DAPM pins */
41{ 38static struct snd_soc_jack_pin hs_jack_pins[] = {
42 if (!palm27x_spk_func) 39 {
43 snd_soc_dapm_enable_pin(codec, "Speaker"); 40 .pin = "Headphone Jack",
44 else 41 .mask = SND_JACK_HEADPHONE,
45 snd_soc_dapm_disable_pin(codec, "Speaker"); 42 },
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->card->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}; 43};
68 44
69static irqreturn_t palm27x_interrupt(int irq, void *v) 45/* Headphones jack detection gpios */
70{ 46static struct snd_soc_jack_gpio hs_jack_gpios[] = {
71 palm27x_spk_func = gpio_get_value(palm27x_ep_gpio); 47 [0] = {
72 palm27x_jack_func = !palm27x_spk_func; 48 /* gpio is set on per-platform basis */
73 return IRQ_HANDLED; 49 .name = "hp-gpio",
74} 50 .report = SND_JACK_HEADPHONE,
75 51 .debounce_time = 200,
76static int palm27x_get_jack(struct snd_kcontrol *kcontrol, 52 },
77 struct snd_ctl_elem_value *ucontrol) 53};
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 54
116/* PalmTX machine dapm widgets */ 55/* Palm27x machine dapm widgets */
117static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = { 56static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", NULL), 57 SND_SOC_DAPM_HP("Headphone Jack", NULL),
119 SND_SOC_DAPM_SPK("Speaker", NULL), 58 SND_SOC_DAPM_SPK("Ext. Speaker", NULL),
59 SND_SOC_DAPM_MIC("Ext. Microphone", NULL),
120}; 60};
121 61
122/* PalmTX audio map */ 62/* PalmTX audio map */
@@ -126,46 +66,66 @@ static const struct snd_soc_dapm_route audio_map[] = {
126 {"Headphone Jack", NULL, "HPOUTR"}, 66 {"Headphone Jack", NULL, "HPOUTR"},
127 67
128 /* ext speaker connected to ROUT2, LOUT2 */ 68 /* ext speaker connected to ROUT2, LOUT2 */
129 {"Speaker", NULL, "LOUT2"}, 69 {"Ext. Speaker", NULL, "LOUT2"},
130 {"Speaker", NULL, "ROUT2"}, 70 {"Ext. Speaker", NULL, "ROUT2"},
131};
132 71
133static const char *jack_function[] = {"Headphone", "Off"}; 72 /* mic connected to MIC1 */
134static const char *spk_function[] = {"On", "Off"}; 73 {"Ext. Microphone", NULL, "MIC1"},
135static const struct soc_enum palm27x_enum[] = {
136 SOC_ENUM_SINGLE_EXT(2, jack_function),
137 SOC_ENUM_SINGLE_EXT(2, spk_function),
138}; 74};
139 75
140static const struct snd_kcontrol_new palm27x_controls[] = { 76static struct snd_soc_card palm27x_asoc;
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 77
147static int palm27x_ac97_init(struct snd_soc_codec *codec) 78static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{ 79{
149 int err; 80 int err;
150 81
82 /* add palm27x specific widgets */
83 err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
84 ARRAY_SIZE(palm27x_dapm_widgets));
85 if (err)
86 return err;
87
88 /* set up palm27x specific audio path audio_map */
89 err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
90 if (err)
91 return err;
92
93 /* connected pins */
94 if (machine_is_palmld())
95 snd_soc_dapm_enable_pin(codec, "MIC1");
96 snd_soc_dapm_enable_pin(codec, "HPOUTL");
97 snd_soc_dapm_enable_pin(codec, "HPOUTR");
98 snd_soc_dapm_enable_pin(codec, "LOUT2");
99 snd_soc_dapm_enable_pin(codec, "ROUT2");
100
101 /* not connected pins */
151 snd_soc_dapm_nc_pin(codec, "OUT3"); 102 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 103 snd_soc_dapm_nc_pin(codec, "MONOOUT");
104 snd_soc_dapm_nc_pin(codec, "LINEINL");
105 snd_soc_dapm_nc_pin(codec, "LINEINR");
106 snd_soc_dapm_nc_pin(codec, "PCBEEP");
107 snd_soc_dapm_nc_pin(codec, "PHONE");
108 snd_soc_dapm_nc_pin(codec, "MIC2");
109
110 err = snd_soc_dapm_sync(codec);
111 if (err)
112 return err;
153 113
154 /* add palm27x specific controls */ 114 /* Jack detection API stuff */
155 err = snd_soc_add_controls(codec, palm27x_controls, 115 err = snd_soc_jack_new(&palm27x_asoc, "Headphone Jack",
156 ARRAY_SIZE(palm27x_controls)); 116 SND_JACK_HEADPHONE, &hs_jack);
157 if (err < 0) 117 if (err)
158 return err; 118 return err;
159 119
160 /* add palm27x specific widgets */ 120 err = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
161 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, 121 hs_jack_pins);
162 ARRAY_SIZE(palm27x_dapm_widgets)); 122 if (err)
123 return err;
163 124
164 /* set up palm27x specific audio path audio_map */ 125 err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios),
165 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 126 hs_jack_gpios);
166 127
167 snd_soc_dapm_sync(codec); 128 return err;
168 return 0;
169} 129}
170 130
171static struct snd_soc_dai_link palm27x_dai[] = { 131static struct snd_soc_dai_link palm27x_dai[] = {
@@ -175,14 +135,12 @@ static struct snd_soc_dai_link palm27x_dai[] = {
175 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI], 135 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
176 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], 136 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
177 .init = palm27x_ac97_init, 137 .init = palm27x_ac97_init,
178 .ops = &palm27x_ops,
179}, 138},
180{ 139{
181 .name = "AC97 Aux", 140 .name = "AC97 Aux",
182 .stream_name = "AC97 Aux", 141 .stream_name = "AC97 Aux",
183 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX], 142 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
184 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], 143 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
185 .ops = &palm27x_ops,
186}, 144},
187}; 145};
188 146
@@ -208,27 +166,17 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
208 machine_is_palmld() || machine_is_palmte2())) 166 machine_is_palmld() || machine_is_palmte2()))
209 return -ENODEV; 167 return -ENODEV;
210 168
211 if (pdev->dev.platform_data) 169 if (!pdev->dev.platform_data) {
212 palm27x_ep_gpio = ((struct palm27x_asoc_info *) 170 dev_err(&pdev->dev, "please supply platform_data\n");
213 (pdev->dev.platform_data))->jack_gpio; 171 return -ENODEV;
214 172 }
215 ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
216 if (ret)
217 return ret;
218 ret = gpio_direction_input(palm27x_ep_gpio);
219 if (ret)
220 goto err_alloc;
221 173
222 if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt, 174 hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *)
223 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 175 (pdev->dev.platform_data))->jack_gpio;
224 "Headphone jack", NULL))
225 goto err_alloc;
226 176
227 palm27x_snd_device = platform_device_alloc("soc-audio", -1); 177 palm27x_snd_device = platform_device_alloc("soc-audio", -1);
228 if (!palm27x_snd_device) { 178 if (!palm27x_snd_device)
229 ret = -ENOMEM; 179 return -ENOMEM;
230 goto err_dev;
231 }
232 180
233 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata); 181 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
234 palm27x_snd_devdata.dev = &palm27x_snd_device->dev; 182 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
@@ -241,18 +189,12 @@ static int palm27x_asoc_probe(struct platform_device *pdev)
241 189
242put_device: 190put_device:
243 platform_device_put(palm27x_snd_device); 191 platform_device_put(palm27x_snd_device);
244err_dev:
245 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
246err_alloc:
247 gpio_free(palm27x_ep_gpio);
248 192
249 return ret; 193 return ret;
250} 194}
251 195
252static int __devexit palm27x_asoc_remove(struct platform_device *pdev) 196static int __devexit palm27x_asoc_remove(struct platform_device *pdev)
253{ 197{
254 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
255 gpio_free(palm27x_ep_gpio);
256 platform_device_unregister(palm27x_snd_device); 198 platform_device_unregister(palm27x_snd_device);
257 return 0; 199 return 0;
258} 200}
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 19c45409d94c..5b9ed6464789 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -375,21 +375,34 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
375 * Set the active slots in TDM/Network mode 375 * Set the active slots in TDM/Network mode
376 */ 376 */
377static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, 377static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
378 unsigned int mask, int slots) 378 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
379{ 379{
380 struct ssp_priv *priv = cpu_dai->private_data; 380 struct ssp_priv *priv = cpu_dai->private_data;
381 struct ssp_device *ssp = priv->dev.ssp; 381 struct ssp_device *ssp = priv->dev.ssp;
382 u32 sscr0; 382 u32 sscr0;
383 383
384 sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7); 384 sscr0 = ssp_read_reg(ssp, SSCR0);
385 sscr0 &= ~(SSCR0_MOD | SSCR0_SlotsPerFrm(8) | SSCR0_EDSS | SSCR0_DSS);
386
387 /* set slot width */
388 if (slot_width > 16)
389 sscr0 |= SSCR0_EDSS | SSCR0_DataSize(slot_width - 16);
390 else
391 sscr0 |= SSCR0_DataSize(slot_width);
392
393 if (slots > 1) {
394 /* enable network mode */
395 sscr0 |= SSCR0_MOD;
385 396
386 /* set number of active slots */ 397 /* set number of active slots */
387 sscr0 |= SSCR0_SlotsPerFrm(slots); 398 sscr0 |= SSCR0_SlotsPerFrm(slots);
399
400 /* set active slot mask */
401 ssp_write_reg(ssp, SSTSA, tx_mask);
402 ssp_write_reg(ssp, SSRSA, rx_mask);
403 }
388 ssp_write_reg(ssp, SSCR0, sscr0); 404 ssp_write_reg(ssp, SSCR0, sscr0);
389 405
390 /* set active slot mask */
391 ssp_write_reg(ssp, SSTSA, mask);
392 ssp_write_reg(ssp, SSRSA, mask);
393 return 0; 406 return 0;
394} 407}
395 408
@@ -457,31 +470,27 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
457 return -EINVAL; 470 return -EINVAL;
458 } 471 }
459 472
460 ssp_write_reg(ssp, SSCR0, sscr0); 473 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
461 ssp_write_reg(ssp, SSCR1, sscr1); 474 case SND_SOC_DAIFMT_NB_NF:
462 ssp_write_reg(ssp, SSPSP, sspsp); 475 sspsp |= SSPSP_SFRMP;
476 break;
477 case SND_SOC_DAIFMT_NB_IF:
478 break;
479 case SND_SOC_DAIFMT_IB_IF:
480 sspsp |= SSPSP_SCMODE(2);
481 break;
482 case SND_SOC_DAIFMT_IB_NF:
483 sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
484 break;
485 default:
486 return -EINVAL;
487 }
463 488
464 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 489 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
465 case SND_SOC_DAIFMT_I2S: 490 case SND_SOC_DAIFMT_I2S:
466 sscr0 |= SSCR0_PSP; 491 sscr0 |= SSCR0_PSP;
467 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL; 492 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
468
469 /* See hw_params() */ 493 /* See hw_params() */
470 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
471 case SND_SOC_DAIFMT_NB_NF:
472 sspsp |= SSPSP_SFRMP;
473 break;
474 case SND_SOC_DAIFMT_NB_IF:
475 break;
476 case SND_SOC_DAIFMT_IB_IF:
477 sspsp |= SSPSP_SCMODE(2);
478 break;
479 case SND_SOC_DAIFMT_IB_NF:
480 sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
481 break;
482 default:
483 return -EINVAL;
484 }
485 break; 494 break;
486 495
487 case SND_SOC_DAIFMT_DSP_A: 496 case SND_SOC_DAIFMT_DSP_A:
@@ -489,22 +498,6 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
489 case SND_SOC_DAIFMT_DSP_B: 498 case SND_SOC_DAIFMT_DSP_B:
490 sscr0 |= SSCR0_MOD | SSCR0_PSP; 499 sscr0 |= SSCR0_MOD | SSCR0_PSP;
491 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT; 500 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
492
493 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
494 case SND_SOC_DAIFMT_NB_NF:
495 sspsp |= SSPSP_SFRMP;
496 break;
497 case SND_SOC_DAIFMT_NB_IF:
498 break;
499 case SND_SOC_DAIFMT_IB_IF:
500 sspsp |= SSPSP_SCMODE(2);
501 break;
502 case SND_SOC_DAIFMT_IB_NF:
503 sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP;
504 break;
505 default:
506 return -EINVAL;
507 }
508 break; 501 break;
509 502
510 default: 503 default:
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index d9c94d71fa61..e9ae7b3a7e00 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -22,6 +22,7 @@
22#include <mach/hardware.h> 22#include <mach/hardware.h>
23#include <mach/regs-ac97.h> 23#include <mach/regs-ac97.h>
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <mach/audio.h>
25 26
26#include "pxa2xx-pcm.h" 27#include "pxa2xx-pcm.h"
27#include "pxa2xx-ac97.h" 28#include "pxa2xx-ac97.h"
@@ -241,9 +242,18 @@ EXPORT_SYMBOL_GPL(soc_ac97_ops);
241static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev) 242static int __devinit pxa2xx_ac97_dev_probe(struct platform_device *pdev)
242{ 243{
243 int i; 244 int i;
245 pxa2xx_audio_ops_t *pdata = pdev->dev.platform_data;
244 246
245 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) 247 if (pdev->id >= 0) {
248 dev_err(&pdev->dev, "PXA2xx has only one AC97 port.\n");
249 return -ENXIO;
250 }
251
252 for (i = 0; i < ARRAY_SIZE(pxa_ac97_dai); i++) {
246 pxa_ac97_dai[i].dev = &pdev->dev; 253 pxa_ac97_dai[i].dev = &pdev->dev;
254 if (pdata && pdata->codec_pdata[0])
255 pxa_ac97_dai[i].ac97_pdata = pdata->codec_pdata[0];
256 }
247 257
248 /* Punt most of the init to the SoC probe; we may need the machine 258 /* Punt most of the init to the SoC probe; we may need the machine
249 * driver to do interesting things with the clocking to get us up 259 * driver to do interesting things with the clocking to get us up
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index df494d1e346f..923428fc1adb 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -1,6 +1,7 @@
1config SND_S3C24XX_SOC 1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3CXXXX chips" 2 tristate "SoC Audio for the Samsung S3CXXXX chips"
3 depends on ARCH_S3C2410 3 depends on ARCH_S3C2410 || ARCH_S3C64XX
4 select S3C64XX_DMA if ARCH_S3C64XX
4 help 5 help
5 Say Y or M if you want to add support for codecs attached to 6 Say Y or M if you want to add support for codecs attached to
6 the S3C24XX AC97 or I2S interfaces. You will also need to 7 the S3C24XX AC97 or I2S interfaces. You will also need to
@@ -38,6 +39,15 @@ config SND_S3C24XX_SOC_NEO1973_WM8753
38 Say Y if you want to add support for SoC audio on smdk2440 39 Say Y if you want to add support for SoC audio on smdk2440
39 with the WM8753. 40 with the WM8753.
40 41
42config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753
43 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
44 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02
45 select SND_S3C24XX_SOC_I2S
46 select SND_SOC_WM8753
47 help
48 This driver provides audio support for the Openmoko Neo FreeRunner
49 smartphone.
50
41config SND_S3C24XX_SOC_JIVE_WM8750 51config SND_S3C24XX_SOC_JIVE_WM8750
42 tristate "SoC I2S Audio support for Jive" 52 tristate "SoC I2S Audio support for Jive"
43 depends on SND_S3C24XX_SOC && MACH_JIVE 53 depends on SND_S3C24XX_SOC && MACH_JIVE
@@ -57,7 +67,7 @@ config SND_S3C24XX_SOC_SMDK2443_WM9710
57 67
58config SND_S3C24XX_SOC_LN2440SBC_ALC650 68config SND_S3C24XX_SOC_LN2440SBC_ALC650
59 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" 69 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
60 depends on SND_S3C24XX_SOC 70 depends on SND_S3C24XX_SOC && ARCH_S3C2410
61 select SND_S3C2443_SOC_AC97 71 select SND_S3C2443_SOC_AC97
62 select SND_SOC_AC97_CODEC 72 select SND_SOC_AC97_CODEC
63 help 73 help
@@ -66,7 +76,26 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
66 76
67config SND_S3C24XX_SOC_S3C24XX_UDA134X 77config SND_S3C24XX_SOC_S3C24XX_UDA134X
68 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" 78 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
69 depends on SND_S3C24XX_SOC 79 depends on SND_S3C24XX_SOC && ARCH_S3C2410
70 select SND_S3C24XX_SOC_I2S 80 select SND_S3C24XX_SOC_I2S
71 select SND_SOC_L3 81 select SND_SOC_L3
72 select SND_SOC_UDA134X 82 select SND_SOC_UDA134X
83
84config SND_S3C24XX_SOC_SIMTEC
85 tristate
86 help
87 Internal node for common S3C24XX/Simtec suppor
88
89config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23
90 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
91 depends on SND_S3C24XX_SOC && ARCH_S3C2410
92 select SND_S3C24XX_SOC_I2S
93 select SND_SOC_TLV320AIC23
94 select SND_S3C24XX_SOC_SIMTEC
95
96config SND_S3C24XX_SOC_SIMTEC_HERMES
97 tristate "SoC I2S Audio support for Simtec Hermes board"
98 depends on SND_S3C24XX_SOC && ARCH_S3C2410
99 select SND_S3C24XX_SOC_I2S
100 select SND_SOC_TLV320AIC3X
101 select SND_S3C24XX_SOC_SIMTEC
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 07a93a2ebe5f..99f5a7dd3fc6 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -16,12 +16,21 @@ obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16# S3C24XX Machine Support 16# S3C24XX Machine Support
17snd-soc-jive-wm8750-objs := jive_wm8750.o 17snd-soc-jive-wm8750-objs := jive_wm8750.o
18snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 18snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
19snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
19snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 20snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
20snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 21snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
21snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o 22snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
24snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
25snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
22 26
23obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 27obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
24obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 28obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
29obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
25obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 30obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
26obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 31obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
27obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o 32obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
33obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
34obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
35obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
36
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
new file mode 100644
index 000000000000..0c52e36ddd87
--- /dev/null
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -0,0 +1,498 @@
1/*
2 * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02)
3 *
4 * Copyright 2007 Openmoko Inc
5 * Author: Graeme Gregory <graeme@openmoko.org>
6 * Copyright 2007 Wolfson Microelectronics PLC.
7 * Author: Graeme Gregory <linux@wolfsonmicro.com>
8 * Copyright 2009 Wolfson Microelectronics
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#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/timer.h>
19#include <linux/interrupt.h>
20#include <linux/platform_device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28
29#include <plat/regs-iis.h>
30
31#include <mach/regs-clock.h>
32#include <asm/io.h>
33#include <mach/gta02.h>
34#include "../codecs/wm8753.h"
35#include "s3c24xx-pcm.h"
36#include "s3c24xx-i2s.h"
37
38static struct snd_soc_card neo1973_gta02;
39
40static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 struct snd_soc_pcm_runtime *rtd = substream->private_data;
44 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
45 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
46 unsigned int pll_out = 0, bclk = 0;
47 int ret = 0;
48 unsigned long iis_clkrate;
49
50 iis_clkrate = s3c24xx_i2s_get_clockrate();
51
52 switch (params_rate(params)) {
53 case 8000:
54 case 16000:
55 pll_out = 12288000;
56 break;
57 case 48000:
58 bclk = WM8753_BCLK_DIV_4;
59 pll_out = 12288000;
60 break;
61 case 96000:
62 bclk = WM8753_BCLK_DIV_2;
63 pll_out = 12288000;
64 break;
65 case 11025:
66 bclk = WM8753_BCLK_DIV_16;
67 pll_out = 11289600;
68 break;
69 case 22050:
70 bclk = WM8753_BCLK_DIV_8;
71 pll_out = 11289600;
72 break;
73 case 44100:
74 bclk = WM8753_BCLK_DIV_4;
75 pll_out = 11289600;
76 break;
77 case 88200:
78 bclk = WM8753_BCLK_DIV_2;
79 pll_out = 11289600;
80 break;
81 }
82
83 /* set codec DAI configuration */
84 ret = snd_soc_dai_set_fmt(codec_dai,
85 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
86 SND_SOC_DAIFMT_CBM_CFM);
87 if (ret < 0)
88 return ret;
89
90 /* set cpu DAI configuration */
91 ret = snd_soc_dai_set_fmt(cpu_dai,
92 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
93 SND_SOC_DAIFMT_CBM_CFM);
94 if (ret < 0)
95 return ret;
96
97 /* set the codec system clock for DAC and ADC */
98 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out,
99 SND_SOC_CLOCK_IN);
100 if (ret < 0)
101 return ret;
102
103 /* set MCLK division for sample rate */
104 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
105 S3C2410_IISMOD_32FS);
106 if (ret < 0)
107 return ret;
108
109 /* set codec BCLK division for sample rate */
110 ret = snd_soc_dai_set_clkdiv(codec_dai,
111 WM8753_BCLKDIV, bclk);
112 if (ret < 0)
113 return ret;
114
115 /* set prescaler division for sample rate */
116 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
117 S3C24XX_PRESCALE(4, 4));
118 if (ret < 0)
119 return ret;
120
121 /* codec PLL input is PCLK/4 */
122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1,
123 iis_clkrate / 4, pll_out);
124 if (ret < 0)
125 return ret;
126
127 return 0;
128}
129
130static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
131{
132 struct snd_soc_pcm_runtime *rtd = substream->private_data;
133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
134
135 /* disable the PLL */
136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0);
137}
138
139/*
140 * Neo1973 WM8753 HiFi DAI opserations.
141 */
142static struct snd_soc_ops neo1973_gta02_hifi_ops = {
143 .hw_params = neo1973_gta02_hifi_hw_params,
144 .hw_free = neo1973_gta02_hifi_hw_free,
145};
146
147static int neo1973_gta02_voice_hw_params(
148 struct snd_pcm_substream *substream,
149 struct snd_pcm_hw_params *params)
150{
151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
152 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
153 unsigned int pcmdiv = 0;
154 int ret = 0;
155 unsigned long iis_clkrate;
156
157 iis_clkrate = s3c24xx_i2s_get_clockrate();
158
159 if (params_rate(params) != 8000)
160 return -EINVAL;
161 if (params_channels(params) != 1)
162 return -EINVAL;
163
164 pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */
165
166 /* todo: gg check mode (DSP_B) against CSR datasheet */
167 /* set codec DAI configuration */
168 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B |
169 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
170 if (ret < 0)
171 return ret;
172
173 /* set the codec system clock for DAC and ADC */
174 ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK,
175 12288000, SND_SOC_CLOCK_IN);
176 if (ret < 0)
177 return ret;
178
179 /* set codec PCM division for sample rate */
180 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV,
181 pcmdiv);
182 if (ret < 0)
183 return ret;
184
185 /* configue and enable PLL for 12.288MHz output */
186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2,
187 iis_clkrate / 4, 12288000);
188 if (ret < 0)
189 return ret;
190
191 return 0;
192}
193
194static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
195{
196 struct snd_soc_pcm_runtime *rtd = substream->private_data;
197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
198
199 /* disable the PLL */
200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0);
201}
202
203static struct snd_soc_ops neo1973_gta02_voice_ops = {
204 .hw_params = neo1973_gta02_voice_hw_params,
205 .hw_free = neo1973_gta02_voice_hw_free,
206};
207
208#define LM4853_AMP 1
209#define LM4853_SPK 2
210
211static u8 lm4853_state;
212
213/* This has no effect, it exists only to maintain compatibility with
214 * existing ALSA state files.
215 */
216static int lm4853_set_state(struct snd_kcontrol *kcontrol,
217 struct snd_ctl_elem_value *ucontrol)
218{
219 int val = ucontrol->value.integer.value[0];
220
221 if (val)
222 lm4853_state |= LM4853_AMP;
223 else
224 lm4853_state &= ~LM4853_AMP;
225
226 return 0;
227}
228
229static int lm4853_get_state(struct snd_kcontrol *kcontrol,
230 struct snd_ctl_elem_value *ucontrol)
231{
232 ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP;
233
234 return 0;
235}
236
237static int lm4853_set_spk(struct snd_kcontrol *kcontrol,
238 struct snd_ctl_elem_value *ucontrol)
239{
240 int val = ucontrol->value.integer.value[0];
241
242 if (val) {
243 lm4853_state |= LM4853_SPK;
244 gpio_set_value(GTA02_GPIO_HP_IN, 0);
245 } else {
246 lm4853_state &= ~LM4853_SPK;
247 gpio_set_value(GTA02_GPIO_HP_IN, 1);
248 }
249
250 return 0;
251}
252
253static int lm4853_get_spk(struct snd_kcontrol *kcontrol,
254 struct snd_ctl_elem_value *ucontrol)
255{
256 ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1;
257
258 return 0;
259}
260
261static int lm4853_event(struct snd_soc_dapm_widget *w,
262 struct snd_kcontrol *k,
263 int event)
264{
265 gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(value));
266
267 return 0;
268}
269
270static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = {
271 SND_SOC_DAPM_SPK("Stereo Out", lm4853_event),
272 SND_SOC_DAPM_LINE("GSM Line Out", NULL),
273 SND_SOC_DAPM_LINE("GSM Line In", NULL),
274 SND_SOC_DAPM_MIC("Headset Mic", NULL),
275 SND_SOC_DAPM_MIC("Handset Mic", NULL),
276 SND_SOC_DAPM_SPK("Handset Spk", NULL),
277};
278
279
280/* example machine audio_mapnections */
281static const struct snd_soc_dapm_route audio_map[] = {
282
283 /* Connections to the lm4853 amp */
284 {"Stereo Out", NULL, "LOUT1"},
285 {"Stereo Out", NULL, "ROUT1"},
286
287 /* Connections to the GSM Module */
288 {"GSM Line Out", NULL, "MONO1"},
289 {"GSM Line Out", NULL, "MONO2"},
290 {"RXP", NULL, "GSM Line In"},
291 {"RXN", NULL, "GSM Line In"},
292
293 /* Connections to Headset */
294 {"MIC1", NULL, "Mic Bias"},
295 {"Mic Bias", NULL, "Headset Mic"},
296
297 /* Call Mic */
298 {"MIC2", NULL, "Mic Bias"},
299 {"MIC2N", NULL, "Mic Bias"},
300 {"Mic Bias", NULL, "Handset Mic"},
301
302 /* Call Speaker */
303 {"Handset Spk", NULL, "LOUT2"},
304 {"Handset Spk", NULL, "ROUT2"},
305
306 /* Connect the ALC pins */
307 {"ACIN", NULL, "ACOP"},
308};
309
310static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
311 SOC_DAPM_PIN_SWITCH("Stereo Out"),
312 SOC_DAPM_PIN_SWITCH("GSM Line Out"),
313 SOC_DAPM_PIN_SWITCH("GSM Line In"),
314 SOC_DAPM_PIN_SWITCH("Headset Mic"),
315 SOC_DAPM_PIN_SWITCH("Handset Mic"),
316 SOC_DAPM_PIN_SWITCH("Handset Spk"),
317
318 /* This has no effect, it exists only to maintain compatibility with
319 * existing ALSA state files.
320 */
321 SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0,
322 lm4853_get_state,
323 lm4853_set_state),
324 SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0,
325 lm4853_get_spk,
326 lm4853_set_spk),
327};
328
329/*
330 * This is an example machine initialisation for a wm8753 connected to a
331 * neo1973 GTA02.
332 */
333static int neo1973_gta02_wm8753_init(struct snd_soc_codec *codec)
334{
335 int err;
336
337 /* set up NC codec pins */
338 snd_soc_dapm_nc_pin(codec, "OUT3");
339 snd_soc_dapm_nc_pin(codec, "OUT4");
340 snd_soc_dapm_nc_pin(codec, "LINE1");
341 snd_soc_dapm_nc_pin(codec, "LINE2");
342
343 /* Add neo1973 gta02 specific widgets */
344 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets,
345 ARRAY_SIZE(wm8753_dapm_widgets));
346
347 /* add neo1973 gta02 specific controls */
348 err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls,
349 ARRAY_SIZE(wm8753_neo1973_gta02_controls));
350
351 if (err < 0)
352 return err;
353
354 /* set up neo1973 gta02 specific audio path audio_map */
355 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
356
357 /* set endpoints to default off mode */
358 snd_soc_dapm_disable_pin(codec, "Stereo Out");
359 snd_soc_dapm_disable_pin(codec, "GSM Line Out");
360 snd_soc_dapm_disable_pin(codec, "GSM Line In");
361 snd_soc_dapm_disable_pin(codec, "Headset Mic");
362 snd_soc_dapm_disable_pin(codec, "Handset Mic");
363 snd_soc_dapm_disable_pin(codec, "Handset Spk");
364
365 snd_soc_dapm_sync(codec);
366
367 return 0;
368}
369
370/*
371 * BT Codec DAI
372 */
373static struct snd_soc_dai bt_dai = {
374 .name = "Bluetooth",
375 .id = 0,
376 .playback = {
377 .channels_min = 1,
378 .channels_max = 1,
379 .rates = SNDRV_PCM_RATE_8000,
380 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
381 .capture = {
382 .channels_min = 1,
383 .channels_max = 1,
384 .rates = SNDRV_PCM_RATE_8000,
385 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
386};
387
388static struct snd_soc_dai_link neo1973_gta02_dai[] = {
389{ /* Hifi Playback - for similatious use with voice below */
390 .name = "WM8753",
391 .stream_name = "WM8753 HiFi",
392 .cpu_dai = &s3c24xx_i2s_dai,
393 .codec_dai = &wm8753_dai[WM8753_DAI_HIFI],
394 .init = neo1973_gta02_wm8753_init,
395 .ops = &neo1973_gta02_hifi_ops,
396},
397{ /* Voice via BT */
398 .name = "Bluetooth",
399 .stream_name = "Voice",
400 .cpu_dai = &bt_dai,
401 .codec_dai = &wm8753_dai[WM8753_DAI_VOICE],
402 .ops = &neo1973_gta02_voice_ops,
403},
404};
405
406static struct snd_soc_card neo1973_gta02 = {
407 .name = "neo1973-gta02",
408 .platform = &s3c24xx_soc_platform,
409 .dai_link = neo1973_gta02_dai,
410 .num_links = ARRAY_SIZE(neo1973_gta02_dai),
411};
412
413static struct snd_soc_device neo1973_gta02_snd_devdata = {
414 .card = &neo1973_gta02,
415 .codec_dev = &soc_codec_dev_wm8753,
416};
417
418static struct platform_device *neo1973_gta02_snd_device;
419
420static int __init neo1973_gta02_init(void)
421{
422 int ret;
423
424 if (!machine_is_neo1973_gta02()) {
425 printk(KERN_INFO
426 "Only GTA02 is supported by this ASoC driver\n");
427 return -ENODEV;
428 }
429
430 /* register bluetooth DAI here */
431 ret = snd_soc_register_dai(&bt_dai);
432 if (ret)
433 return ret;
434
435 neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1);
436 if (!neo1973_gta02_snd_device)
437 return -ENOMEM;
438
439 platform_set_drvdata(neo1973_gta02_snd_device,
440 &neo1973_gta02_snd_devdata);
441 neo1973_gta02_snd_devdata.dev = &neo1973_gta02_snd_device->dev;
442 ret = platform_device_add(neo1973_gta02_snd_device);
443
444 if (ret) {
445 platform_device_put(neo1973_gta02_snd_device);
446 return ret;
447 }
448
449 /* Initialise GPIOs used by amp */
450 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
451 if (ret) {
452 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
453 goto err_unregister_device;
454 }
455
456 ret = gpio_direction_output(GTA02_GPIO_AMP_HP_IN, 1);
457 if (ret) {
458 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN);
459 goto err_free_gpio_hp_in;
460 }
461
462 ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT");
463 if (ret) {
464 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT);
465 goto err_free_gpio_hp_in;
466 }
467
468 ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1);
469 if (ret) {
470 pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT);
471 goto err_free_gpio_amp_shut;
472 }
473
474 return 0;
475
476err_free_gpio_amp_shut:
477 gpio_free(GTA02_GPIO_AMP_SHUT);
478err_free_gpio_hp_in:
479 gpio_free(GTA02_GPIO_HP_IN);
480err_unregister_device:
481 platform_device_unregister(neo1973_gta02_snd_device);
482 return ret;
483}
484module_init(neo1973_gta02_init);
485
486static void __exit neo1973_gta02_exit(void)
487{
488 snd_soc_unregister_dai(&bt_dai);
489 platform_device_unregister(neo1973_gta02_snd_device);
490 gpio_free(GTA02_GPIO_HP_IN);
491 gpio_free(GTA02_GPIO_AMP_SHUT);
492}
493module_exit(neo1973_gta02_exit);
494
495/* Module information */
496MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org");
497MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02");
498MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 1a283170ca92..aa7af0b8d421 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -36,6 +36,7 @@
36#include <mach/dma.h> 36#include <mach/dma.h>
37 37
38#include "s3c-i2s-v2.h" 38#include "s3c-i2s-v2.h"
39#include "s3c24xx-pcm.h"
39 40
40#undef S3C_IIS_V2_SUPPORTED 41#undef S3C_IIS_V2_SUPPORTED
41 42
@@ -357,19 +358,19 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
357#endif 358#endif
358 359
359#ifdef CONFIG_PLAT_S3C64XX 360#ifdef CONFIG_PLAT_S3C64XX
360 iismod &= ~0x606; 361 iismod &= ~(S3C64XX_IISMOD_BLC_MASK | S3C2412_IISMOD_BCLK_MASK);
361 /* Sample size */ 362 /* Sample size */
362 switch (params_format(params)) { 363 switch (params_format(params)) {
363 case SNDRV_PCM_FORMAT_S8: 364 case SNDRV_PCM_FORMAT_S8:
364 /* 8 bit sample, 16fs BCLK */ 365 /* 8 bit sample, 16fs BCLK */
365 iismod |= 0x2004; 366 iismod |= (S3C64XX_IISMOD_BLC_8BIT | S3C2412_IISMOD_BCLK_16FS);
366 break; 367 break;
367 case SNDRV_PCM_FORMAT_S16_LE: 368 case SNDRV_PCM_FORMAT_S16_LE:
368 /* 16 bit sample, 32fs BCLK */ 369 /* 16 bit sample, 32fs BCLK */
369 break; 370 break;
370 case SNDRV_PCM_FORMAT_S24_LE: 371 case SNDRV_PCM_FORMAT_S24_LE:
371 /* 24 bit sample, 48fs BCLK */ 372 /* 24 bit sample, 48fs BCLK */
372 iismod |= 0x4002; 373 iismod |= (S3C64XX_IISMOD_BLC_24BIT | S3C2412_IISMOD_BCLK_48FS);
373 break; 374 break;
374 } 375 }
375#endif 376#endif
@@ -387,6 +388,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
387 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 388 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
388 unsigned long irqs; 389 unsigned long irqs;
389 int ret = 0; 390 int ret = 0;
391 int channel = ((struct s3c24xx_pcm_dma_params *)
392 rtd->dai->cpu_dai->dma_data)->channel;
390 393
391 pr_debug("Entered %s\n", __func__); 394 pr_debug("Entered %s\n", __func__);
392 395
@@ -416,6 +419,14 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
416 s3c2412_snd_txctrl(i2s, 1); 419 s3c2412_snd_txctrl(i2s, 1);
417 420
418 local_irq_restore(irqs); 421 local_irq_restore(irqs);
422
423 /*
424 * Load the next buffer to DMA to meet the reqirement
425 * of the auto reload mechanism of S3C24XX.
426 * This call won't bother S3C64XX.
427 */
428 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
429
419 break; 430 break;
420 431
421 case SNDRV_PCM_TRIGGER_STOP: 432 case SNDRV_PCM_TRIGGER_STOP:
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 3f03d5ddfacd..fc1beb0930b9 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -47,7 +47,7 @@ static struct s3c24xx_ac97_info s3c24xx_ac97;
47 47
48static DECLARE_COMPLETION(ac97_completion); 48static DECLARE_COMPLETION(ac97_completion);
49static u32 codec_ready; 49static u32 codec_ready;
50static DECLARE_MUTEX(ac97_mutex); 50static DEFINE_MUTEX(ac97_mutex);
51 51
52static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97, 52static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
53 unsigned short reg) 53 unsigned short reg)
@@ -56,7 +56,7 @@ static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
56 u32 ac_codec_cmd; 56 u32 ac_codec_cmd;
57 u32 stat, addr, data; 57 u32 stat, addr, data;
58 58
59 down(&ac97_mutex); 59 mutex_lock(&ac97_mutex);
60 60
61 codec_ready = S3C_AC97_GLBSTAT_CODECREADY; 61 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
62 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); 62 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
@@ -79,7 +79,7 @@ static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
79 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x," 79 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x,"
80 " rep addr = %02x\n", reg, addr); 80 " rep addr = %02x\n", reg, addr);
81 81
82 up(&ac97_mutex); 82 mutex_unlock(&ac97_mutex);
83 83
84 return (unsigned short)data; 84 return (unsigned short)data;
85} 85}
@@ -90,7 +90,7 @@ static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
90 u32 ac_glbctrl; 90 u32 ac_glbctrl;
91 u32 ac_codec_cmd; 91 u32 ac_codec_cmd;
92 92
93 down(&ac97_mutex); 93 mutex_lock(&ac97_mutex);
94 94
95 codec_ready = S3C_AC97_GLBSTAT_CODECREADY; 95 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
96 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); 96 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
@@ -109,7 +109,7 @@ static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
109 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; 109 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
110 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD); 110 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
111 111
112 up(&ac97_mutex); 112 mutex_unlock(&ac97_mutex);
113 113
114} 114}
115 115
@@ -290,6 +290,9 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
290 struct snd_soc_dai *dai) 290 struct snd_soc_dai *dai)
291{ 291{
292 u32 ac_glbctrl; 292 u32 ac_glbctrl;
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 int channel = ((struct s3c24xx_pcm_dma_params *)
295 rtd->dai->cpu_dai->dma_data)->channel;
293 296
294 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 297 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
295 switch (cmd) { 298 switch (cmd) {
@@ -312,6 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
312 } 315 }
313 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 316 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
314 317
318 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
319
315 return 0; 320 return 0;
316} 321}
317 322
@@ -334,6 +339,9 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
334 int cmd, struct snd_soc_dai *dai) 339 int cmd, struct snd_soc_dai *dai)
335{ 340{
336 u32 ac_glbctrl; 341 u32 ac_glbctrl;
342 struct snd_soc_pcm_runtime *rtd = substream->private_data;
343 int channel = ((struct s3c24xx_pcm_dma_params *)
344 rtd->dai->cpu_dai->dma_data)->channel;
337 345
338 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 346 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
339 switch (cmd) { 347 switch (cmd) {
@@ -349,6 +357,8 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
349 } 357 }
350 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 358 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
351 359
360 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
361
352 return 0; 362 return 0;
353} 363}
354 364
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 556e35f0ab73..40e2c4790f0d 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -279,6 +279,9 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
279 struct snd_soc_dai *dai) 279 struct snd_soc_dai *dai)
280{ 280{
281 int ret = 0; 281 int ret = 0;
282 struct snd_soc_pcm_runtime *rtd = substream->private_data;
283 int channel = ((struct s3c24xx_pcm_dma_params *)
284 rtd->dai->cpu_dai->dma_data)->channel;
282 285
283 pr_debug("Entered %s\n", __func__); 286 pr_debug("Entered %s\n", __func__);
284 287
@@ -296,6 +299,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
296 s3c24xx_snd_rxctrl(1); 299 s3c24xx_snd_rxctrl(1);
297 else 300 else
298 s3c24xx_snd_txctrl(1); 301 s3c24xx_snd_txctrl(1);
302
303 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
299 break; 304 break;
300 case SNDRV_PCM_TRIGGER_STOP: 305 case SNDRV_PCM_TRIGGER_STOP:
301 case SNDRV_PCM_TRIGGER_SUSPEND: 306 case SNDRV_PCM_TRIGGER_SUSPEND:
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index eecfa5eba06b..5cbbdc80fde3 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -255,7 +255,6 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
255 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 255 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
256 prtd->state |= ST_RUNNING; 256 prtd->state |= ST_RUNNING;
257 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); 257 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START);
258 s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STARTED);
259 break; 258 break;
260 259
261 case SNDRV_PCM_TRIGGER_STOP: 260 case SNDRV_PCM_TRIGGER_STOP:
@@ -318,6 +317,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
318 317
319 pr_debug("Entered %s\n", __func__); 318 pr_debug("Entered %s\n", __func__);
320 319
320 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
321 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); 321 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware);
322 322
323 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); 323 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
new file mode 100644
index 000000000000..1966e0d5652d
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -0,0 +1,394 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.c
2 *
3 * Copyright 2009 Simtec Electronics
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 version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/moduleparam.h>
12#include <linux/platform_device.h>
13#include <linux/gpio.h>
14#include <linux/clk.h>
15#include <linux/i2c.h>
16
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21
22#include <plat/audio-simtec.h>
23
24#include "s3c24xx-pcm.h"
25#include "s3c24xx-i2s.h"
26#include "s3c24xx_simtec.h"
27
28static struct s3c24xx_audio_simtec_pdata *pdata;
29static struct clk *xtal_clk;
30
31static int spk_gain;
32static int spk_unmute;
33
34/**
35 * speaker_gain_get - read the speaker gain setting.
36 * @kcontrol: The control for the speaker gain.
37 * @ucontrol: The value that needs to be updated.
38 *
39 * Read the value for the AMP gain control.
40 */
41static int speaker_gain_get(struct snd_kcontrol *kcontrol,
42 struct snd_ctl_elem_value *ucontrol)
43{
44 ucontrol->value.integer.value[0] = spk_gain;
45 return 0;
46}
47
48/**
49 * speaker_gain_set - set the value of the speaker amp gain
50 * @value: The value to write.
51 */
52static void speaker_gain_set(int value)
53{
54 gpio_set_value_cansleep(pdata->amp_gain[0], value & 1);
55 gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1);
56}
57
58/**
59 * speaker_gain_put - set the speaker gain setting.
60 * @kcontrol: The control for the speaker gain.
61 * @ucontrol: The value that needs to be set.
62 *
63 * Set the value of the speaker gain from the specified
64 * @ucontrol setting.
65 *
66 * Note, if the speaker amp is muted, then we do not set a gain value
67 * as at-least one of the ICs that is fitted will try and power up even
68 * if the main control is set to off.
69 */
70static int speaker_gain_put(struct snd_kcontrol *kcontrol,
71 struct snd_ctl_elem_value *ucontrol)
72{
73 int value = ucontrol->value.integer.value[0];
74
75 spk_gain = value;
76
77 if (!spk_unmute)
78 speaker_gain_set(value);
79
80 return 0;
81}
82
83static const struct snd_kcontrol_new amp_gain_controls[] = {
84 SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0,
85 speaker_gain_get, speaker_gain_put),
86};
87
88/**
89 * spk_unmute_state - set the unmute state of the speaker
90 * @to: zero to unmute, non-zero to ununmute.
91 */
92static void spk_unmute_state(int to)
93{
94 pr_debug("%s: to=%d\n", __func__, to);
95
96 spk_unmute = to;
97 gpio_set_value(pdata->amp_gpio, to);
98
99 /* if we're umuting, also re-set the gain */
100 if (to && pdata->amp_gain[0] > 0)
101 speaker_gain_set(spk_gain);
102}
103
104/**
105 * speaker_unmute_get - read the speaker unmute setting.
106 * @kcontrol: The control for the speaker gain.
107 * @ucontrol: The value that needs to be updated.
108 *
109 * Read the value for the AMP gain control.
110 */
111static int speaker_unmute_get(struct snd_kcontrol *kcontrol,
112 struct snd_ctl_elem_value *ucontrol)
113{
114 ucontrol->value.integer.value[0] = spk_unmute;
115 return 0;
116}
117
118/**
119 * speaker_unmute_put - set the speaker unmute setting.
120 * @kcontrol: The control for the speaker gain.
121 * @ucontrol: The value that needs to be set.
122 *
123 * Set the value of the speaker gain from the specified
124 * @ucontrol setting.
125 */
126static int speaker_unmute_put(struct snd_kcontrol *kcontrol,
127 struct snd_ctl_elem_value *ucontrol)
128{
129 spk_unmute_state(ucontrol->value.integer.value[0]);
130 return 0;
131}
132
133/* This is added as a manual control as the speaker amps create clicks
134 * when their power state is changed, which are far more noticeable than
135 * anything produced by the CODEC itself.
136 */
137static const struct snd_kcontrol_new amp_unmute_controls[] = {
138 SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0,
139 speaker_unmute_get, speaker_unmute_put),
140};
141
142void simtec_audio_init(struct snd_soc_codec *codec)
143{
144 if (pdata->amp_gpio > 0) {
145 pr_debug("%s: adding amp routes\n", __func__);
146
147 snd_soc_add_controls(codec, amp_unmute_controls,
148 ARRAY_SIZE(amp_unmute_controls));
149 }
150
151 if (pdata->amp_gain[0] > 0) {
152 pr_debug("%s: adding amp controls\n", __func__);
153 snd_soc_add_controls(codec, amp_gain_controls,
154 ARRAY_SIZE(amp_gain_controls));
155 }
156}
157EXPORT_SYMBOL_GPL(simtec_audio_init);
158
159#define CODEC_CLOCK 12000000
160
161/**
162 * simtec_hw_params - update hardware parameters
163 * @substream: The audio substream instance.
164 * @params: The parameters requested.
165 *
166 * Update the codec data routing and configuration settings
167 * from the supplied data.
168 */
169static int simtec_hw_params(struct snd_pcm_substream *substream,
170 struct snd_pcm_hw_params *params)
171{
172 struct snd_soc_pcm_runtime *rtd = substream->private_data;
173 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
174 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
175 int ret;
176
177 /* Set the CODEC as the bus clock master, I2S */
178 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
179 SND_SOC_DAIFMT_NB_NF |
180 SND_SOC_DAIFMT_CBM_CFM);
181 if (ret) {
182 pr_err("%s: failed set cpu dai format\n", __func__);
183 return ret;
184 }
185
186 /* Set the CODEC as the bus clock master */
187 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
188 SND_SOC_DAIFMT_NB_NF |
189 SND_SOC_DAIFMT_CBM_CFM);
190 if (ret) {
191 pr_err("%s: failed set codec dai format\n", __func__);
192 return ret;
193 }
194
195 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
196 CODEC_CLOCK, SND_SOC_CLOCK_IN);
197 if (ret) {
198 pr_err( "%s: failed setting codec sysclk\n", __func__);
199 return ret;
200 }
201
202 if (pdata->use_mpllin) {
203 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL,
204 0, SND_SOC_CLOCK_OUT);
205
206 if (ret) {
207 pr_err("%s: failed to set MPLLin as clksrc\n",
208 __func__);
209 return ret;
210 }
211 }
212
213 if (pdata->output_cdclk) {
214 int cdclk_scale;
215
216 cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK;
217 cdclk_scale--;
218
219 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
220 cdclk_scale);
221 }
222
223 return 0;
224}
225
226static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd)
227{
228 /* call any board supplied startup code, this currently only
229 * covers the bast/vr1000 which have a CPLD in the way of the
230 * LRCLK */
231 if (pd->startup)
232 pd->startup();
233
234 return 0;
235}
236
237static struct snd_soc_ops simtec_snd_ops = {
238 .hw_params = simtec_hw_params,
239};
240
241/**
242 * attach_gpio_amp - get and configure the necessary gpios
243 * @dev: The device we're probing.
244 * @pd: The platform data supplied by the board.
245 *
246 * If there is a GPIO based amplifier attached to the board, claim
247 * the necessary GPIO lines for it, and set default values.
248 */
249static int attach_gpio_amp(struct device *dev,
250 struct s3c24xx_audio_simtec_pdata *pd)
251{
252 int ret;
253
254 /* attach gpio amp gain (if any) */
255 if (pdata->amp_gain[0] > 0) {
256 ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0");
257 if (ret) {
258 dev_err(dev, "cannot get amp gpio gain0\n");
259 return ret;
260 }
261
262 ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1");
263 if (ret) {
264 dev_err(dev, "cannot get amp gpio gain1\n");
265 gpio_free(pdata->amp_gain[0]);
266 return ret;
267 }
268
269 gpio_direction_output(pd->amp_gain[0], 0);
270 gpio_direction_output(pd->amp_gain[1], 0);
271 }
272
273 /* note, curently we assume GPA0 isn't valid amp */
274 if (pdata->amp_gpio > 0) {
275 ret = gpio_request(pd->amp_gpio, "gpio-amp");
276 if (ret) {
277 dev_err(dev, "cannot get amp gpio %d (%d)\n",
278 pd->amp_gpio, ret);
279 goto err_amp;
280 }
281
282 /* set the amp off at startup */
283 spk_unmute_state(0);
284 }
285
286 return 0;
287
288err_amp:
289 if (pd->amp_gain[0] > 0) {
290 gpio_free(pd->amp_gain[0]);
291 gpio_free(pd->amp_gain[1]);
292 }
293
294 return ret;
295}
296
297static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd)
298{
299 if (pd->amp_gain[0] > 0) {
300 gpio_free(pd->amp_gain[0]);
301 gpio_free(pd->amp_gain[1]);
302 }
303
304 if (pd->amp_gpio > 0)
305 gpio_free(pd->amp_gpio);
306}
307
308#ifdef CONFIG_PM
309int simtec_audio_resume(struct device *dev)
310{
311 simtec_call_startup(pdata);
312 return 0;
313}
314
315struct dev_pm_ops simtec_audio_pmops = {
316 .resume = simtec_audio_resume,
317};
318EXPORT_SYMBOL_GPL(simtec_audio_pmops);
319#endif
320
321int __devinit simtec_audio_core_probe(struct platform_device *pdev,
322 struct snd_soc_device *socdev)
323{
324 struct platform_device *snd_dev;
325 int ret;
326
327 socdev->card->dai_link->ops = &simtec_snd_ops;
328
329 pdata = pdev->dev.platform_data;
330 if (!pdata) {
331 dev_err(&pdev->dev, "no platform data supplied\n");
332 return -EINVAL;
333 }
334
335 simtec_call_startup(pdata);
336
337 xtal_clk = clk_get(&pdev->dev, "xtal");
338 if (IS_ERR(xtal_clk)) {
339 dev_err(&pdev->dev, "could not get clkout0\n");
340 return -EINVAL;
341 }
342
343 dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk));
344
345 ret = attach_gpio_amp(&pdev->dev, pdata);
346 if (ret)
347 goto err_clk;
348
349 snd_dev = platform_device_alloc("soc-audio", -1);
350 if (!snd_dev) {
351 dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n");
352 ret = -ENOMEM;
353 goto err_gpio;
354 }
355
356 platform_set_drvdata(snd_dev, socdev);
357 socdev->dev = &snd_dev->dev;
358
359 ret = platform_device_add(snd_dev);
360 if (ret) {
361 dev_err(&pdev->dev, "failed to add soc-audio dev\n");
362 goto err_pdev;
363 }
364
365 platform_set_drvdata(pdev, snd_dev);
366 return 0;
367
368err_pdev:
369 platform_device_put(snd_dev);
370
371err_gpio:
372 detach_gpio_amp(pdata);
373
374err_clk:
375 clk_put(xtal_clk);
376 return ret;
377}
378EXPORT_SYMBOL_GPL(simtec_audio_core_probe);
379
380int __devexit simtec_audio_remove(struct platform_device *pdev)
381{
382 struct platform_device *snd_dev = platform_get_drvdata(pdev);
383
384 platform_device_unregister(snd_dev);
385
386 detach_gpio_amp(pdata);
387 clk_put(xtal_clk);
388 return 0;
389}
390EXPORT_SYMBOL_GPL(simtec_audio_remove);
391
392MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
393MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support");
394MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h
new file mode 100644
index 000000000000..2714203af161
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.h
@@ -0,0 +1,22 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.h
2 *
3 * Copyright 2009 Simtec Electronics
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 version 2 as
7 * published by the Free Software Foundation.
8*/
9
10extern void simtec_audio_init(struct snd_soc_codec *codec);
11
12extern int simtec_audio_core_probe(struct platform_device *pdev,
13 struct snd_soc_device *socdev);
14
15extern int simtec_audio_remove(struct platform_device *pdev);
16
17#ifdef CONFIG_PM
18extern struct dev_pm_ops simtec_audio_pmops;
19#define simtec_audio_pm &simtec_audio_pmops
20#else
21#define simtec_audio_pm NULL
22#endif
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
new file mode 100644
index 000000000000..8346bd96eaf5
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
@@ -0,0 +1,153 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
2 *
3 * Copyright 2009 Simtec Electronics
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 version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18
19#include <plat/audio-simtec.h>
20
21#include "s3c24xx-pcm.h"
22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h"
24
25#include "../codecs/tlv320aic3x.h"
26
27static const struct snd_soc_dapm_widget dapm_widgets[] = {
28 SND_SOC_DAPM_LINE("GSM Out", NULL),
29 SND_SOC_DAPM_LINE("GSM In", NULL),
30 SND_SOC_DAPM_LINE("Line In", NULL),
31 SND_SOC_DAPM_LINE("Line Out", NULL),
32 SND_SOC_DAPM_LINE("ZV", NULL),
33 SND_SOC_DAPM_MIC("Mic Jack", NULL),
34 SND_SOC_DAPM_HP("Headphone Jack", NULL),
35};
36
37static const struct snd_soc_dapm_route base_map[] = {
38 /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */
39
40 { "Headphone Jack", NULL, "HPLOUT" },
41 { "Headphone Jack", NULL, "HPLCOM" },
42 { "Headphone Jack", NULL, "HPROUT" },
43 { "Headphone Jack", NULL, "HPRCOM" },
44
45 /* ZV connected to Line1 */
46
47 { "LINE1L", NULL, "ZV" },
48 { "LINE1R", NULL, "ZV" },
49
50 /* Line In connected to Line2 */
51
52 { "LINE2L", NULL, "Line In" },
53 { "LINE2R", NULL, "Line In" },
54
55 /* Microphone connected to MIC3R and MIC_BIAS */
56
57 { "MIC3L", NULL, "Mic Jack" },
58
59 /* GSM connected to MONO_LOUT and MIC3L (in) */
60
61 { "GSM Out", NULL, "MONO_LOUT" },
62 { "MIC3L", NULL, "GSM In" },
63
64 /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are
65 * not using the DAPM to power it up and down as there it makes
66 * a click when powering up. */
67};
68
69/**
70 * simtec_hermes_init - initialise and add controls
71 * @codec; The codec instance to attach to.
72 *
73 * Attach our controls and configure the necessary codec
74 * mappings for our sound card instance.
75*/
76static int simtec_hermes_init(struct snd_soc_codec *codec)
77{
78 snd_soc_dapm_new_controls(codec, dapm_widgets,
79 ARRAY_SIZE(dapm_widgets));
80
81 snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
82
83 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
84 snd_soc_dapm_enable_pin(codec, "Line In");
85 snd_soc_dapm_enable_pin(codec, "Line Out");
86 snd_soc_dapm_enable_pin(codec, "Mic Jack");
87
88 simtec_audio_init(codec);
89 snd_soc_dapm_sync(codec);
90
91 return 0;
92}
93
94static struct aic3x_setup_data codec_setup = {
95};
96
97static struct snd_soc_dai_link simtec_dai_aic33 = {
98 .name = "tlv320aic33",
99 .stream_name = "TLV320AIC33",
100 .cpu_dai = &s3c24xx_i2s_dai,
101 .codec_dai = &aic3x_dai,
102 .init = simtec_hermes_init,
103};
104
105/* simtec audio machine driver */
106static struct snd_soc_card snd_soc_machine_simtec_aic33 = {
107 .name = "Simtec-Hermes",
108 .platform = &s3c24xx_soc_platform,
109 .dai_link = &simtec_dai_aic33,
110 .num_links = 1,
111};
112
113/* simtec audio subsystem */
114static struct snd_soc_device simtec_snd_devdata_aic33 = {
115 .card = &snd_soc_machine_simtec_aic33,
116 .codec_dev = &soc_codec_dev_aic3x,
117 .codec_data = &codec_setup,
118};
119
120static int __devinit simtec_audio_hermes_probe(struct platform_device *pd)
121{
122 dev_info(&pd->dev, "probing....\n");
123 return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic33);
124}
125
126static struct platform_driver simtec_audio_hermes_platdrv = {
127 .driver = {
128 .owner = THIS_MODULE,
129 .name = "s3c24xx-simtec-hermes-snd",
130 .pm = simtec_audio_pm,
131 },
132 .probe = simtec_audio_hermes_probe,
133 .remove = __devexit_p(simtec_audio_remove),
134};
135
136MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd");
137
138static int __init simtec_hermes_modinit(void)
139{
140 return platform_driver_register(&simtec_audio_hermes_platdrv);
141}
142
143static void __exit simtec_hermes_modexit(void)
144{
145 platform_driver_unregister(&simtec_audio_hermes_platdrv);
146}
147
148module_init(simtec_hermes_modinit);
149module_exit(simtec_hermes_modexit);
150
151MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
152MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
153MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
new file mode 100644
index 000000000000..25797e096175
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
@@ -0,0 +1,137 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
2 *
3 * Copyright 2009 Simtec Electronics
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 version 2 as
7 * published by the Free Software Foundation.
8*/
9
10#include <linux/module.h>
11#include <linux/clk.h>
12#include <linux/platform_device.h>
13
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18
19#include <plat/audio-simtec.h>
20
21#include "s3c24xx-pcm.h"
22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h"
24
25#include "../codecs/tlv320aic23.h"
26
27/* supported machines:
28 *
29 * Machine Connections AMP
30 * ------- ----------- ---
31 * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired)
32 * VR1000 HPOUT, LIN None
33 * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
34 * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R)
35 * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R)
36 */
37
38static const struct snd_soc_dapm_widget dapm_widgets[] = {
39 SND_SOC_DAPM_HP("Headphone Jack", NULL),
40 SND_SOC_DAPM_LINE("Line In", NULL),
41 SND_SOC_DAPM_LINE("Line Out", NULL),
42 SND_SOC_DAPM_MIC("Mic Jack", NULL),
43};
44
45static const struct snd_soc_dapm_route base_map[] = {
46 { "Headphone Jack", NULL, "LHPOUT"},
47 { "Headphone Jack", NULL, "RHPOUT"},
48
49 { "Line Out", NULL, "LOUT" },
50 { "Line Out", NULL, "ROUT" },
51
52 { "LLINEIN", NULL, "Line In"},
53 { "RLINEIN", NULL, "Line In"},
54
55 { "MICIN", NULL, "Mic Jack"},
56};
57
58/**
59 * simtec_tlv320aic23_init - initialise and add controls
60 * @codec; The codec instance to attach to.
61 *
62 * Attach our controls and configure the necessary codec
63 * mappings for our sound card instance.
64*/
65static int simtec_tlv320aic23_init(struct snd_soc_codec *codec)
66{
67 snd_soc_dapm_new_controls(codec, dapm_widgets,
68 ARRAY_SIZE(dapm_widgets));
69
70 snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map));
71
72 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
73 snd_soc_dapm_enable_pin(codec, "Line In");
74 snd_soc_dapm_enable_pin(codec, "Line Out");
75 snd_soc_dapm_enable_pin(codec, "Mic Jack");
76
77 simtec_audio_init(codec);
78 snd_soc_dapm_sync(codec);
79
80 return 0;
81}
82
83static struct snd_soc_dai_link simtec_dai_aic23 = {
84 .name = "tlv320aic23",
85 .stream_name = "TLV320AIC23",
86 .cpu_dai = &s3c24xx_i2s_dai,
87 .codec_dai = &tlv320aic23_dai,
88 .init = simtec_tlv320aic23_init,
89};
90
91/* simtec audio machine driver */
92static struct snd_soc_card snd_soc_machine_simtec_aic23 = {
93 .name = "Simtec",
94 .platform = &s3c24xx_soc_platform,
95 .dai_link = &simtec_dai_aic23,
96 .num_links = 1,
97};
98
99/* simtec audio subsystem */
100static struct snd_soc_device simtec_snd_devdata_aic23 = {
101 .card = &snd_soc_machine_simtec_aic23,
102 .codec_dev = &soc_codec_dev_tlv320aic23,
103};
104
105static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd)
106{
107 return simtec_audio_core_probe(pd, &simtec_snd_devdata_aic23);
108}
109
110static struct platform_driver simtec_audio_tlv320aic23_platdrv = {
111 .driver = {
112 .owner = THIS_MODULE,
113 .name = "s3c24xx-simtec-tlv320aic23",
114 .pm = simtec_audio_pm,
115 },
116 .probe = simtec_audio_tlv320aic23_probe,
117 .remove = __devexit_p(simtec_audio_remove),
118};
119
120MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23");
121
122static int __init simtec_tlv320aic23_modinit(void)
123{
124 return platform_driver_register(&simtec_audio_tlv320aic23_platdrv);
125}
126
127static void __exit simtec_tlv320aic23_modexit(void)
128{
129 platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv);
130}
131
132module_init(simtec_tlv320aic23_modinit);
133module_exit(simtec_tlv320aic23_modexit);
134
135MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
136MODULE_DESCRIPTION("ALSA SoC Simtec Audio support");
137MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index b5f95f9781c1..c1b40ac22c05 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -14,6 +14,7 @@
14#include <linux/timer.h> 14#include <linux/timer.h>
15#include <linux/interrupt.h> 15#include <linux/interrupt.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/i2c.h>
17#include <sound/core.h> 18#include <sound/core.h>
18#include <sound/pcm.h> 19#include <sound/pcm.h>
19#include <sound/soc.h> 20#include <sound/soc.h>
@@ -189,8 +190,6 @@ static struct snd_soc_card snd_soc_card_s6105 = {
189 190
190/* s6105 audio private data */ 191/* s6105 audio private data */
191static struct aic3x_setup_data s6105_aic3x_setup = { 192static struct aic3x_setup_data s6105_aic3x_setup = {
192 .i2c_bus = 0,
193 .i2c_address = 0x18,
194}; 193};
195 194
196/* s6105 audio subsystem */ 195/* s6105 audio subsystem */
@@ -211,10 +210,19 @@ static struct s6000_snd_platform_data __initdata s6105_snd_data = {
211 210
212static struct platform_device *s6105_snd_device; 211static struct platform_device *s6105_snd_device;
213 212
213/* temporary i2c device creation until this can be moved into the machine
214 * support file.
215*/
216static struct i2c_board_info i2c_device[] = {
217 { I2C_BOARD_INFO("tlv320aic33", 0x18), }
218};
219
214static int __init s6105_init(void) 220static int __init s6105_init(void)
215{ 221{
216 int ret; 222 int ret;
217 223
224 i2c_register_board_info(0, i2c_device, ARRAY_SIZE(i2c_device));
225
218 s6105_snd_device = platform_device_alloc("soc-audio", -1); 226 s6105_snd_device = platform_device_alloc("soc-audio", -1);
219 if (!s6105_snd_device) 227 if (!s6105_snd_device)
220 return -ENOMEM; 228 return -ENOMEM;
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 54bd604012af..9154b4363db3 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -20,7 +20,12 @@ config SND_SOC_SH4_HAC
20config SND_SOC_SH4_SSI 20config SND_SOC_SH4_SSI
21 tristate 21 tristate
22 22
23 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724
26 select SH_DMA
27 help
28 This option enables FSI sound support
24 29
25## 30##
26## Boards 31## Boards
@@ -35,4 +40,12 @@ config SND_SH7760_AC97
35 This option enables generic sound support for the first 40 This option enables generic sound support for the first
36 AC97 unit of the SH7760. 41 AC97 unit of the SH7760.
37 42
43config SND_FSI_AK4642
44 bool "FSI-AK4642 sound support"
45 depends on SND_SOC_SH4_FSI
46 select SND_SOC_AK4642
47 help
48 This option enables generic sound support for the
49 FSI - AK4642 unit
50
38endmenu 51endmenu
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index a8e8ab81cc6a..a6997872f24e 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -5,10 +5,14 @@ obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
5## audio units found on some SH-4 5## audio units found on some SH-4
6snd-soc-hac-objs := hac.o 6snd-soc-hac-objs := hac.o
7snd-soc-ssi-objs := ssi.o 7snd-soc-ssi-objs := ssi.o
8snd-soc-fsi-objs := fsi.o
8obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o 9obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
9obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o 10obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
11obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
10 12
11## boards 13## boards
12snd-soc-sh7760-ac97-objs := sh7760-ac97.o 14snd-soc-sh7760-ac97-objs := sh7760-ac97.o
15snd-soc-fsi-ak4642-objs := fsi-ak4642.o
13 16
14obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o 17obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
18obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
new file mode 100644
index 000000000000..c7af09729c6e
--- /dev/null
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -0,0 +1,107 @@
1/*
2 * FSI-AK464x sound support for ms7724se
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This file is subject to the terms and conditions of the GNU General Public
8 * License. See the file "COPYING" in the main directory of this archive
9 * for more details.
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/platform_device.h>
15#include <linux/i2c.h>
16#include <linux/io.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21
22#include <sound/sh_fsi.h>
23#include <../sound/soc/codecs/ak4642.h>
24
25static struct snd_soc_dai_link fsi_dai_link = {
26 .name = "AK4642",
27 .stream_name = "AK4642",
28 .cpu_dai = &fsi_soc_dai[0], /* fsi */
29 .codec_dai = &ak4642_dai,
30 .ops = NULL,
31};
32
33static struct snd_soc_card fsi_soc_card = {
34 .name = "FSI",
35 .platform = &fsi_soc_platform,
36 .dai_link = &fsi_dai_link,
37 .num_links = 1,
38};
39
40static struct snd_soc_device fsi_snd_devdata = {
41 .card = &fsi_soc_card,
42 .codec_dev = &soc_codec_dev_ak4642,
43};
44
45#define AK4642_BUS 0
46#define AK4642_ADR 0x12
47static int ak4642_add_i2c_device(void)
48{
49 struct i2c_board_info info;
50 struct i2c_adapter *adapter;
51 struct i2c_client *client;
52
53 memset(&info, 0, sizeof(struct i2c_board_info));
54 info.addr = AK4642_ADR;
55 strlcpy(info.type, "ak4642", I2C_NAME_SIZE);
56
57 adapter = i2c_get_adapter(AK4642_BUS);
58 if (!adapter) {
59 printk(KERN_DEBUG "can't get i2c adapter\n");
60 return -ENODEV;
61 }
62
63 client = i2c_new_device(adapter, &info);
64 i2c_put_adapter(adapter);
65 if (!client) {
66 printk(KERN_DEBUG "can't add i2c device\n");
67 return -ENODEV;
68 }
69
70 return 0;
71}
72
73static struct platform_device *fsi_snd_device;
74
75static int __init fsi_ak4642_init(void)
76{
77 int ret = -ENOMEM;
78
79 ak4642_add_i2c_device();
80
81 fsi_snd_device = platform_device_alloc("soc-audio", -1);
82 if (!fsi_snd_device)
83 goto out;
84
85 platform_set_drvdata(fsi_snd_device,
86 &fsi_snd_devdata);
87 fsi_snd_devdata.dev = &fsi_snd_device->dev;
88 ret = platform_device_add(fsi_snd_device);
89
90 if (ret)
91 platform_device_put(fsi_snd_device);
92
93out:
94 return ret;
95}
96
97static void __exit fsi_ak4642_exit(void)
98{
99 platform_device_unregister(fsi_snd_device);
100}
101
102module_init(fsi_ak4642_init);
103module_exit(fsi_ak4642_exit);
104
105MODULE_LICENSE("GPL");
106MODULE_DESCRIPTION("Generic SH4 FSI-AK4642 sound card");
107MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
new file mode 100644
index 000000000000..44123248b630
--- /dev/null
+++ b/sound/soc/sh/fsi.c
@@ -0,0 +1,1004 @@
1/*
2 * Fifo-attached Serial Interface (FSI) support for SH7724
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * Based on ssi.c
8 * Copyright (c) 2007 Manuel Lauss <mano@roarinelk.homelinux.net>
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/init.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18#include <linux/delay.h>
19#include <linux/list.h>
20#include <linux/clk.h>
21#include <linux/io.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h>
28#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31
32#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004
34#define DOFF_ST 0x0008
35#define DI_FMT 0x000C
36#define DIFF_CTL 0x0010
37#define DIFF_ST 0x0014
38#define CKG1 0x0018
39#define CKG2 0x001C
40#define DIDT 0x0020
41#define DODT 0x0024
42#define MUTE_ST 0x0028
43#define REG_END MUTE_ST
44
45#define INT_ST 0x0200
46#define IEMSK 0x0204
47#define IMSK 0x0208
48#define MUTE 0x020C
49#define CLK_RST 0x0210
50#define SOFT_RST 0x0214
51#define MREG_START INT_ST
52#define MREG_END SOFT_RST
53
54/* DO_FMT */
55/* DI_FMT */
56#define CR_FMT(param) ((param) << 4)
57# define CR_MONO 0x0
58# define CR_MONO_D 0x1
59# define CR_PCM 0x2
60# define CR_I2S 0x3
61# define CR_TDM 0x4
62# define CR_TDM_D 0x5
63
64/* DOFF_CTL */
65/* DIFF_CTL */
66#define IRQ_HALF 0x00100000
67#define FIFO_CLR 0x00000001
68
69/* DOFF_ST */
70#define ERR_OVER 0x00000010
71#define ERR_UNDER 0x00000001
72
73/* CLK_RST */
74#define B_CLK 0x00000010
75#define A_CLK 0x00000001
76
77/* INT_ST */
78#define INT_B_IN (1 << 12)
79#define INT_B_OUT (1 << 8)
80#define INT_A_IN (1 << 4)
81#define INT_A_OUT (1 << 0)
82
83#define FSI_RATES SNDRV_PCM_RATE_8000_96000
84
85#define FSI_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE)
86
87/************************************************************************
88
89
90 struct
91
92
93************************************************************************/
94struct fsi_priv {
95 void __iomem *base;
96 struct snd_pcm_substream *substream;
97
98 int fifo_max;
99 int chan;
100 int dma_chan;
101
102 int byte_offset;
103 int period_len;
104 int buffer_len;
105 int periods;
106};
107
108struct fsi_master {
109 void __iomem *base;
110 int irq;
111 struct clk *clk;
112 struct fsi_priv fsia;
113 struct fsi_priv fsib;
114 struct sh_fsi_platform_info *info;
115};
116
117static struct fsi_master *master;
118
119/************************************************************************
120
121
122 basic read write function
123
124
125************************************************************************/
126static int __fsi_reg_write(u32 reg, u32 data)
127{
128 /* valid data area is 24bit */
129 data &= 0x00ffffff;
130
131 return ctrl_outl(data, reg);
132}
133
134static u32 __fsi_reg_read(u32 reg)
135{
136 return ctrl_inl(reg);
137}
138
139static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
140{
141 u32 val = __fsi_reg_read(reg);
142
143 val &= ~mask;
144 val |= data & mask;
145
146 return __fsi_reg_write(reg, val);
147}
148
149static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
150{
151 if (reg > REG_END)
152 return -1;
153
154 return __fsi_reg_write((u32)(fsi->base + reg), data);
155}
156
157static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
158{
159 if (reg > REG_END)
160 return 0;
161
162 return __fsi_reg_read((u32)(fsi->base + reg));
163}
164
165static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
166{
167 if (reg > REG_END)
168 return -1;
169
170 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
171}
172
173static int fsi_master_write(u32 reg, u32 data)
174{
175 if ((reg < MREG_START) ||
176 (reg > MREG_END))
177 return -1;
178
179 return __fsi_reg_write((u32)(master->base + reg), data);
180}
181
182static u32 fsi_master_read(u32 reg)
183{
184 if ((reg < MREG_START) ||
185 (reg > MREG_END))
186 return 0;
187
188 return __fsi_reg_read((u32)(master->base + reg));
189}
190
191static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
192{
193 if ((reg < MREG_START) ||
194 (reg > MREG_END))
195 return -1;
196
197 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
198}
199
200/************************************************************************
201
202
203 basic function
204
205
206************************************************************************/
207static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream)
208{
209 struct snd_soc_pcm_runtime *rtd;
210 struct fsi_priv *fsi = NULL;
211
212 if (!substream || !master)
213 return NULL;
214
215 rtd = substream->private_data;
216 switch (rtd->dai->cpu_dai->id) {
217 case 0:
218 fsi = &master->fsia;
219 break;
220 case 1:
221 fsi = &master->fsib;
222 break;
223 }
224
225 return fsi;
226}
227
228static int fsi_is_port_a(struct fsi_priv *fsi)
229{
230 /* return
231 * 1 : port a
232 * 0 : port b
233 */
234
235 if (fsi == &master->fsia)
236 return 1;
237
238 return 0;
239}
240
241static u32 fsi_get_info_flags(struct fsi_priv *fsi)
242{
243 int is_porta = fsi_is_port_a(fsi);
244
245 return is_porta ? master->info->porta_flags :
246 master->info->portb_flags;
247}
248
249static int fsi_is_master_mode(struct fsi_priv *fsi, int is_play)
250{
251 u32 mode;
252 u32 flags = fsi_get_info_flags(fsi);
253
254 mode = is_play ? SH_FSI_OUT_SLAVE_MODE : SH_FSI_IN_SLAVE_MODE;
255
256 /* return
257 * 1 : master mode
258 * 0 : slave mode
259 */
260
261 return (mode & flags) != mode;
262}
263
264static u32 fsi_port_ab_io_bit(struct fsi_priv *fsi, int is_play)
265{
266 int is_porta = fsi_is_port_a(fsi);
267 u32 data;
268
269 if (is_porta)
270 data = is_play ? (1 << 0) : (1 << 4);
271 else
272 data = is_play ? (1 << 8) : (1 << 12);
273
274 return data;
275}
276
277static void fsi_stream_push(struct fsi_priv *fsi,
278 struct snd_pcm_substream *substream,
279 u32 buffer_len,
280 u32 period_len)
281{
282 fsi->substream = substream;
283 fsi->buffer_len = buffer_len;
284 fsi->period_len = period_len;
285 fsi->byte_offset = 0;
286 fsi->periods = 0;
287}
288
289static void fsi_stream_pop(struct fsi_priv *fsi)
290{
291 fsi->substream = NULL;
292 fsi->buffer_len = 0;
293 fsi->period_len = 0;
294 fsi->byte_offset = 0;
295 fsi->periods = 0;
296}
297
298static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
299{
300 u32 status;
301 u32 reg = is_play ? DOFF_ST : DIFF_ST;
302 int residue;
303
304 status = fsi_reg_read(fsi, reg);
305 residue = 0x1ff & (status >> 8);
306 residue *= fsi->chan;
307
308 return residue;
309}
310
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************
368
369
370 ctrl function
371
372
373************************************************************************/
374static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
375{
376 u32 data = fsi_port_ab_io_bit(fsi, is_play);
377
378 fsi_master_mask_set(IMSK, data, data);
379 fsi_master_mask_set(IEMSK, data, data);
380}
381
382static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
383{
384 u32 data = fsi_port_ab_io_bit(fsi, is_play);
385
386 fsi_master_mask_set(IMSK, data, 0);
387 fsi_master_mask_set(IEMSK, data, 0);
388}
389
390static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
391{
392 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
393
394 if (enable)
395 fsi_master_mask_set(CLK_RST, val, val);
396 else
397 fsi_master_mask_set(CLK_RST, val, 0);
398}
399
400static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
401{
402 u32 data;
403 u32 ctrl;
404
405 data = fsi_port_ab_io_bit(fsi, is_play);
406 ctrl = is_play ? DOFF_CTL : DIFF_CTL;
407
408 /* set IMSK */
409 fsi_irq_disable(fsi, is_play);
410
411 /* set interrupt generation factor */
412 fsi_reg_write(fsi, ctrl, IRQ_HALF);
413
414 /* clear FIFO */
415 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
416
417 /* clear interrupt factor */
418 fsi_master_mask_set(INT_ST, data, 0);
419}
420
421static void fsi_soft_all_reset(void)
422{
423 u32 status = fsi_master_read(SOFT_RST);
424
425 /* port AB reset */
426 status &= 0x000000ff;
427 fsi_master_write(SOFT_RST, status);
428 mdelay(10);
429
430 /* soft reset */
431 status &= 0x000000f0;
432 fsi_master_write(SOFT_RST, status);
433 status |= 0x00000001;
434 fsi_master_write(SOFT_RST, status);
435 mdelay(10);
436}
437
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi)
478{
479 struct snd_pcm_runtime *runtime;
480 struct snd_pcm_substream *substream = NULL;
481 int send;
482 int fifo_free;
483 int width;
484
485 if (!fsi ||
486 !fsi->substream ||
487 !fsi->substream->runtime)
488 return -EINVAL;
489
490 runtime = fsi->substream->runtime;
491
492 /* FSI FIFO has limit.
493 * So, this driver can not send periods data at a time
494 */
495 if (fsi->byte_offset >=
496 fsi->period_len * (fsi->periods + 1)) {
497
498 substream = fsi->substream;
499 fsi->periods = (fsi->periods + 1) % runtime->periods;
500
501 if (0 == fsi->periods)
502 fsi->byte_offset = 0;
503 }
504
505 /* get 1 channel data width */
506 width = frames_to_bytes(runtime, 1) / fsi->chan;
507
508 /* get send size for alsa */
509 send = (fsi->buffer_len - fsi->byte_offset) / width;
510
511 /* get FIFO free size */
512 fifo_free = (fsi->fifo_max * fsi->chan) - fsi_get_fifo_residue(fsi, 1);
513
514 /* size check */
515 if (fifo_free < send)
516 send = fifo_free;
517
518 if (2 == width)
519 fsi_16data_push(fsi, runtime, send);
520 else if (4 == width)
521 fsi_32data_push(fsi, runtime, send);
522 else
523 return -EINVAL;
524
525 fsi->byte_offset += send * width;
526
527 fsi_irq_enable(fsi, 1);
528
529 if (substream)
530 snd_pcm_period_elapsed(substream);
531
532 return 0;
533}
534
535static irqreturn_t fsi_interrupt(int irq, void *data)
536{
537 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010;
538 u32 int_st = fsi_master_read(INT_ST);
539
540 /* clear irq status */
541 fsi_master_write(SOFT_RST, status);
542 fsi_master_write(SOFT_RST, status | 0x00000010);
543
544 if (int_st & INT_A_OUT)
545 fsi_data_push(&master->fsia);
546 if (int_st & INT_B_OUT)
547 fsi_data_push(&master->fsib);
548
549 fsi_master_write(INT_ST, 0x0000000);
550
551 return IRQ_HANDLED;
552}
553
554/************************************************************************
555
556
557 dai ops
558
559
560************************************************************************/
561static int fsi_dai_startup(struct snd_pcm_substream *substream,
562 struct snd_soc_dai *dai)
563{
564 struct fsi_priv *fsi = fsi_get(substream);
565 const char *msg;
566 u32 flags = fsi_get_info_flags(fsi);
567 u32 fmt;
568 u32 reg;
569 u32 data;
570 int is_play = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
571 int is_master;
572 int ret = 0;
573
574 clk_enable(master->clk);
575
576 /* CKG1 */
577 data = is_play ? (1 << 0) : (1 << 4);
578 is_master = fsi_is_master_mode(fsi, is_play);
579 if (is_master)
580 fsi_reg_mask_set(fsi, CKG1, data, data);
581 else
582 fsi_reg_mask_set(fsi, CKG1, data, 0);
583
584 /* clock inversion (CKG2) */
585 data = 0;
586 switch (SH_FSI_INVERSION_MASK & flags) {
587 case SH_FSI_LRM_INV:
588 data = 1 << 12;
589 break;
590 case SH_FSI_BRM_INV:
591 data = 1 << 8;
592 break;
593 case SH_FSI_LRS_INV:
594 data = 1 << 4;
595 break;
596 case SH_FSI_BRS_INV:
597 data = 1 << 0;
598 break;
599 }
600 fsi_reg_write(fsi, CKG2, data);
601
602 /* do fmt, di fmt */
603 data = 0;
604 reg = is_play ? DO_FMT : DI_FMT;
605 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
606 switch (fmt) {
607 case SH_FSI_FMT_MONO:
608 msg = "MONO";
609 data = CR_FMT(CR_MONO);
610 fsi->chan = 1;
611 break;
612 case SH_FSI_FMT_MONO_DELAY:
613 msg = "MONO Delay";
614 data = CR_FMT(CR_MONO_D);
615 fsi->chan = 1;
616 break;
617 case SH_FSI_FMT_PCM:
618 msg = "PCM";
619 data = CR_FMT(CR_PCM);
620 fsi->chan = 2;
621 break;
622 case SH_FSI_FMT_I2S:
623 msg = "I2S";
624 data = CR_FMT(CR_I2S);
625 fsi->chan = 2;
626 break;
627 case SH_FSI_FMT_TDM:
628 msg = "TDM";
629 data = CR_FMT(CR_TDM) | (fsi->chan - 1);
630 fsi->chan = is_play ?
631 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
632 break;
633 case SH_FSI_FMT_TDM_DELAY:
634 msg = "TDM Delay";
635 data = CR_FMT(CR_TDM_D) | (fsi->chan - 1);
636 fsi->chan = is_play ?
637 SH_FSI_GET_CH_O(flags) : SH_FSI_GET_CH_I(flags);
638 break;
639 default:
640 dev_err(dai->dev, "unknown format.\n");
641 return -EINVAL;
642 }
643
644 switch (fsi->chan) {
645 case 1:
646 fsi->fifo_max = 256;
647 break;
648 case 2:
649 fsi->fifo_max = 128;
650 break;
651 case 3:
652 case 4:
653 fsi->fifo_max = 64;
654 break;
655 case 5:
656 case 6:
657 case 7:
658 case 8:
659 fsi->fifo_max = 32;
660 break;
661 default:
662 dev_err(dai->dev, "channel size error.\n");
663 return -EINVAL;
664 }
665
666 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669
670 /*
671 * clear clk reset if master mode
672 */
673 if (is_master)
674 fsi_clk_ctrl(fsi, 1);
675
676 /* irq setting */
677 fsi_irq_init(fsi, is_play);
678
679 return ret;
680}
681
682static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
683 struct snd_soc_dai *dai)
684{
685 struct fsi_priv *fsi = fsi_get(substream);
686 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
687
688 fsi_irq_disable(fsi, is_play);
689 fsi_clk_ctrl(fsi, 0);
690
691 clk_disable(master->clk);
692}
693
694static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
695 struct snd_soc_dai *dai)
696{
697 struct fsi_priv *fsi = fsi_get(substream);
698 struct snd_pcm_runtime *runtime = substream->runtime;
699 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
700 int ret = 0;
701
702 /* capture not supported */
703 if (!is_play)
704 return -ENODEV;
705
706 switch (cmd) {
707 case SNDRV_PCM_TRIGGER_START:
708 fsi_stream_push(fsi, substream,
709 frames_to_bytes(runtime, runtime->buffer_size),
710 frames_to_bytes(runtime, runtime->period_size));
711 ret = fsi_data_push(fsi);
712 break;
713 case SNDRV_PCM_TRIGGER_STOP:
714 fsi_irq_disable(fsi, is_play);
715 fsi_stream_pop(fsi);
716 break;
717 }
718
719 return ret;
720}
721
722static struct snd_soc_dai_ops fsi_dai_ops = {
723 .startup = fsi_dai_startup,
724 .shutdown = fsi_dai_shutdown,
725 .trigger = fsi_dai_trigger,
726};
727
728/************************************************************************
729
730
731 pcm ops
732
733
734************************************************************************/
735static struct snd_pcm_hardware fsi_pcm_hardware = {
736 .info = SNDRV_PCM_INFO_INTERLEAVED |
737 SNDRV_PCM_INFO_MMAP |
738 SNDRV_PCM_INFO_MMAP_VALID |
739 SNDRV_PCM_INFO_PAUSE,
740 .formats = FSI_FMTS,
741 .rates = FSI_RATES,
742 .rate_min = 8000,
743 .rate_max = 192000,
744 .channels_min = 1,
745 .channels_max = 2,
746 .buffer_bytes_max = 64 * 1024,
747 .period_bytes_min = 32,
748 .period_bytes_max = 8192,
749 .periods_min = 1,
750 .periods_max = 32,
751 .fifo_size = 256,
752};
753
754static int fsi_pcm_open(struct snd_pcm_substream *substream)
755{
756 struct snd_pcm_runtime *runtime = substream->runtime;
757 int ret = 0;
758
759 snd_soc_set_runtime_hwparams(substream, &fsi_pcm_hardware);
760
761 ret = snd_pcm_hw_constraint_integer(runtime,
762 SNDRV_PCM_HW_PARAM_PERIODS);
763
764 return ret;
765}
766
767static int fsi_hw_params(struct snd_pcm_substream *substream,
768 struct snd_pcm_hw_params *hw_params)
769{
770 return snd_pcm_lib_malloc_pages(substream,
771 params_buffer_bytes(hw_params));
772}
773
774static int fsi_hw_free(struct snd_pcm_substream *substream)
775{
776 return snd_pcm_lib_free_pages(substream);
777}
778
779static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{
781 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location;
785
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play);
787 if (location < 0)
788 location = 0;
789
790 return bytes_to_frames(runtime, location);
791}
792
793static struct snd_pcm_ops fsi_pcm_ops = {
794 .open = fsi_pcm_open,
795 .ioctl = snd_pcm_lib_ioctl,
796 .hw_params = fsi_hw_params,
797 .hw_free = fsi_hw_free,
798 .pointer = fsi_pointer,
799};
800
801/************************************************************************
802
803
804 snd_soc_platform
805
806
807************************************************************************/
808#define PREALLOC_BUFFER (32 * 1024)
809#define PREALLOC_BUFFER_MAX (32 * 1024)
810
811static void fsi_pcm_free(struct snd_pcm *pcm)
812{
813 snd_pcm_lib_preallocate_free_for_all(pcm);
814}
815
816static int fsi_pcm_new(struct snd_card *card,
817 struct snd_soc_dai *dai,
818 struct snd_pcm *pcm)
819{
820 /*
821 * dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel
822 * in MMAP mode (i.e. aplay -M)
823 */
824 return snd_pcm_lib_preallocate_pages_for_all(
825 pcm,
826 SNDRV_DMA_TYPE_CONTINUOUS,
827 snd_dma_continuous_data(GFP_KERNEL),
828 PREALLOC_BUFFER, PREALLOC_BUFFER_MAX);
829}
830
831/************************************************************************
832
833
834 alsa struct
835
836
837************************************************************************/
838struct snd_soc_dai fsi_soc_dai[] = {
839 {
840 .name = "FSIA",
841 .id = 0,
842 .playback = {
843 .rates = FSI_RATES,
844 .formats = FSI_FMTS,
845 .channels_min = 1,
846 .channels_max = 8,
847 },
848 /* capture not supported */
849 .ops = &fsi_dai_ops,
850 },
851 {
852 .name = "FSIB",
853 .id = 1,
854 .playback = {
855 .rates = FSI_RATES,
856 .formats = FSI_FMTS,
857 .channels_min = 1,
858 .channels_max = 8,
859 },
860 /* capture not supported */
861 .ops = &fsi_dai_ops,
862 },
863};
864EXPORT_SYMBOL_GPL(fsi_soc_dai);
865
866struct snd_soc_platform fsi_soc_platform = {
867 .name = "fsi-pcm",
868 .pcm_ops = &fsi_pcm_ops,
869 .pcm_new = fsi_pcm_new,
870 .pcm_free = fsi_pcm_free,
871};
872EXPORT_SYMBOL_GPL(fsi_soc_platform);
873
874/************************************************************************
875
876
877 platform function
878
879
880************************************************************************/
881static int fsi_probe(struct platform_device *pdev)
882{
883 struct resource *res;
884 char clk_name[8];
885 unsigned int irq;
886 int ret;
887
888 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
889 irq = platform_get_irq(pdev, 0);
890 if (!res || !irq) {
891 dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
892 ret = -ENODEV;
893 goto exit;
894 }
895
896 master = kzalloc(sizeof(*master), GFP_KERNEL);
897 if (!master) {
898 dev_err(&pdev->dev, "Could not allocate master\n");
899 ret = -ENOMEM;
900 goto exit;
901 }
902
903 master->base = ioremap_nocache(res->start, resource_size(res));
904 if (!master->base) {
905 ret = -ENXIO;
906 dev_err(&pdev->dev, "Unable to ioremap FSI registers.\n");
907 goto exit_kfree;
908 }
909
910 master->irq = irq;
911 master->info = pdev->dev.platform_data;
912 master->fsia.base = master->base;
913 master->fsib.base = master->base + 0x40;
914
915 master->fsia.dma_chan = -1;
916 master->fsib.dma_chan = -1;
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO;
930 goto exit_free_dma;
931 }
932
933 fsi_soc_dai[0].dev = &pdev->dev;
934 fsi_soc_dai[1].dev = &pdev->dev;
935
936 fsi_soft_all_reset();
937
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma;
942 }
943
944 ret = snd_soc_register_platform(&fsi_soc_platform);
945 if (ret < 0) {
946 dev_err(&pdev->dev, "cannot snd soc register\n");
947 goto exit_free_irq;
948 }
949
950 return snd_soc_register_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
951
952exit_free_irq:
953 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap:
957 iounmap(master->base);
958exit_kfree:
959 kfree(master);
960 master = NULL;
961exit:
962 return ret;
963}
964
965static int fsi_remove(struct platform_device *pdev)
966{
967 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
968 snd_soc_unregister_platform(&fsi_soc_platform);
969
970 clk_put(master->clk);
971
972 fsi_free_dma_chan();
973
974 free_irq(master->irq, master);
975
976 iounmap(master->base);
977 kfree(master);
978 master = NULL;
979 return 0;
980}
981
982static struct platform_driver fsi_driver = {
983 .driver = {
984 .name = "sh_fsi",
985 },
986 .probe = fsi_probe,
987 .remove = fsi_remove,
988};
989
990static int __init fsi_mobile_init(void)
991{
992 return platform_driver_register(&fsi_driver);
993}
994
995static void __exit fsi_mobile_exit(void)
996{
997 platform_driver_unregister(&fsi_driver);
998}
999module_init(fsi_mobile_init);
1000module_exit(fsi_mobile_exit);
1001
1002MODULE_LICENSE("GPL");
1003MODULE_DESCRIPTION("SuperH onchip FSI audio driver");
1004MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
new file mode 100644
index 000000000000..c8ceddc2a26c
--- /dev/null
+++ b/sound/soc/soc-cache.c
@@ -0,0 +1,218 @@
1/*
2 * soc-cache.c -- ASoC register cache helpers
3 *
4 * Copyright 2009 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 it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/i2c.h>
15#include <linux/spi/spi.h>
16#include <sound/soc.h>
17
18static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
19 unsigned int reg)
20{
21 u16 *cache = codec->reg_cache;
22 if (reg >= codec->reg_cache_size)
23 return -1;
24 return cache[reg];
25}
26
27static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
28 unsigned int value)
29{
30 u16 *cache = codec->reg_cache;
31 u8 data[2];
32 int ret;
33
34 BUG_ON(codec->volatile_register);
35
36 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
37 data[1] = value & 0x00ff;
38
39 if (reg < codec->reg_cache_size)
40 cache[reg] = value;
41 ret = codec->hw_write(codec->control_data, data, 2);
42 if (ret == 2)
43 return 0;
44 if (ret < 0)
45 return ret;
46 else
47 return -EIO;
48}
49
50#if defined(CONFIG_SPI_MASTER)
51static int snd_soc_7_9_spi_write(void *control_data, const char *data,
52 int len)
53{
54 struct spi_device *spi = control_data;
55 struct spi_transfer t;
56 struct spi_message m;
57 u8 msg[2];
58
59 if (len <= 0)
60 return 0;
61
62 msg[0] = data[0];
63 msg[1] = data[1];
64
65 spi_message_init(&m);
66 memset(&t, 0, (sizeof t));
67
68 t.tx_buf = &msg[0];
69 t.len = len;
70
71 spi_message_add_tail(&t, &m);
72 spi_sync(spi, &m);
73
74 return len;
75}
76#else
77#define snd_soc_7_9_spi_write NULL
78#endif
79
80static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u16 *reg_cache = codec->reg_cache;
84 u8 data[3];
85
86 data[0] = reg;
87 data[1] = (value >> 8) & 0xff;
88 data[2] = value & 0xff;
89
90 if (!snd_soc_codec_volatile_register(codec, reg))
91 reg_cache[reg] = value;
92
93 if (codec->hw_write(codec->control_data, data, 3) == 3)
94 return 0;
95 else
96 return -EIO;
97}
98
99static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
100 unsigned int reg)
101{
102 u16 *cache = codec->reg_cache;
103
104 if (reg >= codec->reg_cache_size ||
105 snd_soc_codec_volatile_register(codec, reg))
106 return codec->hw_read(codec, reg);
107 else
108 return cache[reg];
109}
110
111#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
112static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
113 unsigned int r)
114{
115 struct i2c_msg xfer[2];
116 u8 reg = r;
117 u16 data;
118 int ret;
119 struct i2c_client *client = codec->control_data;
120
121 /* Write register */
122 xfer[0].addr = client->addr;
123 xfer[0].flags = 0;
124 xfer[0].len = 1;
125 xfer[0].buf = &reg;
126
127 /* Read data */
128 xfer[1].addr = client->addr;
129 xfer[1].flags = I2C_M_RD;
130 xfer[1].len = 2;
131 xfer[1].buf = (u8 *)&data;
132
133 ret = i2c_transfer(client->adapter, xfer, 2);
134 if (ret != 2) {
135 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
136 return 0;
137 }
138
139 return (data >> 8) | ((data & 0xff) << 8);
140}
141#else
142#define snd_soc_8_16_read_i2c NULL
143#endif
144
145static struct {
146 int addr_bits;
147 int data_bits;
148 int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int);
149 int (*spi_write)(void *, const char *, int);
150 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
151 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
152} io_types[] = {
153 { 7, 9, snd_soc_7_9_write, snd_soc_7_9_spi_write, snd_soc_7_9_read },
154 { 8, 16, snd_soc_8_16_write, NULL, snd_soc_8_16_read,
155 snd_soc_8_16_read_i2c },
156};
157
158/**
159 * snd_soc_codec_set_cache_io: Set up standard I/O functions.
160 *
161 * @codec: CODEC to configure.
162 * @type: Type of cache.
163 * @addr_bits: Number of bits of register address data.
164 * @data_bits: Number of bits of data per register.
165 * @control: Control bus used.
166 *
167 * Register formats are frequently shared between many I2C and SPI
168 * devices. In order to promote code reuse the ASoC core provides
169 * some standard implementations of CODEC read and write operations
170 * which can be set up using this function.
171 *
172 * The caller is responsible for allocating and initialising the
173 * actual cache.
174 *
175 * Note that at present this code cannot be used by CODECs with
176 * volatile registers.
177 */
178int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
179 int addr_bits, int data_bits,
180 enum snd_soc_control_type control)
181{
182 int i;
183
184 for (i = 0; i < ARRAY_SIZE(io_types); i++)
185 if (io_types[i].addr_bits == addr_bits &&
186 io_types[i].data_bits == data_bits)
187 break;
188 if (i == ARRAY_SIZE(io_types)) {
189 printk(KERN_ERR
190 "No I/O functions for %d bit address %d bit data\n",
191 addr_bits, data_bits);
192 return -EINVAL;
193 }
194
195 codec->write = io_types[i].write;
196 codec->read = io_types[i].read;
197
198 switch (control) {
199 case SND_SOC_CUSTOM:
200 break;
201
202 case SND_SOC_I2C:
203#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
204 codec->hw_write = (hw_write_t)i2c_master_send;
205#endif
206 if (io_types[i].i2c_read)
207 codec->hw_read = io_types[i].i2c_read;
208 break;
209
210 case SND_SOC_SPI:
211 if (io_types[i].spi_write)
212 codec->hw_write = io_types[i].spi_write;
213 break;
214 }
215
216 return 0;
217}
218EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1d70829464ef..7ff04ad2a97e 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -28,6 +28,7 @@
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h> 29#include <linux/debugfs.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <sound/ac97_codec.h>
31#include <sound/core.h> 32#include <sound/core.h>
32#include <sound/pcm.h> 33#include <sound/pcm.h>
33#include <sound/pcm_params.h> 34#include <sound/pcm_params.h>
@@ -619,8 +620,9 @@ static struct snd_pcm_ops soc_pcm_ops = {
619 620
620#ifdef CONFIG_PM 621#ifdef CONFIG_PM
621/* powers down audio subsystem for suspend */ 622/* powers down audio subsystem for suspend */
622static int soc_suspend(struct platform_device *pdev, pm_message_t state) 623static int soc_suspend(struct device *dev)
623{ 624{
625 struct platform_device *pdev = to_platform_device(dev);
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 626 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_card *card = socdev->card; 627 struct snd_soc_card *card = socdev->card;
626 struct snd_soc_platform *platform = card->platform; 628 struct snd_soc_platform *platform = card->platform;
@@ -656,7 +658,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
656 snd_pcm_suspend_all(card->dai_link[i].pcm); 658 snd_pcm_suspend_all(card->dai_link[i].pcm);
657 659
658 if (card->suspend_pre) 660 if (card->suspend_pre)
659 card->suspend_pre(pdev, state); 661 card->suspend_pre(pdev, PMSG_SUSPEND);
660 662
661 for (i = 0; i < card->num_links; i++) { 663 for (i = 0; i < card->num_links; i++) {
662 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 664 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
@@ -682,7 +684,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
682 } 684 }
683 685
684 if (codec_dev->suspend) 686 if (codec_dev->suspend)
685 codec_dev->suspend(pdev, state); 687 codec_dev->suspend(pdev, PMSG_SUSPEND);
686 688
687 for (i = 0; i < card->num_links; i++) { 689 for (i = 0; i < card->num_links; i++) {
688 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai; 690 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
@@ -691,7 +693,7 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
691 } 693 }
692 694
693 if (card->suspend_post) 695 if (card->suspend_post)
694 card->suspend_post(pdev, state); 696 card->suspend_post(pdev, PMSG_SUSPEND);
695 697
696 return 0; 698 return 0;
697} 699}
@@ -765,8 +767,9 @@ static void soc_resume_deferred(struct work_struct *work)
765} 767}
766 768
767/* powers up audio subsystem after a suspend */ 769/* powers up audio subsystem after a suspend */
768static int soc_resume(struct platform_device *pdev) 770static int soc_resume(struct device *dev)
769{ 771{
772 struct platform_device *pdev = to_platform_device(dev);
770 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 773 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
771 struct snd_soc_card *card = socdev->card; 774 struct snd_soc_card *card = socdev->card;
772 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai; 775 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
@@ -788,6 +791,44 @@ static int soc_resume(struct platform_device *pdev)
788 return 0; 791 return 0;
789} 792}
790 793
794/**
795 * snd_soc_suspend_device: Notify core of device suspend
796 *
797 * @dev: Device being suspended.
798 *
799 * In order to ensure that the entire audio subsystem is suspended in a
800 * coordinated fashion ASoC devices should suspend themselves when
801 * called by ASoC. When the standard kernel suspend process asks the
802 * device to suspend it should call this function to initiate a suspend
803 * of the entire ASoC card.
804 *
805 * \note Currently this function is stubbed out.
806 */
807int snd_soc_suspend_device(struct device *dev)
808{
809 return 0;
810}
811EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
812
813/**
814 * snd_soc_resume_device: Notify core of device resume
815 *
816 * @dev: Device being resumed.
817 *
818 * In order to ensure that the entire audio subsystem is resumed in a
819 * coordinated fashion ASoC devices should resume themselves when called
820 * by ASoC. When the standard kernel resume process asks the device
821 * to resume it should call this function. Once all the components of
822 * the card have notified that they are ready to be resumed the card
823 * will be resumed.
824 *
825 * \note Currently this function is stubbed out.
826 */
827int snd_soc_resume_device(struct device *dev)
828{
829 return 0;
830}
831EXPORT_SYMBOL_GPL(snd_soc_resume_device);
791#else 832#else
792#define soc_suspend NULL 833#define soc_suspend NULL
793#define soc_resume NULL 834#define soc_resume NULL
@@ -981,16 +1022,39 @@ static int soc_remove(struct platform_device *pdev)
981 return 0; 1022 return 0;
982} 1023}
983 1024
1025static int soc_poweroff(struct device *dev)
1026{
1027 struct platform_device *pdev = to_platform_device(dev);
1028 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1029 struct snd_soc_card *card = socdev->card;
1030
1031 if (!card->instantiated)
1032 return 0;
1033
1034 /* Flush out pmdown_time work - we actually do want to run it
1035 * now, we're shutting down so no imminent restart. */
1036 run_delayed_work(&card->delayed_work);
1037
1038 snd_soc_dapm_shutdown(socdev);
1039
1040 return 0;
1041}
1042
1043static struct dev_pm_ops soc_pm_ops = {
1044 .suspend = soc_suspend,
1045 .resume = soc_resume,
1046 .poweroff = soc_poweroff,
1047};
1048
984/* ASoC platform driver */ 1049/* ASoC platform driver */
985static struct platform_driver soc_driver = { 1050static struct platform_driver soc_driver = {
986 .driver = { 1051 .driver = {
987 .name = "soc-audio", 1052 .name = "soc-audio",
988 .owner = THIS_MODULE, 1053 .owner = THIS_MODULE,
1054 .pm = &soc_pm_ops,
989 }, 1055 },
990 .probe = soc_probe, 1056 .probe = soc_probe,
991 .remove = soc_remove, 1057 .remove = soc_remove,
992 .suspend = soc_suspend,
993 .resume = soc_resume,
994}; 1058};
995 1059
996/* create a new pcm */ 1060/* create a new pcm */
@@ -1062,6 +1126,23 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1062 return ret; 1126 return ret;
1063} 1127}
1064 1128
1129/**
1130 * snd_soc_codec_volatile_register: Report if a register is volatile.
1131 *
1132 * @codec: CODEC to query.
1133 * @reg: Register to query.
1134 *
1135 * Boolean function indiciating if a CODEC register is volatile.
1136 */
1137int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1138{
1139 if (codec->volatile_register)
1140 return codec->volatile_register(reg);
1141 else
1142 return 0;
1143}
1144EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
1145
1065/* codec register dump */ 1146/* codec register dump */
1066static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 1147static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1067{ 1148{
@@ -1075,6 +1156,9 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1075 1156
1076 count += sprintf(buf, "%s registers\n", codec->name); 1157 count += sprintf(buf, "%s registers\n", codec->name);
1077 for (i = 0; i < codec->reg_cache_size; i += step) { 1158 for (i = 0; i < codec->reg_cache_size; i += step) {
1159 if (codec->readable_register && !codec->readable_register(i))
1160 continue;
1161
1078 count += sprintf(buf + count, "%2x: ", i); 1162 count += sprintf(buf + count, "%2x: ", i);
1079 if (count >= PAGE_SIZE - 1) 1163 if (count >= PAGE_SIZE - 1)
1080 break; 1164 break;
@@ -1183,10 +1267,18 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1183 if (!codec->debugfs_pop_time) 1267 if (!codec->debugfs_pop_time)
1184 printk(KERN_WARNING 1268 printk(KERN_WARNING
1185 "Failed to create pop time debugfs file\n"); 1269 "Failed to create pop time debugfs file\n");
1270
1271 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1272 if (!codec->debugfs_dapm)
1273 printk(KERN_WARNING
1274 "Failed to create DAPM debugfs directory\n");
1275
1276 snd_soc_dapm_debugfs_init(codec);
1186} 1277}
1187 1278
1188static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 1279static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1189{ 1280{
1281 debugfs_remove_recursive(codec->debugfs_dapm);
1190 debugfs_remove(codec->debugfs_pop_time); 1282 debugfs_remove(codec->debugfs_pop_time);
1191 debugfs_remove(codec->debugfs_reg); 1283 debugfs_remove(codec->debugfs_reg);
1192} 1284}
@@ -1264,10 +1356,10 @@ EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
1264 * Returns 1 for change else 0. 1356 * Returns 1 for change else 0.
1265 */ 1357 */
1266int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 1358int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1267 unsigned short mask, unsigned short value) 1359 unsigned int mask, unsigned int value)
1268{ 1360{
1269 int change; 1361 int change;
1270 unsigned short old, new; 1362 unsigned int old, new;
1271 1363
1272 mutex_lock(&io_mutex); 1364 mutex_lock(&io_mutex);
1273 old = snd_soc_read(codec, reg); 1365 old = snd_soc_read(codec, reg);
@@ -1294,10 +1386,10 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1294 * Returns 1 for change else 0. 1386 * Returns 1 for change else 0.
1295 */ 1387 */
1296int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, 1388int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1297 unsigned short mask, unsigned short value) 1389 unsigned int mask, unsigned int value)
1298{ 1390{
1299 int change; 1391 int change;
1300 unsigned short old, new; 1392 unsigned int old, new;
1301 1393
1302 mutex_lock(&io_mutex); 1394 mutex_lock(&io_mutex);
1303 old = snd_soc_read(codec, reg); 1395 old = snd_soc_read(codec, reg);
@@ -1381,8 +1473,11 @@ int snd_soc_init_card(struct snd_soc_device *socdev)
1381 continue; 1473 continue;
1382 } 1474 }
1383 } 1475 }
1384 if (card->dai_link[i].codec_dai->ac97_control) 1476 if (card->dai_link[i].codec_dai->ac97_control) {
1385 ac97 = 1; 1477 ac97 = 1;
1478 snd_ac97_dev_add_pdata(codec->ac97,
1479 card->dai_link[i].cpu_dai->ac97_pdata);
1480 }
1386 } 1481 }
1387 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1482 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1388 "%s", card->name); 1483 "%s", card->name);
@@ -1586,7 +1681,7 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1586{ 1681{
1587 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1682 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1588 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1683 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1589 unsigned short val, bitmask; 1684 unsigned int val, bitmask;
1590 1685
1591 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1686 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1592 ; 1687 ;
@@ -1615,8 +1710,8 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1615{ 1710{
1616 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1711 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1617 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1712 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1618 unsigned short val; 1713 unsigned int val;
1619 unsigned short mask, bitmask; 1714 unsigned int mask, bitmask;
1620 1715
1621 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1716 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1622 ; 1717 ;
@@ -1652,7 +1747,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
1652{ 1747{
1653 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1748 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1654 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1749 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1655 unsigned short reg_val, val, mux; 1750 unsigned int reg_val, val, mux;
1656 1751
1657 reg_val = snd_soc_read(codec, e->reg); 1752 reg_val = snd_soc_read(codec, e->reg);
1658 val = (reg_val >> e->shift_l) & e->mask; 1753 val = (reg_val >> e->shift_l) & e->mask;
@@ -1691,8 +1786,8 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1691{ 1786{
1692 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 1787 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1693 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1788 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1694 unsigned short val; 1789 unsigned int val;
1695 unsigned short mask; 1790 unsigned int mask;
1696 1791
1697 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1792 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1698 return -EINVAL; 1793 return -EINVAL;
@@ -1852,7 +1947,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1852 int max = mc->max; 1947 int max = mc->max;
1853 unsigned int mask = (1 << fls(max)) - 1; 1948 unsigned int mask = (1 << fls(max)) - 1;
1854 unsigned int invert = mc->invert; 1949 unsigned int invert = mc->invert;
1855 unsigned short val, val2, val_mask; 1950 unsigned int val, val2, val_mask;
1856 1951
1857 val = (ucontrol->value.integer.value[0] & mask); 1952 val = (ucontrol->value.integer.value[0] & mask);
1858 if (invert) 1953 if (invert)
@@ -1918,7 +2013,7 @@ int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1918 unsigned int reg2 = mc->rreg; 2013 unsigned int reg2 = mc->rreg;
1919 unsigned int shift = mc->shift; 2014 unsigned int shift = mc->shift;
1920 int max = mc->max; 2015 int max = mc->max;
1921 unsigned int mask = (1<<fls(max))-1; 2016 unsigned int mask = (1 << fls(max)) - 1;
1922 unsigned int invert = mc->invert; 2017 unsigned int invert = mc->invert;
1923 2018
1924 ucontrol->value.integer.value[0] = 2019 ucontrol->value.integer.value[0] =
@@ -1958,7 +2053,7 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1958 unsigned int mask = (1 << fls(max)) - 1; 2053 unsigned int mask = (1 << fls(max)) - 1;
1959 unsigned int invert = mc->invert; 2054 unsigned int invert = mc->invert;
1960 int err; 2055 int err;
1961 unsigned short val, val2, val_mask; 2056 unsigned int val, val2, val_mask;
1962 2057
1963 val_mask = mask << shift; 2058 val_mask = mask << shift;
1964 val = (ucontrol->value.integer.value[0] & mask); 2059 val = (ucontrol->value.integer.value[0] & mask);
@@ -2050,7 +2145,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2050 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 2145 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2051 unsigned int reg = mc->reg; 2146 unsigned int reg = mc->reg;
2052 int min = mc->min; 2147 int min = mc->min;
2053 unsigned short val; 2148 unsigned int val;
2054 2149
2055 val = (ucontrol->value.integer.value[0]+min) & 0xff; 2150 val = (ucontrol->value.integer.value[0]+min) & 0xff;
2056 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; 2151 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
@@ -2136,17 +2231,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
2136/** 2231/**
2137 * snd_soc_dai_set_tdm_slot - configure DAI TDM. 2232 * snd_soc_dai_set_tdm_slot - configure DAI TDM.
2138 * @dai: DAI 2233 * @dai: DAI
2139 * @mask: DAI specific mask representing used slots. 2234 * @tx_mask: bitmask representing active TX slots.
2235 * @rx_mask: bitmask representing active RX slots.
2140 * @slots: Number of slots in use. 2236 * @slots: Number of slots in use.
2237 * @slot_width: Width in bits for each slot.
2141 * 2238 *
2142 * Configures a DAI for TDM operation. Both mask and slots are codec and DAI 2239 * Configures a DAI for TDM operation. Both mask and slots are codec and DAI
2143 * specific. 2240 * specific.
2144 */ 2241 */
2145int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2242int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2146 unsigned int mask, int slots) 2243 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
2147{ 2244{
2148 if (dai->ops && dai->ops->set_tdm_slot) 2245 if (dai->ops && dai->ops->set_tdm_slot)
2149 return dai->ops->set_tdm_slot(dai, mask, slots); 2246 return dai->ops->set_tdm_slot(dai, tx_mask, rx_mask,
2247 slots, slot_width);
2150 else 2248 else
2151 return -EINVAL; 2249 return -EINVAL;
2152} 2250}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 21c69074aa17..0d8b08ef8731 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -37,6 +37,7 @@
37#include <linux/bitops.h> 37#include <linux/bitops.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h>
40#include <sound/core.h> 41#include <sound/core.h>
41#include <sound/pcm.h> 42#include <sound/pcm.h>
42#include <sound/pcm_params.h> 43#include <sound/pcm_params.h>
@@ -52,19 +53,41 @@
52 53
53/* dapm power sequences - make this per codec in the future */ 54/* dapm power sequences - make this per codec in the future */
54static int dapm_up_seq[] = { 55static int dapm_up_seq[] = {
55 snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias, 56 [snd_soc_dapm_pre] = 0,
56 snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux, 57 [snd_soc_dapm_supply] = 1,
57 snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, 58 [snd_soc_dapm_micbias] = 2,
58 snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 59 [snd_soc_dapm_aif_in] = 3,
59 snd_soc_dapm_post 60 [snd_soc_dapm_aif_out] = 3,
61 [snd_soc_dapm_mic] = 4,
62 [snd_soc_dapm_mux] = 5,
63 [snd_soc_dapm_value_mux] = 5,
64 [snd_soc_dapm_dac] = 6,
65 [snd_soc_dapm_mixer] = 7,
66 [snd_soc_dapm_mixer_named_ctl] = 7,
67 [snd_soc_dapm_pga] = 8,
68 [snd_soc_dapm_adc] = 9,
69 [snd_soc_dapm_hp] = 10,
70 [snd_soc_dapm_spk] = 10,
71 [snd_soc_dapm_post] = 11,
60}; 72};
61 73
62static int dapm_down_seq[] = { 74static int dapm_down_seq[] = {
63 snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, 75 [snd_soc_dapm_pre] = 0,
64 snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, 76 [snd_soc_dapm_adc] = 1,
65 snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, 77 [snd_soc_dapm_hp] = 2,
66 snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply, 78 [snd_soc_dapm_spk] = 2,
67 snd_soc_dapm_post 79 [snd_soc_dapm_pga] = 4,
80 [snd_soc_dapm_mixer_named_ctl] = 5,
81 [snd_soc_dapm_mixer] = 5,
82 [snd_soc_dapm_dac] = 6,
83 [snd_soc_dapm_mic] = 7,
84 [snd_soc_dapm_micbias] = 8,
85 [snd_soc_dapm_mux] = 9,
86 [snd_soc_dapm_value_mux] = 9,
87 [snd_soc_dapm_aif_in] = 10,
88 [snd_soc_dapm_aif_out] = 10,
89 [snd_soc_dapm_supply] = 11,
90 [snd_soc_dapm_post] = 12,
68}; 91};
69 92
70static void pop_wait(u32 pop_time) 93static void pop_wait(u32 pop_time)
@@ -130,8 +153,12 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
130 153
131 if (card->set_bias_level) 154 if (card->set_bias_level)
132 ret = card->set_bias_level(card, level); 155 ret = card->set_bias_level(card, level);
133 if (ret == 0 && codec->set_bias_level) 156 if (ret == 0) {
134 ret = codec->set_bias_level(codec, level); 157 if (codec->set_bias_level)
158 ret = codec->set_bias_level(codec, level);
159 else
160 codec->bias_level = level;
161 }
135 162
136 return ret; 163 return ret;
137} 164}
@@ -206,6 +233,8 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
206 case snd_soc_dapm_micbias: 233 case snd_soc_dapm_micbias:
207 case snd_soc_dapm_vmid: 234 case snd_soc_dapm_vmid:
208 case snd_soc_dapm_supply: 235 case snd_soc_dapm_supply:
236 case snd_soc_dapm_aif_in:
237 case snd_soc_dapm_aif_out:
209 p->connect = 1; 238 p->connect = 1;
210 break; 239 break;
211 /* does effect routing - dynamically connected */ 240 /* does effect routing - dynamically connected */
@@ -268,7 +297,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec,
268static int dapm_update_bits(struct snd_soc_dapm_widget *widget) 297static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
269{ 298{
270 int change, power; 299 int change, power;
271 unsigned short old, new; 300 unsigned int old, new;
272 struct snd_soc_codec *codec = widget->codec; 301 struct snd_soc_codec *codec = widget->codec;
273 302
274 /* check for valid widgets */ 303 /* check for valid widgets */
@@ -479,8 +508,14 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget)
479 if (widget->id == snd_soc_dapm_supply) 508 if (widget->id == snd_soc_dapm_supply)
480 return 0; 509 return 0;
481 510
482 if (widget->id == snd_soc_dapm_adc && widget->active) 511 switch (widget->id) {
483 return 1; 512 case snd_soc_dapm_adc:
513 case snd_soc_dapm_aif_out:
514 if (widget->active)
515 return 1;
516 default:
517 break;
518 }
484 519
485 if (widget->connected) { 520 if (widget->connected) {
486 /* connected pin ? */ 521 /* connected pin ? */
@@ -519,8 +554,14 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget)
519 return 0; 554 return 0;
520 555
521 /* active stream ? */ 556 /* active stream ? */
522 if (widget->id == snd_soc_dapm_dac && widget->active) 557 switch (widget->id) {
523 return 1; 558 case snd_soc_dapm_dac:
559 case snd_soc_dapm_aif_in:
560 if (widget->active)
561 return 1;
562 default:
563 break;
564 }
524 565
525 if (widget->connected) { 566 if (widget->connected) {
526 /* connected pin ? */ 567 /* connected pin ? */
@@ -689,53 +730,211 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
689 return power; 730 return power;
690} 731}
691 732
692/* 733static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
693 * Scan a single DAPM widget for a complete audio path and update the 734 struct snd_soc_dapm_widget *b,
694 * power status appropriately. 735 int sort[])
695 */
696static int dapm_power_widget(struct snd_soc_codec *codec, int event,
697 struct snd_soc_dapm_widget *w)
698{ 736{
699 int ret; 737 if (sort[a->id] != sort[b->id])
738 return sort[a->id] - sort[b->id];
739 if (a->reg != b->reg)
740 return a->reg - b->reg;
700 741
701 switch (w->id) { 742 return 0;
702 case snd_soc_dapm_pre: 743}
703 if (!w->event)
704 return 0;
705 744
706 if (event == SND_SOC_DAPM_STREAM_START) { 745/* Insert a widget in order into a DAPM power sequence. */
707 ret = w->event(w, 746static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
708 NULL, SND_SOC_DAPM_PRE_PMU); 747 struct list_head *list,
748 int sort[])
749{
750 struct snd_soc_dapm_widget *w;
751
752 list_for_each_entry(w, list, power_list)
753 if (dapm_seq_compare(new_widget, w, sort) < 0) {
754 list_add_tail(&new_widget->power_list, &w->power_list);
755 return;
756 }
757
758 list_add_tail(&new_widget->power_list, list);
759}
760
761/* Apply the coalesced changes from a DAPM sequence */
762static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
763 struct list_head *pending)
764{
765 struct snd_soc_dapm_widget *w;
766 int reg, power, ret;
767 unsigned int value = 0;
768 unsigned int mask = 0;
769 unsigned int cur_mask;
770
771 reg = list_first_entry(pending, struct snd_soc_dapm_widget,
772 power_list)->reg;
773
774 list_for_each_entry(w, pending, power_list) {
775 cur_mask = 1 << w->shift;
776 BUG_ON(reg != w->reg);
777
778 if (w->invert)
779 power = !w->power;
780 else
781 power = w->power;
782
783 mask |= cur_mask;
784 if (power)
785 value |= cur_mask;
786
787 pop_dbg(codec->pop_time,
788 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
789 w->name, reg, value, mask);
790
791 /* power up pre event */
792 if (w->power && w->event &&
793 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) {
794 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
795 w->name);
796 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
709 if (ret < 0) 797 if (ret < 0)
710 return ret; 798 pr_err("%s: pre event failed: %d\n",
711 } else if (event == SND_SOC_DAPM_STREAM_STOP) { 799 w->name, ret);
712 ret = w->event(w, 800 }
713 NULL, SND_SOC_DAPM_PRE_PMD); 801
802 /* power down pre event */
803 if (!w->power && w->event &&
804 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
805 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
806 w->name);
807 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
714 if (ret < 0) 808 if (ret < 0)
715 return ret; 809 pr_err("%s: pre event failed: %d\n",
810 w->name, ret);
716 } 811 }
717 return 0;
718 812
719 case snd_soc_dapm_post: 813 /* Lower PGA volume to reduce pops */
720 if (!w->event) 814 if (w->id == snd_soc_dapm_pga && !w->power)
721 return 0; 815 dapm_set_pga(w, w->power);
816 }
722 817
723 if (event == SND_SOC_DAPM_STREAM_START) { 818 if (reg >= 0) {
819 pop_dbg(codec->pop_time,
820 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
821 value, mask, reg, codec->pop_time);
822 pop_wait(codec->pop_time);
823 snd_soc_update_bits(codec, reg, mask, value);
824 }
825
826 list_for_each_entry(w, pending, power_list) {
827 /* Raise PGA volume to reduce pops */
828 if (w->id == snd_soc_dapm_pga && w->power)
829 dapm_set_pga(w, w->power);
830
831 /* power up post event */
832 if (w->power && w->event &&
833 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
834 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
835 w->name);
724 ret = w->event(w, 836 ret = w->event(w,
725 NULL, SND_SOC_DAPM_POST_PMU); 837 NULL, SND_SOC_DAPM_POST_PMU);
726 if (ret < 0) 838 if (ret < 0)
727 return ret; 839 pr_err("%s: post event failed: %d\n",
728 } else if (event == SND_SOC_DAPM_STREAM_STOP) { 840 w->name, ret);
729 ret = w->event(w, 841 }
730 NULL, SND_SOC_DAPM_POST_PMD); 842
843 /* power down post event */
844 if (!w->power && w->event &&
845 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
846 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
847 w->name);
848 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
731 if (ret < 0) 849 if (ret < 0)
732 return ret; 850 pr_err("%s: post event failed: %d\n",
851 w->name, ret);
733 } 852 }
734 return 0; 853 }
854}
735 855
736 default: 856/* Apply a DAPM power sequence.
737 return dapm_generic_apply_power(w); 857 *
858 * We walk over a pre-sorted list of widgets to apply power to. In
859 * order to minimise the number of writes to the device required
860 * multiple widgets will be updated in a single write where possible.
861 * Currently anything that requires more than a single write is not
862 * handled.
863 */
864static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
865 int event, int sort[])
866{
867 struct snd_soc_dapm_widget *w, *n;
868 LIST_HEAD(pending);
869 int cur_sort = -1;
870 int cur_reg = SND_SOC_NOPM;
871 int ret;
872
873 list_for_each_entry_safe(w, n, list, power_list) {
874 ret = 0;
875
876 /* Do we need to apply any queued changes? */
877 if (sort[w->id] != cur_sort || w->reg != cur_reg) {
878 if (!list_empty(&pending))
879 dapm_seq_run_coalesced(codec, &pending);
880
881 INIT_LIST_HEAD(&pending);
882 cur_sort = -1;
883 cur_reg = SND_SOC_NOPM;
884 }
885
886 switch (w->id) {
887 case snd_soc_dapm_pre:
888 if (!w->event)
889 list_for_each_entry_safe_continue(w, n, list,
890 power_list);
891
892 if (event == SND_SOC_DAPM_STREAM_START)
893 ret = w->event(w,
894 NULL, SND_SOC_DAPM_PRE_PMU);
895 else if (event == SND_SOC_DAPM_STREAM_STOP)
896 ret = w->event(w,
897 NULL, SND_SOC_DAPM_PRE_PMD);
898 break;
899
900 case snd_soc_dapm_post:
901 if (!w->event)
902 list_for_each_entry_safe_continue(w, n, list,
903 power_list);
904
905 if (event == SND_SOC_DAPM_STREAM_START)
906 ret = w->event(w,
907 NULL, SND_SOC_DAPM_POST_PMU);
908 else if (event == SND_SOC_DAPM_STREAM_STOP)
909 ret = w->event(w,
910 NULL, SND_SOC_DAPM_POST_PMD);
911 break;
912
913 case snd_soc_dapm_input:
914 case snd_soc_dapm_output:
915 case snd_soc_dapm_hp:
916 case snd_soc_dapm_mic:
917 case snd_soc_dapm_line:
918 case snd_soc_dapm_spk:
919 /* No register support currently */
920 ret = dapm_generic_apply_power(w);
921 break;
922
923 default:
924 /* Queue it up for application */
925 cur_sort = sort[w->id];
926 cur_reg = w->reg;
927 list_move(&w->power_list, &pending);
928 break;
929 }
930
931 if (ret < 0)
932 pr_err("Failed to apply widget power: %d\n",
933 ret);
738 } 934 }
935
936 if (!list_empty(&pending))
937 dapm_seq_run_coalesced(codec, &pending);
739} 938}
740 939
741/* 940/*
@@ -751,23 +950,22 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
751{ 950{
752 struct snd_soc_device *socdev = codec->socdev; 951 struct snd_soc_device *socdev = codec->socdev;
753 struct snd_soc_dapm_widget *w; 952 struct snd_soc_dapm_widget *w;
953 LIST_HEAD(up_list);
954 LIST_HEAD(down_list);
754 int ret = 0; 955 int ret = 0;
755 int i, power; 956 int power;
756 int sys_power = 0; 957 int sys_power = 0;
757 958
758 INIT_LIST_HEAD(&codec->up_list);
759 INIT_LIST_HEAD(&codec->down_list);
760
761 /* Check which widgets we need to power and store them in 959 /* Check which widgets we need to power and store them in
762 * lists indicating if they should be powered up or down. 960 * lists indicating if they should be powered up or down.
763 */ 961 */
764 list_for_each_entry(w, &codec->dapm_widgets, list) { 962 list_for_each_entry(w, &codec->dapm_widgets, list) {
765 switch (w->id) { 963 switch (w->id) {
766 case snd_soc_dapm_pre: 964 case snd_soc_dapm_pre:
767 list_add_tail(&codec->down_list, &w->power_list); 965 dapm_seq_insert(w, &down_list, dapm_down_seq);
768 break; 966 break;
769 case snd_soc_dapm_post: 967 case snd_soc_dapm_post:
770 list_add_tail(&codec->up_list, &w->power_list); 968 dapm_seq_insert(w, &up_list, dapm_up_seq);
771 break; 969 break;
772 970
773 default: 971 default:
@@ -782,16 +980,31 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
782 continue; 980 continue;
783 981
784 if (power) 982 if (power)
785 list_add_tail(&w->power_list, &codec->up_list); 983 dapm_seq_insert(w, &up_list, dapm_up_seq);
786 else 984 else
787 list_add_tail(&w->power_list, 985 dapm_seq_insert(w, &down_list, dapm_down_seq);
788 &codec->down_list);
789 986
790 w->power = power; 987 w->power = power;
791 break; 988 break;
792 } 989 }
793 } 990 }
794 991
992 /* If there are no DAPM widgets then try to figure out power from the
993 * event type.
994 */
995 if (list_empty(&codec->dapm_widgets)) {
996 switch (event) {
997 case SND_SOC_DAPM_STREAM_START:
998 case SND_SOC_DAPM_STREAM_RESUME:
999 sys_power = 1;
1000 break;
1001 case SND_SOC_DAPM_STREAM_NOP:
1002 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
1003 default:
1004 break;
1005 }
1006 }
1007
795 /* If we're changing to all on or all off then prepare */ 1008 /* If we're changing to all on or all off then prepare */
796 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1009 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
797 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1010 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
@@ -802,32 +1015,10 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
802 } 1015 }
803 1016
804 /* Power down widgets first; try to avoid amplifying pops. */ 1017 /* Power down widgets first; try to avoid amplifying pops. */
805 for (i = 0; i < ARRAY_SIZE(dapm_down_seq); i++) { 1018 dapm_seq_run(codec, &down_list, event, dapm_down_seq);
806 list_for_each_entry(w, &codec->down_list, power_list) {
807 /* is widget in stream order */
808 if (w->id != dapm_down_seq[i])
809 continue;
810
811 ret = dapm_power_widget(codec, event, w);
812 if (ret != 0)
813 pr_err("Failed to power down %s: %d\n",
814 w->name, ret);
815 }
816 }
817 1019
818 /* Now power up. */ 1020 /* Now power up. */
819 for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) { 1021 dapm_seq_run(codec, &up_list, event, dapm_up_seq);
820 list_for_each_entry(w, &codec->up_list, power_list) {
821 /* is widget in stream order */
822 if (w->id != dapm_up_seq[i])
823 continue;
824
825 ret = dapm_power_widget(codec, event, w);
826 if (ret != 0)
827 pr_err("Failed to power up %s: %d\n",
828 w->name, ret);
829 }
830 }
831 1022
832 /* If we just powered the last thing off drop to standby bias */ 1023 /* If we just powered the last thing off drop to standby bias */
833 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 1024 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) {
@@ -845,6 +1036,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
845 pr_err("Failed to apply active bias: %d\n", ret); 1036 pr_err("Failed to apply active bias: %d\n", ret);
846 } 1037 }
847 1038
1039 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n",
1040 codec->pop_time);
1041
848 return 0; 1042 return 0;
849} 1043}
850 1044
@@ -881,6 +1075,8 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
881 case snd_soc_dapm_mixer: 1075 case snd_soc_dapm_mixer:
882 case snd_soc_dapm_mixer_named_ctl: 1076 case snd_soc_dapm_mixer_named_ctl:
883 case snd_soc_dapm_supply: 1077 case snd_soc_dapm_supply:
1078 case snd_soc_dapm_aif_in:
1079 case snd_soc_dapm_aif_out:
884 if (w->name) { 1080 if (w->name) {
885 in = is_connected_input_ep(w); 1081 in = is_connected_input_ep(w);
886 dapm_clear_walk(w->codec); 1082 dapm_clear_walk(w->codec);
@@ -906,6 +1102,92 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
906} 1102}
907#endif 1103#endif
908 1104
1105#ifdef CONFIG_DEBUG_FS
1106static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1107{
1108 file->private_data = inode->i_private;
1109 return 0;
1110}
1111
1112static ssize_t dapm_widget_power_read_file(struct file *file,
1113 char __user *user_buf,
1114 size_t count, loff_t *ppos)
1115{
1116 struct snd_soc_dapm_widget *w = file->private_data;
1117 char *buf;
1118 int in, out;
1119 ssize_t ret;
1120 struct snd_soc_dapm_path *p = NULL;
1121
1122 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1123 if (!buf)
1124 return -ENOMEM;
1125
1126 in = is_connected_input_ep(w);
1127 dapm_clear_walk(w->codec);
1128 out = is_connected_output_ep(w);
1129 dapm_clear_walk(w->codec);
1130
1131 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n",
1132 w->name, w->power ? "On" : "Off", in, out);
1133
1134 if (w->active && w->sname)
1135 ret += snprintf(buf, PAGE_SIZE - ret, " stream %s active\n",
1136 w->sname);
1137
1138 list_for_each_entry(p, &w->sources, list_sink) {
1139 if (p->connect)
1140 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1141 " in %s %s\n",
1142 p->name ? p->name : "static",
1143 p->source->name);
1144 }
1145 list_for_each_entry(p, &w->sinks, list_source) {
1146 if (p->connect)
1147 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1148 " out %s %s\n",
1149 p->name ? p->name : "static",
1150 p->sink->name);
1151 }
1152
1153 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1154
1155 kfree(buf);
1156 return ret;
1157}
1158
1159static const struct file_operations dapm_widget_power_fops = {
1160 .open = dapm_widget_power_open_file,
1161 .read = dapm_widget_power_read_file,
1162};
1163
1164void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1165{
1166 struct snd_soc_dapm_widget *w;
1167 struct dentry *d;
1168
1169 if (!codec->debugfs_dapm)
1170 return;
1171
1172 list_for_each_entry(w, &codec->dapm_widgets, list) {
1173 if (!w->name)
1174 continue;
1175
1176 d = debugfs_create_file(w->name, 0444,
1177 codec->debugfs_dapm, w,
1178 &dapm_widget_power_fops);
1179 if (!d)
1180 printk(KERN_WARNING
1181 "ASoC: Failed to create %s debugfs file\n",
1182 w->name);
1183 }
1184}
1185#else
1186void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1187{
1188}
1189#endif
1190
909/* test and update the power status of a mux widget */ 1191/* test and update the power status of a mux widget */
910static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1192static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
911 struct snd_kcontrol *kcontrol, int mask, 1193 struct snd_kcontrol *kcontrol, int mask,
@@ -1138,8 +1420,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1138 if (wsink->id == snd_soc_dapm_input) { 1420 if (wsink->id == snd_soc_dapm_input) {
1139 if (wsource->id == snd_soc_dapm_micbias || 1421 if (wsource->id == snd_soc_dapm_micbias ||
1140 wsource->id == snd_soc_dapm_mic || 1422 wsource->id == snd_soc_dapm_mic ||
1141 wsink->id == snd_soc_dapm_line || 1423 wsource->id == snd_soc_dapm_line ||
1142 wsink->id == snd_soc_dapm_output) 1424 wsource->id == snd_soc_dapm_output)
1143 wsink->ext = 1; 1425 wsink->ext = 1;
1144 } 1426 }
1145 if (wsource->id == snd_soc_dapm_output) { 1427 if (wsource->id == snd_soc_dapm_output) {
@@ -1171,6 +1453,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1171 case snd_soc_dapm_pre: 1453 case snd_soc_dapm_pre:
1172 case snd_soc_dapm_post: 1454 case snd_soc_dapm_post:
1173 case snd_soc_dapm_supply: 1455 case snd_soc_dapm_supply:
1456 case snd_soc_dapm_aif_in:
1457 case snd_soc_dapm_aif_out:
1174 list_add(&path->list, &codec->dapm_paths); 1458 list_add(&path->list, &codec->dapm_paths);
1175 list_add(&path->list_sink, &wsink->sources); 1459 list_add(&path->list_sink, &wsink->sources);
1176 list_add(&path->list_source, &wsource->sinks); 1460 list_add(&path->list_source, &wsource->sinks);
@@ -1273,9 +1557,11 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1273 dapm_new_mux(codec, w); 1557 dapm_new_mux(codec, w);
1274 break; 1558 break;
1275 case snd_soc_dapm_adc: 1559 case snd_soc_dapm_adc:
1560 case snd_soc_dapm_aif_out:
1276 w->power_check = dapm_adc_check_power; 1561 w->power_check = dapm_adc_check_power;
1277 break; 1562 break;
1278 case snd_soc_dapm_dac: 1563 case snd_soc_dapm_dac:
1564 case snd_soc_dapm_aif_in:
1279 w->power_check = dapm_dac_check_power; 1565 w->power_check = dapm_dac_check_power;
1280 break; 1566 break;
1281 case snd_soc_dapm_pga: 1567 case snd_soc_dapm_pga:
@@ -1372,7 +1658,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1372 int max = mc->max; 1658 int max = mc->max;
1373 unsigned int mask = (1 << fls(max)) - 1; 1659 unsigned int mask = (1 << fls(max)) - 1;
1374 unsigned int invert = mc->invert; 1660 unsigned int invert = mc->invert;
1375 unsigned short val, val2, val_mask; 1661 unsigned int val, val2, val_mask;
1376 int ret; 1662 int ret;
1377 1663
1378 val = (ucontrol->value.integer.value[0] & mask); 1664 val = (ucontrol->value.integer.value[0] & mask);
@@ -1436,7 +1722,7 @@ int snd_soc_dapm_get_enum_double(struct snd_kcontrol *kcontrol,
1436{ 1722{
1437 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1723 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1438 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1724 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1439 unsigned short val, bitmask; 1725 unsigned int val, bitmask;
1440 1726
1441 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1727 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1442 ; 1728 ;
@@ -1464,8 +1750,8 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1464{ 1750{
1465 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1751 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1466 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1752 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1467 unsigned short val, mux; 1753 unsigned int val, mux;
1468 unsigned short mask, bitmask; 1754 unsigned int mask, bitmask;
1469 int ret = 0; 1755 int ret = 0;
1470 1756
1471 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1757 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
@@ -1523,7 +1809,7 @@ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
1523{ 1809{
1524 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1810 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1525 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1811 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1526 unsigned short reg_val, val, mux; 1812 unsigned int reg_val, val, mux;
1527 1813
1528 reg_val = snd_soc_read(widget->codec, e->reg); 1814 reg_val = snd_soc_read(widget->codec, e->reg);
1529 val = (reg_val >> e->shift_l) & e->mask; 1815 val = (reg_val >> e->shift_l) & e->mask;
@@ -1563,8 +1849,8 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1563{ 1849{
1564 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1850 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1565 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1851 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1566 unsigned short val, mux; 1852 unsigned int val, mux;
1567 unsigned short mask; 1853 unsigned int mask;
1568 int ret = 0; 1854 int ret = 0;
1569 1855
1570 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1856 if (ucontrol->value.enumerated.item[0] > e->max - 1)
@@ -1880,6 +2166,36 @@ void snd_soc_dapm_free(struct snd_soc_device *socdev)
1880} 2166}
1881EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2167EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
1882 2168
2169/*
2170 * snd_soc_dapm_shutdown - callback for system shutdown
2171 */
2172void snd_soc_dapm_shutdown(struct snd_soc_device *socdev)
2173{
2174 struct snd_soc_codec *codec = socdev->card->codec;
2175 struct snd_soc_dapm_widget *w;
2176 LIST_HEAD(down_list);
2177 int powerdown = 0;
2178
2179 list_for_each_entry(w, &codec->dapm_widgets, list) {
2180 if (w->power) {
2181 dapm_seq_insert(w, &down_list, dapm_down_seq);
2182 w->power = 0;
2183 powerdown = 1;
2184 }
2185 }
2186
2187 /* If there were no widgets to power down we're already in
2188 * standby.
2189 */
2190 if (powerdown) {
2191 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_PREPARE);
2192 dapm_seq_run(codec, &down_list, 0, dapm_down_seq);
2193 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_STANDBY);
2194 }
2195
2196 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
2197}
2198
1883/* Module information */ 2199/* Module information */
1884MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk"); 2200MODULE_AUTHOR("Liam Girdwood, lrg@slimlogic.co.uk");
1885MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC"); 2201MODULE_DESCRIPTION("Dynamic Audio Power Management core for ALSA SoC");
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 28346fb2e70c..1d455ab79490 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -73,14 +73,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
73 oldstatus = jack->status; 73 oldstatus = jack->status;
74 74
75 jack->status &= ~mask; 75 jack->status &= ~mask;
76 jack->status |= status; 76 jack->status |= status & mask;
77 77
78 /* The DAPM sync is expensive enough to be worth skipping */ 78 /* The DAPM sync is expensive enough to be worth skipping.
79 if (jack->status == oldstatus) 79 * However, empty mask means pin synchronization is desired. */
80 if (mask && (jack->status == oldstatus))
80 goto out; 81 goto out;
81 82
82 list_for_each_entry(pin, &jack->pins, list) { 83 list_for_each_entry(pin, &jack->pins, list) {
83 enable = pin->mask & status; 84 enable = pin->mask & jack->status;
84 85
85 if (pin->invert) 86 if (pin->invert)
86 enable = !enable; 87 enable = !enable;
@@ -220,6 +221,9 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
220 if (ret) 221 if (ret)
221 goto err; 222 goto err;
222 223
224 INIT_WORK(&gpios[i].work, gpio_work);
225 gpios[i].jack = jack;
226
223 ret = request_irq(gpio_to_irq(gpios[i].gpio), 227 ret = request_irq(gpio_to_irq(gpios[i].gpio),
224 gpio_handler, 228 gpio_handler,
225 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 229 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
@@ -228,8 +232,13 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
228 if (ret) 232 if (ret)
229 goto err; 233 goto err;
230 234
231 INIT_WORK(&gpios[i].work, gpio_work); 235#ifdef CONFIG_GPIO_SYSFS
232 gpios[i].jack = jack; 236 /* Expose GPIO value over sysfs for diagnostic purposes */
237 gpio_export(gpios[i].gpio, false);
238#endif
239
240 /* Update initial jack status */
241 snd_soc_jack_gpio_detect(&gpios[i]);
233 } 242 }
234 243
235 return 0; 244 return 0;
@@ -258,6 +267,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
258 int i; 267 int i;
259 268
260 for (i = 0; i < count; i++) { 269 for (i = 0; i < count; i++) {
270#ifdef CONFIG_GPIO_SYSFS
271 gpio_unexport(gpios[i].gpio);
272#endif
261 free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]); 273 free_irq(gpio_to_irq(gpios[i].gpio), &gpios[i]);
262 gpio_free(gpios[i].gpio); 274 gpio_free(gpios[i].gpio);
263 gpios[i].jack = NULL; 275 gpios[i].jack = NULL;
diff --git a/sound/soc/txx9/txx9aclc.c b/sound/soc/txx9/txx9aclc.c
index 938a58a5a244..efed64b8b026 100644
--- a/sound/soc/txx9/txx9aclc.c
+++ b/sound/soc/txx9/txx9aclc.c
@@ -297,15 +297,17 @@ static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
297static bool filter(struct dma_chan *chan, void *param) 297static bool filter(struct dma_chan *chan, void *param)
298{ 298{
299 struct txx9aclc_dmadata *dmadata = param; 299 struct txx9aclc_dmadata *dmadata = param;
300 char devname[20 + 2]; /* FIXME: old BUS_ID_SIZE + 2 */ 300 char *devname;
301 bool found = false;
301 302
302 snprintf(devname, sizeof(devname), "%s.%d", dmadata->dma_res->name, 303 devname = kasprintf(GFP_KERNEL, "%s.%d", dmadata->dma_res->name,
303 (int)dmadata->dma_res->start); 304 (int)dmadata->dma_res->start);
304 if (strcmp(dev_name(chan->device->dev), devname) == 0) { 305 if (strcmp(dev_name(chan->device->dev), devname) == 0) {
305 chan->private = &dmadata->dma_slave; 306 chan->private = &dmadata->dma_slave;
306 return true; 307 found = true;
307 } 308 }
308 return false; 309 kfree(devname);
310 return found;
309} 311}
310 312
311static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, 313static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev,
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 44b9cdc8a83b..3a53c79f48b8 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2124,8 +2124,8 @@ static void proc_dump_substream_formats(struct snd_usb_substream *subs, struct s
2124 fp = list_entry(p, struct audioformat, list); 2124 fp = list_entry(p, struct audioformat, list);
2125 snd_iprintf(buffer, " Interface %d\n", fp->iface); 2125 snd_iprintf(buffer, " Interface %d\n", fp->iface);
2126 snd_iprintf(buffer, " Altset %d\n", fp->altsetting); 2126 snd_iprintf(buffer, " Altset %d\n", fp->altsetting);
2127 snd_iprintf(buffer, " Format: %#x (%d bits)\n", 2127 snd_iprintf(buffer, " Format: %s\n",
2128 fp->format, snd_pcm_format_width(fp->format)); 2128 snd_pcm_format_name(fp->format));
2129 snd_iprintf(buffer, " Channels: %d\n", fp->channels); 2129 snd_iprintf(buffer, " Channels: %d\n", fp->channels);
2130 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n", 2130 snd_iprintf(buffer, " Endpoint: %d %s (%s)\n",
2131 fp->endpoint & USB_ENDPOINT_NUMBER_MASK, 2131 fp->endpoint & USB_ENDPOINT_NUMBER_MASK,