aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt9
-rw-r--r--Documentation/networking/ip-sysctl.txt8
-rw-r--r--Documentation/sound/alsa/HD-Audio-Models.txt5
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt27
-rw-r--r--MAINTAINERS15
-rw-r--r--Makefile2
-rw-r--r--arch/arm/include/asm/cacheflush.h3
-rw-r--r--arch/arm/kernel/setup.c1
-rw-r--r--arch/arm/mach-gemini/gpio.c4
-rw-r--r--arch/arm/mach-omap2/mux.c12
-rw-r--r--arch/arm/mm/alignment.c3
-rw-r--r--arch/arm/plat-mxc/Makefile4
-rw-r--r--arch/arm/plat-mxc/ssi-fiq-ksym.c20
-rw-r--r--arch/arm/plat-mxc/ssi-fiq.S134
-rw-r--r--arch/arm/tools/mach-types46
-rw-r--r--arch/ia64/include/asm/acpi.h1
-rw-r--r--arch/ia64/include/asm/elf.h4
-rw-r--r--arch/ia64/sn/kernel/setup.c2
-rw-r--r--arch/microblaze/include/asm/io.h2
-rw-r--r--arch/microblaze/kernel/cpu/cache.c27
-rw-r--r--arch/mips/bcm47xx/prom.c8
-rw-r--r--arch/mips/mm/highmem.c1
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/kernel/pci.c7
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c3
-rw-r--r--arch/powerpc/platforms/85xx/smp.c21
-rw-r--r--arch/sh/include/asm/siu.h26
-rw-r--r--arch/sh/kernel/ptrace_64.c11
-rw-r--r--arch/sh/kernel/signal_64.c4
-rw-r--r--arch/sparc/include/asm/stat.h4
-rw-r--r--arch/sparc/kernel/kstack.h4
-rw-r--r--arch/sparc/kernel/of_device_32.c2
-rw-r--r--arch/sparc/kernel/pci.c7
-rw-r--r--arch/sparc/kernel/tsb.S6
-rw-r--r--arch/x86/include/asm/elf.h5
-rw-r--r--arch/x86/include/asm/processor.h2
-rw-r--r--arch/x86/kernel/acpi/boot.c8
-rw-r--r--arch/x86/kernel/hw_breakpoint.c30
-rw-r--r--arch/x86/kernel/process_64.c1
-rw-r--r--arch/x86/kernel/ptrace.c7
-rw-r--r--block/blk-core.c11
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/acpi/processor_idle.c36
-rw-r--r--drivers/acpi/processor_pdc.c14
-rw-r--r--drivers/acpi/processor_perflib.c6
-rw-r--r--drivers/acpi/scan.c27
-rw-r--r--drivers/acpi/tables.c4
-rw-r--r--drivers/base/class.c2
-rw-r--r--drivers/clocksource/cs5535-clockevt.c2
-rw-r--r--drivers/firewire/net.c53
-rw-r--r--drivers/firewire/ohci.c13
-rw-r--r--drivers/gpu/drm/drm_edid.c47
-rw-r--r--drivers/gpu/drm/drm_mm.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c30
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c7
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_mem.c113
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dac.c6
-rw-r--r--drivers/gpu/drm/nouveau/nv17_tv.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv50_instmem.c58
-rw-r--r--drivers/gpu/drm/radeon/atom.c7
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c2
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c3
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon.h9
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c9
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c10
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h3
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c36
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.h4
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c107
-rw-r--r--drivers/gpu/drm/radeon/rv770.c9
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c6
-rw-r--r--drivers/gpu/drm/ttm/ttm_tt.c18
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c49
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c108
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c3
-rw-r--r--drivers/gpu/vga/vgaarb.c2
-rw-r--r--drivers/input/input-polldev.c6
-rw-r--r--drivers/input/serio/i8042.c8
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c8
-rw-r--r--drivers/md/dm-log-userspace-transfer.c10
-rw-r--r--drivers/md/dm-raid1.c2
-rw-r--r--drivers/md/dm-region-hash.c5
-rw-r--r--drivers/md/dm-snap-persistent.c2
-rw-r--r--drivers/md/dm-stripe.c2
-rw-r--r--drivers/md/dm-sysfs.c8
-rw-r--r--drivers/md/dm.c21
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig4
-rw-r--r--drivers/media/dvb/frontends/l64781.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c8
-rw-r--r--drivers/media/video/bt8xx/bttvp.h1
-rw-r--r--drivers/media/video/mt9t112.c2
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c2
-rw-r--r--drivers/mfd/twl-core.c18
-rw-r--r--drivers/net/benet/be_cmds.c1
-rw-r--r--drivers/net/e1000/e1000_main.c19
-rw-r--r--drivers/net/ixgbe/ixgbe_82598.c22
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c4
-rw-r--r--drivers/net/sfc/efx.c1
-rw-r--r--drivers/net/sfc/falcon_boards.c45
-rw-r--r--drivers/net/sfc/mcdi.c2
-rw-r--r--drivers/net/sfc/qt202x_phy.c2
-rw-r--r--drivers/net/tc35815.c1
-rw-r--r--drivers/net/usb/cdc_ether.c5
-rw-r--r--drivers/net/via-velocity.c41
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c4
-rw-r--r--drivers/net/wireless/b43/b43.h1
-rw-r--r--drivers/net/wireless/b43/main.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c22
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c1
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--drivers/platform/x86/acer-wmi.c2
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c2
-rw-r--r--drivers/scsi/arm/fas216.c2
-rw-r--r--drivers/scsi/fcoe/fcoe.c18
-rw-r--r--drivers/scsi/fcoe/libfcoe.c2
-rw-r--r--drivers/scsi/libfc/fc_exch.c2
-rw-r--r--drivers/scsi/libfc/fc_fcp.c3
-rw-r--r--drivers/scsi/libfc/fc_lport.c3
-rw-r--r--drivers/scsi/libfc/fc_rport.c2
-rw-r--r--drivers/scsi/libiscsi_tcp.c8
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c18
-rw-r--r--drivers/serial/8250.c7
-rw-r--r--drivers/ssb/main.c3
-rw-r--r--drivers/usb/core/devio.c48
-rw-r--r--drivers/usb/gadget/f_eem.c3
-rw-r--r--drivers/usb/gadget/multi.c2
-rw-r--r--drivers/usb/gadget/r8a66597-udc.c1
-rw-r--r--drivers/usb/gadget/s3c-hsotg.c1
-rw-r--r--drivers/usb/host/ehci-hub.c13
-rw-r--r--drivers/usb/host/fhci-tds.c6
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb.c1
-rw-r--r--drivers/usb/otg/Kconfig1
-rw-r--r--drivers/usb/serial/ftdi_sio.c25
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h18
-rw-r--r--drivers/usb/serial/sierra.c1
-rw-r--r--drivers/usb/storage/unusual_devs.h2
-rw-r--r--drivers/video/efifb.c11
-rw-r--r--drivers/watchdog/bfin_wdt.c13
-rw-r--r--fs/btrfs/file.c6
-rw-r--r--fs/cachefiles/namei.c12
-rw-r--r--fs/exec.c1
-rw-r--r--fs/namei.c14
-rw-r--r--fs/nfs/direct.c3
-rw-r--r--fs/nfsd/vfs.c3
-rw-r--r--fs/proc/base.c24
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/sysfs/inode.c35
-rw-r--r--include/linux/amba/bus.h6
-rw-r--r--include/linux/blkdev.h4
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/hw_breakpoint.h2
-rw-r--r--include/linux/i2c/twl.h4
-rw-r--r--include/linux/input.h1
-rw-r--r--include/linux/kfifo.h2
-rw-r--r--include/linux/perf_event.h6
-rw-r--r--include/sound/soc-dai.h2
-rw-r--r--include/sound/soc-dapm.h32
-rw-r--r--include/sound/soc.h26
-rw-r--r--include/sound/tlv320dac33-plat.h1
-rw-r--r--include/sound/tpa6130a2-plat.h6
-rw-r--r--include/sound/wm2000.h26
-rw-r--r--include/sound/wm8904.h57
-rw-r--r--include/sound/wm8955.h26
-rw-r--r--kernel/hw_breakpoint.c2
-rw-r--r--kernel/kfifo.c3
-rw-r--r--kernel/perf_event.c13
-rw-r--r--kernel/softirq.c15
-rw-r--r--kernel/sys.c2
-rw-r--r--kernel/trace/trace_kprobe.c2
-rw-r--r--kernel/trace/trace_stack.c24
-rw-r--r--lib/idr.c4
-rw-r--r--mm/migrate.c36
-rw-r--r--mm/oom_kill.c2
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/ethtool.c1
-rw-r--r--net/core/net-sysfs.c3
-rw-r--r--net/ipv4/devinet.c7
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/ipcomp.c6
-rw-r--r--net/ipv4/tcp_input.c6
-rw-r--r--net/ipv6/addrconf.c16
-rw-r--r--net/ipv6/ipcomp6.c6
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/rate.c3
-rw-r--r--net/mac80211/scan.c18
-rw-r--r--net/xfrm/xfrm_state.c12
-rw-r--r--sound/pci/hda/Kconfig2
-rw-r--r--sound/pci/hda/Makefile4
-rw-r--r--sound/pci/hda/hda_codec.c75
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/hda_eld.c6
-rw-r--r--sound/pci/hda/hda_hwdep.c53
-rw-r--r--sound/pci/hda/hda_intel.c39
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_conexant.c255
-rw-r--r--sound/pci/hda/patch_hdmi.c849
-rw-r--r--sound/pci/hda/patch_intelhdmi.c821
-rw-r--r--sound/pci/hda/patch_nvhdmi.c275
-rw-r--r--sound/pci/hda/patch_realtek.c840
-rw-r--r--sound/pci/hda/patch_sigmatel.c151
-rw-r--r--sound/pci/via82xx.c6
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c8
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c3
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c3
-rw-r--r--sound/soc/codecs/Kconfig24
-rw-r--r--sound/soc/codecs/Makefile16
-rw-r--r--sound/soc/codecs/ad1836.c96
-rw-r--r--sound/soc/codecs/ad1836.h1
-rw-r--r--sound/soc/codecs/ad1938.c228
-rw-r--r--sound/soc/codecs/ak4104.c10
-rw-r--r--sound/soc/codecs/cs4270.c91
-rw-r--r--sound/soc/codecs/da7210.c589
-rw-r--r--sound/soc/codecs/da7210.h24
-rw-r--r--sound/soc/codecs/tlv320aic3x.c75
-rw-r--r--sound/soc/codecs/tlv320dac33.c311
-rw-r--r--sound/soc/codecs/tpa6130a2.c115
-rw-r--r--sound/soc/codecs/twl4030.c33
-rw-r--r--sound/soc/codecs/twl4030.h2
-rw-r--r--sound/soc/codecs/wm2000.c888
-rw-r--r--sound/soc/codecs/wm2000.h79
-rw-r--r--sound/soc/codecs/wm8727.c66
-rw-r--r--sound/soc/codecs/wm8731.c3
-rw-r--r--sound/soc/codecs/wm8753.c8
-rw-r--r--sound/soc/codecs/wm8776.c2
-rw-r--r--sound/soc/codecs/wm8904.c2656
-rw-r--r--sound/soc/codecs/wm8904.h1681
-rw-r--r--sound/soc/codecs/wm8955.c1151
-rw-r--r--sound/soc/codecs/wm8955.h489
-rw-r--r--sound/soc/codecs/wm8961.c3
-rw-r--r--sound/soc/codecs/wm8974.c12
-rw-r--r--sound/soc/codecs/wm8974.h12
-rw-r--r--sound/soc/codecs/wm8978.c1149
-rw-r--r--sound/soc/codecs/wm8978.h86
-rw-r--r--sound/soc/codecs/wm8990.c8
-rw-r--r--sound/soc/codecs/wm8993.c307
-rw-r--r--sound/soc/codecs/wm8994.c3867
-rw-r--r--sound/soc/codecs/wm8994.h26
-rw-r--r--sound/soc/codecs/wm9713.c64
-rw-r--r--sound/soc/codecs/wm_hubs.c148
-rw-r--r--sound/soc/codecs/wm_hubs.h6
-rw-r--r--sound/soc/davinci/davinci-mcasp.c17
-rw-r--r--sound/soc/davinci/davinci-mcasp.h1
-rw-r--r--sound/soc/davinci/davinci-pcm.c2
-rw-r--r--sound/soc/imx/Kconfig20
-rw-r--r--sound/soc/imx/Makefile14
-rw-r--r--sound/soc/imx/imx-pcm-dma-mx2.c313
-rw-r--r--sound/soc/imx/imx-pcm-fiq.c297
-rw-r--r--sound/soc/imx/imx-ssi.c758
-rw-r--r--sound/soc/imx/imx-ssi.h237
-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.c318
-rw-r--r--sound/soc/imx/mxc-ssi.c860
-rw-r--r--sound/soc/imx/mxc-ssi.h238
-rw-r--r--sound/soc/imx/phycore-ac97.c90
-rw-r--r--sound/soc/omap/Kconfig11
-rw-r--r--sound/soc/omap/Makefile2
-rw-r--r--sound/soc/omap/mcpdm.c484
-rw-r--r--sound/soc/omap/mcpdm.h151
-rw-r--r--sound/soc/omap/omap-mcbsp.c2
-rw-r--r--sound/soc/omap/omap-mcpdm.c251
-rw-r--r--sound/soc/omap/omap-mcpdm.h29
-rw-r--r--sound/soc/omap/omap-pcm.c15
-rw-r--r--sound/soc/omap/omap-pcm.h4
-rw-r--r--sound/soc/omap/omap3beagle.c6
-rw-r--r--sound/soc/omap/omap3pandora.c42
-rw-r--r--sound/soc/pxa/pxa-ssp.c12
-rw-r--r--sound/soc/pxa/raumfeld.c61
-rw-r--r--sound/soc/s3c24xx/Kconfig22
-rw-r--r--sound/soc/s3c24xx/Makefile7
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c4
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.c518
-rw-r--r--sound/soc/s3c24xx/s3c-ac97.h23
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c3
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c432
-rw-r--r--sound/soc/s3c24xx/s3c24xx-ac97.h25
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c120
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c4
-rw-r--r--sound/soc/s3c24xx/smdk_wm9713.c94
-rw-r--r--sound/soc/sh/Kconfig23
-rw-r--r--sound/soc/sh/Makefile6
-rw-r--r--sound/soc/sh/fsi-da7210.c83
-rw-r--r--sound/soc/sh/fsi.c227
-rw-r--r--sound/soc/sh/migor.c218
-rw-r--r--sound/soc/sh/siu.h193
-rw-r--r--sound/soc/sh/siu_dai.c847
-rw-r--r--sound/soc/sh/siu_pcm.c616
-rw-r--r--sound/soc/soc-cache.c213
-rw-r--r--sound/soc/soc-core.c63
-rw-r--r--sound/soc/soc-dapm.c142
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/event.c4
-rw-r--r--tools/perf/util/probe-event.c3
305 files changed, 23296 insertions, 5427 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 736d45602886..e7848a0d99eb 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -199,6 +199,10 @@ and is between 256 and 4096 characters. It is defined in the file
199 acpi_display_output=video 199 acpi_display_output=video
200 See above. 200 See above.
201 201
202 acpi_early_pdc_eval [HW,ACPI] Evaluate processor _PDC methods
203 early. Needed on some platforms to properly
204 initialize the EC.
205
202 acpi_irq_balance [HW,ACPI] 206 acpi_irq_balance [HW,ACPI]
203 ACPI will balance active IRQs 207 ACPI will balance active IRQs
204 default in APIC mode 208 default in APIC mode
@@ -311,6 +315,11 @@ and is between 256 and 4096 characters. It is defined in the file
311 aic79xx= [HW,SCSI] 315 aic79xx= [HW,SCSI]
312 See Documentation/scsi/aic79xx.txt. 316 See Documentation/scsi/aic79xx.txt.
313 317
318 alignment= [KNL,ARM]
319 Allow the default userspace alignment fault handler
320 behaviour to be specified. Bit 0 enables warnings,
321 bit 1 enables fixups, and bit 2 sends a segfault.
322
314 amd_iommu= [HW,X86-84] 323 amd_iommu= [HW,X86-84]
315 Pass parameters to the AMD IOMMU driver in the system. 324 Pass parameters to the AMD IOMMU driver in the system.
316 Possible values are: 325 Possible values are:
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 006b39dec87d..e87f3cdc8a6a 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1074,10 +1074,10 @@ regen_max_retry - INTEGER
1074 Default: 5 1074 Default: 5
1075 1075
1076max_addresses - INTEGER 1076max_addresses - INTEGER
1077 Number of maximum addresses per interface. 0 disables limitation. 1077 Maximum number of autoconfigured addresses per interface. Setting
1078 It is recommended not set too large value (or 0) because it would 1078 to zero disables the limitation. It is not recommended to set this
1079 be too easy way to crash kernel to allow to create too much of 1079 value too large (or to zero) because it would be an easy way to
1080 autoconfigured addresses. 1080 crash the kernel by allowing too many addresses to be created.
1081 Default: 16 1081 Default: 16
1082 1082
1083disable_ipv6 - BOOLEAN 1083disable_ipv6 - BOOLEAN
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt
index e72cee9e2a71..1d38b0dfba95 100644
--- a/Documentation/sound/alsa/HD-Audio-Models.txt
+++ b/Documentation/sound/alsa/HD-Audio-Models.txt
@@ -124,6 +124,8 @@ ALC882/883/885/888/889
124 asus-a7m ASUS A7M 124 asus-a7m ASUS A7M
125 macpro MacPro support 125 macpro MacPro support
126 mb5 Macbook 5,1 126 mb5 Macbook 5,1
127 macmini3 Macmini 3,1
128 mba21 Macbook Air 2,1
127 mbp3 Macbook Pro rev3 129 mbp3 Macbook Pro rev3
128 imac24 iMac 24'' with jack detection 130 imac24 iMac 24'' with jack detection
129 imac91 iMac 9,1 131 imac91 iMac 9,1
@@ -279,13 +281,16 @@ Conexant 5051
279 laptop Basic Laptop config (default) 281 laptop Basic Laptop config (default)
280 hp HP Spartan laptop 282 hp HP Spartan laptop
281 hp-dv6736 HP dv6736 283 hp-dv6736 HP dv6736
284 hp-f700 HP Compaq Presario F700
282 lenovo-x200 Lenovo X200 laptop 285 lenovo-x200 Lenovo X200 laptop
286 toshiba Toshiba Satellite M300
283 287
284Conexant 5066 288Conexant 5066
285============= 289=============
286 laptop Basic Laptop config (default) 290 laptop Basic Laptop config (default)
287 dell-laptop Dell laptops 291 dell-laptop Dell laptops
288 olpc-xo-1_5 OLPC XO 1.5 292 olpc-xo-1_5 OLPC XO 1.5
293 ideapad Lenovo IdeaPad U150
289 294
290STAC9200 295STAC9200
291======== 296========
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 6325bec06a72..f4dd3bf99d12 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -452,6 +452,33 @@ Similarly, the lines after `[verb]` are parsed as `init_verbs`
452sysfs entries, and the lines after `[hint]` are parsed as `hints` 452sysfs entries, and the lines after `[hint]` are parsed as `hints`
453sysfs entries, respectively. 453sysfs entries, respectively.
454 454
455Another example to override the codec vendor id from 0x12345678 to
4560xdeadbeef is like below:
457------------------------------------------------------------------------
458 [codec]
459 0x12345678 0xabcd1234 2
460
461 [vendor_id]
462 0xdeadbeef
463------------------------------------------------------------------------
464
465In the similar way, you can override the codec subsystem_id via
466`[subsystem_id]`, the revision id via `[revision_id]` line.
467Also, the codec chip name can be rewritten via `[chip_name]` line.
468------------------------------------------------------------------------
469 [codec]
470 0x12345678 0xabcd1234 2
471
472 [subsystem_id]
473 0xffff1111
474
475 [revision_id]
476 0x10
477
478 [chip_name]
479 My-own NEWS-0002
480------------------------------------------------------------------------
481
455The hd-audio driver reads the file via request_firmware(). Thus, 482The hd-audio driver reads the file via request_firmware(). Thus,
456a patch file has to be located on the appropriate firmware path, 483a patch file has to be located on the appropriate firmware path,
457typically, /lib/firmware. For example, when you pass the option 484typically, /lib/firmware. For example, when you pass the option
diff --git a/MAINTAINERS b/MAINTAINERS
index 412eff60c33d..2533fc45a44a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -616,10 +616,10 @@ M: Richard Purdie <rpurdie@rpsys.net>
616S: Maintained 616S: Maintained
617 617
618ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE 618ARM/CORTINA SYSTEMS GEMINI ARM ARCHITECTURE
619M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 619M: Paulius Zaleckas <paulius.zaleckas@gmail.com>
620L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 620L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
621T: git git://gitorious.org/linux-gemini/mainline.git 621T: git git://gitorious.org/linux-gemini/mainline.git
622S: Maintained 622S: Odd Fixes
623F: arch/arm/mach-gemini/ 623F: arch/arm/mach-gemini/
624 624
625ARM/EBSA110 MACHINE SUPPORT 625ARM/EBSA110 MACHINE SUPPORT
@@ -641,9 +641,9 @@ T: topgit git://git.openezx.org/openezx.git
641F: arch/arm/mach-pxa/ezx.c 641F: arch/arm/mach-pxa/ezx.c
642 642
643ARM/FARADAY FA526 PORT 643ARM/FARADAY FA526 PORT
644M: Paulius Zaleckas <paulius.zaleckas@teltonika.lt> 644M: Paulius Zaleckas <paulius.zaleckas@gmail.com>
645L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 645L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
646S: Maintained 646S: Odd Fixes
647F: arch/arm/mm/*-fa* 647F: arch/arm/mm/*-fa*
648 648
649ARM/FOOTBRIDGE ARCHITECTURE 649ARM/FOOTBRIDGE ARCHITECTURE
@@ -1733,10 +1733,9 @@ F: include/linux/tfrc.h
1733F: net/dccp/ 1733F: net/dccp/
1734 1734
1735DECnet NETWORK LAYER 1735DECnet NETWORK LAYER
1736M: Christine Caulfield <christine.caulfield@googlemail.com>
1737W: http://linux-decnet.sourceforge.net 1736W: http://linux-decnet.sourceforge.net
1738L: linux-decnet-user@lists.sourceforge.net 1737L: linux-decnet-user@lists.sourceforge.net
1739S: Maintained 1738S: Orphan
1740F: Documentation/networking/decnet.txt 1739F: Documentation/networking/decnet.txt
1741F: net/decnet/ 1740F: net/decnet/
1742 1741
@@ -3490,9 +3489,9 @@ S: Maintained
3490F: drivers/net/wireless/libertas/ 3489F: drivers/net/wireless/libertas/
3491 3490
3492MARVELL MV643XX ETHERNET DRIVER 3491MARVELL MV643XX ETHERNET DRIVER
3493M: Lennert Buytenhek <buytenh@marvell.com> 3492M: Lennert Buytenhek <buytenh@wantstofly.org>
3494L: netdev@vger.kernel.org 3493L: netdev@vger.kernel.org
3495S: Supported 3494S: Maintained
3496F: drivers/net/mv643xx_eth.* 3495F: drivers/net/mv643xx_eth.*
3497F: include/linux/mv643xx.h 3496F: include/linux/mv643xx.h
3498 3497
diff --git a/Makefile b/Makefile
index 12b1aa1103ee..1b24895212d8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
1VERSION = 2 1VERSION = 2
2PATCHLEVEL = 6 2PATCHLEVEL = 6
3SUBLEVEL = 33 3SUBLEVEL = 33
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/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index c77d2fa1f6e5..8113bb5fb66e 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -42,7 +42,8 @@
42#endif 42#endif
43 43
44#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \ 44#if defined(CONFIG_CPU_ARM920T) || defined(CONFIG_CPU_ARM922T) || \
45 defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) 45 defined(CONFIG_CPU_ARM925T) || defined(CONFIG_CPU_ARM1020) || \
46 defined(CONFIG_CPU_ARM1026)
46# define MULTI_CACHE 1 47# define MULTI_CACHE 1
47#endif 48#endif
48 49
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c6c57b640b6b..621acad8ea43 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -102,6 +102,7 @@ struct cpu_cache_fns cpu_cache;
102#endif 102#endif
103#ifdef CONFIG_OUTER_CACHE 103#ifdef CONFIG_OUTER_CACHE
104struct outer_cache_fns outer_cache; 104struct outer_cache_fns outer_cache;
105EXPORT_SYMBOL(outer_cache);
105#endif 106#endif
106 107
107struct stack { 108struct stack {
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index e7263854bc7b..fe3bd5ac8b10 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -86,7 +86,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)
86 unsigned int reg_both, reg_level, reg_type; 86 unsigned int reg_both, reg_level, reg_type;
87 87
88 reg_type = __raw_readl(base + GPIO_INT_TYPE); 88 reg_type = __raw_readl(base + GPIO_INT_TYPE);
89 reg_level = __raw_readl(base + GPIO_INT_BOTH_EDGE); 89 reg_level = __raw_readl(base + GPIO_INT_LEVEL);
90 reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE); 90 reg_both = __raw_readl(base + GPIO_INT_BOTH_EDGE);
91 91
92 switch (type) { 92 switch (type) {
@@ -117,7 +117,7 @@ static int gpio_set_irq_type(unsigned int irq, unsigned int type)
117 } 117 }
118 118
119 __raw_writel(reg_type, base + GPIO_INT_TYPE); 119 __raw_writel(reg_type, base + GPIO_INT_TYPE);
120 __raw_writel(reg_level, base + GPIO_INT_BOTH_EDGE); 120 __raw_writel(reg_level, base + GPIO_INT_LEVEL);
121 __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE); 121 __raw_writel(reg_both, base + GPIO_INT_BOTH_EDGE);
122 122
123 gpio_ack_irq(irq); 123 gpio_ack_irq(irq);
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index 5fedc50c58e4..5fef73f4743d 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -961,16 +961,14 @@ static void __init omap_mux_init_list(struct omap_mux *superset)
961 while (superset->reg_offset != OMAP_MUX_TERMINATOR) { 961 while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
962 struct omap_mux *entry; 962 struct omap_mux *entry;
963 963
964#ifndef CONFIG_OMAP_MUX 964#ifdef CONFIG_OMAP_MUX
965 /* Skip pins that are not muxed as GPIO by bootloader */ 965 if (!superset->muxnames || !superset->muxnames[0]) {
966 if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
967 superset++; 966 superset++;
968 continue; 967 continue;
969 } 968 }
970#endif 969#else
971 970 /* Skip pins that are not muxed as GPIO by bootloader */
972#if defined(CONFIG_OMAP_MUX) && defined(CONFIG_DEBUG_FS) 971 if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
973 if (!superset->muxnames || !superset->muxnames[0]) {
974 superset++; 972 superset++;
975 continue; 973 continue;
976 } 974 }
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
index b270d6228fe2..62820eda84d9 100644
--- a/arch/arm/mm/alignment.c
+++ b/arch/arm/mm/alignment.c
@@ -11,6 +11,7 @@
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14#include <linux/moduleparam.h>
14#include <linux/compiler.h> 15#include <linux/compiler.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/errno.h> 17#include <linux/errno.h>
@@ -77,6 +78,8 @@ static unsigned long ai_dword;
77static unsigned long ai_multi; 78static unsigned long ai_multi;
78static int ai_usermode; 79static int ai_usermode;
79 80
81core_param(alignment, ai_usermode, int, 0600);
82
80#define UM_WARN (1 << 0) 83#define UM_WARN (1 << 0)
81#define UM_FIXUP (1 << 1) 84#define UM_FIXUP (1 << 1)
82#define UM_SIGNAL (1 << 2) 85#define UM_SIGNAL (1 << 2)
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 996cbac6932c..6cee38df58b2 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -13,3 +13,7 @@ obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
13obj-$(CONFIG_MXC_ULPI) += ulpi.o 13obj-$(CONFIG_MXC_ULPI) += ulpi.o
14obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o 14obj-$(CONFIG_ARCH_MXC_AUDMUX_V1) += audmux-v1.o
15obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o 15obj-$(CONFIG_ARCH_MXC_AUDMUX_V2) += audmux-v2.o
16ifdef CONFIG_SND_IMX_SOC
17obj-y += ssi-fiq.o
18obj-y += ssi-fiq-ksym.o
19endif
diff --git a/arch/arm/plat-mxc/ssi-fiq-ksym.c b/arch/arm/plat-mxc/ssi-fiq-ksym.c
new file mode 100644
index 000000000000..b5fad454da78
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq-ksym.c
@@ -0,0 +1,20 @@
1/*
2 * Exported ksyms for the SSI FIQ handler
3 *
4 * Copyright (C) 2009, Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12
13#include <mach/ssi.h>
14
15EXPORT_SYMBOL(imx_ssi_fiq_tx_buffer);
16EXPORT_SYMBOL(imx_ssi_fiq_rx_buffer);
17EXPORT_SYMBOL(imx_ssi_fiq_start);
18EXPORT_SYMBOL(imx_ssi_fiq_end);
19EXPORT_SYMBOL(imx_ssi_fiq_base);
20
diff --git a/arch/arm/plat-mxc/ssi-fiq.S b/arch/arm/plat-mxc/ssi-fiq.S
new file mode 100644
index 000000000000..4ddce565b353
--- /dev/null
+++ b/arch/arm/plat-mxc/ssi-fiq.S
@@ -0,0 +1,134 @@
1/*
2 * Copyright (C) 2009 Sascha Hauer <s.hauer@pengutronix.de>
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#include <linux/linkage.h>
10#include <asm/assembler.h>
11
12/*
13 * r8 = bit 0-15: tx offset, bit 16-31: tx buffer size
14 * r9 = bit 0-15: rx offset, bit 16-31: rx buffer size
15 */
16
17#define SSI_STX0 0x00
18#define SSI_SRX0 0x08
19#define SSI_SISR 0x14
20#define SSI_SIER 0x18
21#define SSI_SACNT 0x38
22
23#define SSI_SACNT_AC97EN (1 << 0)
24
25#define SSI_SIER_TFE0_EN (1 << 0)
26#define SSI_SISR_TFE0 (1 << 0)
27#define SSI_SISR_RFF0 (1 << 2)
28#define SSI_SIER_RFF0_EN (1 << 2)
29
30 .text
31 .global imx_ssi_fiq_start
32 .global imx_ssi_fiq_end
33 .global imx_ssi_fiq_base
34 .global imx_ssi_fiq_rx_buffer
35 .global imx_ssi_fiq_tx_buffer
36
37imx_ssi_fiq_start:
38 ldr r12, imx_ssi_fiq_base
39
40 /* TX */
41 ldr r11, imx_ssi_fiq_tx_buffer
42
43 /* shall we send? */
44 ldr r13, [r12, #SSI_SIER]
45 tst r13, #SSI_SIER_TFE0_EN
46 beq 1f
47
48 /* TX FIFO empty? */
49 ldr r13, [r12, #SSI_SISR]
50 tst r13, #SSI_SISR_TFE0
51 beq 1f
52
53 mov r10, #0x10000
54 sub r10, #1
55 and r10, r10, r8 /* r10: current buffer offset */
56
57 add r11, r11, r10
58
59 ldrh r13, [r11]
60 strh r13, [r12, #SSI_STX0]
61
62 ldrh r13, [r11, #2]
63 strh r13, [r12, #SSI_STX0]
64
65 ldrh r13, [r11, #4]
66 strh r13, [r12, #SSI_STX0]
67
68 ldrh r13, [r11, #6]
69 strh r13, [r12, #SSI_STX0]
70
71 add r10, #8
72 lsr r13, r8, #16 /* r13: buffer size */
73 cmp r10, r13
74 lslgt r8, r13, #16
75 addle r8, #8
761:
77 /* RX */
78
79 /* shall we receive? */
80 ldr r13, [r12, #SSI_SIER]
81 tst r13, #SSI_SIER_RFF0_EN
82 beq 1f
83
84 /* RX FIFO full? */
85 ldr r13, [r12, #SSI_SISR]
86 tst r13, #SSI_SISR_RFF0
87 beq 1f
88
89 ldr r11, imx_ssi_fiq_rx_buffer
90
91 mov r10, #0x10000
92 sub r10, #1
93 and r10, r10, r9 /* r10: current buffer offset */
94
95 add r11, r11, r10
96
97 ldr r13, [r12, #SSI_SACNT]
98 tst r13, #SSI_SACNT_AC97EN
99
100 ldr r13, [r12, #SSI_SRX0]
101 strh r13, [r11]
102
103 ldr r13, [r12, #SSI_SRX0]
104 strh r13, [r11, #2]
105
106 /* dummy read to skip slot 12 */
107 ldrne r13, [r12, #SSI_SRX0]
108
109 ldr r13, [r12, #SSI_SRX0]
110 strh r13, [r11, #4]
111
112 ldr r13, [r12, #SSI_SRX0]
113 strh r13, [r11, #6]
114
115 /* dummy read to skip slot 12 */
116 ldrne r13, [r12, #SSI_SRX0]
117
118 add r10, #8
119 lsr r13, r9, #16 /* r13: buffer size */
120 cmp r10, r13
121 lslgt r9, r13, #16
122 addle r9, #8
123
1241:
125 @ return from FIQ
126 subs pc, lr, #4
127imx_ssi_fiq_base:
128 .word 0x0
129imx_ssi_fiq_rx_buffer:
130 .word 0x0
131imx_ssi_fiq_tx_buffer:
132 .word 0x0
133imx_ssi_fiq_end:
134
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 5a79fc6ee818..31c2f4c30a95 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
12# 12#
13# http://www.arm.linux.org.uk/developer/machines/?action=new 13# http://www.arm.linux.org.uk/developer/machines/?action=new
14# 14#
15# Last update: Thu Jan 28 22:15:54 2010 15# Last update: Sat Feb 20 14:16:15 2010
16# 16#
17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number 17# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
18# 18#
@@ -2257,7 +2257,7 @@ oratisalog MACH_ORATISALOG ORATISALOG 2268
2257oratismadi MACH_ORATISMADI ORATISMADI 2269 2257oratismadi MACH_ORATISMADI ORATISMADI 2269
2258oratisot16 MACH_ORATISOT16 ORATISOT16 2270 2258oratisot16 MACH_ORATISOT16 ORATISOT16 2270
2259oratisdesk MACH_ORATISDESK ORATISDESK 2271 2259oratisdesk MACH_ORATISDESK ORATISDESK 2271
2260v2_ca9 MACH_V2P_CA9 V2P_CA9 2272 2260vexpress MACH_VEXPRESS VEXPRESS 2272
2261sintexo MACH_SINTEXO SINTEXO 2273 2261sintexo MACH_SINTEXO SINTEXO 2273
2262cm3389 MACH_CM3389 CM3389 2274 2262cm3389 MACH_CM3389 CM3389 2274
2263omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275 2263omap3_cio MACH_OMAP3_CIO OMAP3_CIO 2275
@@ -2636,3 +2636,45 @@ hw90240 MACH_HW90240 HW90240 2648
2636dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649 2636dm365_leopard MACH_DM365_LEOPARD DM365_LEOPARD 2649
2637mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650 2637mityomapl138 MACH_MITYOMAPL138 MITYOMAPL138 2650
2638scat110 MACH_SCAT110 SCAT110 2651 2638scat110 MACH_SCAT110 SCAT110 2651
2639acer_a1 MACH_ACER_A1 ACER_A1 2652
2640cmcontrol MACH_CMCONTROL CMCONTROL 2653
2641pelco_lamar MACH_PELCO_LAMAR PELCO_LAMAR 2654
2642rfp43 MACH_RFP43 RFP43 2655
2643sk86r0301 MACH_SK86R0301 SK86R0301 2656
2644ctpxa MACH_CTPXA CTPXA 2657
2645epb_arm9_a MACH_EPB_ARM9_A EPB_ARM9_A 2658
2646guruplug MACH_GURUPLUG GURUPLUG 2659
2647spear310 MACH_SPEAR310 SPEAR310 2660
2648spear320 MACH_SPEAR320 SPEAR320 2661
2649robotx MACH_ROBOTX ROBOTX 2662
2650lsxhl MACH_LSXHL LSXHL 2663
2651smartlite MACH_SMARTLITE SMARTLITE 2664
2652cws2 MACH_CWS2 CWS2 2665
2653m619 MACH_M619 M619 2666
2654smartview MACH_SMARTVIEW SMARTVIEW 2667
2655lsa_salsa MACH_LSA_SALSA LSA_SALSA 2668
2656kizbox MACH_KIZBOX KIZBOX 2669
2657htccharmer MACH_HTCCHARMER HTCCHARMER 2670
2658guf_neso_lt MACH_GUF_NESO_LT GUF_NESO_LT 2671
2659pm9g45 MACH_PM9G45 PM9G45 2672
2660htcpanther MACH_HTCPANTHER HTCPANTHER 2673
2661htcpanther_cdma MACH_HTCPANTHER_CDMA HTCPANTHER_CDMA 2674
2662reb01 MACH_REB01 REB01 2675
2663aquila MACH_AQUILA AQUILA 2676
2664spark_sls_hw2 MACH_SPARK_SLS_HW2 SPARK_SLS_HW2 2677
2665sheeva_esata MACH_ESATA_SHEEVAPLUG ESATA_SHEEVAPLUG 2678
2666surf7x30 MACH_SURF7X30 SURF7X30 2679
2667micro2440 MACH_MICRO2440 MICRO2440 2680
2668am2440 MACH_AM2440 AM2440 2681
2669tq2440 MACH_TQ2440 TQ2440 2682
2670lpc2478oem MACH_LPC2478OEM LPC2478OEM 2683
2671ak880x MACH_AK880X AK880X 2684
2672cobra3530 MACH_COBRA3530 COBRA3530 2685
2673pmppb MACH_PMPPB PMPPB 2686
2674u6715 MACH_U6715 U6715 2687
2675axar1500_sender MACH_AXAR1500_SENDER AXAR1500_SENDER 2688
2676g30_dvb MACH_G30_DVB G30_DVB 2689
2677vc088x MACH_VC088X VC088X 2690
2678mioa702 MACH_MIOA702 MIOA702 2691
2679hpmin MACH_HPMIN HPMIN 2692
2680ak880xak MACH_AK880XAK AK880XAK 2693
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index 7ae58892ba8d..e97b255d97bc 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -94,6 +94,7 @@ ia64_acpi_release_global_lock (unsigned int *lock)
94#define acpi_noirq 0 /* ACPI always enabled on IA64 */ 94#define acpi_noirq 0 /* ACPI always enabled on IA64 */
95#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ 95#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
96#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ 96#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */
97#define acpi_ht 0 /* no HT-only mode on IA64 */
97#endif 98#endif
98#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ 99#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
99static inline void disable_acpi(void) { } 100static inline void disable_acpi(void) { }
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index e14108b19c09..4c41656ede87 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -201,7 +201,9 @@ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
201 relevant until we have real hardware to play with... */ 201 relevant until we have real hardware to play with... */
202#define ELF_PLATFORM NULL 202#define ELF_PLATFORM NULL
203 203
204#define SET_PERSONALITY(ex) set_personality(PER_LINUX) 204#define SET_PERSONALITY(ex) \
205 set_personality((current->personality & ~PER_MASK) | PER_LINUX)
206
205#define elf_read_implies_exec(ex, executable_stack) \ 207#define elf_read_implies_exec(ex, executable_stack) \
206 ((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0) 208 ((executable_stack!=EXSTACK_DISABLE_X) && ((ex).e_flags & EF_IA_64_LINUX_EXECUTABLE_STACK) != 0)
207 209
diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
index ece1bf994499..e456f062f241 100644
--- a/arch/ia64/sn/kernel/setup.c
+++ b/arch/ia64/sn/kernel/setup.c
@@ -71,7 +71,7 @@ EXPORT_SYMBOL(sn_rtc_cycles_per_second);
71DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); 71DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info);
72EXPORT_PER_CPU_SYMBOL(__sn_hub_info); 72EXPORT_PER_CPU_SYMBOL(__sn_hub_info);
73 73
74DEFINE_PER_CPU(short [MAX_COMPACT_NODES], __sn_cnodeid_to_nasid); 74DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]);
75EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); 75EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid);
76 76
77DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); 77DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda);
diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h
index fc9997b73c09..267c7c779e53 100644
--- a/arch/microblaze/include/asm/io.h
+++ b/arch/microblaze/include/asm/io.h
@@ -217,7 +217,7 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
217 * Little endian 217 * Little endian
218 */ 218 */
219 219
220#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a)); 220#define out_le32(a, v) __raw_writel(__cpu_to_le32(v), (a))
221#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a)) 221#define out_le16(a, v) __raw_writew(__cpu_to_le16(v), (a))
222 222
223#define in_le32(a) __le32_to_cpu(__raw_readl(a)) 223#define in_le32(a) __le32_to_cpu(__raw_readl(a))
diff --git a/arch/microblaze/kernel/cpu/cache.c b/arch/microblaze/kernel/cpu/cache.c
index d9d63831cc2f..2a56bccce4e0 100644
--- a/arch/microblaze/kernel/cpu/cache.c
+++ b/arch/microblaze/kernel/cpu/cache.c
@@ -172,16 +172,15 @@ do { \
172/* It is used only first parameter for OP - for wic, wdc */ 172/* It is used only first parameter for OP - for wic, wdc */
173#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \ 173#define CACHE_RANGE_LOOP_1(start, end, line_length, op) \
174do { \ 174do { \
175 int step = -line_length; \ 175 int volatile temp; \
176 int count = end - start; \ 176 BUG_ON(end - start <= 0); \
177 BUG_ON(count <= 0); \
178 \ 177 \
179 __asm__ __volatile__ (" 1: addk %0, %0, %1; \ 178 __asm__ __volatile__ (" 1: " #op " %1, r0; \
180 " #op " %0, r0; \ 179 cmpu %0, %1, %2; \
181 bgtid %1, 1b; \ 180 bgtid %0, 1b; \
182 addk %1, %1, %2; \ 181 addk %1, %1, %3; \
183 " : : "r" (start), "r" (count), \ 182 " : : "r" (temp), "r" (start), "r" (end),\
184 "r" (step) : "memory"); \ 183 "r" (line_length) : "memory"); \
185} while (0); 184} while (0);
186 185
187static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end) 186static void __flush_icache_range_msr_irq(unsigned long start, unsigned long end)
@@ -313,16 +312,6 @@ static void __invalidate_dcache_all_wb(void)
313 pr_debug("%s\n", __func__); 312 pr_debug("%s\n", __func__);
314 CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length, 313 CACHE_ALL_LOOP2(cpuinfo.dcache_size, cpuinfo.dcache_line_length,
315 wdc.clear) 314 wdc.clear)
316
317#if 0
318 unsigned int i;
319
320 pr_debug("%s\n", __func__);
321
322 /* Just loop through cache size and invalidate it */
323 for (i = 0; i < cpuinfo.dcache_size; i += cpuinfo.dcache_line_length)
324 __invalidate_dcache(0, i);
325#endif
326} 315}
327 316
328static void __invalidate_dcache_range_wb(unsigned long start, 317static void __invalidate_dcache_range_wb(unsigned long start,
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index c51405e57921..29d3cbf9555f 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -141,6 +141,14 @@ static __init void prom_init_mem(void)
141 break; 141 break;
142 } 142 }
143 143
144 /* Ignoring the last page when ddr size is 128M. Cached
145 * accesses to last page is causing the processor to prefetch
146 * using address above 128M stepping out of the ddr address
147 * space.
148 */
149 if (mem == 0x8000000)
150 mem -= 0x1000;
151
144 add_memory_region(0, mem, BOOT_MEM_RAM); 152 add_memory_region(0, mem, BOOT_MEM_RAM);
145} 153}
146 154
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c
index e274fda329f4..127d732474bf 100644
--- a/arch/mips/mm/highmem.c
+++ b/arch/mips/mm/highmem.c
@@ -1,5 +1,6 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/highmem.h> 2#include <linux/highmem.h>
3#include <linux/sched.h>
3#include <linux/smp.h> 4#include <linux/smp.h>
4#include <asm/fixmap.h> 5#include <asm/fixmap.h>
5#include <asm/tlbflush.h> 6#include <asm/tlbflush.h>
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 524d9352f17e..f388dc68f605 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -18,7 +18,6 @@ config PARISC
18 select BUG 18 select BUG
19 select HAVE_PERF_EVENTS 19 select HAVE_PERF_EVENTS
20 select GENERIC_ATOMIC64 if !64BIT 20 select GENERIC_ATOMIC64 if !64BIT
21 select HAVE_ARCH_TRACEHOOK
22 help 21 help
23 The PA-RISC microprocessor is designed by Hewlett-Packard and used 22 The PA-RISC microprocessor is designed by Hewlett-Packard and used
24 in many of their workstations & servers (HP9000 700 and 800 series, 23 in many of their workstations & servers (HP9000 700 and 800 series,
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c
index f7064abc3bb6..9e74bfe071dc 100644
--- a/arch/parisc/kernel/pci.c
+++ b/arch/parisc/kernel/pci.c
@@ -18,7 +18,6 @@
18 18
19#include <asm/io.h> 19#include <asm/io.h>
20#include <asm/system.h> 20#include <asm/system.h>
21#include <asm/cache.h> /* for L1_CACHE_BYTES */
22#include <asm/superio.h> 21#include <asm/superio.h>
23 22
24#define DEBUG_RESOURCES 0 23#define DEBUG_RESOURCES 0
@@ -123,6 +122,10 @@ static int __init pcibios_init(void)
123 } else { 122 } else {
124 printk(KERN_WARNING "pci_bios != NULL but init() is!\n"); 123 printk(KERN_WARNING "pci_bios != NULL but init() is!\n");
125 } 124 }
125
126 /* Set the CLS for PCI as early as possible. */
127 pci_cache_line_size = pci_dfl_cache_line_size;
128
126 return 0; 129 return 0;
127} 130}
128 131
@@ -171,7 +174,7 @@ void pcibios_set_master(struct pci_dev *dev)
171 ** upper byte is PCI_LATENCY_TIMER. 174 ** upper byte is PCI_LATENCY_TIMER.
172 */ 175 */
173 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE, 176 pci_write_config_word(dev, PCI_CACHE_LINE_SIZE,
174 (0x80 << 8) | (L1_CACHE_BYTES / sizeof(u32))); 177 (0x80 << 8) | pci_cache_line_size);
175} 178}
176 179
177 180
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 21f61b8c445b..cc29c0f5300d 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -338,7 +338,8 @@ static void __init mpc85xx_mds_pic_init(void)
338 } 338 }
339 339
340 mpic = mpic_alloc(np, r.start, 340 mpic = mpic_alloc(np, r.start,
341 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 341 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN |
342 MPIC_BROKEN_FRR_NIRQS,
342 0, 256, " OpenPIC "); 343 0, 256, " OpenPIC ");
343 BUG_ON(mpic == NULL); 344 BUG_ON(mpic == NULL);
344 of_node_put(np); 345 of_node_put(np);
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 04160a4cc699..a15f582300d8 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -46,6 +46,7 @@ smp_85xx_kick_cpu(int nr)
46 __iomem u32 *bptr_vaddr; 46 __iomem u32 *bptr_vaddr;
47 struct device_node *np; 47 struct device_node *np;
48 int n = 0; 48 int n = 0;
49 int ioremappable;
49 50
50 WARN_ON (nr < 0 || nr >= NR_CPUS); 51 WARN_ON (nr < 0 || nr >= NR_CPUS);
51 52
@@ -59,21 +60,37 @@ smp_85xx_kick_cpu(int nr)
59 return; 60 return;
60 } 61 }
61 62
63 /*
64 * A secondary core could be in a spinloop in the bootpage
65 * (0xfffff000), somewhere in highmem, or somewhere in lowmem.
66 * The bootpage and highmem can be accessed via ioremap(), but
67 * we need to directly access the spinloop if its in lowmem.
68 */
69 ioremappable = *cpu_rel_addr > virt_to_phys(high_memory);
70
62 /* Map the spin table */ 71 /* Map the spin table */
63 bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); 72 if (ioremappable)
73 bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY);
74 else
75 bptr_vaddr = phys_to_virt(*cpu_rel_addr);
64 76
65 local_irq_save(flags); 77 local_irq_save(flags);
66 78
67 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr); 79 out_be32(bptr_vaddr + BOOT_ENTRY_PIR, nr);
68 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); 80 out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start));
69 81
82 if (!ioremappable)
83 flush_dcache_range((ulong)bptr_vaddr,
84 (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY));
85
70 /* Wait a bit for the CPU to ack. */ 86 /* Wait a bit for the CPU to ack. */
71 while ((__secondary_hold_acknowledge != nr) && (++n < 1000)) 87 while ((__secondary_hold_acknowledge != nr) && (++n < 1000))
72 mdelay(1); 88 mdelay(1);
73 89
74 local_irq_restore(flags); 90 local_irq_restore(flags);
75 91
76 iounmap(bptr_vaddr); 92 if (ioremappable)
93 iounmap(bptr_vaddr);
77 94
78 pr_debug("waited %d msecs for CPU #%d.\n", n, nr); 95 pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
79} 96}
diff --git a/arch/sh/include/asm/siu.h b/arch/sh/include/asm/siu.h
new file mode 100644
index 000000000000..57565a3b551f
--- /dev/null
+++ b/arch/sh/include/asm/siu.h
@@ -0,0 +1,26 @@
1/*
2 * platform header for the SIU ASoC driver
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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 ASM_SIU_H
12#define ASM_SIU_H
13
14#include <asm/dma-sh.h>
15
16struct device;
17
18struct siu_platform {
19 struct device *dma_dev;
20 enum sh_dmae_slave_chan_id dma_slave_tx_a;
21 enum sh_dmae_slave_chan_id dma_slave_rx_a;
22 enum sh_dmae_slave_chan_id dma_slave_tx_b;
23 enum sh_dmae_slave_chan_id dma_slave_rx_b;
24};
25
26#endif /* ASM_SIU_H */
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 873ebdc4f98e..b063eb8b18e3 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -133,6 +133,8 @@ void user_enable_single_step(struct task_struct *child)
133 struct pt_regs *regs = child->thread.uregs; 133 struct pt_regs *regs = child->thread.uregs;
134 134
135 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */ 135 regs->sr |= SR_SSTEP; /* auto-resetting upon exception */
136
137 set_tsk_thread_flag(child, TIF_SINGLESTEP);
136} 138}
137 139
138void user_disable_single_step(struct task_struct *child) 140void user_disable_single_step(struct task_struct *child)
@@ -140,6 +142,8 @@ void user_disable_single_step(struct task_struct *child)
140 struct pt_regs *regs = child->thread.uregs; 142 struct pt_regs *regs = child->thread.uregs;
141 143
142 regs->sr &= ~SR_SSTEP; 144 regs->sr &= ~SR_SSTEP;
145
146 clear_tsk_thread_flag(child, TIF_SINGLESTEP);
143} 147}
144 148
145static int genregs_get(struct task_struct *target, 149static int genregs_get(struct task_struct *target,
@@ -454,6 +458,8 @@ asmlinkage long long do_syscall_trace_enter(struct pt_regs *regs)
454 458
455asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) 459asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
456{ 460{
461 int step;
462
457 if (unlikely(current->audit_context)) 463 if (unlikely(current->audit_context))
458 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]), 464 audit_syscall_exit(AUDITSC_RESULT(regs->regs[9]),
459 regs->regs[9]); 465 regs->regs[9]);
@@ -461,8 +467,9 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
461 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) 467 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
462 trace_sys_exit(regs, regs->regs[9]); 468 trace_sys_exit(regs, regs->regs[9]);
463 469
464 if (test_thread_flag(TIF_SYSCALL_TRACE)) 470 step = test_thread_flag(TIF_SINGLESTEP);
465 tracehook_report_syscall_exit(regs, 0); 471 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
472 tracehook_report_syscall_exit(regs, step);
466} 473}
467 474
468/* Called with interrupts disabled */ 475/* Called with interrupts disabled */
diff --git a/arch/sh/kernel/signal_64.c b/arch/sh/kernel/signal_64.c
index ce76dbdef294..580e97d46ca5 100644
--- a/arch/sh/kernel/signal_64.c
+++ b/arch/sh/kernel/signal_64.c
@@ -118,7 +118,9 @@ static int do_signal(struct pt_regs *regs, sigset_t *oldset)
118 * clear the TS_RESTORE_SIGMASK flag. 118 * clear the TS_RESTORE_SIGMASK flag.
119 */ 119 */
120 current_thread_info()->status &= ~TS_RESTORE_SIGMASK; 120 current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
121 tracehook_signal_handler(signr, &info, &ka, regs, 0); 121
122 tracehook_signal_handler(signr, &info, &ka, regs,
123 test_thread_flag(TIF_SINGLESTEP));
122 return 1; 124 return 1;
123 } 125 }
124 } 126 }
diff --git a/arch/sparc/include/asm/stat.h b/arch/sparc/include/asm/stat.h
index 55db5eca08e2..39327d6a57eb 100644
--- a/arch/sparc/include/asm/stat.h
+++ b/arch/sparc/include/asm/stat.h
@@ -53,8 +53,8 @@ struct stat {
53 ino_t st_ino; 53 ino_t st_ino;
54 mode_t st_mode; 54 mode_t st_mode;
55 short st_nlink; 55 short st_nlink;
56 uid_t st_uid; 56 uid16_t st_uid;
57 gid_t st_gid; 57 gid16_t st_gid;
58 unsigned short st_rdev; 58 unsigned short st_rdev;
59 off_t st_size; 59 off_t st_size;
60 time_t st_atime; 60 time_t st_atime;
diff --git a/arch/sparc/kernel/kstack.h b/arch/sparc/kernel/kstack.h
index 4248d969272f..5247283d1c03 100644
--- a/arch/sparc/kernel/kstack.h
+++ b/arch/sparc/kernel/kstack.h
@@ -11,6 +11,10 @@ static inline bool kstack_valid(struct thread_info *tp, unsigned long sp)
11{ 11{
12 unsigned long base = (unsigned long) tp; 12 unsigned long base = (unsigned long) tp;
13 13
14 /* Stack pointer must be 16-byte aligned. */
15 if (sp & (16UL - 1))
16 return false;
17
14 if (sp >= (base + sizeof(struct thread_info)) && 18 if (sp >= (base + sizeof(struct thread_info)) &&
15 sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf))) 19 sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
16 return true; 20 return true;
diff --git a/arch/sparc/kernel/of_device_32.c b/arch/sparc/kernel/of_device_32.c
index 4c26eb59e742..53a58b349849 100644
--- a/arch/sparc/kernel/of_device_32.c
+++ b/arch/sparc/kernel/of_device_32.c
@@ -105,7 +105,7 @@ static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
105 105
106static int of_bus_ambapp_match(struct device_node *np) 106static int of_bus_ambapp_match(struct device_node *np)
107{ 107{
108 return !strcmp(np->name, "ambapp"); 108 return !strcmp(np->type, "ambapp");
109} 109}
110 110
111static void of_bus_ambapp_count_cells(struct device_node *child, 111static void of_bus_ambapp_count_cells(struct device_node *child,
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 539e83f8e087..592b03d85167 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -247,6 +247,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
247 struct pci_bus *bus, int devfn) 247 struct pci_bus *bus, int devfn)
248{ 248{
249 struct dev_archdata *sd; 249 struct dev_archdata *sd;
250 struct pci_slot *slot;
250 struct of_device *op; 251 struct of_device *op;
251 struct pci_dev *dev; 252 struct pci_dev *dev;
252 const char *type; 253 const char *type;
@@ -286,6 +287,11 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
286 dev->dev.bus = &pci_bus_type; 287 dev->dev.bus = &pci_bus_type;
287 dev->devfn = devfn; 288 dev->devfn = devfn;
288 dev->multifunction = 0; /* maybe a lie? */ 289 dev->multifunction = 0; /* maybe a lie? */
290 set_pcie_port_type(dev);
291
292 list_for_each_entry(slot, &dev->bus->slots, list)
293 if (PCI_SLOT(dev->devfn) == slot->number)
294 dev->slot = slot;
289 295
290 dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff); 296 dev->vendor = of_getintprop_default(node, "vendor-id", 0xffff);
291 dev->device = of_getintprop_default(node, "device-id", 0xffff); 297 dev->device = of_getintprop_default(node, "device-id", 0xffff);
@@ -322,6 +328,7 @@ static struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
322 328
323 dev->current_state = 4; /* unknown power state */ 329 dev->current_state = 4; /* unknown power state */
324 dev->error_state = pci_channel_io_normal; 330 dev->error_state = pci_channel_io_normal;
331 dev->dma_mask = 0xffffffff;
325 332
326 if (!strcmp(node->name, "pci")) { 333 if (!strcmp(node->name, "pci")) {
327 /* a PCI-PCI bridge */ 334 /* a PCI-PCI bridge */
diff --git a/arch/sparc/kernel/tsb.S b/arch/sparc/kernel/tsb.S
index 8c91d9b29a2f..db15d123f054 100644
--- a/arch/sparc/kernel/tsb.S
+++ b/arch/sparc/kernel/tsb.S
@@ -191,10 +191,12 @@ tsb_dtlb_load:
191 191
192tsb_itlb_load: 192tsb_itlb_load:
193 /* Executable bit must be set. */ 193 /* Executable bit must be set. */
194661: andcc %g5, _PAGE_EXEC_4U, %g0 194661: sethi %hi(_PAGE_EXEC_4U), %g4
195 .section .sun4v_1insn_patch, "ax" 195 andcc %g5, %g4, %g0
196 .section .sun4v_2insn_patch, "ax"
196 .word 661b 197 .word 661b
197 andcc %g5, _PAGE_EXEC_4V, %g0 198 andcc %g5, _PAGE_EXEC_4V, %g0
199 nop
198 .previous 200 .previous
199 201
200 be,pn %xcc, tsb_do_fault 202 be,pn %xcc, tsb_do_fault
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
index 1994d3f58443..f2ad2163109d 100644
--- a/arch/x86/include/asm/elf.h
+++ b/arch/x86/include/asm/elf.h
@@ -170,10 +170,7 @@ static inline void elf_common_init(struct thread_struct *t,
170} 170}
171 171
172#define ELF_PLAT_INIT(_r, load_addr) \ 172#define ELF_PLAT_INIT(_r, load_addr) \
173do { \ 173 elf_common_init(&current->thread, _r, 0)
174 elf_common_init(&current->thread, _r, 0); \
175 clear_thread_flag(TIF_IA32); \
176} while (0)
177 174
178#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \ 175#define COMPAT_ELF_PLAT_INIT(regs, load_addr) \
179 elf_common_init(&current->thread, regs, __USER_DS) 176 elf_common_init(&current->thread, regs, __USER_DS)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index fc801bab1b3b..b753ea59703a 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -450,6 +450,8 @@ struct thread_struct {
450 struct perf_event *ptrace_bps[HBP_NUM]; 450 struct perf_event *ptrace_bps[HBP_NUM];
451 /* Debug status used for traps, single steps, etc... */ 451 /* Debug status used for traps, single steps, etc... */
452 unsigned long debugreg6; 452 unsigned long debugreg6;
453 /* Keep track of the exact dr7 value set by the user */
454 unsigned long ptrace_dr7;
453 /* Fault info: */ 455 /* Fault info: */
454 unsigned long cr2; 456 unsigned long cr2;
455 unsigned long trap_no; 457 unsigned long trap_no;
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0acbcdfa5ca4..af1c5833ff23 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -1344,14 +1344,6 @@ static struct dmi_system_id __initdata acpi_dmi_table[] = {
1344 }, 1344 },
1345 { 1345 {
1346 .callback = force_acpi_ht, 1346 .callback = force_acpi_ht,
1347 .ident = "ASUS P2B-DS",
1348 .matches = {
1349 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
1350 DMI_MATCH(DMI_BOARD_NAME, "P2B-DS"),
1351 },
1352 },
1353 {
1354 .callback = force_acpi_ht,
1355 .ident = "ASUS CUR-DLS", 1347 .ident = "ASUS CUR-DLS",
1356 .matches = { 1348 .matches = {
1357 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), 1349 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
index 05d5fec64a94..bb6006e3e295 100644
--- a/arch/x86/kernel/hw_breakpoint.c
+++ b/arch/x86/kernel/hw_breakpoint.c
@@ -212,25 +212,6 @@ static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len)
212 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); 212 return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
213} 213}
214 214
215/*
216 * Store a breakpoint's encoded address, length, and type.
217 */
218static int arch_store_info(struct perf_event *bp)
219{
220 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
221 /*
222 * For kernel-addresses, either the address or symbol name can be
223 * specified.
224 */
225 if (info->name)
226 info->address = (unsigned long)
227 kallsyms_lookup_name(info->name);
228 if (info->address)
229 return 0;
230
231 return -EINVAL;
232}
233
234int arch_bp_generic_fields(int x86_len, int x86_type, 215int arch_bp_generic_fields(int x86_len, int x86_type,
235 int *gen_len, int *gen_type) 216 int *gen_len, int *gen_type)
236{ 217{
@@ -362,10 +343,13 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
362 return ret; 343 return ret;
363 } 344 }
364 345
365 ret = arch_store_info(bp); 346 /*
366 347 * For kernel-addresses, either the address or symbol name can be
367 if (ret < 0) 348 * specified.
368 return ret; 349 */
350 if (info->name)
351 info->address = (unsigned long)
352 kallsyms_lookup_name(info->name);
369 /* 353 /*
370 * Check that the low-order bits of the address are appropriate 354 * Check that the low-order bits of the address are appropriate
371 * for the alignment implied by len. 355 * for the alignment implied by len.
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 41a26a82470a..126f0b493d04 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -527,6 +527,7 @@ void set_personality_ia32(void)
527 527
528 /* Make sure to be in 32bit mode */ 528 /* Make sure to be in 32bit mode */
529 set_thread_flag(TIF_IA32); 529 set_thread_flag(TIF_IA32);
530 current->personality |= force_personality32;
530 531
531 /* Prepare the first "return" to user space */ 532 /* Prepare the first "return" to user space */
532 current_thread_info()->status |= TS_COMPAT; 533 current_thread_info()->status |= TS_COMPAT;
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index 017d937639fe..0c1033d61e59 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -702,7 +702,7 @@ static unsigned long ptrace_get_debugreg(struct task_struct *tsk, int n)
702 } else if (n == 6) { 702 } else if (n == 6) {
703 val = thread->debugreg6; 703 val = thread->debugreg6;
704 } else if (n == 7) { 704 } else if (n == 7) {
705 val = ptrace_get_dr7(thread->ptrace_bps); 705 val = thread->ptrace_dr7;
706 } 706 }
707 return val; 707 return val;
708} 708}
@@ -778,8 +778,11 @@ int ptrace_set_debugreg(struct task_struct *tsk, int n, unsigned long val)
778 return rc; 778 return rc;
779 } 779 }
780 /* All that's left is DR7 */ 780 /* All that's left is DR7 */
781 if (n == 7) 781 if (n == 7) {
782 rc = ptrace_write_dr7(tsk, val); 782 rc = ptrace_write_dr7(tsk, val);
783 if (!rc)
784 thread->ptrace_dr7 = val;
785 }
783 786
784ret_path: 787ret_path:
785 return rc; 788 return rc;
diff --git a/block/blk-core.c b/block/blk-core.c
index 718897e6d37f..d1a9a0a64f95 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1147,7 +1147,7 @@ void init_request_from_bio(struct request *req, struct bio *bio)
1147 */ 1147 */
1148static inline bool queue_should_plug(struct request_queue *q) 1148static inline bool queue_should_plug(struct request_queue *q)
1149{ 1149{
1150 return !(blk_queue_nonrot(q) && blk_queue_queuing(q)); 1150 return !(blk_queue_nonrot(q) && blk_queue_tagged(q));
1151} 1151}
1152 1152
1153static int __make_request(struct request_queue *q, struct bio *bio) 1153static int __make_request(struct request_queue *q, struct bio *bio)
@@ -1859,15 +1859,8 @@ void blk_dequeue_request(struct request *rq)
1859 * and to it is freed is accounted as io that is in progress at 1859 * and to it is freed is accounted as io that is in progress at
1860 * the driver side. 1860 * the driver side.
1861 */ 1861 */
1862 if (blk_account_rq(rq)) { 1862 if (blk_account_rq(rq))
1863 q->in_flight[rq_is_sync(rq)]++; 1863 q->in_flight[rq_is_sync(rq)]++;
1864 /*
1865 * Mark this device as supporting hardware queuing, if
1866 * we have more IOs in flight than 4.
1867 */
1868 if (!blk_queue_queuing(q) && queue_in_flight(q) > 4)
1869 set_bit(QUEUE_FLAG_CQ, &q->queue_flags);
1870 }
1871} 1864}
1872 1865
1873/** 1866/**
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index bbc2c1315c47..b2586f57e1f5 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -935,6 +935,7 @@ static int dock_add(acpi_handle handle)
935 struct platform_device *dd; 935 struct platform_device *dd;
936 936
937 id = dock_station_count; 937 id = dock_station_count;
938 memset(&ds, 0, sizeof(ds));
938 dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds)); 939 dd = platform_device_register_data(NULL, "dock", id, &ds, sizeof(ds));
939 if (IS_ERR(dd)) 940 if (IS_ERR(dd))
940 return PTR_ERR(dd); 941 return PTR_ERR(dd);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7c0441f63b39..cc978a8c00b7 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -110,6 +110,14 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
110 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), 110 DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
111 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")}, 111 DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
112 (void *)2}, 112 (void *)2},
113 { set_max_cstate, "Pavilion zv5000", {
114 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
115 DMI_MATCH(DMI_PRODUCT_NAME,"Pavilion zv5000 (DS502A#ABA)")},
116 (void *)1},
117 { set_max_cstate, "Asus L8400B", {
118 DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."),
119 DMI_MATCH(DMI_PRODUCT_NAME,"L8400B series Notebook PC")},
120 (void *)1},
113 {}, 121 {},
114}; 122};
115 123
@@ -872,12 +880,14 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
872 return(acpi_idle_enter_c1(dev, state)); 880 return(acpi_idle_enter_c1(dev, state));
873 881
874 local_irq_disable(); 882 local_irq_disable();
875 current_thread_info()->status &= ~TS_POLLING; 883 if (cx->entry_method != ACPI_CSTATE_FFH) {
876 /* 884 current_thread_info()->status &= ~TS_POLLING;
877 * TS_POLLING-cleared state must be visible before we test 885 /*
878 * NEED_RESCHED: 886 * TS_POLLING-cleared state must be visible before we test
879 */ 887 * NEED_RESCHED:
880 smp_mb(); 888 */
889 smp_mb();
890 }
881 891
882 if (unlikely(need_resched())) { 892 if (unlikely(need_resched())) {
883 current_thread_info()->status |= TS_POLLING; 893 current_thread_info()->status |= TS_POLLING;
@@ -957,12 +967,14 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
957 } 967 }
958 968
959 local_irq_disable(); 969 local_irq_disable();
960 current_thread_info()->status &= ~TS_POLLING; 970 if (cx->entry_method != ACPI_CSTATE_FFH) {
961 /* 971 current_thread_info()->status &= ~TS_POLLING;
962 * TS_POLLING-cleared state must be visible before we test 972 /*
963 * NEED_RESCHED: 973 * TS_POLLING-cleared state must be visible before we test
964 */ 974 * NEED_RESCHED:
965 smp_mb(); 975 */
976 smp_mb();
977 }
966 978
967 if (unlikely(need_resched())) { 979 if (unlikely(need_resched())) {
968 current_thread_info()->status |= TS_POLLING; 980 current_thread_info()->status |= TS_POLLING;
diff --git a/drivers/acpi/processor_pdc.c b/drivers/acpi/processor_pdc.c
index 7247819dbd80..e306ba9aa34e 100644
--- a/drivers/acpi/processor_pdc.c
+++ b/drivers/acpi/processor_pdc.c
@@ -125,6 +125,8 @@ acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
125 return status; 125 return status;
126} 126}
127 127
128static int early_pdc_done;
129
128void acpi_processor_set_pdc(acpi_handle handle) 130void acpi_processor_set_pdc(acpi_handle handle)
129{ 131{
130 struct acpi_object_list *obj_list; 132 struct acpi_object_list *obj_list;
@@ -132,6 +134,9 @@ void acpi_processor_set_pdc(acpi_handle handle)
132 if (arch_has_acpi_pdc() == false) 134 if (arch_has_acpi_pdc() == false)
133 return; 135 return;
134 136
137 if (early_pdc_done)
138 return;
139
135 obj_list = acpi_processor_alloc_pdc(); 140 obj_list = acpi_processor_alloc_pdc();
136 if (!obj_list) 141 if (!obj_list)
137 return; 142 return;
@@ -151,6 +156,13 @@ static int set_early_pdc_optin(const struct dmi_system_id *id)
151 return 0; 156 return 0;
152} 157}
153 158
159static int param_early_pdc_optin(char *s)
160{
161 early_pdc_optin = 1;
162 return 1;
163}
164__setup("acpi_early_pdc_eval", param_early_pdc_optin);
165
154static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = { 166static struct dmi_system_id __cpuinitdata early_pdc_optin_table[] = {
155 { 167 {
156 set_early_pdc_optin, "HP Envy", { 168 set_early_pdc_optin, "HP Envy", {
@@ -192,4 +204,6 @@ void __init acpi_early_processor_set_pdc(void)
192 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT, 204 acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
193 ACPI_UINT32_MAX, 205 ACPI_UINT32_MAX,
194 early_init_pdc, NULL, NULL, NULL); 206 early_init_pdc, NULL, NULL, NULL);
207
208 early_pdc_done = 1;
195} 209}
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 2cabadcc4d8c..a959f6a07508 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -413,7 +413,11 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr)
413 if (result) 413 if (result)
414 goto update_bios; 414 goto update_bios;
415 415
416 return 0; 416 /* We need to call _PPC once when cpufreq starts */
417 if (ignore_ppc != 1)
418 result = acpi_processor_get_platform_limit(pr);
419
420 return result;
417 421
418 /* 422 /*
419 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that 423 * Having _PPC but missing frequencies (_PSS, _PCT) is a very good hint that
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index ff9f6226085d..3e009674f333 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1336,9 +1336,25 @@ static int acpi_bus_scan(acpi_handle handle, struct acpi_bus_ops *ops,
1336 1336
1337 if (child) 1337 if (child)
1338 *child = device; 1338 *child = device;
1339 return 0; 1339
1340 if (device)
1341 return 0;
1342 else
1343 return -ENODEV;
1340} 1344}
1341 1345
1346/*
1347 * acpi_bus_add and acpi_bus_start
1348 *
1349 * scan a given ACPI tree and (probably recently hot-plugged)
1350 * create and add or starts found devices.
1351 *
1352 * If no devices were found -ENODEV is returned which does not
1353 * mean that this is a real error, there just have been no suitable
1354 * ACPI objects in the table trunk from which the kernel could create
1355 * a device and add/start an appropriate driver.
1356 */
1357
1342int 1358int
1343acpi_bus_add(struct acpi_device **child, 1359acpi_bus_add(struct acpi_device **child,
1344 struct acpi_device *parent, acpi_handle handle, int type) 1360 struct acpi_device *parent, acpi_handle handle, int type)
@@ -1348,8 +1364,7 @@ acpi_bus_add(struct acpi_device **child,
1348 memset(&ops, 0, sizeof(ops)); 1364 memset(&ops, 0, sizeof(ops));
1349 ops.acpi_op_add = 1; 1365 ops.acpi_op_add = 1;
1350 1366
1351 acpi_bus_scan(handle, &ops, child); 1367 return acpi_bus_scan(handle, &ops, child);
1352 return 0;
1353} 1368}
1354EXPORT_SYMBOL(acpi_bus_add); 1369EXPORT_SYMBOL(acpi_bus_add);
1355 1370
@@ -1357,11 +1372,13 @@ int acpi_bus_start(struct acpi_device *device)
1357{ 1372{
1358 struct acpi_bus_ops ops; 1373 struct acpi_bus_ops ops;
1359 1374
1375 if (!device)
1376 return -EINVAL;
1377
1360 memset(&ops, 0, sizeof(ops)); 1378 memset(&ops, 0, sizeof(ops));
1361 ops.acpi_op_start = 1; 1379 ops.acpi_op_start = 1;
1362 1380
1363 acpi_bus_scan(device->handle, &ops, NULL); 1381 return acpi_bus_scan(device->handle, &ops, NULL);
1364 return 0;
1365} 1382}
1366EXPORT_SYMBOL(acpi_bus_start); 1383EXPORT_SYMBOL(acpi_bus_start);
1367 1384
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index f336bca7c450..8a0ed2800e63 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -213,7 +213,7 @@ acpi_table_parse_entries(char *id,
213 unsigned long table_end; 213 unsigned long table_end;
214 acpi_size tbl_size; 214 acpi_size tbl_size;
215 215
216 if (acpi_disabled) 216 if (acpi_disabled && !acpi_ht)
217 return -ENODEV; 217 return -ENODEV;
218 218
219 if (!handler) 219 if (!handler)
@@ -280,7 +280,7 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
280 struct acpi_table_header *table = NULL; 280 struct acpi_table_header *table = NULL;
281 acpi_size tbl_size; 281 acpi_size tbl_size;
282 282
283 if (acpi_disabled) 283 if (acpi_disabled && !acpi_ht)
284 return -ENODEV; 284 return -ENODEV;
285 285
286 if (!handler) 286 if (!handler)
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 161746deab4b..6e2c3b064f53 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -59,6 +59,8 @@ static void class_release(struct kobject *kobj)
59 else 59 else
60 pr_debug("class '%s' does not have a release() function, " 60 pr_debug("class '%s' does not have a release() function, "
61 "be careful\n", class->name); 61 "be careful\n", class->name);
62
63 kfree(cp);
62} 64}
63 65
64static struct sysfs_ops class_sysfs_ops = { 66static struct sysfs_ops class_sysfs_ops = {
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c
index 27d20fac19d1..b314a999aabe 100644
--- a/drivers/clocksource/cs5535-clockevt.c
+++ b/drivers/clocksource/cs5535-clockevt.c
@@ -21,7 +21,7 @@
21 21
22#define DRV_NAME "cs5535-clockevt" 22#define DRV_NAME "cs5535-clockevt"
23 23
24static int timer_irq = CONFIG_CS5535_MFGPT_DEFAULT_IRQ; 24static int timer_irq;
25module_param_named(irq, timer_irq, int, 0644); 25module_param_named(irq, timer_irq, int, 0644);
26MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks."); 26MODULE_PARM_DESC(irq, "Which IRQ to use for the clock source MFGPT ticks.");
27 27
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index cbaf420c36c5..2d3dc7ded0a9 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -893,20 +893,31 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
893 893
894static struct kmem_cache *fwnet_packet_task_cache; 894static struct kmem_cache *fwnet_packet_task_cache;
895 895
896static void fwnet_free_ptask(struct fwnet_packet_task *ptask)
897{
898 dev_kfree_skb_any(ptask->skb);
899 kmem_cache_free(fwnet_packet_task_cache, ptask);
900}
901
896static int fwnet_send_packet(struct fwnet_packet_task *ptask); 902static int fwnet_send_packet(struct fwnet_packet_task *ptask);
897 903
898static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask) 904static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
899{ 905{
900 struct fwnet_device *dev; 906 struct fwnet_device *dev = ptask->dev;
901 unsigned long flags; 907 unsigned long flags;
902 908 bool free;
903 dev = ptask->dev;
904 909
905 spin_lock_irqsave(&dev->lock, flags); 910 spin_lock_irqsave(&dev->lock, flags);
906 list_del(&ptask->pt_link);
907 spin_unlock_irqrestore(&dev->lock, flags);
908 911
909 ptask->outstanding_pkts--; /* FIXME access inside lock */ 912 ptask->outstanding_pkts--;
913
914 /* Check whether we or the networking TX soft-IRQ is last user. */
915 free = (ptask->outstanding_pkts == 0 && !list_empty(&ptask->pt_link));
916
917 if (ptask->outstanding_pkts == 0)
918 list_del(&ptask->pt_link);
919
920 spin_unlock_irqrestore(&dev->lock, flags);
910 921
911 if (ptask->outstanding_pkts > 0) { 922 if (ptask->outstanding_pkts > 0) {
912 u16 dg_size; 923 u16 dg_size;
@@ -951,10 +962,10 @@ static void fwnet_transmit_packet_done(struct fwnet_packet_task *ptask)
951 ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE; 962 ptask->max_payload = skb->len + RFC2374_FRAG_HDR_SIZE;
952 } 963 }
953 fwnet_send_packet(ptask); 964 fwnet_send_packet(ptask);
954 } else {
955 dev_kfree_skb_any(ptask->skb);
956 kmem_cache_free(fwnet_packet_task_cache, ptask);
957 } 965 }
966
967 if (free)
968 fwnet_free_ptask(ptask);
958} 969}
959 970
960static void fwnet_write_complete(struct fw_card *card, int rcode, 971static void fwnet_write_complete(struct fw_card *card, int rcode,
@@ -977,6 +988,7 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
977 unsigned tx_len; 988 unsigned tx_len;
978 struct rfc2734_header *bufhdr; 989 struct rfc2734_header *bufhdr;
979 unsigned long flags; 990 unsigned long flags;
991 bool free;
980 992
981 dev = ptask->dev; 993 dev = ptask->dev;
982 tx_len = ptask->max_payload; 994 tx_len = ptask->max_payload;
@@ -1022,12 +1034,16 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
1022 generation, SCODE_100, 0ULL, ptask->skb->data, 1034 generation, SCODE_100, 0ULL, ptask->skb->data,
1023 tx_len + 8, fwnet_write_complete, ptask); 1035 tx_len + 8, fwnet_write_complete, ptask);
1024 1036
1025 /* FIXME race? */
1026 spin_lock_irqsave(&dev->lock, flags); 1037 spin_lock_irqsave(&dev->lock, flags);
1027 list_add_tail(&ptask->pt_link, &dev->broadcasted_list); 1038
1039 /* If the AT tasklet already ran, we may be last user. */
1040 free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
1041 if (!free)
1042 list_add_tail(&ptask->pt_link, &dev->broadcasted_list);
1043
1028 spin_unlock_irqrestore(&dev->lock, flags); 1044 spin_unlock_irqrestore(&dev->lock, flags);
1029 1045
1030 return 0; 1046 goto out;
1031 } 1047 }
1032 1048
1033 fw_send_request(dev->card, &ptask->transaction, 1049 fw_send_request(dev->card, &ptask->transaction,
@@ -1035,12 +1051,19 @@ static int fwnet_send_packet(struct fwnet_packet_task *ptask)
1035 ptask->generation, ptask->speed, ptask->fifo_addr, 1051 ptask->generation, ptask->speed, ptask->fifo_addr,
1036 ptask->skb->data, tx_len, fwnet_write_complete, ptask); 1052 ptask->skb->data, tx_len, fwnet_write_complete, ptask);
1037 1053
1038 /* FIXME race? */
1039 spin_lock_irqsave(&dev->lock, flags); 1054 spin_lock_irqsave(&dev->lock, flags);
1040 list_add_tail(&ptask->pt_link, &dev->sent_list); 1055
1056 /* If the AT tasklet already ran, we may be last user. */
1057 free = (ptask->outstanding_pkts == 0 && list_empty(&ptask->pt_link));
1058 if (!free)
1059 list_add_tail(&ptask->pt_link, &dev->sent_list);
1060
1041 spin_unlock_irqrestore(&dev->lock, flags); 1061 spin_unlock_irqrestore(&dev->lock, flags);
1042 1062
1043 dev->netdev->trans_start = jiffies; 1063 dev->netdev->trans_start = jiffies;
1064 out:
1065 if (free)
1066 fwnet_free_ptask(ptask);
1044 1067
1045 return 0; 1068 return 0;
1046} 1069}
@@ -1298,6 +1321,8 @@ static netdev_tx_t fwnet_tx(struct sk_buff *skb, struct net_device *net)
1298 spin_unlock_irqrestore(&dev->lock, flags); 1321 spin_unlock_irqrestore(&dev->lock, flags);
1299 1322
1300 ptask->max_payload = max_payload; 1323 ptask->max_payload = max_payload;
1324 INIT_LIST_HEAD(&ptask->pt_link);
1325
1301 fwnet_send_packet(ptask); 1326 fwnet_send_packet(ptask);
1302 1327
1303 return NETDEV_TX_OK; 1328 return NETDEV_TX_OK;
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 2345d4103fe6..43ebf337b131 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -2101,11 +2101,6 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base,
2101 u32 payload_index, payload_end_index, next_page_index; 2101 u32 payload_index, payload_end_index, next_page_index;
2102 int page, end_page, i, length, offset; 2102 int page, end_page, i, length, offset;
2103 2103
2104 /*
2105 * FIXME: Cycle lost behavior should be configurable: lose
2106 * packet, retransmit or terminate..
2107 */
2108
2109 p = packet; 2104 p = packet;
2110 payload_index = payload; 2105 payload_index = payload;
2111 2106
@@ -2135,6 +2130,14 @@ static int ohci_queue_iso_transmit(struct fw_iso_context *base,
2135 if (!p->skip) { 2130 if (!p->skip) {
2136 d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE); 2131 d[0].control = cpu_to_le16(DESCRIPTOR_KEY_IMMEDIATE);
2137 d[0].req_count = cpu_to_le16(8); 2132 d[0].req_count = cpu_to_le16(8);
2133 /*
2134 * Link the skip address to this descriptor itself. This causes
2135 * a context to skip a cycle whenever lost cycles or FIFO
2136 * overruns occur, without dropping the data. The application
2137 * should then decide whether this is an error condition or not.
2138 * FIXME: Make the context's cycle-lost behaviour configurable?
2139 */
2140 d[0].branch_address = cpu_to_le32(d_bus | z);
2138 2141
2139 header = (__le32 *) &d[1]; 2142 header = (__le32 *) &d[1];
2140 header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) | 2143 header[0] = cpu_to_le32(IT_HEADER_SY(p->sy) |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f665b05592f3..ab6c97330412 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -598,6 +598,50 @@ struct drm_display_mode *drm_mode_std(struct drm_device *dev,
598 return mode; 598 return mode;
599} 599}
600 600
601/*
602 * EDID is delightfully ambiguous about how interlaced modes are to be
603 * encoded. Our internal representation is of frame height, but some
604 * HDTV detailed timings are encoded as field height.
605 *
606 * The format list here is from CEA, in frame size. Technically we
607 * should be checking refresh rate too. Whatever.
608 */
609static void
610drm_mode_do_interlace_quirk(struct drm_display_mode *mode,
611 struct detailed_pixel_timing *pt)
612{
613 int i;
614 static const struct {
615 int w, h;
616 } cea_interlaced[] = {
617 { 1920, 1080 },
618 { 720, 480 },
619 { 1440, 480 },
620 { 2880, 480 },
621 { 720, 576 },
622 { 1440, 576 },
623 { 2880, 576 },
624 };
625 static const int n_sizes =
626 sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
627
628 if (!(pt->misc & DRM_EDID_PT_INTERLACED))
629 return;
630
631 for (i = 0; i < n_sizes; i++) {
632 if ((mode->hdisplay == cea_interlaced[i].w) &&
633 (mode->vdisplay == cea_interlaced[i].h / 2)) {
634 mode->vdisplay *= 2;
635 mode->vsync_start *= 2;
636 mode->vsync_end *= 2;
637 mode->vtotal *= 2;
638 mode->vtotal |= 1;
639 }
640 }
641
642 mode->flags |= DRM_MODE_FLAG_INTERLACE;
643}
644
601/** 645/**
602 * drm_mode_detailed - create a new mode from an EDID detailed timing section 646 * drm_mode_detailed - create a new mode from an EDID detailed timing section
603 * @dev: DRM device (needed to create new mode) 647 * @dev: DRM device (needed to create new mode)
@@ -680,8 +724,7 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
680 724
681 drm_mode_set_name(mode); 725 drm_mode_set_name(mode);
682 726
683 if (pt->misc & DRM_EDID_PT_INTERLACED) 727 drm_mode_do_interlace_quirk(mode, pt);
684 mode->flags |= DRM_MODE_FLAG_INTERLACE;
685 728
686 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) { 729 if (quirks & EDID_QUIRK_DETAILED_SYNC_PP) {
687 pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE; 730 pt->misc |= DRM_EDID_PT_HSYNC_POSITIVE | DRM_EDID_PT_VSYNC_POSITIVE;
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index cdec32977129..2ac074c8f5d2 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -405,7 +405,8 @@ struct drm_mm_node *drm_mm_search_free_in_range(const struct drm_mm *mm,
405 wasted += alignment - tmp; 405 wasted += alignment - tmp;
406 } 406 }
407 407
408 if (entry->size >= size + wasted) { 408 if (entry->size >= size + wasted &&
409 (entry->start + wasted + size) <= end) {
409 if (!best_match) 410 if (!best_match)
410 return entry; 411 return entry;
411 if (entry->size < best_size) { 412 if (entry->size < best_size) {
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 79beffcf5936..cf4cb3e9a0c2 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -176,6 +176,8 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
176 176
177static int i915_drm_freeze(struct drm_device *dev) 177static int i915_drm_freeze(struct drm_device *dev)
178{ 178{
179 struct drm_i915_private *dev_priv = dev->dev_private;
180
179 pci_save_state(dev->pdev); 181 pci_save_state(dev->pdev);
180 182
181 /* If KMS is active, we do the leavevt stuff here */ 183 /* If KMS is active, we do the leavevt stuff here */
@@ -191,17 +193,12 @@ static int i915_drm_freeze(struct drm_device *dev)
191 193
192 i915_save_state(dev); 194 i915_save_state(dev);
193 195
194 return 0;
195}
196
197static void i915_drm_suspend(struct drm_device *dev)
198{
199 struct drm_i915_private *dev_priv = dev->dev_private;
200
201 intel_opregion_free(dev, 1); 196 intel_opregion_free(dev, 1);
202 197
203 /* Modeset on resume, not lid events */ 198 /* Modeset on resume, not lid events */
204 dev_priv->modeset_on_lid = 0; 199 dev_priv->modeset_on_lid = 0;
200
201 return 0;
205} 202}
206 203
207static int i915_suspend(struct drm_device *dev, pm_message_t state) 204static int i915_suspend(struct drm_device *dev, pm_message_t state)
@@ -221,8 +218,6 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
221 if (error) 218 if (error)
222 return error; 219 return error;
223 220
224 i915_drm_suspend(dev);
225
226 if (state.event == PM_EVENT_SUSPEND) { 221 if (state.event == PM_EVENT_SUSPEND) {
227 /* Shut down the device */ 222 /* Shut down the device */
228 pci_disable_device(dev->pdev); 223 pci_disable_device(dev->pdev);
@@ -237,6 +232,10 @@ static int i915_drm_thaw(struct drm_device *dev)
237 struct drm_i915_private *dev_priv = dev->dev_private; 232 struct drm_i915_private *dev_priv = dev->dev_private;
238 int error = 0; 233 int error = 0;
239 234
235 i915_restore_state(dev);
236
237 intel_opregion_init(dev, 1);
238
240 /* KMS EnterVT equivalent */ 239 /* KMS EnterVT equivalent */
241 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 240 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
242 mutex_lock(&dev->struct_mutex); 241 mutex_lock(&dev->struct_mutex);
@@ -263,10 +262,6 @@ static int i915_resume(struct drm_device *dev)
263 262
264 pci_set_master(dev->pdev); 263 pci_set_master(dev->pdev);
265 264
266 i915_restore_state(dev);
267
268 intel_opregion_init(dev, 1);
269
270 return i915_drm_thaw(dev); 265 return i915_drm_thaw(dev);
271} 266}
272 267
@@ -423,8 +418,6 @@ static int i915_pm_suspend(struct device *dev)
423 if (error) 418 if (error)
424 return error; 419 return error;
425 420
426 i915_drm_suspend(drm_dev);
427
428 pci_disable_device(pdev); 421 pci_disable_device(pdev);
429 pci_set_power_state(pdev, PCI_D3hot); 422 pci_set_power_state(pdev, PCI_D3hot);
430 423
@@ -464,13 +457,8 @@ static int i915_pm_poweroff(struct device *dev)
464{ 457{
465 struct pci_dev *pdev = to_pci_dev(dev); 458 struct pci_dev *pdev = to_pci_dev(dev);
466 struct drm_device *drm_dev = pci_get_drvdata(pdev); 459 struct drm_device *drm_dev = pci_get_drvdata(pdev);
467 int error;
468
469 error = i915_drm_freeze(drm_dev);
470 if (!error)
471 i915_drm_suspend(drm_dev);
472 460
473 return error; 461 return i915_drm_freeze(drm_dev);
474} 462}
475 463
476const struct dev_pm_ops i915_pm_ops = { 464const struct dev_pm_ops i915_pm_ops = {
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index b1d0acbae4e4..c2e8a45780d5 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -636,6 +636,13 @@ static const struct dmi_system_id bad_lid_status[] = {
636 DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"), 636 DMI_MATCH(DMI_PRODUCT_NAME, "PC-81005"),
637 }, 637 },
638 }, 638 },
639 {
640 .ident = "Clevo M5x0N",
641 .matches = {
642 DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
643 DMI_MATCH(DMI_BOARD_NAME, "M5x0N"),
644 },
645 },
639 { } 646 { }
640}; 647};
641 648
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 2cd0fad17dac..0e9cd1d49130 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -5861,13 +5861,12 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table,
5861 struct drm_nouveau_private *dev_priv = dev->dev_private; 5861 struct drm_nouveau_private *dev_priv = dev->dev_private;
5862 struct nvbios *bios = &dev_priv->VBIOS; 5862 struct nvbios *bios = &dev_priv->VBIOS;
5863 struct init_exec iexec = { true, false }; 5863 struct init_exec iexec = { true, false };
5864 unsigned long flags;
5865 5864
5866 spin_lock_irqsave(&bios->lock, flags); 5865 mutex_lock(&bios->lock);
5867 bios->display.output = dcbent; 5866 bios->display.output = dcbent;
5868 parse_init_table(bios, table, &iexec); 5867 parse_init_table(bios, table, &iexec);
5869 bios->display.output = NULL; 5868 bios->display.output = NULL;
5870 spin_unlock_irqrestore(&bios->lock, flags); 5869 mutex_unlock(&bios->lock);
5871} 5870}
5872 5871
5873static bool NVInitVBIOS(struct drm_device *dev) 5872static bool NVInitVBIOS(struct drm_device *dev)
@@ -5876,7 +5875,7 @@ static bool NVInitVBIOS(struct drm_device *dev)
5876 struct nvbios *bios = &dev_priv->VBIOS; 5875 struct nvbios *bios = &dev_priv->VBIOS;
5877 5876
5878 memset(bios, 0, sizeof(struct nvbios)); 5877 memset(bios, 0, sizeof(struct nvbios));
5879 spin_lock_init(&bios->lock); 5878 mutex_init(&bios->lock);
5880 bios->dev = dev; 5879 bios->dev = dev;
5881 5880
5882 if (!NVShadowVBIOS(dev, bios->data)) 5881 if (!NVShadowVBIOS(dev, bios->data))
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h
index 68446fd4146b..fd94bd6dc264 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.h
@@ -205,7 +205,7 @@ struct nvbios {
205 struct drm_device *dev; 205 struct drm_device *dev;
206 struct nouveau_bios_info pub; 206 struct nouveau_bios_info pub;
207 207
208 spinlock_t lock; 208 struct mutex lock;
209 209
210 uint8_t data[NV_PROM_SIZE]; 210 uint8_t data[NV_PROM_SIZE];
211 unsigned int length; 211 unsigned int length;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 5445cefdd03e..1c15ef37b71c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -583,6 +583,7 @@ struct drm_nouveau_private {
583 uint64_t vm_end; 583 uint64_t vm_end;
584 struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; 584 struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR];
585 int vm_vram_pt_nr; 585 int vm_vram_pt_nr;
586 uint64_t vram_sys_base;
586 587
587 /* the mtrr covering the FB */ 588 /* the mtrr covering the FB */
588 int fb_mtrr; 589 int fb_mtrr;
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c
index 8f3a12f614ed..2dc09dbd817d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_mem.c
+++ b/drivers/gpu/drm/nouveau/nouveau_mem.c
@@ -285,53 +285,50 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
285 uint32_t flags, uint64_t phys) 285 uint32_t flags, uint64_t phys)
286{ 286{
287 struct drm_nouveau_private *dev_priv = dev->dev_private; 287 struct drm_nouveau_private *dev_priv = dev->dev_private;
288 struct nouveau_gpuobj **pgt; 288 struct nouveau_gpuobj *pgt;
289 unsigned psz, pfl, pages; 289 unsigned block;
290 290 int i;
291 if (virt >= dev_priv->vm_gart_base &&
292 (virt + size) < (dev_priv->vm_gart_base + dev_priv->vm_gart_size)) {
293 psz = 12;
294 pgt = &dev_priv->gart_info.sg_ctxdma;
295 pfl = 0x21;
296 virt -= dev_priv->vm_gart_base;
297 } else
298 if (virt >= dev_priv->vm_vram_base &&
299 (virt + size) < (dev_priv->vm_vram_base + dev_priv->vm_vram_size)) {
300 psz = 16;
301 pgt = dev_priv->vm_vram_pt;
302 pfl = 0x01;
303 virt -= dev_priv->vm_vram_base;
304 } else {
305 NV_ERROR(dev, "Invalid address: 0x%16llx-0x%16llx\n",
306 virt, virt + size - 1);
307 return -EINVAL;
308 }
309 291
310 pages = size >> psz; 292 virt = ((virt - dev_priv->vm_vram_base) >> 16) << 1;
293 size = (size >> 16) << 1;
294
295 phys |= ((uint64_t)flags << 32);
296 phys |= 1;
297 if (dev_priv->vram_sys_base) {
298 phys += dev_priv->vram_sys_base;
299 phys |= 0x30;
300 }
311 301
312 dev_priv->engine.instmem.prepare_access(dev, true); 302 dev_priv->engine.instmem.prepare_access(dev, true);
313 if (flags & 0x80000000) { 303 while (size) {
314 while (pages--) { 304 unsigned offset_h = upper_32_bits(phys);
315 struct nouveau_gpuobj *pt = pgt[virt >> 29]; 305 unsigned offset_l = lower_32_bits(phys);
316 unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1; 306 unsigned pte, end;
307
308 for (i = 7; i >= 0; i--) {
309 block = 1 << (i + 1);
310 if (size >= block && !(virt & (block - 1)))
311 break;
312 }
313 offset_l |= (i << 7);
317 314
318 nv_wo32(dev, pt, pte++, 0x00000000); 315 phys += block << 15;
319 nv_wo32(dev, pt, pte++, 0x00000000); 316 size -= block;
320 317
321 virt += (1 << psz); 318 while (block) {
322 } 319 pgt = dev_priv->vm_vram_pt[virt >> 14];
323 } else { 320 pte = virt & 0x3ffe;
324 while (pages--) {
325 struct nouveau_gpuobj *pt = pgt[virt >> 29];
326 unsigned pte = ((virt & 0x1fffffffULL) >> psz) << 1;
327 unsigned offset_h = upper_32_bits(phys) & 0xff;
328 unsigned offset_l = lower_32_bits(phys);
329 321
330 nv_wo32(dev, pt, pte++, offset_l | pfl); 322 end = pte + block;
331 nv_wo32(dev, pt, pte++, offset_h | flags); 323 if (end > 16384)
324 end = 16384;
325 block -= (end - pte);
326 virt += (end - pte);
332 327
333 phys += (1 << psz); 328 while (pte < end) {
334 virt += (1 << psz); 329 nv_wo32(dev, pgt, pte++, offset_l);
330 nv_wo32(dev, pgt, pte++, offset_h);
331 }
335 } 332 }
336 } 333 }
337 dev_priv->engine.instmem.finish_access(dev); 334 dev_priv->engine.instmem.finish_access(dev);
@@ -356,7 +353,41 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size,
356void 353void
357nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) 354nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size)
358{ 355{
359 nv50_mem_vm_bind_linear(dev, virt, size, 0x80000000, 0); 356 struct drm_nouveau_private *dev_priv = dev->dev_private;
357 struct nouveau_gpuobj *pgt;
358 unsigned pages, pte, end;
359
360 virt -= dev_priv->vm_vram_base;
361 pages = (size >> 16) << 1;
362
363 dev_priv->engine.instmem.prepare_access(dev, true);
364 while (pages) {
365 pgt = dev_priv->vm_vram_pt[virt >> 29];
366 pte = (virt & 0x1ffe0000ULL) >> 15;
367
368 end = pte + pages;
369 if (end > 16384)
370 end = 16384;
371 pages -= (end - pte);
372 virt += (end - pte) << 15;
373
374 while (pte < end)
375 nv_wo32(dev, pgt, pte++, 0);
376 }
377 dev_priv->engine.instmem.finish_access(dev);
378
379 nv_wr32(dev, 0x100c80, 0x00050001);
380 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
381 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
382 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
383 return;
384 }
385
386 nv_wr32(dev, 0x100c80, 0x00000001);
387 if (!nv_wait(0x100c80, 0x00000001, 0x00000000)) {
388 NV_ERROR(dev, "timeout: (0x100c80 & 1) == 0 (2)\n");
389 NV_ERROR(dev, "0x100c80 = 0x%08x\n", nv_rd32(dev, 0x100c80));
390 }
360} 391}
361 392
362/* 393/*
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c
index d0e038d28948..1d73b15d70da 100644
--- a/drivers/gpu/drm/nouveau/nv04_dac.c
+++ b/drivers/gpu/drm/nouveau/nv04_dac.c
@@ -119,7 +119,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
119 struct drm_connector *connector) 119 struct drm_connector *connector)
120{ 120{
121 struct drm_device *dev = encoder->dev; 121 struct drm_device *dev = encoder->dev;
122 uint8_t saved_seq1, saved_pi, saved_rpc1; 122 uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode;
123 uint8_t saved_palette0[3], saved_palette_mask; 123 uint8_t saved_palette0[3], saved_palette_mask;
124 uint32_t saved_rtest_ctrl, saved_rgen_ctrl; 124 uint32_t saved_rtest_ctrl, saved_rgen_ctrl;
125 int i; 125 int i;
@@ -135,6 +135,9 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
135 /* only implemented for head A for now */ 135 /* only implemented for head A for now */
136 NVSetOwner(dev, 0); 136 NVSetOwner(dev, 0);
137 137
138 saved_cr_mode = NVReadVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX);
139 NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode | 0x80);
140
138 saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX); 141 saved_seq1 = NVReadVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX);
139 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20); 142 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1 & ~0x20);
140 143
@@ -203,6 +206,7 @@ out:
203 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi); 206 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_PIXEL_INDEX, saved_pi);
204 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1); 207 NVWriteVgaCrtc(dev, 0, NV_CIO_CRE_RPC1_INDEX, saved_rpc1);
205 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1); 208 NVWriteVgaSeq(dev, 0, NV_VIO_SR_CLOCK_INDEX, saved_seq1);
209 NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
206 210
207 if (blue == 0x18) { 211 if (blue == 0x18) {
208 NV_INFO(dev, "Load detected on head A\n"); 212 NV_INFO(dev, "Load detected on head A\n");
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c
index 58b917c3341b..21ac6e49b6ee 100644
--- a/drivers/gpu/drm/nouveau/nv17_tv.c
+++ b/drivers/gpu/drm/nouveau/nv17_tv.c
@@ -579,6 +579,8 @@ static void nv17_tv_restore(struct drm_encoder *encoder)
579 nouveau_encoder(encoder)->restore.output); 579 nouveau_encoder(encoder)->restore.output);
580 580
581 nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state); 581 nv17_tv_state_load(dev, &to_tv_enc(encoder)->saved_state);
582
583 nouveau_encoder(encoder)->last_dpms = NV_DPMS_CLEARED;
582} 584}
583 585
584static int nv17_tv_create_resources(struct drm_encoder *encoder, 586static int nv17_tv_create_resources(struct drm_encoder *encoder,
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c
index 94400f777e7f..f0dc4e36ef05 100644
--- a/drivers/gpu/drm/nouveau/nv50_instmem.c
+++ b/drivers/gpu/drm/nouveau/nv50_instmem.c
@@ -76,6 +76,11 @@ nv50_instmem_init(struct drm_device *dev)
76 for (i = 0x1700; i <= 0x1710; i += 4) 76 for (i = 0x1700; i <= 0x1710; i += 4)
77 priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i); 77 priv->save1700[(i-0x1700)/4] = nv_rd32(dev, i);
78 78
79 if (dev_priv->chipset == 0xaa || dev_priv->chipset == 0xac)
80 dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10) << 12;
81 else
82 dev_priv->vram_sys_base = 0;
83
79 /* Reserve the last MiB of VRAM, we should probably try to avoid 84 /* Reserve the last MiB of VRAM, we should probably try to avoid
80 * setting up the below tables over the top of the VBIOS image at 85 * setting up the below tables over the top of the VBIOS image at
81 * some point. 86 * some point.
@@ -172,16 +177,28 @@ nv50_instmem_init(struct drm_device *dev)
172 * We map the entire fake channel into the start of the PRAMIN BAR 177 * We map the entire fake channel into the start of the PRAMIN BAR
173 */ 178 */
174 ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000, 179 ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pt_size, 0x1000,
175 0, &priv->pramin_pt); 180 0, &priv->pramin_pt);
176 if (ret) 181 if (ret)
177 return ret; 182 return ret;
178 183
179 for (i = 0, v = c_offset; i < pt_size; i += 8, v += 0x1000) { 184 v = c_offset | 1;
180 if (v < (c_offset + c_size)) 185 if (dev_priv->vram_sys_base) {
181 BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v | 1); 186 v += dev_priv->vram_sys_base;
182 else 187 v |= 0x30;
183 BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000009); 188 }
189
190 i = 0;
191 while (v < dev_priv->vram_sys_base + c_offset + c_size) {
192 BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, v);
193 BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
194 v += 0x1000;
195 i += 8;
196 }
197
198 while (i < pt_size) {
199 BAR0_WI32(priv->pramin_pt->gpuobj, i + 0, 0x00000000);
184 BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000); 200 BAR0_WI32(priv->pramin_pt->gpuobj, i + 4, 0x00000000);
201 i += 8;
185 } 202 }
186 203
187 BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63); 204 BAR0_WI32(chan->vm_pd, 0x00, priv->pramin_pt->instance | 0x63);
@@ -416,7 +433,9 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
416{ 433{
417 struct drm_nouveau_private *dev_priv = dev->dev_private; 434 struct drm_nouveau_private *dev_priv = dev->dev_private;
418 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; 435 struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv;
419 uint32_t pte, pte_end, vram; 436 struct nouveau_gpuobj *pramin_pt = priv->pramin_pt->gpuobj;
437 uint32_t pte, pte_end;
438 uint64_t vram;
420 439
421 if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) 440 if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound)
422 return -EINVAL; 441 return -EINVAL;
@@ -424,20 +443,24 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
424 NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n", 443 NV_DEBUG(dev, "st=0x%0llx sz=0x%0llx\n",
425 gpuobj->im_pramin->start, gpuobj->im_pramin->size); 444 gpuobj->im_pramin->start, gpuobj->im_pramin->size);
426 445
427 pte = (gpuobj->im_pramin->start >> 12) << 3; 446 pte = (gpuobj->im_pramin->start >> 12) << 1;
428 pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; 447 pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
429 vram = gpuobj->im_backing_start; 448 vram = gpuobj->im_backing_start;
430 449
431 NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n", 450 NV_DEBUG(dev, "pramin=0x%llx, pte=%d, pte_end=%d\n",
432 gpuobj->im_pramin->start, pte, pte_end); 451 gpuobj->im_pramin->start, pte, pte_end);
433 NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start); 452 NV_DEBUG(dev, "first vram page: 0x%08x\n", gpuobj->im_backing_start);
434 453
454 vram |= 1;
455 if (dev_priv->vram_sys_base) {
456 vram += dev_priv->vram_sys_base;
457 vram |= 0x30;
458 }
459
435 dev_priv->engine.instmem.prepare_access(dev, true); 460 dev_priv->engine.instmem.prepare_access(dev, true);
436 while (pte < pte_end) { 461 while (pte < pte_end) {
437 nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, vram | 1); 462 nv_wo32(dev, pramin_pt, pte++, lower_32_bits(vram));
438 nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); 463 nv_wo32(dev, pramin_pt, pte++, upper_32_bits(vram));
439
440 pte += 8;
441 vram += NV50_INSTMEM_PAGE_SIZE; 464 vram += NV50_INSTMEM_PAGE_SIZE;
442 } 465 }
443 dev_priv->engine.instmem.finish_access(dev); 466 dev_priv->engine.instmem.finish_access(dev);
@@ -470,14 +493,13 @@ nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj)
470 if (gpuobj->im_bound == 0) 493 if (gpuobj->im_bound == 0)
471 return -EINVAL; 494 return -EINVAL;
472 495
473 pte = (gpuobj->im_pramin->start >> 12) << 3; 496 pte = (gpuobj->im_pramin->start >> 12) << 1;
474 pte_end = ((gpuobj->im_pramin->size >> 12) << 3) + pte; 497 pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte;
475 498
476 dev_priv->engine.instmem.prepare_access(dev, true); 499 dev_priv->engine.instmem.prepare_access(dev, true);
477 while (pte < pte_end) { 500 while (pte < pte_end) {
478 nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 0)/4, 0x00000009); 501 nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
479 nv_wo32(dev, priv->pramin_pt->gpuobj, (pte + 4)/4, 0x00000000); 502 nv_wo32(dev, priv->pramin_pt->gpuobj, pte++, 0x00000000);
480 pte += 8;
481 } 503 }
482 dev_priv->engine.instmem.finish_access(dev); 504 dev_priv->engine.instmem.finish_access(dev);
483 505
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c
index e3b44562d265..7f152f66f196 100644
--- a/drivers/gpu/drm/radeon/atom.c
+++ b/drivers/gpu/drm/radeon/atom.c
@@ -24,6 +24,7 @@
24 24
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/sched.h> 26#include <linux/sched.h>
27#include <asm/unaligned.h>
27 28
28#define ATOM_DEBUG 29#define ATOM_DEBUG
29 30
@@ -212,7 +213,9 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
212 case ATOM_ARG_PS: 213 case ATOM_ARG_PS:
213 idx = U8(*ptr); 214 idx = U8(*ptr);
214 (*ptr)++; 215 (*ptr)++;
215 val = le32_to_cpu(ctx->ps[idx]); 216 /* get_unaligned_le32 avoids unaligned accesses from atombios
217 * tables, noticed on a DEC Alpha. */
218 val = get_unaligned_le32((u32 *)&ctx->ps[idx]);
216 if (print) 219 if (print)
217 DEBUG("PS[0x%02X,0x%04X]", idx, val); 220 DEBUG("PS[0x%02X,0x%04X]", idx, val);
218 break; 221 break;
@@ -640,7 +643,7 @@ static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
640 uint8_t count = U8((*ptr)++); 643 uint8_t count = U8((*ptr)++);
641 SDEBUG(" count: %d\n", count); 644 SDEBUG(" count: %d\n", count);
642 if (arg == ATOM_UNIT_MICROSEC) 645 if (arg == ATOM_UNIT_MICROSEC)
643 schedule_timeout_uninterruptible(usecs_to_jiffies(count)); 646 udelay(count);
644 else 647 else
645 schedule_timeout_uninterruptible(msecs_to_jiffies(count)); 648 schedule_timeout_uninterruptible(msecs_to_jiffies(count));
646} 649}
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index b32eeea5bb8b..99915a682d59 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -350,7 +350,7 @@ retry:
350 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); 350 atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
351 351
352 if (args.ucReplyStatus && !args.ucDataOutLen) { 352 if (args.ucReplyStatus && !args.ucDataOutLen) {
353 if (args.ucReplyStatus == 0x20 && retry_count < 10) 353 if (args.ucReplyStatus == 0x20 && retry_count++ < 10)
354 goto retry; 354 goto retry;
355 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n", 355 DRM_DEBUG("failed to get auxch %02x%02x %02x %02x 0x%02x %02x after %d retries\n",
356 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3], 356 req_bytes[1], req_bytes[0], req_bytes[2], req_bytes[3],
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c
index af1c3ca8a4cb..446b765ac72a 100644
--- a/drivers/gpu/drm/radeon/r600_blit_kms.c
+++ b/drivers/gpu/drm/radeon/r600_blit_kms.c
@@ -543,9 +543,6 @@ int r600_vb_ib_get(struct radeon_device *rdev)
543void r600_vb_ib_put(struct radeon_device *rdev) 543void r600_vb_ib_put(struct radeon_device *rdev)
544{ 544{
545 radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence); 545 radeon_fence_emit(rdev, rdev->r600_blit.vb_ib->fence);
546 mutex_lock(&rdev->ib_pool.mutex);
547 list_add_tail(&rdev->r600_blit.vb_ib->list, &rdev->ib_pool.scheduled_ibs);
548 mutex_unlock(&rdev->ib_pool.mutex);
549 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); 546 radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
550} 547}
551 548
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
index 6d5a711c2e91..75bcf35a0931 100644
--- a/drivers/gpu/drm/radeon/r600_cp.c
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -1428,9 +1428,12 @@ static void r700_gfx_init(struct drm_device *dev,
1428 1428
1429 gb_tiling_config |= R600_BANK_SWAPS(1); 1429 gb_tiling_config |= R600_BANK_SWAPS(1);
1430 1430
1431 backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes, 1431 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV740)
1432 dev_priv->r600_max_backends, 1432 backend_map = 0x28;
1433 (0xff << dev_priv->r600_max_backends) & 0xff); 1433 else
1434 backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
1435 dev_priv->r600_max_backends,
1436 (0xff << dev_priv->r600_max_backends) & 0xff);
1434 gb_tiling_config |= R600_BACKEND_MAP(backend_map); 1437 gb_tiling_config |= R600_BACKEND_MAP(backend_map);
1435 1438
1436 cc_gc_shader_pipe_config = 1439 cc_gc_shader_pipe_config =
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f57480ba1355..c0356bb193e5 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -96,6 +96,7 @@ extern int radeon_audio;
96 * symbol; 96 * symbol;
97 */ 97 */
98#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ 98#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
99/* RADEON_IB_POOL_SIZE must be a power of 2 */
99#define RADEON_IB_POOL_SIZE 16 100#define RADEON_IB_POOL_SIZE 16
100#define RADEON_DEBUGFS_MAX_NUM_FILES 32 101#define RADEON_DEBUGFS_MAX_NUM_FILES 32
101#define RADEONFB_CONN_LIMIT 4 102#define RADEONFB_CONN_LIMIT 4
@@ -363,11 +364,12 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev);
363 */ 364 */
364struct radeon_ib { 365struct radeon_ib {
365 struct list_head list; 366 struct list_head list;
366 unsigned long idx; 367 unsigned idx;
367 uint64_t gpu_addr; 368 uint64_t gpu_addr;
368 struct radeon_fence *fence; 369 struct radeon_fence *fence;
369 uint32_t *ptr; 370 uint32_t *ptr;
370 uint32_t length_dw; 371 uint32_t length_dw;
372 bool free;
371}; 373};
372 374
373/* 375/*
@@ -377,10 +379,9 @@ struct radeon_ib {
377struct radeon_ib_pool { 379struct radeon_ib_pool {
378 struct mutex mutex; 380 struct mutex mutex;
379 struct radeon_bo *robj; 381 struct radeon_bo *robj;
380 struct list_head scheduled_ibs;
381 struct radeon_ib ibs[RADEON_IB_POOL_SIZE]; 382 struct radeon_ib ibs[RADEON_IB_POOL_SIZE];
382 bool ready; 383 bool ready;
383 DECLARE_BITMAP(alloc_bm, RADEON_IB_POOL_SIZE); 384 unsigned head_id;
384}; 385};
385 386
386struct radeon_cp { 387struct radeon_cp {
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 2dcda6115874..4d8831548a5f 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -206,6 +206,15 @@ static bool radeon_atom_apply_quirks(struct drm_device *dev,
206 *connector_type = DRM_MODE_CONNECTOR_DVID; 206 *connector_type = DRM_MODE_CONNECTOR_DVID;
207 } 207 }
208 208
209 /* Asrock RS600 board lists the DVI port as HDMI */
210 if ((dev->pdev->device == 0x7941) &&
211 (dev->pdev->subsystem_vendor == 0x1849) &&
212 (dev->pdev->subsystem_device == 0x7941)) {
213 if ((*connector_type == DRM_MODE_CONNECTOR_HDMIA) &&
214 (supported_device == ATOM_DEVICE_DFP3_SUPPORT))
215 *connector_type = DRM_MODE_CONNECTOR_DVID;
216 }
217
209 /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */ 218 /* a-bit f-i90hd - ciaranm on #radeonhd - this board has no DVI */
210 if ((dev->pdev->device == 0x7941) && 219 if ((dev->pdev->device == 0x7941) &&
211 (dev->pdev->subsystem_vendor == 0x147b) && 220 (dev->pdev->subsystem_vendor == 0x147b) &&
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index 238188540017..65f81942f399 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -780,7 +780,7 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect
780 * connected and the DVI port disconnected. If the edid doesn't 780 * connected and the DVI port disconnected. If the edid doesn't
781 * say HDMI, vice versa. 781 * say HDMI, vice versa.
782 */ 782 */
783 if (radeon_connector->shared_ddc && connector_status_connected) { 783 if (radeon_connector->shared_ddc && (ret == connector_status_connected)) {
784 struct drm_device *dev = connector->dev; 784 struct drm_device *dev = connector->dev;
785 struct drm_connector *list_connector; 785 struct drm_connector *list_connector;
786 struct radeon_connector *list_radeon_connector; 786 struct radeon_connector *list_radeon_connector;
@@ -1060,8 +1060,7 @@ radeon_add_atom_connector(struct drm_device *dev,
1060 return; 1060 return;
1061 } 1061 }
1062 if (radeon_connector->ddc_bus && i2c_bus->valid) { 1062 if (radeon_connector->ddc_bus && i2c_bus->valid) {
1063 if (memcmp(&radeon_connector->ddc_bus->rec, i2c_bus, 1063 if (radeon_connector->ddc_bus->rec.i2c_id == i2c_bus->i2c_id) {
1064 sizeof(struct radeon_i2c_bus_rec)) == 0) {
1065 radeon_connector->shared_ddc = true; 1064 radeon_connector->shared_ddc = true;
1066 shared_ddc = true; 1065 shared_ddc = true;
1067 } 1066 }
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 1190148cf5e6..e9d085021c1f 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -86,7 +86,7 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p)
86 &p->validated); 86 &p->validated);
87 } 87 }
88 } 88 }
89 return radeon_bo_list_validate(&p->validated, p->ib->fence); 89 return radeon_bo_list_validate(&p->validated);
90} 90}
91 91
92int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) 92int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data)
@@ -189,12 +189,10 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error)
189{ 189{
190 unsigned i; 190 unsigned i;
191 191
192 if (error && parser->ib) { 192 if (!error && parser->ib) {
193 radeon_bo_list_unvalidate(&parser->validated, 193 radeon_bo_list_fence(&parser->validated, parser->ib->fence);
194 parser->ib->fence);
195 } else {
196 radeon_bo_list_unreserve(&parser->validated);
197 } 194 }
195 radeon_bo_list_unreserve(&parser->validated);
198 for (i = 0; i < parser->nrelocs; i++) { 196 for (i = 0; i < parser->nrelocs; i++) {
199 if (parser->relocs[i].gobj) { 197 if (parser->relocs[i].gobj) {
200 mutex_lock(&parser->rdev->ddev->struct_mutex); 198 mutex_lock(&parser->rdev->ddev->struct_mutex);
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index e13785282a82..c57ad606504d 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -106,9 +106,10 @@
106 * 1.29- R500 3D cmd buffer support 106 * 1.29- R500 3D cmd buffer support
107 * 1.30- Add support for occlusion queries 107 * 1.30- Add support for occlusion queries
108 * 1.31- Add support for num Z pipes from GET_PARAM 108 * 1.31- Add support for num Z pipes from GET_PARAM
109 * 1.32- fixes for rv740 setup
109 */ 110 */
110#define DRIVER_MAJOR 1 111#define DRIVER_MAJOR 1
111#define DRIVER_MINOR 31 112#define DRIVER_MINOR 32
112#define DRIVER_PATCHLEVEL 0 113#define DRIVER_PATCHLEVEL 0
113 114
114enum radeon_cp_microcode_version { 115enum radeon_cp_microcode_version {
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c
index d72a71bff218..f1da370928eb 100644
--- a/drivers/gpu/drm/radeon/radeon_object.c
+++ b/drivers/gpu/drm/radeon/radeon_object.c
@@ -306,11 +306,10 @@ void radeon_bo_list_unreserve(struct list_head *head)
306 } 306 }
307} 307}
308 308
309int radeon_bo_list_validate(struct list_head *head, void *fence) 309int radeon_bo_list_validate(struct list_head *head)
310{ 310{
311 struct radeon_bo_list *lobj; 311 struct radeon_bo_list *lobj;
312 struct radeon_bo *bo; 312 struct radeon_bo *bo;
313 struct radeon_fence *old_fence = NULL;
314 int r; 313 int r;
315 314
316 r = radeon_bo_list_reserve(head); 315 r = radeon_bo_list_reserve(head);
@@ -334,32 +333,27 @@ int radeon_bo_list_validate(struct list_head *head, void *fence)
334 } 333 }
335 lobj->gpu_offset = radeon_bo_gpu_offset(bo); 334 lobj->gpu_offset = radeon_bo_gpu_offset(bo);
336 lobj->tiling_flags = bo->tiling_flags; 335 lobj->tiling_flags = bo->tiling_flags;
337 if (fence) {
338 old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
339 bo->tbo.sync_obj = radeon_fence_ref(fence);
340 bo->tbo.sync_obj_arg = NULL;
341 }
342 if (old_fence) {
343 radeon_fence_unref(&old_fence);
344 }
345 } 336 }
346 return 0; 337 return 0;
347} 338}
348 339
349void radeon_bo_list_unvalidate(struct list_head *head, void *fence) 340void radeon_bo_list_fence(struct list_head *head, void *fence)
350{ 341{
351 struct radeon_bo_list *lobj; 342 struct radeon_bo_list *lobj;
352 struct radeon_fence *old_fence; 343 struct radeon_bo *bo;
353 344 struct radeon_fence *old_fence = NULL;
354 if (fence) 345
355 list_for_each_entry(lobj, head, list) { 346 list_for_each_entry(lobj, head, list) {
356 old_fence = to_radeon_fence(lobj->bo->tbo.sync_obj); 347 bo = lobj->bo;
357 if (old_fence == fence) { 348 spin_lock(&bo->tbo.lock);
358 lobj->bo->tbo.sync_obj = NULL; 349 old_fence = (struct radeon_fence *)bo->tbo.sync_obj;
359 radeon_fence_unref(&old_fence); 350 bo->tbo.sync_obj = radeon_fence_ref(fence);
360 } 351 bo->tbo.sync_obj_arg = NULL;
352 spin_unlock(&bo->tbo.lock);
353 if (old_fence) {
354 radeon_fence_unref(&old_fence);
361 } 355 }
362 radeon_bo_list_unreserve(head); 356 }
363} 357}
364 358
365int radeon_bo_fbdev_mmap(struct radeon_bo *bo, 359int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h
index a02f18011ad1..7ab43de1e244 100644
--- a/drivers/gpu/drm/radeon/radeon_object.h
+++ b/drivers/gpu/drm/radeon/radeon_object.h
@@ -156,8 +156,8 @@ extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj,
156 struct list_head *head); 156 struct list_head *head);
157extern int radeon_bo_list_reserve(struct list_head *head); 157extern int radeon_bo_list_reserve(struct list_head *head);
158extern void radeon_bo_list_unreserve(struct list_head *head); 158extern void radeon_bo_list_unreserve(struct list_head *head);
159extern int radeon_bo_list_validate(struct list_head *head, void *fence); 159extern int radeon_bo_list_validate(struct list_head *head);
160extern void radeon_bo_list_unvalidate(struct list_head *head, void *fence); 160extern void radeon_bo_list_fence(struct list_head *head, void *fence);
161extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, 161extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo,
162 struct vm_area_struct *vma); 162 struct vm_area_struct *vma);
163extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, 163extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo,
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 4d12b2d17b4d..6579eb4c1f28 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -41,68 +41,55 @@ int radeon_ib_get(struct radeon_device *rdev, struct radeon_ib **ib)
41{ 41{
42 struct radeon_fence *fence; 42 struct radeon_fence *fence;
43 struct radeon_ib *nib; 43 struct radeon_ib *nib;
44 unsigned long i; 44 int r = 0, i, c;
45 int r = 0;
46 45
47 *ib = NULL; 46 *ib = NULL;
48 r = radeon_fence_create(rdev, &fence); 47 r = radeon_fence_create(rdev, &fence);
49 if (r) { 48 if (r) {
50 DRM_ERROR("failed to create fence for new IB\n"); 49 dev_err(rdev->dev, "failed to create fence for new IB\n");
51 return r; 50 return r;
52 } 51 }
53 mutex_lock(&rdev->ib_pool.mutex); 52 mutex_lock(&rdev->ib_pool.mutex);
54 i = find_first_zero_bit(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); 53 for (i = rdev->ib_pool.head_id, c = 0, nib = NULL; c < RADEON_IB_POOL_SIZE; c++, i++) {
55 if (i < RADEON_IB_POOL_SIZE) { 54 i &= (RADEON_IB_POOL_SIZE - 1);
56 set_bit(i, rdev->ib_pool.alloc_bm); 55 if (rdev->ib_pool.ibs[i].free) {
57 rdev->ib_pool.ibs[i].length_dw = 0; 56 nib = &rdev->ib_pool.ibs[i];
58 *ib = &rdev->ib_pool.ibs[i]; 57 break;
59 mutex_unlock(&rdev->ib_pool.mutex); 58 }
60 goto out;
61 } 59 }
62 if (list_empty(&rdev->ib_pool.scheduled_ibs)) { 60 if (nib == NULL) {
63 /* we go do nothings here */ 61 /* This should never happen, it means we allocated all
62 * IB and haven't scheduled one yet, return EBUSY to
63 * userspace hoping that on ioctl recall we get better
64 * luck
65 */
66 dev_err(rdev->dev, "no free indirect buffer !\n");
64 mutex_unlock(&rdev->ib_pool.mutex); 67 mutex_unlock(&rdev->ib_pool.mutex);
65 DRM_ERROR("all IB allocated none scheduled.\n"); 68 radeon_fence_unref(&fence);
66 r = -EINVAL; 69 return -EBUSY;
67 goto out;
68 } 70 }
69 /* get the first ib on the scheduled list */ 71 rdev->ib_pool.head_id = (nib->idx + 1) & (RADEON_IB_POOL_SIZE - 1);
70 nib = list_entry(rdev->ib_pool.scheduled_ibs.next, 72 nib->free = false;
71 struct radeon_ib, list); 73 if (nib->fence) {
72 if (nib->fence == NULL) {
73 /* we go do nothings here */
74 mutex_unlock(&rdev->ib_pool.mutex); 74 mutex_unlock(&rdev->ib_pool.mutex);
75 DRM_ERROR("IB %lu scheduled without a fence.\n", nib->idx); 75 r = radeon_fence_wait(nib->fence, false);
76 r = -EINVAL; 76 if (r) {
77 goto out; 77 dev_err(rdev->dev, "error waiting fence of IB(%u:0x%016lX:%u)\n",
78 } 78 nib->idx, (unsigned long)nib->gpu_addr, nib->length_dw);
79 mutex_unlock(&rdev->ib_pool.mutex); 79 mutex_lock(&rdev->ib_pool.mutex);
80 80 nib->free = true;
81 r = radeon_fence_wait(nib->fence, false); 81 mutex_unlock(&rdev->ib_pool.mutex);
82 if (r) { 82 radeon_fence_unref(&fence);
83 DRM_ERROR("radeon: IB(%lu:0x%016lX:%u)\n", nib->idx, 83 return r;
84 (unsigned long)nib->gpu_addr, nib->length_dw); 84 }
85 DRM_ERROR("radeon: GPU lockup detected, fail to get a IB\n"); 85 mutex_lock(&rdev->ib_pool.mutex);
86 goto out;
87 } 86 }
88 radeon_fence_unref(&nib->fence); 87 radeon_fence_unref(&nib->fence);
89 88 nib->fence = fence;
90 nib->length_dw = 0; 89 nib->length_dw = 0;
91
92 /* scheduled list is accessed here */
93 mutex_lock(&rdev->ib_pool.mutex);
94 list_del(&nib->list);
95 INIT_LIST_HEAD(&nib->list);
96 mutex_unlock(&rdev->ib_pool.mutex); 90 mutex_unlock(&rdev->ib_pool.mutex);
97
98 *ib = nib; 91 *ib = nib;
99out: 92 return 0;
100 if (r) {
101 radeon_fence_unref(&fence);
102 } else {
103 (*ib)->fence = fence;
104 }
105 return r;
106} 93}
107 94
108void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib) 95void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
@@ -113,19 +100,10 @@ void radeon_ib_free(struct radeon_device *rdev, struct radeon_ib **ib)
113 if (tmp == NULL) { 100 if (tmp == NULL) {
114 return; 101 return;
115 } 102 }
116 mutex_lock(&rdev->ib_pool.mutex); 103 if (!tmp->fence->emited)
117 if (!list_empty(&tmp->list) && !radeon_fence_signaled(tmp->fence)) {
118 /* IB is scheduled & not signaled don't do anythings */
119 mutex_unlock(&rdev->ib_pool.mutex);
120 return;
121 }
122 list_del(&tmp->list);
123 INIT_LIST_HEAD(&tmp->list);
124 if (tmp->fence)
125 radeon_fence_unref(&tmp->fence); 104 radeon_fence_unref(&tmp->fence);
126 105 mutex_lock(&rdev->ib_pool.mutex);
127 tmp->length_dw = 0; 106 tmp->free = true;
128 clear_bit(tmp->idx, rdev->ib_pool.alloc_bm);
129 mutex_unlock(&rdev->ib_pool.mutex); 107 mutex_unlock(&rdev->ib_pool.mutex);
130} 108}
131 109
@@ -135,7 +113,7 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
135 113
136 if (!ib->length_dw || !rdev->cp.ready) { 114 if (!ib->length_dw || !rdev->cp.ready) {
137 /* TODO: Nothings in the ib we should report. */ 115 /* TODO: Nothings in the ib we should report. */
138 DRM_ERROR("radeon: couldn't schedule IB(%lu).\n", ib->idx); 116 DRM_ERROR("radeon: couldn't schedule IB(%u).\n", ib->idx);
139 return -EINVAL; 117 return -EINVAL;
140 } 118 }
141 119
@@ -148,7 +126,8 @@ int radeon_ib_schedule(struct radeon_device *rdev, struct radeon_ib *ib)
148 radeon_ring_ib_execute(rdev, ib); 126 radeon_ring_ib_execute(rdev, ib);
149 radeon_fence_emit(rdev, ib->fence); 127 radeon_fence_emit(rdev, ib->fence);
150 mutex_lock(&rdev->ib_pool.mutex); 128 mutex_lock(&rdev->ib_pool.mutex);
151 list_add_tail(&ib->list, &rdev->ib_pool.scheduled_ibs); 129 /* once scheduled IB is considered free and protected by the fence */
130 ib->free = true;
152 mutex_unlock(&rdev->ib_pool.mutex); 131 mutex_unlock(&rdev->ib_pool.mutex);
153 radeon_ring_unlock_commit(rdev); 132 radeon_ring_unlock_commit(rdev);
154 return 0; 133 return 0;
@@ -164,7 +143,6 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
164 if (rdev->ib_pool.robj) 143 if (rdev->ib_pool.robj)
165 return 0; 144 return 0;
166 /* Allocate 1M object buffer */ 145 /* Allocate 1M object buffer */
167 INIT_LIST_HEAD(&rdev->ib_pool.scheduled_ibs);
168 r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, 146 r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024,
169 true, RADEON_GEM_DOMAIN_GTT, 147 true, RADEON_GEM_DOMAIN_GTT,
170 &rdev->ib_pool.robj); 148 &rdev->ib_pool.robj);
@@ -195,9 +173,9 @@ int radeon_ib_pool_init(struct radeon_device *rdev)
195 rdev->ib_pool.ibs[i].ptr = ptr + offset; 173 rdev->ib_pool.ibs[i].ptr = ptr + offset;
196 rdev->ib_pool.ibs[i].idx = i; 174 rdev->ib_pool.ibs[i].idx = i;
197 rdev->ib_pool.ibs[i].length_dw = 0; 175 rdev->ib_pool.ibs[i].length_dw = 0;
198 INIT_LIST_HEAD(&rdev->ib_pool.ibs[i].list); 176 rdev->ib_pool.ibs[i].free = true;
199 } 177 }
200 bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE); 178 rdev->ib_pool.head_id = 0;
201 rdev->ib_pool.ready = true; 179 rdev->ib_pool.ready = true;
202 DRM_INFO("radeon: ib pool ready.\n"); 180 DRM_INFO("radeon: ib pool ready.\n");
203 if (radeon_debugfs_ib_init(rdev)) { 181 if (radeon_debugfs_ib_init(rdev)) {
@@ -214,7 +192,6 @@ void radeon_ib_pool_fini(struct radeon_device *rdev)
214 return; 192 return;
215 } 193 }
216 mutex_lock(&rdev->ib_pool.mutex); 194 mutex_lock(&rdev->ib_pool.mutex);
217 bitmap_zero(rdev->ib_pool.alloc_bm, RADEON_IB_POOL_SIZE);
218 if (rdev->ib_pool.robj) { 195 if (rdev->ib_pool.robj) {
219 r = radeon_bo_reserve(rdev->ib_pool.robj, false); 196 r = radeon_bo_reserve(rdev->ib_pool.robj, false);
220 if (likely(r == 0)) { 197 if (likely(r == 0)) {
@@ -363,7 +340,7 @@ static int radeon_debugfs_ib_info(struct seq_file *m, void *data)
363 if (ib == NULL) { 340 if (ib == NULL) {
364 return 0; 341 return 0;
365 } 342 }
366 seq_printf(m, "IB %04lu\n", ib->idx); 343 seq_printf(m, "IB %04u\n", ib->idx);
367 seq_printf(m, "IB fence %p\n", ib->fence); 344 seq_printf(m, "IB fence %p\n", ib->fence);
368 seq_printf(m, "IB size %05u dwords\n", ib->length_dw); 345 seq_printf(m, "IB size %05u dwords\n", ib->length_dw);
369 for (i = 0; i < ib->length_dw; i++) { 346 for (i = 0; i < ib->length_dw; i++) {
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index 5943d561fd1e..03021674d097 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -549,9 +549,12 @@ static void rv770_gpu_init(struct radeon_device *rdev)
549 549
550 gb_tiling_config |= BANK_SWAPS(1); 550 gb_tiling_config |= BANK_SWAPS(1);
551 551
552 backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes, 552 if (rdev->family == CHIP_RV740)
553 rdev->config.rv770.max_backends, 553 backend_map = 0x28;
554 (0xff << rdev->config.rv770.max_backends) & 0xff); 554 else
555 backend_map = r700_get_tile_pipe_to_backend_map(rdev->config.rv770.max_tile_pipes,
556 rdev->config.rv770.max_backends,
557 (0xff << rdev->config.rv770.max_backends) & 0xff);
555 gb_tiling_config |= BACKEND_MAP(backend_map); 558 gb_tiling_config |= BACKEND_MAP(backend_map);
556 559
557 cc_gc_shader_pipe_config = 560 cc_gc_shader_pipe_config =
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index 1a3e909b7bba..c7320ce4567d 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1020,6 +1020,12 @@ static int ttm_bo_mem_compat(struct ttm_placement *placement,
1020 struct ttm_mem_reg *mem) 1020 struct ttm_mem_reg *mem)
1021{ 1021{
1022 int i; 1022 int i;
1023 struct drm_mm_node *node = mem->mm_node;
1024
1025 if (node && placement->lpfn != 0 &&
1026 (node->start < placement->fpfn ||
1027 node->start + node->size > placement->lpfn))
1028 return -1;
1023 1029
1024 for (i = 0; i < placement->num_placement; i++) { 1030 for (i = 0; i < placement->num_placement; i++) {
1025 if ((placement->placement[i] & mem->placement & 1031 if ((placement->placement[i] & mem->placement &
diff --git a/drivers/gpu/drm/ttm/ttm_tt.c b/drivers/gpu/drm/ttm/ttm_tt.c
index e2123af7775a..3d47a2c12322 100644
--- a/drivers/gpu/drm/ttm/ttm_tt.c
+++ b/drivers/gpu/drm/ttm/ttm_tt.c
@@ -196,14 +196,15 @@ EXPORT_SYMBOL(ttm_tt_populate);
196 196
197#ifdef CONFIG_X86 197#ifdef CONFIG_X86
198static inline int ttm_tt_set_page_caching(struct page *p, 198static inline int ttm_tt_set_page_caching(struct page *p,
199 enum ttm_caching_state c_state) 199 enum ttm_caching_state c_old,
200 enum ttm_caching_state c_new)
200{ 201{
201 int ret = 0; 202 int ret = 0;
202 203
203 if (PageHighMem(p)) 204 if (PageHighMem(p))
204 return 0; 205 return 0;
205 206
206 if (get_page_memtype(p) != -1) { 207 if (c_old != tt_cached) {
207 /* p isn't in the default caching state, set it to 208 /* p isn't in the default caching state, set it to
208 * writeback first to free its current memtype. */ 209 * writeback first to free its current memtype. */
209 210
@@ -212,16 +213,17 @@ static inline int ttm_tt_set_page_caching(struct page *p,
212 return ret; 213 return ret;
213 } 214 }
214 215
215 if (c_state == tt_wc) 216 if (c_new == tt_wc)
216 ret = set_memory_wc((unsigned long) page_address(p), 1); 217 ret = set_memory_wc((unsigned long) page_address(p), 1);
217 else if (c_state == tt_uncached) 218 else if (c_new == tt_uncached)
218 ret = set_pages_uc(p, 1); 219 ret = set_pages_uc(p, 1);
219 220
220 return ret; 221 return ret;
221} 222}
222#else /* CONFIG_X86 */ 223#else /* CONFIG_X86 */
223static inline int ttm_tt_set_page_caching(struct page *p, 224static inline int ttm_tt_set_page_caching(struct page *p,
224 enum ttm_caching_state c_state) 225 enum ttm_caching_state c_old,
226 enum ttm_caching_state c_new)
225{ 227{
226 return 0; 228 return 0;
227} 229}
@@ -254,7 +256,9 @@ static int ttm_tt_set_caching(struct ttm_tt *ttm,
254 for (i = 0; i < ttm->num_pages; ++i) { 256 for (i = 0; i < ttm->num_pages; ++i) {
255 cur_page = ttm->pages[i]; 257 cur_page = ttm->pages[i];
256 if (likely(cur_page != NULL)) { 258 if (likely(cur_page != NULL)) {
257 ret = ttm_tt_set_page_caching(cur_page, c_state); 259 ret = ttm_tt_set_page_caching(cur_page,
260 ttm->caching_state,
261 c_state);
258 if (unlikely(ret != 0)) 262 if (unlikely(ret != 0))
259 goto out_err; 263 goto out_err;
260 } 264 }
@@ -268,7 +272,7 @@ out_err:
268 for (j = 0; j < i; ++j) { 272 for (j = 0; j < i; ++j) {
269 cur_page = ttm->pages[j]; 273 cur_page = ttm->pages[j];
270 if (likely(cur_page != NULL)) { 274 if (likely(cur_page != NULL)) {
271 (void)ttm_tt_set_page_caching(cur_page, 275 (void)ttm_tt_set_page_caching(cur_page, c_state,
272 ttm->caching_state); 276 ttm->caching_state);
273 } 277 }
274 } 278 }
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
index a6e8f687fa64..0c9c0811f42d 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
@@ -348,22 +348,19 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
348 */ 348 */
349 349
350 DRM_INFO("It appears like vesafb is loaded. " 350 DRM_INFO("It appears like vesafb is loaded. "
351 "Ignore above error if any. Entering stealth mode.\n"); 351 "Ignore above error if any.\n");
352 ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); 352 ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe");
353 if (unlikely(ret != 0)) { 353 if (unlikely(ret != 0)) {
354 DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); 354 DRM_ERROR("Failed reserving the SVGA MMIO resource.\n");
355 goto out_no_device; 355 goto out_no_device;
356 } 356 }
357 vmw_kms_init(dev_priv);
358 vmw_overlay_init(dev_priv);
359 } else {
360 ret = vmw_request_device(dev_priv);
361 if (unlikely(ret != 0))
362 goto out_no_device;
363 vmw_kms_init(dev_priv);
364 vmw_overlay_init(dev_priv);
365 vmw_fb_init(dev_priv);
366 } 357 }
358 ret = vmw_request_device(dev_priv);
359 if (unlikely(ret != 0))
360 goto out_no_device;
361 vmw_kms_init(dev_priv);
362 vmw_overlay_init(dev_priv);
363 vmw_fb_init(dev_priv);
367 364
368 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; 365 dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier;
369 register_pm_notifier(&dev_priv->pm_nb); 366 register_pm_notifier(&dev_priv->pm_nb);
@@ -406,17 +403,15 @@ static int vmw_driver_unload(struct drm_device *dev)
406 403
407 unregister_pm_notifier(&dev_priv->pm_nb); 404 unregister_pm_notifier(&dev_priv->pm_nb);
408 405
409 if (!dev_priv->stealth) { 406 vmw_fb_close(dev_priv);
410 vmw_fb_close(dev_priv); 407 vmw_kms_close(dev_priv);
411 vmw_kms_close(dev_priv); 408 vmw_overlay_close(dev_priv);
412 vmw_overlay_close(dev_priv); 409 vmw_release_device(dev_priv);
413 vmw_release_device(dev_priv); 410 if (dev_priv->stealth)
414 pci_release_regions(dev->pdev);
415 } else {
416 vmw_kms_close(dev_priv);
417 vmw_overlay_close(dev_priv);
418 pci_release_region(dev->pdev, 2); 411 pci_release_region(dev->pdev, 2);
419 } 412 else
413 pci_release_regions(dev->pdev);
414
420 if (dev_priv->capabilities & SVGA_CAP_IRQMASK) 415 if (dev_priv->capabilities & SVGA_CAP_IRQMASK)
421 drm_irq_uninstall(dev_priv->dev); 416 drm_irq_uninstall(dev_priv->dev);
422 if (dev->devname == vmw_devname) 417 if (dev->devname == vmw_devname)
@@ -585,11 +580,6 @@ static int vmw_master_set(struct drm_device *dev,
585 int ret = 0; 580 int ret = 0;
586 581
587 DRM_INFO("Master set.\n"); 582 DRM_INFO("Master set.\n");
588 if (dev_priv->stealth) {
589 ret = vmw_request_device(dev_priv);
590 if (unlikely(ret != 0))
591 return ret;
592 }
593 583
594 if (active) { 584 if (active) {
595 BUG_ON(active != &dev_priv->fbdev_master); 585 BUG_ON(active != &dev_priv->fbdev_master);
@@ -649,18 +639,11 @@ static void vmw_master_drop(struct drm_device *dev,
649 639
650 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); 640 ttm_lock_set_kill(&vmaster->lock, true, SIGTERM);
651 641
652 if (dev_priv->stealth) {
653 ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM);
654 if (unlikely(ret != 0))
655 DRM_ERROR("Unable to clean VRAM on master drop.\n");
656 vmw_release_device(dev_priv);
657 }
658 dev_priv->active_master = &dev_priv->fbdev_master; 642 dev_priv->active_master = &dev_priv->fbdev_master;
659 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); 643 ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM);
660 ttm_vt_unlock(&dev_priv->fbdev_master.lock); 644 ttm_vt_unlock(&dev_priv->fbdev_master.lock);
661 645
662 if (!dev_priv->stealth) 646 vmw_fb_on(dev_priv);
663 vmw_fb_on(dev_priv);
664} 647}
665 648
666 649
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
index d69caf92ffe7..0897359b3e4e 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
@@ -182,25 +182,19 @@ static int vmw_cmd_present_check(struct vmw_private *dev_priv,
182 return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid); 182 return vmw_cmd_sid_check(dev_priv, sw_context, &cmd->body.sid);
183} 183}
184 184
185static int vmw_cmd_dma(struct vmw_private *dev_priv, 185static int vmw_translate_guest_ptr(struct vmw_private *dev_priv,
186 struct vmw_sw_context *sw_context, 186 struct vmw_sw_context *sw_context,
187 SVGA3dCmdHeader *header) 187 SVGAGuestPtr *ptr,
188 struct vmw_dma_buffer **vmw_bo_p)
188{ 189{
189 uint32_t handle;
190 struct vmw_dma_buffer *vmw_bo = NULL; 190 struct vmw_dma_buffer *vmw_bo = NULL;
191 struct ttm_buffer_object *bo; 191 struct ttm_buffer_object *bo;
192 struct vmw_surface *srf = NULL; 192 uint32_t handle = ptr->gmrId;
193 struct vmw_dma_cmd {
194 SVGA3dCmdHeader header;
195 SVGA3dCmdSurfaceDMA dma;
196 } *cmd;
197 struct vmw_relocation *reloc; 193 struct vmw_relocation *reloc;
198 int ret;
199 uint32_t cur_validate_node; 194 uint32_t cur_validate_node;
200 struct ttm_validate_buffer *val_buf; 195 struct ttm_validate_buffer *val_buf;
196 int ret;
201 197
202 cmd = container_of(header, struct vmw_dma_cmd, header);
203 handle = cmd->dma.guest.ptr.gmrId;
204 ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo); 198 ret = vmw_user_dmabuf_lookup(sw_context->tfile, handle, &vmw_bo);
205 if (unlikely(ret != 0)) { 199 if (unlikely(ret != 0)) {
206 DRM_ERROR("Could not find or use GMR region.\n"); 200 DRM_ERROR("Could not find or use GMR region.\n");
@@ -209,14 +203,14 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
209 bo = &vmw_bo->base; 203 bo = &vmw_bo->base;
210 204
211 if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) { 205 if (unlikely(sw_context->cur_reloc >= VMWGFX_MAX_RELOCATIONS)) {
212 DRM_ERROR("Max number of DMA commands per submission" 206 DRM_ERROR("Max number relocations per submission"
213 " exceeded\n"); 207 " exceeded\n");
214 ret = -EINVAL; 208 ret = -EINVAL;
215 goto out_no_reloc; 209 goto out_no_reloc;
216 } 210 }
217 211
218 reloc = &sw_context->relocs[sw_context->cur_reloc++]; 212 reloc = &sw_context->relocs[sw_context->cur_reloc++];
219 reloc->location = &cmd->dma.guest.ptr; 213 reloc->location = ptr;
220 214
221 cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf); 215 cur_validate_node = vmw_dmabuf_validate_node(bo, sw_context->cur_val_buf);
222 if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) { 216 if (unlikely(cur_validate_node >= VMWGFX_MAX_GMRS)) {
@@ -234,7 +228,89 @@ static int vmw_cmd_dma(struct vmw_private *dev_priv,
234 list_add_tail(&val_buf->head, &sw_context->validate_nodes); 228 list_add_tail(&val_buf->head, &sw_context->validate_nodes);
235 ++sw_context->cur_val_buf; 229 ++sw_context->cur_val_buf;
236 } 230 }
231 *vmw_bo_p = vmw_bo;
232 return 0;
233
234out_no_reloc:
235 vmw_dmabuf_unreference(&vmw_bo);
236 vmw_bo_p = NULL;
237 return ret;
238}
239
240static int vmw_cmd_end_query(struct vmw_private *dev_priv,
241 struct vmw_sw_context *sw_context,
242 SVGA3dCmdHeader *header)
243{
244 struct vmw_dma_buffer *vmw_bo;
245 struct vmw_query_cmd {
246 SVGA3dCmdHeader header;
247 SVGA3dCmdEndQuery q;
248 } *cmd;
249 int ret;
250
251 cmd = container_of(header, struct vmw_query_cmd, header);
252 ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
253 if (unlikely(ret != 0))
254 return ret;
255
256 ret = vmw_translate_guest_ptr(dev_priv, sw_context,
257 &cmd->q.guestResult,
258 &vmw_bo);
259 if (unlikely(ret != 0))
260 return ret;
261
262 vmw_dmabuf_unreference(&vmw_bo);
263 return 0;
264}
237 265
266static int vmw_cmd_wait_query(struct vmw_private *dev_priv,
267 struct vmw_sw_context *sw_context,
268 SVGA3dCmdHeader *header)
269{
270 struct vmw_dma_buffer *vmw_bo;
271 struct vmw_query_cmd {
272 SVGA3dCmdHeader header;
273 SVGA3dCmdWaitForQuery q;
274 } *cmd;
275 int ret;
276
277 cmd = container_of(header, struct vmw_query_cmd, header);
278 ret = vmw_cmd_cid_check(dev_priv, sw_context, header);
279 if (unlikely(ret != 0))
280 return ret;
281
282 ret = vmw_translate_guest_ptr(dev_priv, sw_context,
283 &cmd->q.guestResult,
284 &vmw_bo);
285 if (unlikely(ret != 0))
286 return ret;
287
288 vmw_dmabuf_unreference(&vmw_bo);
289 return 0;
290}
291
292
293static int vmw_cmd_dma(struct vmw_private *dev_priv,
294 struct vmw_sw_context *sw_context,
295 SVGA3dCmdHeader *header)
296{
297 struct vmw_dma_buffer *vmw_bo = NULL;
298 struct ttm_buffer_object *bo;
299 struct vmw_surface *srf = NULL;
300 struct vmw_dma_cmd {
301 SVGA3dCmdHeader header;
302 SVGA3dCmdSurfaceDMA dma;
303 } *cmd;
304 int ret;
305
306 cmd = container_of(header, struct vmw_dma_cmd, header);
307 ret = vmw_translate_guest_ptr(dev_priv, sw_context,
308 &cmd->dma.guest.ptr,
309 &vmw_bo);
310 if (unlikely(ret != 0))
311 return ret;
312
313 bo = &vmw_bo->base;
238 ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile, 314 ret = vmw_user_surface_lookup_handle(dev_priv, sw_context->tfile,
239 cmd->dma.host.sid, &srf); 315 cmd->dma.host.sid, &srf);
240 if (ret) { 316 if (ret) {
@@ -379,8 +455,8 @@ static vmw_cmd_func vmw_cmd_funcs[SVGA_3D_CMD_MAX] = {
379 VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw), 455 VMW_CMD_DEF(SVGA_3D_CMD_DRAW_PRIMITIVES, &vmw_cmd_draw),
380 VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check), 456 VMW_CMD_DEF(SVGA_3D_CMD_SETSCISSORRECT, &vmw_cmd_cid_check),
381 VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check), 457 VMW_CMD_DEF(SVGA_3D_CMD_BEGIN_QUERY, &vmw_cmd_cid_check),
382 VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_cid_check), 458 VMW_CMD_DEF(SVGA_3D_CMD_END_QUERY, &vmw_cmd_end_query),
383 VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_cid_check), 459 VMW_CMD_DEF(SVGA_3D_CMD_WAIT_FOR_QUERY, &vmw_cmd_wait_query),
384 VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok), 460 VMW_CMD_DEF(SVGA_3D_CMD_PRESENT_READBACK, &vmw_cmd_ok),
385 VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN, 461 VMW_CMD_DEF(SVGA_3D_CMD_BLIT_SURFACE_TO_SCREEN,
386 &vmw_cmd_blt_surf_screen_check) 462 &vmw_cmd_blt_surf_screen_check)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
index 4f4f6432be8b..a93367041cdc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
@@ -559,6 +559,9 @@ int vmw_fb_init(struct vmw_private *vmw_priv)
559 info->pixmap.scan_align = 1; 559 info->pixmap.scan_align = 1;
560#endif 560#endif
561 561
562 info->aperture_base = vmw_priv->vram_start;
563 info->aperture_size = vmw_priv->vram_size;
564
562 /* 565 /*
563 * Dirty & Deferred IO 566 * Dirty & Deferred IO
564 */ 567 */
diff --git a/drivers/gpu/vga/vgaarb.c b/drivers/gpu/vga/vgaarb.c
index 24b56dc54597..2f6cf69ecb39 100644
--- a/drivers/gpu/vga/vgaarb.c
+++ b/drivers/gpu/vga/vgaarb.c
@@ -961,7 +961,7 @@ static ssize_t vga_arb_write(struct file *file, const char __user * buf,
961 remaining -= 7; 961 remaining -= 7;
962 pr_devel("client 0x%p called 'target'\n", priv); 962 pr_devel("client 0x%p called 'target'\n", priv);
963 /* if target is default */ 963 /* if target is default */
964 if (!strncmp(kbuf, "default", 7)) 964 if (!strncmp(curr_pos, "default", 7))
965 pdev = pci_dev_get(vga_default_device()); 965 pdev = pci_dev_get(vga_default_device());
966 else { 966 else {
967 if (!vga_pci_str_to_vars(curr_pos, remaining, 967 if (!vga_pci_str_to_vars(curr_pos, remaining,
diff --git a/drivers/input/input-polldev.c b/drivers/input/input-polldev.c
index aa6713b4a988..291d9393d359 100644
--- a/drivers/input/input-polldev.c
+++ b/drivers/input/input-polldev.c
@@ -100,6 +100,12 @@ static void input_close_polled_device(struct input_dev *input)
100 struct input_polled_dev *dev = input_get_drvdata(input); 100 struct input_polled_dev *dev = input_get_drvdata(input);
101 101
102 cancel_delayed_work_sync(&dev->work); 102 cancel_delayed_work_sync(&dev->work);
103 /*
104 * Clean up work struct to remove references to the workqueue.
105 * It may be destroyed by the next call. This causes problems
106 * at next device open-close in case of poll_interval == 0.
107 */
108 INIT_DELAYED_WORK(&dev->work, dev->work.work.func);
103 input_polldev_stop_workqueue(); 109 input_polldev_stop_workqueue();
104 110
105 if (dev->close) 111 if (dev->close)
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
index d84a36e545f6..b54aee7cd9e3 100644
--- a/drivers/input/serio/i8042.c
+++ b/drivers/input/serio/i8042.c
@@ -1161,9 +1161,17 @@ static int i8042_pm_restore(struct device *dev)
1161 return 0; 1161 return 0;
1162} 1162}
1163 1163
1164static int i8042_pm_thaw(struct device *dev)
1165{
1166 i8042_interrupt(0, NULL);
1167
1168 return 0;
1169}
1170
1164static const struct dev_pm_ops i8042_pm_ops = { 1171static const struct dev_pm_ops i8042_pm_ops = {
1165 .suspend = i8042_pm_reset, 1172 .suspend = i8042_pm_reset,
1166 .resume = i8042_pm_restore, 1173 .resume = i8042_pm_restore,
1174 .thaw = i8042_pm_thaw,
1167 .poweroff = i8042_pm_reset, 1175 .poweroff = i8042_pm_reset,
1168 .restore = i8042_pm_restore, 1176 .restore = i8042_pm_restore,
1169}; 1177};
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 09a5e7341bd5..5256123a5228 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -618,8 +618,8 @@ static int idealtek_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
618#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 618#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
619static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) 619static int general_touch_read_data(struct usbtouch_usb *dev, unsigned char *pkt)
620{ 620{
621 dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1] ; 621 dev->x = (pkt[2] << 8) | pkt[1];
622 dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3] ; 622 dev->y = (pkt[4] << 8) | pkt[3];
623 dev->press = pkt[5] & 0xff; 623 dev->press = pkt[5] & 0xff;
624 dev->touch = pkt[0] & 0x01; 624 dev->touch = pkt[0] & 0x01;
625 625
@@ -809,9 +809,9 @@ static struct usbtouch_device_info usbtouch_dev_info[] = {
809#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH 809#ifdef CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH
810 [DEVTYPE_GENERAL_TOUCH] = { 810 [DEVTYPE_GENERAL_TOUCH] = {
811 .min_xc = 0x0, 811 .min_xc = 0x0,
812 .max_xc = 0x0500, 812 .max_xc = 0x7fff,
813 .min_yc = 0x0, 813 .min_yc = 0x0,
814 .max_yc = 0x0500, 814 .max_yc = 0x7fff,
815 .rept_size = 7, 815 .rept_size = 7,
816 .read_data = general_touch_read_data, 816 .read_data = general_touch_read_data,
817 }, 817 },
diff --git a/drivers/md/dm-log-userspace-transfer.c b/drivers/md/dm-log-userspace-transfer.c
index 54abf9e303b7..f1c8cae70b4b 100644
--- a/drivers/md/dm-log-userspace-transfer.c
+++ b/drivers/md/dm-log-userspace-transfer.c
@@ -172,11 +172,15 @@ int dm_consult_userspace(const char *uuid, uint64_t luid, int request_type,
172{ 172{
173 int r = 0; 173 int r = 0;
174 size_t dummy = 0; 174 size_t dummy = 0;
175 int overhead_size = 175 int overhead_size = sizeof(struct dm_ulog_request) + sizeof(struct cn_msg);
176 sizeof(struct dm_ulog_request *) + sizeof(struct cn_msg);
177 struct dm_ulog_request *tfr = prealloced_ulog_tfr; 176 struct dm_ulog_request *tfr = prealloced_ulog_tfr;
178 struct receiving_pkg pkg; 177 struct receiving_pkg pkg;
179 178
179 /*
180 * Given the space needed to hold the 'struct cn_msg' and
181 * 'struct dm_ulog_request' - do we have enough payload
182 * space remaining?
183 */
180 if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) { 184 if (data_size > (DM_ULOG_PREALLOCED_SIZE - overhead_size)) {
181 DMINFO("Size of tfr exceeds preallocated size"); 185 DMINFO("Size of tfr exceeds preallocated size");
182 return -EINVAL; 186 return -EINVAL;
@@ -191,7 +195,7 @@ resend:
191 */ 195 */
192 mutex_lock(&dm_ulog_lock); 196 mutex_lock(&dm_ulog_lock);
193 197
194 memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - overhead_size); 198 memset(tfr, 0, DM_ULOG_PREALLOCED_SIZE - sizeof(struct cn_msg));
195 memcpy(tfr->uuid, uuid, DM_UUID_LEN); 199 memcpy(tfr->uuid, uuid, DM_UUID_LEN);
196 tfr->luid = luid; 200 tfr->luid = luid;
197 tfr->seq = dm_ulog_seq++; 201 tfr->seq = dm_ulog_seq++;
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index ad779bd13aec..6c1046df81f6 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -724,7 +724,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
724 /* 724 /*
725 * Dispatch io. 725 * Dispatch io.
726 */ 726 */
727 if (unlikely(ms->log_failure)) { 727 if (unlikely(ms->log_failure) && errors_handled(ms)) {
728 spin_lock_irq(&ms->lock); 728 spin_lock_irq(&ms->lock);
729 bio_list_merge(&ms->failures, &sync); 729 bio_list_merge(&ms->failures, &sync);
730 spin_unlock_irq(&ms->lock); 730 spin_unlock_irq(&ms->lock);
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index 5f19ceb6fe91..168bd38f5006 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -660,10 +660,9 @@ void dm_rh_recovery_end(struct dm_region *reg, int success)
660 spin_lock_irq(&rh->region_lock); 660 spin_lock_irq(&rh->region_lock);
661 if (success) 661 if (success)
662 list_add(&reg->list, &reg->rh->recovered_regions); 662 list_add(&reg->list, &reg->rh->recovered_regions);
663 else { 663 else
664 reg->state = DM_RH_NOSYNC;
665 list_add(&reg->list, &reg->rh->failed_recovered_regions); 664 list_add(&reg->list, &reg->rh->failed_recovered_regions);
666 } 665
667 spin_unlock_irq(&rh->region_lock); 666 spin_unlock_irq(&rh->region_lock);
668 667
669 rh->wakeup_workers(rh->context); 668 rh->wakeup_workers(rh->context);
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 7d08879689ac..c097d8a4823d 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -254,7 +254,7 @@ static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, int rw,
254 * Issue the synchronous I/O from a different thread 254 * Issue the synchronous I/O from a different thread
255 * to avoid generic_make_request recursion. 255 * to avoid generic_make_request recursion.
256 */ 256 */
257 INIT_WORK(&req.work, do_metadata); 257 INIT_WORK_ON_STACK(&req.work, do_metadata);
258 queue_work(ps->metadata_wq, &req.work); 258 queue_work(ps->metadata_wq, &req.work);
259 flush_workqueue(ps->metadata_wq); 259 flush_workqueue(ps->metadata_wq);
260 260
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index e0efc1adcaff..bd58703ee8f6 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -110,7 +110,7 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
110 } 110 }
111 111
112 stripes = simple_strtoul(argv[0], &end, 10); 112 stripes = simple_strtoul(argv[0], &end, 10);
113 if (*end) { 113 if (!stripes || *end) {
114 ti->error = "Invalid stripe count"; 114 ti->error = "Invalid stripe count";
115 return -EINVAL; 115 return -EINVAL;
116 } 116 }
diff --git a/drivers/md/dm-sysfs.c b/drivers/md/dm-sysfs.c
index f53392df7b97..f91b40942e07 100644
--- a/drivers/md/dm-sysfs.c
+++ b/drivers/md/dm-sysfs.c
@@ -80,20 +80,12 @@ static struct sysfs_ops dm_sysfs_ops = {
80}; 80};
81 81
82/* 82/*
83 * The sysfs structure is embedded in md struct, nothing to do here
84 */
85static void dm_sysfs_release(struct kobject *kobj)
86{
87}
88
89/*
90 * dm kobject is embedded in mapped_device structure 83 * dm kobject is embedded in mapped_device structure
91 * no need to define release function here 84 * no need to define release function here
92 */ 85 */
93static struct kobj_type dm_ktype = { 86static struct kobj_type dm_ktype = {
94 .sysfs_ops = &dm_sysfs_ops, 87 .sysfs_ops = &dm_sysfs_ops,
95 .default_attrs = dm_attrs, 88 .default_attrs = dm_attrs,
96 .release = dm_sysfs_release
97}; 89};
98 90
99/* 91/*
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 3167480b532c..aa4e2aa86d49 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1595,10 +1595,15 @@ static int dm_prep_fn(struct request_queue *q, struct request *rq)
1595 return BLKPREP_OK; 1595 return BLKPREP_OK;
1596} 1596}
1597 1597
1598static void map_request(struct dm_target *ti, struct request *clone, 1598/*
1599 struct mapped_device *md) 1599 * Returns:
1600 * 0 : the request has been processed (not requeued)
1601 * !0 : the request has been requeued
1602 */
1603static int map_request(struct dm_target *ti, struct request *clone,
1604 struct mapped_device *md)
1600{ 1605{
1601 int r; 1606 int r, requeued = 0;
1602 struct dm_rq_target_io *tio = clone->end_io_data; 1607 struct dm_rq_target_io *tio = clone->end_io_data;
1603 1608
1604 /* 1609 /*
@@ -1625,6 +1630,7 @@ static void map_request(struct dm_target *ti, struct request *clone,
1625 case DM_MAPIO_REQUEUE: 1630 case DM_MAPIO_REQUEUE:
1626 /* The target wants to requeue the I/O */ 1631 /* The target wants to requeue the I/O */
1627 dm_requeue_unmapped_request(clone); 1632 dm_requeue_unmapped_request(clone);
1633 requeued = 1;
1628 break; 1634 break;
1629 default: 1635 default:
1630 if (r > 0) { 1636 if (r > 0) {
@@ -1636,6 +1642,8 @@ static void map_request(struct dm_target *ti, struct request *clone,
1636 dm_kill_unmapped_request(clone, r); 1642 dm_kill_unmapped_request(clone, r);
1637 break; 1643 break;
1638 } 1644 }
1645
1646 return requeued;
1639} 1647}
1640 1648
1641/* 1649/*
@@ -1677,12 +1685,17 @@ static void dm_request_fn(struct request_queue *q)
1677 atomic_inc(&md->pending[rq_data_dir(clone)]); 1685 atomic_inc(&md->pending[rq_data_dir(clone)]);
1678 1686
1679 spin_unlock(q->queue_lock); 1687 spin_unlock(q->queue_lock);
1680 map_request(ti, clone, md); 1688 if (map_request(ti, clone, md))
1689 goto requeued;
1690
1681 spin_lock_irq(q->queue_lock); 1691 spin_lock_irq(q->queue_lock);
1682 } 1692 }
1683 1693
1684 goto out; 1694 goto out;
1685 1695
1696requeued:
1697 spin_lock_irq(q->queue_lock);
1698
1686plug_and_out: 1699plug_and_out:
1687 if (!elv_queue_empty(q)) 1700 if (!elv_queue_empty(q))
1688 /* Some requests still remain, retry later */ 1701 /* Some requests still remain, retry later */
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 1b249897c9fb..465295b1d14b 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -112,11 +112,13 @@ config DVB_USB_CXUSB
112 select DVB_MT352 if !DVB_FE_CUSTOMISE 112 select DVB_MT352 if !DVB_FE_CUSTOMISE
113 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 113 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
114 select DVB_DIB7000P if !DVB_FE_CUSTOMISE 114 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
115 select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE
116 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE 115 select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
116 select DVB_ATBM8830 if !DVB_FE_CUSTOMISE
117 select DVB_LGS8GXX if !DVB_FE_CUSTOMISE
117 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE 118 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
118 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE 119 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
119 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 120 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
121 select MEDIA_TUNER_MAX2165 if !MEDIA_TUNER_CUSTOMISE
120 help 122 help
121 Say Y here to support the Conexant USB2.0 hybrid reference design. 123 Say Y here to support the Conexant USB2.0 hybrid reference design.
122 Currently, only DVB and ATSC modes are supported, analog mode 124 Currently, only DVB and ATSC modes are supported, analog mode
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c
index 3051b64aa17c..445fa1068064 100644
--- a/drivers/media/dvb/frontends/l64781.c
+++ b/drivers/media/dvb/frontends/l64781.c
@@ -192,8 +192,8 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa
192 spi_bias *= qam_tab[p->constellation]; 192 spi_bias *= qam_tab[p->constellation];
193 spi_bias /= p->code_rate_HP + 1; 193 spi_bias /= p->code_rate_HP + 1;
194 spi_bias /= (guard_tab[p->guard_interval] + 32); 194 spi_bias /= (guard_tab[p->guard_interval] + 32);
195 spi_bias *= 1000ULL; 195 spi_bias *= 1000;
196 spi_bias /= 1000ULL + ppm/1000; 196 spi_bias /= 1000 + ppm/1000;
197 spi_bias *= p->code_rate_HP; 197 spi_bias *= p->code_rate_HP;
198 198
199 val0x04 = (p->transmission_mode << 2) | p->guard_interval; 199 val0x04 = (p->transmission_mode << 2) | p->guard_interval;
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index 3182a406bdd1..ae08b077fd04 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -4461,6 +4461,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
4461 request_modules(btv); 4461 request_modules(btv);
4462 } 4462 }
4463 4463
4464 init_bttv_i2c_ir(btv);
4464 bttv_input_init(btv); 4465 bttv_input_init(btv);
4465 4466
4466 /* everything is fine */ 4467 /* everything is fine */
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index 63aa31a041e8..407fa61e4cda 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -388,7 +388,12 @@ int __devinit init_bttv_i2c(struct bttv *btv)
388 if (0 == btv->i2c_rc && i2c_scan) 388 if (0 == btv->i2c_rc && i2c_scan)
389 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client); 389 do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
390 390
391 /* Instantiate the IR receiver device, if present */ 391 return btv->i2c_rc;
392}
393
394/* Instantiate the I2C IR receiver device, if present */
395void __devinit init_bttv_i2c_ir(struct bttv *btv)
396{
392 if (0 == btv->i2c_rc) { 397 if (0 == btv->i2c_rc) {
393 struct i2c_board_info info; 398 struct i2c_board_info info;
394 /* The external IR receiver is at i2c address 0x34 (0x35 for 399 /* The external IR receiver is at i2c address 0x34 (0x35 for
@@ -408,7 +413,6 @@ int __devinit init_bttv_i2c(struct bttv *btv)
408 strlcpy(info.type, "ir_video", I2C_NAME_SIZE); 413 strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
409 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list); 414 i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
410 } 415 }
411 return btv->i2c_rc;
412} 416}
413 417
414int __devexit fini_bttv_i2c(struct bttv *btv) 418int __devexit fini_bttv_i2c(struct bttv *btv)
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index a1d0e9c9f286..6cccc2a17eee 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -279,6 +279,7 @@ extern unsigned int bttv_debug;
279extern unsigned int bttv_gpio; 279extern unsigned int bttv_gpio;
280extern void bttv_gpio_tracking(struct bttv *btv, char *comment); 280extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
281extern int init_bttv_i2c(struct bttv *btv); 281extern int init_bttv_i2c(struct bttv *btv);
282extern void init_bttv_i2c_ir(struct bttv *btv);
282extern int fini_bttv_i2c(struct bttv *btv); 283extern int fini_bttv_i2c(struct bttv *btv);
283 284
284#define bttv_printk if (bttv_verbose) printk 285#define bttv_printk if (bttv_verbose) printk
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index fc4dd6045720..7438f8d775ba 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -514,7 +514,7 @@ static int mt9t112_init_pll(const struct i2c_client *client)
514 /* poll to verify out of standby. Must Poll this bit */ 514 /* poll to verify out of standby. Must Poll this bit */
515 for (i = 0; i < 100; i++) { 515 for (i = 0; i < 100; i++) {
516 mt9t112_reg_read(data, client, 0x0018); 516 mt9t112_reg_read(data, client, 0x0018);
517 if (0x4000 & data) 517 if (!(0x4000 & data))
518 break; 518 break;
519 519
520 mdelay(10); 520 mdelay(10);
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 50b415e07eda..f7f7e04cf485 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -753,7 +753,7 @@ int pwc_set_shutter_speed(struct pwc_device *pdev, int mode, int value)
753 buf[0] = 0xff; /* fixed */ 753 buf[0] = 0xff; /* fixed */
754 754
755 ret = send_control_msg(pdev, 755 ret = send_control_msg(pdev,
756 SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, sizeof(buf)); 756 SET_LUM_CTL, SHUTTER_MODE_FORMATTER, &buf, 1);
757 757
758 if (!mode && ret >= 0) { 758 if (!mode && ret >= 0) {
759 if (value < 0) 759 if (value < 0)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 2a7606534196..19a930d06241 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -115,7 +115,8 @@
115#define twl_has_watchdog() false 115#define twl_has_watchdog() false
116#endif 116#endif
117 117
118#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) 118#if defined(CONFIG_TWL4030_CODEC) || defined(CONFIG_TWL4030_CODEC_MODULE) ||\
119 defined(CONFIG_SND_SOC_TWL6030) || defined(CONFIG_SND_SOC_TWL6030_MODULE)
119#define twl_has_codec() true 120#define twl_has_codec() true
120#else 121#else
121#define twl_has_codec() false 122#define twl_has_codec() false
@@ -711,8 +712,19 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
711 return PTR_ERR(child); 712 return PTR_ERR(child);
712 } 713 }
713 714
714 if (twl_has_codec() && pdata->codec) { 715 if (twl_has_codec() && pdata->codec && twl_class_is_4030()) {
715 child = add_child(1, "twl4030_codec", 716 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
717 child = add_child(sub_chip_id, "twl4030_codec",
718 pdata->codec, sizeof(*pdata->codec),
719 false, 0, 0);
720 if (IS_ERR(child))
721 return PTR_ERR(child);
722 }
723
724 /* Phoenix*/
725 if (twl_has_codec() && pdata->codec && twl_class_is_6030()) {
726 sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
727 child = add_child(sub_chip_id, "twl6030_codec",
716 pdata->codec, sizeof(*pdata->codec), 728 pdata->codec, sizeof(*pdata->codec),
717 false, 0, 0); 729 false, 0, 0);
718 if (IS_ERR(child)) 730 if (IS_ERR(child))
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index fee6eee7ae5b..006cb2efcd22 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -296,6 +296,7 @@ static void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr,
296 req_hdr->opcode = opcode; 296 req_hdr->opcode = opcode;
297 req_hdr->subsystem = subsystem; 297 req_hdr->subsystem = subsystem;
298 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr)); 298 req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
299 req_hdr->version = 0;
299} 300}
300 301
301static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages, 302static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index d29bb532eccf..765543663a4f 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4006,11 +4006,21 @@ check_page:
4006 } 4006 }
4007 } 4007 }
4008 4008
4009 if (!buffer_info->dma) 4009 if (!buffer_info->dma) {
4010 buffer_info->dma = pci_map_page(pdev, 4010 buffer_info->dma = pci_map_page(pdev,
4011 buffer_info->page, 0, 4011 buffer_info->page, 0,
4012 buffer_info->length, 4012 buffer_info->length,
4013 PCI_DMA_FROMDEVICE); 4013 PCI_DMA_FROMDEVICE);
4014 if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
4015 put_page(buffer_info->page);
4016 dev_kfree_skb(skb);
4017 buffer_info->page = NULL;
4018 buffer_info->skb = NULL;
4019 buffer_info->dma = 0;
4020 adapter->alloc_rx_buff_failed++;
4021 break; /* while !buffer_info->skb */
4022 }
4023 }
4014 4024
4015 rx_desc = E1000_RX_DESC(*rx_ring, i); 4025 rx_desc = E1000_RX_DESC(*rx_ring, i);
4016 rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); 4026 rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
@@ -4101,6 +4111,13 @@ map_skb:
4101 skb->data, 4111 skb->data,
4102 buffer_info->length, 4112 buffer_info->length,
4103 PCI_DMA_FROMDEVICE); 4113 PCI_DMA_FROMDEVICE);
4114 if (pci_dma_mapping_error(pdev, buffer_info->dma)) {
4115 dev_kfree_skb(skb);
4116 buffer_info->skb = NULL;
4117 buffer_info->dma = 0;
4118 adapter->alloc_rx_buff_failed++;
4119 break; /* while !buffer_info->skb */
4120 }
4104 4121
4105 /* 4122 /*
4106 * XXX if it was allocated cleanly it will never map to a 4123 * XXX if it was allocated cleanly it will never map to a
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 3103f4165311..35a06b47587b 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -357,12 +357,34 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
357 u32 fctrl_reg; 357 u32 fctrl_reg;
358 u32 rmcs_reg; 358 u32 rmcs_reg;
359 u32 reg; 359 u32 reg;
360 u32 link_speed = 0;
361 bool link_up;
360 362
361#ifdef CONFIG_DCB 363#ifdef CONFIG_DCB
362 if (hw->fc.requested_mode == ixgbe_fc_pfc) 364 if (hw->fc.requested_mode == ixgbe_fc_pfc)
363 goto out; 365 goto out;
364 366
365#endif /* CONFIG_DCB */ 367#endif /* CONFIG_DCB */
368 /*
369 * On 82598 having Rx FC on causes resets while doing 1G
370 * so if it's on turn it off once we know link_speed. For
371 * more details see 82598 Specification update.
372 */
373 hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
374 if (link_up && link_speed == IXGBE_LINK_SPEED_1GB_FULL) {
375 switch (hw->fc.requested_mode) {
376 case ixgbe_fc_full:
377 hw->fc.requested_mode = ixgbe_fc_tx_pause;
378 break;
379 case ixgbe_fc_rx_pause:
380 hw->fc.requested_mode = ixgbe_fc_none;
381 break;
382 default:
383 /* no change */
384 break;
385 }
386 }
387
366 /* Negotiate the fc mode to use */ 388 /* Negotiate the fc mode to use */
367 ret_val = ixgbe_fc_autoneg(hw); 389 ret_val = ixgbe_fc_autoneg(hw);
368 if (ret_val) 390 if (ret_val)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7b7c8486c0bf..951b73cf5ca2 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -5763,6 +5763,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
5763 if (err) 5763 if (err)
5764 goto err_sw_init; 5764 goto err_sw_init;
5765 5765
5766 /* Make it possible the adapter to be woken up via WOL */
5767 if (adapter->hw.mac.type == ixgbe_mac_82599EB)
5768 IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
5769
5766 /* 5770 /*
5767 * If there is a fan on this device and it has failed log the 5771 * If there is a fan on this device and it has failed log the
5768 * failure. 5772 * failure.
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 103e8b0e2a0d..46997e177ee3 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -2284,6 +2284,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
2284 fail2: 2284 fail2:
2285 efx_fini_struct(efx); 2285 efx_fini_struct(efx);
2286 fail1: 2286 fail1:
2287 WARN_ON(rc > 0);
2287 EFX_LOG(efx, "initialisation failed. rc=%d\n", rc); 2288 EFX_LOG(efx, "initialisation failed. rc=%d\n", rc);
2288 free_netdev(net_dev); 2289 free_netdev(net_dev);
2289 return rc; 2290 return rc;
diff --git a/drivers/net/sfc/falcon_boards.c b/drivers/net/sfc/falcon_boards.c
index bf0b96af5334..5712fddd72f2 100644
--- a/drivers/net/sfc/falcon_boards.c
+++ b/drivers/net/sfc/falcon_boards.c
@@ -29,6 +29,15 @@
29#define FALCON_BOARD_SFN4111T 0x51 29#define FALCON_BOARD_SFN4111T 0x51
30#define FALCON_BOARD_SFN4112F 0x52 30#define FALCON_BOARD_SFN4112F 0x52
31 31
32/* Board temperature is about 15°C above ambient when air flow is
33 * limited. */
34#define FALCON_BOARD_TEMP_BIAS 15
35
36/* SFC4000 datasheet says: 'The maximum permitted junction temperature
37 * is 125°C; the thermal design of the environment for the SFC4000
38 * should aim to keep this well below 100°C.' */
39#define FALCON_JUNC_TEMP_MAX 90
40
32/***************************************************************************** 41/*****************************************************************************
33 * Support for LM87 sensor chip used on several boards 42 * Support for LM87 sensor chip used on several boards
34 */ 43 */
@@ -548,16 +557,16 @@ fail_hwmon:
548static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */ 557static u8 sfe4002_lm87_channel = 0x03; /* use AIN not FAN inputs */
549 558
550static const u8 sfe4002_lm87_regs[] = { 559static const u8 sfe4002_lm87_regs[] = {
551 LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ 560 LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */
552 LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ 561 LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
553 LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ 562 LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
554 LM87_IN_LIMITS(3, 0xb0, 0xc9), /* 5V: 4.6-5.2V */ 563 LM87_IN_LIMITS(3, 0xac, 0xd4), /* 5V: 5.0V +/- 10% */
555 LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ 564 LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
556 LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ 565 LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
557 LM87_AIN_LIMITS(0, 0xa0, 0xb2), /* AIN1: 1.66V +/- 5% */ 566 LM87_AIN_LIMITS(0, 0x98, 0xbb), /* AIN1: 1.66V +/- 10% */
558 LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ 567 LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */
559 LM87_TEMP_INT_LIMITS(10, 60), /* board */ 568 LM87_TEMP_INT_LIMITS(0, 80 + FALCON_BOARD_TEMP_BIAS),
560 LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ 569 LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
561 0 570 0
562}; 571};
563 572
@@ -619,14 +628,14 @@ static int sfe4002_init(struct efx_nic *efx)
619static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */ 628static u8 sfn4112f_lm87_channel = 0x03; /* use AIN not FAN inputs */
620 629
621static const u8 sfn4112f_lm87_regs[] = { 630static const u8 sfn4112f_lm87_regs[] = {
622 LM87_IN_LIMITS(0, 0x83, 0x91), /* 2.5V: 1.8V +/- 5% */ 631 LM87_IN_LIMITS(0, 0x7c, 0x99), /* 2.5V: 1.8V +/- 10% */
623 LM87_IN_LIMITS(1, 0x51, 0x5a), /* Vccp1: 1.2V +/- 5% */ 632 LM87_IN_LIMITS(1, 0x4c, 0x5e), /* Vccp1: 1.2V +/- 10% */
624 LM87_IN_LIMITS(2, 0xb6, 0xca), /* 3.3V: 3.3V +/- 5% */ 633 LM87_IN_LIMITS(2, 0xac, 0xd4), /* 3.3V: 3.3V +/- 10% */
625 LM87_IN_LIMITS(4, 0xb0, 0xe0), /* 12V: 11-14V */ 634 LM87_IN_LIMITS(4, 0xac, 0xe0), /* 12V: 10.8-14V */
626 LM87_IN_LIMITS(5, 0x44, 0x4b), /* Vccp2: 1.0V +/- 5% */ 635 LM87_IN_LIMITS(5, 0x3f, 0x4f), /* Vccp2: 1.0V +/- 10% */
627 LM87_AIN_LIMITS(1, 0x91, 0xa1), /* AIN2: 1.5V +/- 5% */ 636 LM87_AIN_LIMITS(1, 0x8a, 0xa9), /* AIN2: 1.5V +/- 10% */
628 LM87_TEMP_INT_LIMITS(10, 60), /* board */ 637 LM87_TEMP_INT_LIMITS(0, 60 + FALCON_BOARD_TEMP_BIAS),
629 LM87_TEMP_EXT1_LIMITS(10, 70), /* Falcon */ 638 LM87_TEMP_EXT1_LIMITS(0, FALCON_JUNC_TEMP_MAX),
630 0 639 0
631}; 640};
632 641
diff --git a/drivers/net/sfc/mcdi.c b/drivers/net/sfc/mcdi.c
index 9f035b9f0350..f66b3da6ddff 100644
--- a/drivers/net/sfc/mcdi.c
+++ b/drivers/net/sfc/mcdi.c
@@ -127,7 +127,7 @@ static int efx_mcdi_poll(struct efx_nic *efx)
127 efx_dword_t reg; 127 efx_dword_t reg;
128 128
129 /* Check for a reboot atomically with respect to efx_mcdi_copyout() */ 129 /* Check for a reboot atomically with respect to efx_mcdi_copyout() */
130 rc = efx_mcdi_poll_reboot(efx); 130 rc = -efx_mcdi_poll_reboot(efx);
131 if (rc) 131 if (rc)
132 goto out; 132 goto out;
133 133
diff --git a/drivers/net/sfc/qt202x_phy.c b/drivers/net/sfc/qt202x_phy.c
index e0d13a451019..67eec7a6e487 100644
--- a/drivers/net/sfc/qt202x_phy.c
+++ b/drivers/net/sfc/qt202x_phy.c
@@ -320,7 +320,7 @@ static int qt202x_reset_phy(struct efx_nic *efx)
320 320
321 falcon_board(efx)->type->init_phy(efx); 321 falcon_board(efx)->type->init_phy(efx);
322 322
323 return rc; 323 return 0;
324 324
325 fail: 325 fail:
326 EFX_ERR(efx, "PHY reset timed out\n"); 326 EFX_ERR(efx, "PHY reset timed out\n");
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 75a669d48e5e..d71c1976072e 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1437,7 +1437,6 @@ static int tc35815_do_interrupt(struct net_device *dev, u32 status, int limit)
1437 /* Transmit complete. */ 1437 /* Transmit complete. */
1438 lp->lstats.tx_ints++; 1438 lp->lstats.tx_ints++;
1439 tc35815_txdone(dev); 1439 tc35815_txdone(dev);
1440 netif_wake_queue(dev);
1441 if (ret < 0) 1440 if (ret < 0)
1442 ret = 0; 1441 ret = 0;
1443 } 1442 }
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 4f27f022fbf7..5f3b9eaeb04f 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -584,6 +584,11 @@ static const struct usb_device_id products [] = {
584 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 584 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
585 .driver_info = (unsigned long) &mbm_info, 585 .driver_info = (unsigned long) &mbm_info,
586}, { 586}, {
587 /* Ericsson C3607w ver 2 */
588 USB_DEVICE_AND_INTERFACE_INFO(0x0bdb, 0x190b, USB_CLASS_COMM,
589 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
590 .driver_info = (unsigned long) &mbm_info,
591}, {
587 /* Toshiba F3507g */ 592 /* Toshiba F3507g */
588 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM, 593 USB_DEVICE_AND_INTERFACE_INFO(0x0930, 0x130b, USB_CLASS_COMM,
589 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE), 594 USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index c93f58f5c6f2..317aa34b21cf 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1877,13 +1877,12 @@ static void velocity_error(struct velocity_info *vptr, int status)
1877/** 1877/**
1878 * tx_srv - transmit interrupt service 1878 * tx_srv - transmit interrupt service
1879 * @vptr; Velocity 1879 * @vptr; Velocity
1880 * @status:
1881 * 1880 *
1882 * Scan the queues looking for transmitted packets that 1881 * Scan the queues looking for transmitted packets that
1883 * we can complete and clean up. Update any statistics as 1882 * we can complete and clean up. Update any statistics as
1884 * necessary/ 1883 * necessary/
1885 */ 1884 */
1886static int velocity_tx_srv(struct velocity_info *vptr, u32 status) 1885static int velocity_tx_srv(struct velocity_info *vptr)
1887{ 1886{
1888 struct tx_desc *td; 1887 struct tx_desc *td;
1889 int qnum; 1888 int qnum;
@@ -2090,14 +2089,12 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
2090/** 2089/**
2091 * velocity_rx_srv - service RX interrupt 2090 * velocity_rx_srv - service RX interrupt
2092 * @vptr: velocity 2091 * @vptr: velocity
2093 * @status: adapter status (unused)
2094 * 2092 *
2095 * Walk the receive ring of the velocity adapter and remove 2093 * Walk the receive ring of the velocity adapter and remove
2096 * any received packets from the receive queue. Hand the ring 2094 * any received packets from the receive queue. Hand the ring
2097 * slots back to the adapter for reuse. 2095 * slots back to the adapter for reuse.
2098 */ 2096 */
2099static int velocity_rx_srv(struct velocity_info *vptr, int status, 2097static int velocity_rx_srv(struct velocity_info *vptr, int budget_left)
2100 int budget_left)
2101{ 2098{
2102 struct net_device_stats *stats = &vptr->dev->stats; 2099 struct net_device_stats *stats = &vptr->dev->stats;
2103 int rd_curr = vptr->rx.curr; 2100 int rd_curr = vptr->rx.curr;
@@ -2151,32 +2148,24 @@ static int velocity_poll(struct napi_struct *napi, int budget)
2151 struct velocity_info *vptr = container_of(napi, 2148 struct velocity_info *vptr = container_of(napi,
2152 struct velocity_info, napi); 2149 struct velocity_info, napi);
2153 unsigned int rx_done; 2150 unsigned int rx_done;
2154 u32 isr_status; 2151 unsigned long flags;
2155
2156 spin_lock(&vptr->lock);
2157 isr_status = mac_read_isr(vptr->mac_regs);
2158
2159 /* Ack the interrupt */
2160 mac_write_isr(vptr->mac_regs, isr_status);
2161 if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
2162 velocity_error(vptr, isr_status);
2163 2152
2153 spin_lock_irqsave(&vptr->lock, flags);
2164 /* 2154 /*
2165 * Do rx and tx twice for performance (taken from the VIA 2155 * Do rx and tx twice for performance (taken from the VIA
2166 * out-of-tree driver). 2156 * out-of-tree driver).
2167 */ 2157 */
2168 rx_done = velocity_rx_srv(vptr, isr_status, budget / 2); 2158 rx_done = velocity_rx_srv(vptr, budget / 2);
2169 velocity_tx_srv(vptr, isr_status); 2159 velocity_tx_srv(vptr);
2170 rx_done += velocity_rx_srv(vptr, isr_status, budget - rx_done); 2160 rx_done += velocity_rx_srv(vptr, budget - rx_done);
2171 velocity_tx_srv(vptr, isr_status); 2161 velocity_tx_srv(vptr);
2172
2173 spin_unlock(&vptr->lock);
2174 2162
2175 /* If budget not fully consumed, exit the polling mode */ 2163 /* If budget not fully consumed, exit the polling mode */
2176 if (rx_done < budget) { 2164 if (rx_done < budget) {
2177 napi_complete(napi); 2165 napi_complete(napi);
2178 mac_enable_int(vptr->mac_regs); 2166 mac_enable_int(vptr->mac_regs);
2179 } 2167 }
2168 spin_unlock_irqrestore(&vptr->lock, flags);
2180 2169
2181 return rx_done; 2170 return rx_done;
2182} 2171}
@@ -2206,10 +2195,17 @@ static irqreturn_t velocity_intr(int irq, void *dev_instance)
2206 return IRQ_NONE; 2195 return IRQ_NONE;
2207 } 2196 }
2208 2197
2198 /* Ack the interrupt */
2199 mac_write_isr(vptr->mac_regs, isr_status);
2200
2209 if (likely(napi_schedule_prep(&vptr->napi))) { 2201 if (likely(napi_schedule_prep(&vptr->napi))) {
2210 mac_disable_int(vptr->mac_regs); 2202 mac_disable_int(vptr->mac_regs);
2211 __napi_schedule(&vptr->napi); 2203 __napi_schedule(&vptr->napi);
2212 } 2204 }
2205
2206 if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
2207 velocity_error(vptr, isr_status);
2208
2213 spin_unlock(&vptr->lock); 2209 spin_unlock(&vptr->lock);
2214 2210
2215 return IRQ_HANDLED; 2211 return IRQ_HANDLED;
@@ -3100,7 +3096,7 @@ static int velocity_resume(struct pci_dev *pdev)
3100 velocity_init_registers(vptr, VELOCITY_INIT_WOL); 3096 velocity_init_registers(vptr, VELOCITY_INIT_WOL);
3101 mac_disable_int(vptr->mac_regs); 3097 mac_disable_int(vptr->mac_regs);
3102 3098
3103 velocity_tx_srv(vptr, 0); 3099 velocity_tx_srv(vptr);
3104 3100
3105 for (i = 0; i < vptr->tx.numq; i++) { 3101 for (i = 0; i < vptr->tx.numq; i++) {
3106 if (vptr->tx.used[i]) 3102 if (vptr->tx.used[i])
@@ -3344,6 +3340,7 @@ static int velocity_set_coalesce(struct net_device *dev,
3344{ 3340{
3345 struct velocity_info *vptr = netdev_priv(dev); 3341 struct velocity_info *vptr = netdev_priv(dev);
3346 int max_us = 0x3f * 64; 3342 int max_us = 0x3f * 64;
3343 unsigned long flags;
3347 3344
3348 /* 6 bits of */ 3345 /* 6 bits of */
3349 if (ecmd->tx_coalesce_usecs > max_us) 3346 if (ecmd->tx_coalesce_usecs > max_us)
@@ -3365,6 +3362,7 @@ static int velocity_set_coalesce(struct net_device *dev,
3365 ecmd->tx_coalesce_usecs); 3362 ecmd->tx_coalesce_usecs);
3366 3363
3367 /* Setup the interrupt suppression and queue timers */ 3364 /* Setup the interrupt suppression and queue timers */
3365 spin_lock_irqsave(&vptr->lock, flags);
3368 mac_disable_int(vptr->mac_regs); 3366 mac_disable_int(vptr->mac_regs);
3369 setup_adaptive_interrupts(vptr); 3367 setup_adaptive_interrupts(vptr);
3370 setup_queue_timers(vptr); 3368 setup_queue_timers(vptr);
@@ -3372,6 +3370,7 @@ static int velocity_set_coalesce(struct net_device *dev,
3372 mac_write_int_mask(vptr->int_mask, vptr->mac_regs); 3370 mac_write_int_mask(vptr->int_mask, vptr->mac_regs);
3373 mac_clear_isr(vptr->mac_regs); 3371 mac_clear_isr(vptr->mac_regs);
3374 mac_enable_int(vptr->mac_regs); 3372 mac_enable_int(vptr->mac_regs);
3373 spin_unlock_irqrestore(&vptr->lock, flags);
3375 3374
3376 return 0; 3375 return 0;
3377} 3376}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index fa12b9060b0b..29bf33692f71 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1615,7 +1615,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1615 bf->bf_frmlen -= padsize; 1615 bf->bf_frmlen -= padsize;
1616 } 1616 }
1617 1617
1618 if (conf_is_ht(&hw->conf) && !is_pae(skb)) 1618 if (conf_is_ht(&hw->conf))
1619 bf->bf_state.bf_type |= BUF_HT; 1619 bf->bf_state.bf_type |= BUF_HT;
1620 1620
1621 bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); 1621 bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
@@ -1701,7 +1701,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
1701 goto tx_done; 1701 goto tx_done;
1702 } 1702 }
1703 1703
1704 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { 1704 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && !is_pae(skb)) {
1705 /* 1705 /*
1706 * Try aggregation if it's a unicast data frame 1706 * Try aggregation if it's a unicast data frame
1707 * and the destination is HT capable. 1707 * and the destination is HT capable.
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index fe3bf9491997..c484cc253892 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -115,6 +115,7 @@
115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */ 115#define B43_MMIO_TSF_2 0x636 /* core rev < 3 only */
116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */ 116#define B43_MMIO_TSF_3 0x638 /* core rev < 3 only */
117#define B43_MMIO_RNG 0x65A 117#define B43_MMIO_RNG 0x65A
118#define B43_MMIO_IFSSLOT 0x684 /* Interframe slot time */
118#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */ 119#define B43_MMIO_IFSCTL 0x688 /* Interframe space control */
119#define B43_MMIO_IFSCTL_USE_EDCF 0x0004 120#define B43_MMIO_IFSCTL_USE_EDCF 0x0004
120#define B43_MMIO_POWERUP_DELAY 0x6A8 121#define B43_MMIO_POWERUP_DELAY 0x6A8
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 4c41cfe44f26..490fb45d1d05 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -628,10 +628,17 @@ static void b43_upload_card_macaddress(struct b43_wldev *dev)
628static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time) 628static void b43_set_slot_time(struct b43_wldev *dev, u16 slot_time)
629{ 629{
630 /* slot_time is in usec. */ 630 /* slot_time is in usec. */
631 if (dev->phy.type != B43_PHYTYPE_G) 631 /* This test used to exit for all but a G PHY. */
632 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
632 return; 633 return;
633 b43_write16(dev, 0x684, 510 + slot_time); 634 b43_write16(dev, B43_MMIO_IFSSLOT, 510 + slot_time);
634 b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time); 635 /* Shared memory location 0x0010 is the slot time and should be
636 * set to slot_time; however, this register is initially 0 and changing
637 * the value adversely affects the transmit rate for BCM4311
638 * devices. Until this behavior is unterstood, delete this step
639 *
640 * b43_shm_write16(dev, B43_SHM_SHARED, 0x0010, slot_time);
641 */
635} 642}
636 643
637static void b43_short_slot_timing_enable(struct b43_wldev *dev) 644static void b43_short_slot_timing_enable(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 9b4b8b5c7574..31462813bac0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2008,7 +2008,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2008 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn " 2008 IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2009 "%d index %d\n", scd_ssn , index); 2009 "%d index %d\n", scd_ssn , index);
2010 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 2010 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
2011 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 2011 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2012 2012
2013 if (priv->mac80211_registered && 2013 if (priv->mac80211_registered &&
2014 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 2014 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index de45f308b744..cffaae772d51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -1125,7 +1125,7 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1125 scd_ssn , index, txq_id, txq->swq_id); 1125 scd_ssn , index, txq_id, txq->swq_id);
1126 1126
1127 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 1127 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1128 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1128 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1129 1129
1130 if (priv->mac80211_registered && 1130 if (priv->mac80211_registered &&
1131 (iwl_queue_space(&txq->q) > txq->q.low_mark) && 1131 (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
@@ -1153,16 +1153,14 @@ static void iwl5000_rx_reply_tx(struct iwl_priv *priv,
1153 tx_resp->failure_frame); 1153 tx_resp->failure_frame);
1154 1154
1155 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 1155 freed = iwl_tx_queue_reclaim(priv, txq_id, index);
1156 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1156 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1157 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1158 1157
1159 if (priv->mac80211_registered && 1158 if (priv->mac80211_registered &&
1160 (iwl_queue_space(&txq->q) > txq->q.low_mark)) 1159 (iwl_queue_space(&txq->q) > txq->q.low_mark))
1161 iwl_wake_queue(priv, txq_id); 1160 iwl_wake_queue(priv, txq_id);
1162 } 1161 }
1163 1162
1164 if (ieee80211_is_data_qos(tx_resp->frame_ctrl)) 1163 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1165 iwl_txq_check_empty(priv, sta_id, tid, txq_id);
1166 1164
1167 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 1165 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
1168 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 1166 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5461f105bd2d..f36f804804fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2745,6 +2745,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2745 priv->staging_rxon.flags = 0; 2745 priv->staging_rxon.flags = 0;
2746 2746
2747 iwl_set_rxon_channel(priv, conf->channel); 2747 iwl_set_rxon_channel(priv, conf->channel);
2748 iwl_set_rxon_ht(priv, ht_conf);
2748 2749
2749 iwl_set_flags_for_band(priv, conf->channel->band); 2750 iwl_set_flags_for_band(priv, conf->channel->band);
2750 spin_unlock_irqrestore(&priv->lock, flags); 2751 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 27ca859e7453..b69e972671b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -446,6 +446,8 @@ void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
446int iwl_hw_tx_queue_init(struct iwl_priv *priv, 446int iwl_hw_tx_queue_init(struct iwl_priv *priv,
447 struct iwl_tx_queue *txq); 447 struct iwl_tx_queue *txq);
448int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq); 448int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
449void iwl_free_tfds_in_queue(struct iwl_priv *priv,
450 int sta_id, int tid, int freed);
449int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq, 451int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
450 int slots_num, u32 txq_id); 452 int slots_num, u32 txq_id);
451void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id); 453void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 6f36b6e79f5e..2dbce85404aa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -928,7 +928,10 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv,
928 if (ieee80211_is_mgmt(fc) || 928 if (ieee80211_is_mgmt(fc) ||
929 ieee80211_has_protected(fc) || 929 ieee80211_has_protected(fc) ||
930 ieee80211_has_morefrags(fc) || 930 ieee80211_has_morefrags(fc) ||
931 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) 931 le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG ||
932 (ieee80211_is_data_qos(fc) &&
933 *ieee80211_get_qos_ctl(hdr) &
934 IEEE80211_QOS_CONTROL_A_MSDU_PRESENT))
932 ret = skb_linearize(skb); 935 ret = skb_linearize(skb);
933 else 936 else
934 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ? 937 ret = __pskb_pull_tail(skb, min_t(u16, IWL_LINK_HDR_MAX, len)) ?
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 87ce2bd292c7..8f4071562857 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -120,6 +120,20 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
120EXPORT_SYMBOL(iwl_txq_update_write_ptr); 120EXPORT_SYMBOL(iwl_txq_update_write_ptr);
121 121
122 122
123void iwl_free_tfds_in_queue(struct iwl_priv *priv,
124 int sta_id, int tid, int freed)
125{
126 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
127 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
128 else {
129 IWL_ERR(priv, "free more than tfds_in_queue (%u:%d)\n",
130 priv->stations[sta_id].tid[tid].tfds_in_queue,
131 freed);
132 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
133 }
134}
135EXPORT_SYMBOL(iwl_free_tfds_in_queue);
136
123/** 137/**
124 * iwl_tx_queue_free - Deallocate DMA queue. 138 * iwl_tx_queue_free - Deallocate DMA queue.
125 * @txq: Transmit queue to deallocate. 139 * @txq: Transmit queue to deallocate.
@@ -1131,6 +1145,7 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1131 struct iwl_queue *q = &txq->q; 1145 struct iwl_queue *q = &txq->q;
1132 struct iwl_tx_info *tx_info; 1146 struct iwl_tx_info *tx_info;
1133 int nfreed = 0; 1147 int nfreed = 0;
1148 struct ieee80211_hdr *hdr;
1134 1149
1135 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { 1150 if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) {
1136 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " 1151 IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, "
@@ -1145,13 +1160,16 @@ int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1145 1160
1146 tx_info = &txq->txb[txq->q.read_ptr]; 1161 tx_info = &txq->txb[txq->q.read_ptr];
1147 iwl_tx_status(priv, tx_info->skb[0]); 1162 iwl_tx_status(priv, tx_info->skb[0]);
1163
1164 hdr = (struct ieee80211_hdr *)tx_info->skb[0]->data;
1165 if (hdr && ieee80211_is_data_qos(hdr->frame_control))
1166 nfreed++;
1148 tx_info->skb[0] = NULL; 1167 tx_info->skb[0] = NULL;
1149 1168
1150 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl) 1169 if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
1151 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq); 1170 priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
1152 1171
1153 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 1172 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
1154 nfreed++;
1155 } 1173 }
1156 return nfreed; 1174 return nfreed;
1157} 1175}
@@ -1559,7 +1577,7 @@ void iwl_rx_reply_compressed_ba(struct iwl_priv *priv,
1559 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) { 1577 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1560 /* calculate mac80211 ampdu sw queue to wake */ 1578 /* calculate mac80211 ampdu sw queue to wake */
1561 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index); 1579 int freed = iwl_tx_queue_reclaim(priv, scd_flow, index);
1562 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1580 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
1563 1581
1564 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) && 1582 if ((iwl_queue_space(&txq->q) > txq->q.low_mark) &&
1565 priv->mac80211_registered && 1583 priv->mac80211_registered &&
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 6d6ed7485175..f727b4a83196 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -794,7 +794,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
794 } 794 }
795 795
796 bss->bss = kzalloc(bss_len, GFP_KERNEL); 796 bss->bss = kzalloc(bss_len, GFP_KERNEL);
797 if (!bss) { 797 if (!bss->bss) {
798 kfree(bss); 798 kfree(bss);
799 IWM_ERR(iwm, "Couldn't allocate bss\n"); 799 IWM_ERR(iwm, "Couldn't allocate bss\n");
800 return -ENOMEM; 800 return -ENOMEM;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index bc5726dd5fe4..7ba3052b0708 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -65,6 +65,7 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
65 /* Sitecom */ 65 /* Sitecom */
66 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187}, 66 {USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
67 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B}, 67 {USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
68 {USB_DEVICE(0x0df6, 0x0029), .driver_info = DEVICE_RTL8187B},
68 /* Sphairon Access Systems GmbH */ 69 /* Sphairon Access Systems GmbH */
69 {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187}, 70 {USB_DEVICE(0x114B, 0x0150), .driver_info = DEVICE_RTL8187},
70 /* Dick Smith Electronics */ 71 /* Dick Smith Electronics */
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 8e952fdab764..cb2fd01eddae 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -720,12 +720,6 @@ static int acpiphp_bus_add(struct acpiphp_func *func)
720 -ret_val); 720 -ret_val);
721 goto acpiphp_bus_add_out; 721 goto acpiphp_bus_add_out;
722 } 722 }
723 /*
724 * try to start anyway. We could have failed to add
725 * simply because this bus had previously been added
726 * on another add. Don't bother with the return value
727 * we just keep going.
728 */
729 ret_val = acpi_bus_start(device); 723 ret_val = acpi_bus_start(device);
730 724
731acpiphp_bus_add_out: 725acpiphp_bus_add_out:
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index 07d14dfdf0b4..226b3e93498c 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -934,7 +934,7 @@ static int __devinit acer_backlight_init(struct device *dev)
934 acer_backlight_device = bd; 934 acer_backlight_device = bd;
935 935
936 bd->props.power = FB_BLANK_UNBLANK; 936 bd->props.power = FB_BLANK_UNBLANK;
937 bd->props.brightness = max_brightness; 937 bd->props.brightness = read_brightness(bd);
938 bd->props.max_brightness = max_brightness; 938 bd->props.max_brightness = max_brightness;
939 backlight_update_status(bd); 939 backlight_update_status(bd);
940 return 0; 940 return 0;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index e67e4feb35cb..eb603f1d55ca 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -5771,7 +5771,7 @@ static void thermal_exit(void)
5771 case TPACPI_THERMAL_ACPI_TMP07: 5771 case TPACPI_THERMAL_ACPI_TMP07:
5772 case TPACPI_THERMAL_ACPI_UPDT: 5772 case TPACPI_THERMAL_ACPI_UPDT:
5773 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj, 5773 sysfs_remove_group(&tpacpi_sensors_pdev->dev.kobj,
5774 &thermal_temp_input16_group); 5774 &thermal_temp_input8_group);
5775 break; 5775 break;
5776 case TPACPI_THERMAL_NONE: 5776 case TPACPI_THERMAL_NONE:
5777 default: 5777 default:
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 477542602284..9e71ac611146 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2516,7 +2516,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
2516 if (info->scsi.phase == PHASE_IDLE) 2516 if (info->scsi.phase == PHASE_IDLE)
2517 fas216_kick(info); 2517 fas216_kick(info);
2518 2518
2519 mod_timer(&info->eh_timer, 30 * HZ); 2519 mod_timer(&info->eh_timer, jiffies + 30 * HZ);
2520 spin_unlock_irqrestore(&info->host_lock, flags); 2520 spin_unlock_irqrestore(&info->host_lock, flags);
2521 2521
2522 /* 2522 /*
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
index 10be9f36a4cc..2f47ae7cce91 100644
--- a/drivers/scsi/fcoe/fcoe.c
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -2009,6 +2009,8 @@ static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
2009 fcoe_interface_cleanup(fcoe); 2009 fcoe_interface_cleanup(fcoe);
2010 rtnl_unlock(); 2010 rtnl_unlock();
2011 fcoe_if_destroy(fcoe->ctlr.lp); 2011 fcoe_if_destroy(fcoe->ctlr.lp);
2012 module_put(THIS_MODULE);
2013
2012out_putdev: 2014out_putdev:
2013 dev_put(netdev); 2015 dev_put(netdev);
2014out_nodev: 2016out_nodev:
@@ -2059,6 +2061,11 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2059 } 2061 }
2060#endif 2062#endif
2061 2063
2064 if (!try_module_get(THIS_MODULE)) {
2065 rc = -EINVAL;
2066 goto out_nomod;
2067 }
2068
2062 rtnl_lock(); 2069 rtnl_lock();
2063 netdev = fcoe_if_to_netdev(buffer); 2070 netdev = fcoe_if_to_netdev(buffer);
2064 if (!netdev) { 2071 if (!netdev) {
@@ -2099,17 +2106,24 @@ static int fcoe_create(const char *buffer, struct kernel_param *kp)
2099 if (!fcoe_link_ok(lport)) 2106 if (!fcoe_link_ok(lport))
2100 fcoe_ctlr_link_up(&fcoe->ctlr); 2107 fcoe_ctlr_link_up(&fcoe->ctlr);
2101 2108
2102 rc = 0;
2103out_free:
2104 /* 2109 /*
2105 * Release from init in fcoe_interface_create(), on success lport 2110 * Release from init in fcoe_interface_create(), on success lport
2106 * should be holding a reference taken in fcoe_if_create(). 2111 * should be holding a reference taken in fcoe_if_create().
2107 */ 2112 */
2108 fcoe_interface_put(fcoe); 2113 fcoe_interface_put(fcoe);
2114 dev_put(netdev);
2115 rtnl_unlock();
2116 mutex_unlock(&fcoe_config_mutex);
2117
2118 return 0;
2119out_free:
2120 fcoe_interface_put(fcoe);
2109out_putdev: 2121out_putdev:
2110 dev_put(netdev); 2122 dev_put(netdev);
2111out_nodev: 2123out_nodev:
2112 rtnl_unlock(); 2124 rtnl_unlock();
2125 module_put(THIS_MODULE);
2126out_nomod:
2113 mutex_unlock(&fcoe_config_mutex); 2127 mutex_unlock(&fcoe_config_mutex);
2114 return rc; 2128 return rc;
2115} 2129}
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 9823291395ad..511cb6b371ee 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -1187,7 +1187,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1187 next_timer = fip->ctlr_ka_time; 1187 next_timer = fip->ctlr_ka_time;
1188 1188
1189 if (time_after_eq(jiffies, fip->port_ka_time)) { 1189 if (time_after_eq(jiffies, fip->port_ka_time)) {
1190 fip->port_ka_time += jiffies + 1190 fip->port_ka_time = jiffies +
1191 msecs_to_jiffies(FIP_VN_KA_PERIOD); 1191 msecs_to_jiffies(FIP_VN_KA_PERIOD);
1192 fip->send_port_ka = 1; 1192 fip->send_port_ka = 1;
1193 } 1193 }
diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c
index 19d711cb938c..7f4364770e4a 100644
--- a/drivers/scsi/libfc/fc_exch.c
+++ b/drivers/scsi/libfc/fc_exch.c
@@ -1890,7 +1890,7 @@ static struct fc_seq *fc_exch_seq_send(struct fc_lport *lport,
1890 fc_exch_setup_hdr(ep, fp, ep->f_ctl); 1890 fc_exch_setup_hdr(ep, fp, ep->f_ctl);
1891 sp->cnt++; 1891 sp->cnt++;
1892 1892
1893 if (ep->xid <= lport->lro_xid) 1893 if (ep->xid <= lport->lro_xid && fh->fh_r_ctl == FC_RCTL_DD_UNSOL_CMD)
1894 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid); 1894 fc_fcp_ddp_setup(fr_fsp(fp), ep->xid);
1895 1895
1896 if (unlikely(lport->tt.frame_send(lport, fp))) 1896 if (unlikely(lport->tt.frame_send(lport, fp)))
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 881d5dfe8c74..6fde2fabfd9b 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -298,9 +298,6 @@ void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid)
298{ 298{
299 struct fc_lport *lport; 299 struct fc_lport *lport;
300 300
301 if (!fsp)
302 return;
303
304 lport = fsp->lp; 301 lport = fsp->lp;
305 if ((fsp->req_flags & FC_SRB_READ) && 302 if ((fsp->req_flags & FC_SRB_READ) &&
306 (lport->lro_enabled) && (lport->tt.ddp_setup)) { 303 (lport->lro_enabled) && (lport->tt.ddp_setup)) {
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 0b165024a219..7ec8ce75007c 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -1800,7 +1800,8 @@ int fc_lport_bsg_request(struct fc_bsg_job *job)
1800 u32 did; 1800 u32 did;
1801 1801
1802 job->reply->reply_payload_rcv_len = 0; 1802 job->reply->reply_payload_rcv_len = 0;
1803 rsp->resid_len = job->reply_payload.payload_len; 1803 if (rsp)
1804 rsp->resid_len = job->reply_payload.payload_len;
1804 1805
1805 mutex_lock(&lport->lp_mutex); 1806 mutex_lock(&lport->lp_mutex);
1806 1807
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 02300523b234..97923bb07765 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -623,7 +623,7 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
623 623
624 tov = ntohl(plp->fl_csp.sp_e_d_tov); 624 tov = ntohl(plp->fl_csp.sp_e_d_tov);
625 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR) 625 if (ntohs(plp->fl_csp.sp_features) & FC_SP_FT_EDTR)
626 tov /= 1000; 626 tov /= 1000000;
627 if (tov > rdata->e_d_tov) 627 if (tov > rdata->e_d_tov)
628 rdata->e_d_tov = tov; 628 rdata->e_d_tov = tov;
629 csp_seq = ntohs(plp->fl_csp.sp_tot_seq); 629 csp_seq = ntohs(plp->fl_csp.sp_tot_seq);
diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
index db6856c138fc..4ad87fd74ddd 100644
--- a/drivers/scsi/libiscsi_tcp.c
+++ b/drivers/scsi/libiscsi_tcp.c
@@ -992,12 +992,10 @@ static struct iscsi_r2t_info *iscsi_tcp_get_curr_r2t(struct iscsi_task *task)
992 if (r2t == NULL) { 992 if (r2t == NULL) {
993 if (kfifo_out(&tcp_task->r2tqueue, 993 if (kfifo_out(&tcp_task->r2tqueue,
994 (void *)&tcp_task->r2t, sizeof(void *)) != 994 (void *)&tcp_task->r2t, sizeof(void *)) !=
995 sizeof(void *)) { 995 sizeof(void *))
996 WARN_ONCE(1, "unexpected fifo state");
997 r2t = NULL; 996 r2t = NULL;
998 } 997 else
999 998 r2t = tcp_task->r2t;
1000 r2t = tcp_task->r2t;
1001 } 999 }
1002 spin_unlock_bh(&session->lock); 1000 spin_unlock_bh(&session->lock);
1003 } 1001 }
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index 708ea3157b60..d9b8ca5116bc 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -3781,6 +3781,7 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
3781 compat_alloc_user_space(sizeof(struct megasas_iocpacket)); 3781 compat_alloc_user_space(sizeof(struct megasas_iocpacket));
3782 int i; 3782 int i;
3783 int error = 0; 3783 int error = 0;
3784 compat_uptr_t ptr;
3784 3785
3785 if (clear_user(ioc, sizeof(*ioc))) 3786 if (clear_user(ioc, sizeof(*ioc)))
3786 return -EFAULT; 3787 return -EFAULT;
@@ -3793,9 +3794,22 @@ static int megasas_mgmt_compat_ioctl_fw(struct file *file, unsigned long arg)
3793 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32))) 3794 copy_in_user(&ioc->sge_count, &cioc->sge_count, sizeof(u32)))
3794 return -EFAULT; 3795 return -EFAULT;
3795 3796
3796 for (i = 0; i < MAX_IOCTL_SGE; i++) { 3797 /*
3797 compat_uptr_t ptr; 3798 * The sense_ptr is used in megasas_mgmt_fw_ioctl only when
3799 * sense_len is not null, so prepare the 64bit value under
3800 * the same condition.
3801 */
3802 if (ioc->sense_len) {
3803 void __user **sense_ioc_ptr =
3804 (void __user **)(ioc->frame.raw + ioc->sense_off);
3805 compat_uptr_t *sense_cioc_ptr =
3806 (compat_uptr_t *)(cioc->frame.raw + cioc->sense_off);
3807 if (get_user(ptr, sense_cioc_ptr) ||
3808 put_user(compat_ptr(ptr), sense_ioc_ptr))
3809 return -EFAULT;
3810 }
3798 3811
3812 for (i = 0; i < MAX_IOCTL_SGE; i++) {
3799 if (get_user(ptr, &cioc->sgl[i].iov_base) || 3813 if (get_user(ptr, &cioc->sgl[i].iov_base) ||
3800 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) || 3814 put_user(compat_ptr(ptr), &ioc->sgl[i].iov_base) ||
3801 copy_in_user(&ioc->sgl[i].iov_len, 3815 copy_in_user(&ioc->sgl[i].iov_len,
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index c3e37c8e7e26..e9b15c3746fa 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -83,6 +83,9 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */
83 83
84#define PASS_LIMIT 256 84#define PASS_LIMIT 256
85 85
86#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
87
88
86/* 89/*
87 * We default to IRQ0 for the "no irq" hack. Some 90 * We default to IRQ0 for the "no irq" hack. Some
88 * machine types want others as well - they're free 91 * machine types want others as well - they're free
@@ -1792,7 +1795,7 @@ static unsigned int serial8250_tx_empty(struct uart_port *port)
1792 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; 1795 up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
1793 spin_unlock_irqrestore(&up->port.lock, flags); 1796 spin_unlock_irqrestore(&up->port.lock, flags);
1794 1797
1795 return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; 1798 return (lsr & BOTH_EMPTY) == BOTH_EMPTY ? TIOCSER_TEMT : 0;
1796} 1799}
1797 1800
1798static unsigned int serial8250_get_mctrl(struct uart_port *port) 1801static unsigned int serial8250_get_mctrl(struct uart_port *port)
@@ -1850,8 +1853,6 @@ static void serial8250_break_ctl(struct uart_port *port, int break_state)
1850 spin_unlock_irqrestore(&up->port.lock, flags); 1853 spin_unlock_irqrestore(&up->port.lock, flags);
1851} 1854}
1852 1855
1853#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
1854
1855/* 1856/*
1856 * Wait for transmitter & holding register to empty 1857 * Wait for transmitter & holding register to empty
1857 */ 1858 */
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index 5681ebed9c65..03dfd27c4bfb 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -494,8 +494,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
494#endif 494#endif
495 break; 495 break;
496 case SSB_BUSTYPE_SDIO: 496 case SSB_BUSTYPE_SDIO:
497#ifdef CONFIG_SSB_SDIO 497#ifdef CONFIG_SSB_SDIOHOST
498 sdev->irq = bus->host_sdio->dev.irq;
499 dev->parent = &bus->host_sdio->dev; 498 dev->parent = &bus->host_sdio->dev;
500#endif 499#endif
501 break; 500 break;
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 6e8bcdfd23b4..a678186f218f 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1312,9 +1312,9 @@ static int processcompl(struct async *as, void __user * __user *arg)
1312 void __user *addr = as->userurb; 1312 void __user *addr = as->userurb;
1313 unsigned int i; 1313 unsigned int i;
1314 1314
1315 if (as->userbuffer) 1315 if (as->userbuffer && urb->actual_length)
1316 if (copy_to_user(as->userbuffer, urb->transfer_buffer, 1316 if (copy_to_user(as->userbuffer, urb->transfer_buffer,
1317 urb->transfer_buffer_length)) 1317 urb->actual_length))
1318 goto err_out; 1318 goto err_out;
1319 if (put_user(as->status, &userurb->status)) 1319 if (put_user(as->status, &userurb->status))
1320 goto err_out; 1320 goto err_out;
@@ -1334,14 +1334,11 @@ static int processcompl(struct async *as, void __user * __user *arg)
1334 } 1334 }
1335 } 1335 }
1336 1336
1337 free_async(as);
1338
1339 if (put_user(addr, (void __user * __user *)arg)) 1337 if (put_user(addr, (void __user * __user *)arg))
1340 return -EFAULT; 1338 return -EFAULT;
1341 return 0; 1339 return 0;
1342 1340
1343err_out: 1341err_out:
1344 free_async(as);
1345 return -EFAULT; 1342 return -EFAULT;
1346} 1343}
1347 1344
@@ -1371,8 +1368,11 @@ static struct async *reap_as(struct dev_state *ps)
1371static int proc_reapurb(struct dev_state *ps, void __user *arg) 1368static int proc_reapurb(struct dev_state *ps, void __user *arg)
1372{ 1369{
1373 struct async *as = reap_as(ps); 1370 struct async *as = reap_as(ps);
1374 if (as) 1371 if (as) {
1375 return processcompl(as, (void __user * __user *)arg); 1372 int retval = processcompl(as, (void __user * __user *)arg);
1373 free_async(as);
1374 return retval;
1375 }
1376 if (signal_pending(current)) 1376 if (signal_pending(current))
1377 return -EINTR; 1377 return -EINTR;
1378 return -EIO; 1378 return -EIO;
@@ -1380,11 +1380,16 @@ static int proc_reapurb(struct dev_state *ps, void __user *arg)
1380 1380
1381static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg) 1381static int proc_reapurbnonblock(struct dev_state *ps, void __user *arg)
1382{ 1382{
1383 int retval;
1383 struct async *as; 1384 struct async *as;
1384 1385
1385 if (!(as = async_getcompleted(ps))) 1386 as = async_getcompleted(ps);
1386 return -EAGAIN; 1387 retval = -EAGAIN;
1387 return processcompl(as, (void __user * __user *)arg); 1388 if (as) {
1389 retval = processcompl(as, (void __user * __user *)arg);
1390 free_async(as);
1391 }
1392 return retval;
1388} 1393}
1389 1394
1390#ifdef CONFIG_COMPAT 1395#ifdef CONFIG_COMPAT
@@ -1475,9 +1480,9 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1475 void __user *addr = as->userurb; 1480 void __user *addr = as->userurb;
1476 unsigned int i; 1481 unsigned int i;
1477 1482
1478 if (as->userbuffer) 1483 if (as->userbuffer && urb->actual_length)
1479 if (copy_to_user(as->userbuffer, urb->transfer_buffer, 1484 if (copy_to_user(as->userbuffer, urb->transfer_buffer,
1480 urb->transfer_buffer_length)) 1485 urb->actual_length))
1481 return -EFAULT; 1486 return -EFAULT;
1482 if (put_user(as->status, &userurb->status)) 1487 if (put_user(as->status, &userurb->status))
1483 return -EFAULT; 1488 return -EFAULT;
@@ -1497,7 +1502,6 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1497 } 1502 }
1498 } 1503 }
1499 1504
1500 free_async(as);
1501 if (put_user(ptr_to_compat(addr), (u32 __user *)arg)) 1505 if (put_user(ptr_to_compat(addr), (u32 __user *)arg))
1502 return -EFAULT; 1506 return -EFAULT;
1503 return 0; 1507 return 0;
@@ -1506,8 +1510,11 @@ static int processcompl_compat(struct async *as, void __user * __user *arg)
1506static int proc_reapurb_compat(struct dev_state *ps, void __user *arg) 1510static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
1507{ 1511{
1508 struct async *as = reap_as(ps); 1512 struct async *as = reap_as(ps);
1509 if (as) 1513 if (as) {
1510 return processcompl_compat(as, (void __user * __user *)arg); 1514 int retval = processcompl_compat(as, (void __user * __user *)arg);
1515 free_async(as);
1516 return retval;
1517 }
1511 if (signal_pending(current)) 1518 if (signal_pending(current))
1512 return -EINTR; 1519 return -EINTR;
1513 return -EIO; 1520 return -EIO;
@@ -1515,11 +1522,16 @@ static int proc_reapurb_compat(struct dev_state *ps, void __user *arg)
1515 1522
1516static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg) 1523static int proc_reapurbnonblock_compat(struct dev_state *ps, void __user *arg)
1517{ 1524{
1525 int retval;
1518 struct async *as; 1526 struct async *as;
1519 1527
1520 if (!(as = async_getcompleted(ps))) 1528 retval = -EAGAIN;
1521 return -EAGAIN; 1529 as = async_getcompleted(ps);
1522 return processcompl_compat(as, (void __user * __user *)arg); 1530 if (as) {
1531 retval = processcompl_compat(as, (void __user * __user *)arg);
1532 free_async(as);
1533 }
1534 return retval;
1523} 1535}
1524 1536
1525 1537
diff --git a/drivers/usb/gadget/f_eem.c b/drivers/usb/gadget/f_eem.c
index 0a577d5694fd..d4f0db58a8ad 100644
--- a/drivers/usb/gadget/f_eem.c
+++ b/drivers/usb/gadget/f_eem.c
@@ -358,7 +358,7 @@ done:
358 * b15: bmType (0 == data) 358 * b15: bmType (0 == data)
359 */ 359 */
360 len = skb->len; 360 len = skb->len;
361 put_unaligned_le16((len & 0x3FFF) | BIT(14), skb_push(skb, 2)); 361 put_unaligned_le16(len & 0x3FFF, skb_push(skb, 2));
362 362
363 /* add a zero-length EEM packet, if needed */ 363 /* add a zero-length EEM packet, if needed */
364 if (padlen) 364 if (padlen)
@@ -464,7 +464,6 @@ static int eem_unwrap(struct gether *port,
464 } 464 }
465 465
466 /* validate CRC */ 466 /* validate CRC */
467 crc = get_unaligned_le32(skb->data + len - ETH_FCS_LEN);
468 if (header & BIT(14)) { 467 if (header & BIT(14)) {
469 crc = get_unaligned_le32(skb->data + len 468 crc = get_unaligned_le32(skb->data + len
470 - ETH_FCS_LEN); 469 - ETH_FCS_LEN);
diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c
index 429560100b10..76496f5d272c 100644
--- a/drivers/usb/gadget/multi.c
+++ b/drivers/usb/gadget/multi.c
@@ -29,7 +29,7 @@
29#if defined USB_ETH_RNDIS 29#if defined USB_ETH_RNDIS
30# undef USB_ETH_RNDIS 30# undef USB_ETH_RNDIS
31#endif 31#endif
32#ifdef CONFIG_USB_ETH_RNDIS 32#ifdef CONFIG_USB_G_MULTI_RNDIS
33# define USB_ETH_RNDIS y 33# define USB_ETH_RNDIS y
34#endif 34#endif
35 35
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c
index e220fb8091a3..8b45145b9136 100644
--- a/drivers/usb/gadget/r8a66597-udc.c
+++ b/drivers/usb/gadget/r8a66597-udc.c
@@ -26,6 +26,7 @@
26#include <linux/io.h> 26#include <linux/io.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/err.h>
29 30
30#include <linux/usb/ch9.h> 31#include <linux/usb/ch9.h>
31#include <linux/usb/gadget.h> 32#include <linux/usb/gadget.h>
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 4b5dbd0127f5..5fc80a104150 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -2582,6 +2582,7 @@ err:
2582 hsotg->gadget.dev.driver = NULL; 2582 hsotg->gadget.dev.driver = NULL;
2583 return ret; 2583 return ret;
2584} 2584}
2585EXPORT_SYMBOL(usb_gadget_register_driver);
2585 2586
2586int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) 2587int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
2587{ 2588{
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index c75d9270c752..19372673bf09 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -196,7 +196,9 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
196 if (hostpc_reg) { 196 if (hostpc_reg) {
197 u32 t3; 197 u32 t3;
198 198
199 spin_unlock_irq(&ehci->lock);
199 msleep(5);/* 5ms for HCD enter low pwr mode */ 200 msleep(5);/* 5ms for HCD enter low pwr mode */
201 spin_lock_irq(&ehci->lock);
200 t3 = ehci_readl(ehci, hostpc_reg); 202 t3 = ehci_readl(ehci, hostpc_reg);
201 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg); 203 ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
202 t3 = ehci_readl(ehci, hostpc_reg); 204 t3 = ehci_readl(ehci, hostpc_reg);
@@ -904,17 +906,18 @@ static int ehci_hub_control (
904 if ((temp & PORT_PE) == 0 906 if ((temp & PORT_PE) == 0
905 || (temp & PORT_RESET) != 0) 907 || (temp & PORT_RESET) != 0)
906 goto error; 908 goto error;
907 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); 909
908 /* After above check the port must be connected. 910 /* After above check the port must be connected.
909 * Set appropriate bit thus could put phy into low power 911 * Set appropriate bit thus could put phy into low power
910 * mode if we have hostpc feature 912 * mode if we have hostpc feature
911 */ 913 */
914 temp &= ~PORT_WKCONN_E;
915 temp |= PORT_WKDISC_E | PORT_WKOC_E;
916 ehci_writel(ehci, temp | PORT_SUSPEND, status_reg);
912 if (hostpc_reg) { 917 if (hostpc_reg) {
913 temp &= ~PORT_WKCONN_E; 918 spin_unlock_irqrestore(&ehci->lock, flags);
914 temp |= (PORT_WKDISC_E | PORT_WKOC_E);
915 ehci_writel(ehci, temp | PORT_SUSPEND,
916 status_reg);
917 msleep(5);/* 5ms for HCD enter low pwr mode */ 919 msleep(5);/* 5ms for HCD enter low pwr mode */
920 spin_lock_irqsave(&ehci->lock, flags);
918 temp1 = ehci_readl(ehci, hostpc_reg); 921 temp1 = ehci_readl(ehci, hostpc_reg);
919 ehci_writel(ehci, temp1 | HOSTPC_PHCD, 922 ehci_writel(ehci, temp1 | HOSTPC_PHCD,
920 hostpc_reg); 923 hostpc_reg);
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c
index d224ab467a40..e1232890c78b 100644
--- a/drivers/usb/host/fhci-tds.c
+++ b/drivers/usb/host/fhci-tds.c
@@ -105,7 +105,7 @@ void fhci_ep0_free(struct fhci_usb *usb)
105 if (ep->td_base) 105 if (ep->td_base)
106 cpm_muram_free(cpm_muram_offset(ep->td_base)); 106 cpm_muram_free(cpm_muram_offset(ep->td_base));
107 107
108 if (ep->conf_frame_Q) { 108 if (kfifo_initialized(&ep->conf_frame_Q)) {
109 size = cq_howmany(&ep->conf_frame_Q); 109 size = cq_howmany(&ep->conf_frame_Q);
110 for (; size; size--) { 110 for (; size; size--) {
111 struct packet *pkt = cq_get(&ep->conf_frame_Q); 111 struct packet *pkt = cq_get(&ep->conf_frame_Q);
@@ -115,7 +115,7 @@ void fhci_ep0_free(struct fhci_usb *usb)
115 cq_delete(&ep->conf_frame_Q); 115 cq_delete(&ep->conf_frame_Q);
116 } 116 }
117 117
118 if (ep->empty_frame_Q) { 118 if (kfifo_initialized(&ep->empty_frame_Q)) {
119 size = cq_howmany(&ep->empty_frame_Q); 119 size = cq_howmany(&ep->empty_frame_Q);
120 for (; size; size--) { 120 for (; size; size--) {
121 struct packet *pkt = cq_get(&ep->empty_frame_Q); 121 struct packet *pkt = cq_get(&ep->empty_frame_Q);
@@ -125,7 +125,7 @@ void fhci_ep0_free(struct fhci_usb *usb)
125 cq_delete(&ep->empty_frame_Q); 125 cq_delete(&ep->empty_frame_Q);
126 } 126 }
127 127
128 if (ep->dummy_packets_Q) { 128 if (kfifo_initialized(&ep->dummy_packets_Q)) {
129 size = cq_howmany(&ep->dummy_packets_Q); 129 size = cq_howmany(&ep->dummy_packets_Q);
130 for (; size; size--) { 130 for (; size; size--) {
131 u8 *buff = cq_get(&ep->dummy_packets_Q); 131 u8 *buff = cq_get(&ep->dummy_packets_Q);
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c
index 0025847743f3..8b37a4b9839e 100644
--- a/drivers/usb/misc/sisusbvga/sisusb.c
+++ b/drivers/usb/misc/sisusbvga/sisusb.c
@@ -3245,6 +3245,7 @@ static struct usb_device_id sisusb_table [] = {
3245 { USB_DEVICE(0x0711, 0x0902) }, 3245 { USB_DEVICE(0x0711, 0x0902) },
3246 { USB_DEVICE(0x0711, 0x0903) }, 3246 { USB_DEVICE(0x0711, 0x0903) },
3247 { USB_DEVICE(0x0711, 0x0918) }, 3247 { USB_DEVICE(0x0711, 0x0918) },
3248 { USB_DEVICE(0x0711, 0x0920) },
3248 { USB_DEVICE(0x182d, 0x021c) }, 3249 { USB_DEVICE(0x182d, 0x021c) },
3249 { USB_DEVICE(0x182d, 0x0269) }, 3250 { USB_DEVICE(0x182d, 0x0269) },
3250 { } 3251 { }
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig
index de56b3d743d7..3d2d3e549bd1 100644
--- a/drivers/usb/otg/Kconfig
+++ b/drivers/usb/otg/Kconfig
@@ -44,6 +44,7 @@ config ISP1301_OMAP
44config USB_ULPI 44config USB_ULPI
45 bool "Generic ULPI Transceiver Driver" 45 bool "Generic ULPI Transceiver Driver"
46 depends on ARM 46 depends on ARM
47 select USB_OTG_UTILS
47 help 48 help
48 Enable this to support ULPI connected USB OTG transceivers which 49 Enable this to support ULPI connected USB OTG transceivers which
49 are likely found on embedded boards. 50 are likely found on embedded boards.
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 216f187582ab..7638828e7317 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -50,7 +50,7 @@
50 * Version Information 50 * Version Information
51 */ 51 */
52#define DRIVER_VERSION "v1.5.0" 52#define DRIVER_VERSION "v1.5.0"
53#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" 53#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr"
54#define DRIVER_DESC "USB FTDI Serial Converters Driver" 54#define DRIVER_DESC "USB FTDI Serial Converters Driver"
55 55
56static int debug; 56static int debug;
@@ -145,10 +145,15 @@ static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = {
145 145
146 146
147 147
148/*
149 * Device ID not listed? Test via module params product/vendor or
150 * /sys/bus/usb/ftdi_sio/new_id, then send patch/report!
151 */
148static struct usb_device_id id_table_combined [] = { 152static struct usb_device_id id_table_combined [] = {
149 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) }, 153 { USB_DEVICE(FTDI_VID, FTDI_AMC232_PID) },
150 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) }, 154 { USB_DEVICE(FTDI_VID, FTDI_CANUSB_PID) },
151 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) }, 155 { USB_DEVICE(FTDI_VID, FTDI_CANDAPTER_PID) },
156 { USB_DEVICE(FTDI_VID, FTDI_NXTCAM_PID) },
152 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) }, 157 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_0_PID) },
153 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) }, 158 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_1_PID) },
154 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) }, 159 { USB_DEVICE(FTDI_VID, FTDI_SCS_DEVICE_2_PID) },
@@ -552,9 +557,16 @@ static struct usb_device_id id_table_combined [] = {
552 { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) }, 557 { USB_DEVICE(FTDI_VID, FTDI_IBS_PEDO_PID) },
553 { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) }, 558 { USB_DEVICE(FTDI_VID, FTDI_IBS_PROD_PID) },
554 /* 559 /*
555 * Due to many user requests for multiple ELV devices we enable 560 * ELV devices:
556 * them by default.
557 */ 561 */
562 { USB_DEVICE(FTDI_VID, FTDI_ELV_USR_PID) },
563 { USB_DEVICE(FTDI_VID, FTDI_ELV_MSM1_PID) },
564 { USB_DEVICE(FTDI_VID, FTDI_ELV_KL100_PID) },
565 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS550_PID) },
566 { USB_DEVICE(FTDI_VID, FTDI_ELV_EC3000_PID) },
567 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS888_PID) },
568 { USB_DEVICE(FTDI_VID, FTDI_ELV_TWS550_PID) },
569 { USB_DEVICE(FTDI_VID, FTDI_ELV_FEM_PID) },
558 { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) }, 570 { USB_DEVICE(FTDI_VID, FTDI_ELV_CLI7000_PID) },
559 { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) }, 571 { USB_DEVICE(FTDI_VID, FTDI_ELV_PPS7330_PID) },
560 { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) }, 572 { USB_DEVICE(FTDI_VID, FTDI_ELV_TFM100_PID) },
@@ -571,11 +583,17 @@ static struct usb_device_id id_table_combined [] = {
571 { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) }, 583 { USB_DEVICE(FTDI_VID, FTDI_ELV_PCK100_PID) },
572 { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) }, 584 { USB_DEVICE(FTDI_VID, FTDI_ELV_RFP500_PID) },
573 { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) }, 585 { USB_DEVICE(FTDI_VID, FTDI_ELV_FS20SIG_PID) },
586 { USB_DEVICE(FTDI_VID, FTDI_ELV_UTP8_PID) },
574 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) }, 587 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS300PC_PID) },
588 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS444PC_PID) },
575 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) }, 589 { USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
576 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) }, 590 { USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
577 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) }, 591 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
578 { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) }, 592 { USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
593 { USB_DEVICE(FTDI_VID, FTDI_ELV_UMS100_PID) },
594 { USB_DEVICE(FTDI_VID, FTDI_ELV_TFD128_PID) },
595 { USB_DEVICE(FTDI_VID, FTDI_ELV_FM3RX_PID) },
596 { USB_DEVICE(FTDI_VID, FTDI_ELV_WS777_PID) },
579 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, 597 { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
580 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, 598 { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
581 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, 599 { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
@@ -697,6 +715,7 @@ static struct usb_device_id id_table_combined [] = {
697 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, 715 { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
698 { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, 716 { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
699 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, 717 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
718 { USB_DEVICE(PAPOUCH_VID, PAPOUCH_AD4USB_PID) },
700 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, 719 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
701 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, 720 { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
702 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, 721 { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) },
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index da92b4952ffb..c8951aeed983 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -38,6 +38,8 @@
38/* www.candapter.com Ewert Energy Systems CANdapter device */ 38/* www.candapter.com Ewert Energy Systems CANdapter device */
39#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */ 39#define FTDI_CANDAPTER_PID 0x9F80 /* Product Id */
40 40
41#define FTDI_NXTCAM_PID 0xABB8 /* NXTCam for Mindstorms NXT */
42
41/* OOCDlink by Joern Kaipf <joernk@web.de> 43/* OOCDlink by Joern Kaipf <joernk@web.de>
42 * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */ 44 * (http://www.joernonline.de/dw/doku.php?id=start&idx=projects:oocdlink) */
43#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */ 45#define FTDI_OOCDLINK_PID 0xbaf8 /* Amontec JTAGkey */
@@ -161,22 +163,37 @@
161/* 163/*
162 * ELV USB devices submitted by Christian Abt of ELV (www.elv.de). 164 * ELV USB devices submitted by Christian Abt of ELV (www.elv.de).
163 * All of these devices use FTDI's vendor ID (0x0403). 165 * All of these devices use FTDI's vendor ID (0x0403).
166 * Further IDs taken from ELV Windows .inf file.
164 * 167 *
165 * The previously included PID for the UO 100 module was incorrect. 168 * The previously included PID for the UO 100 module was incorrect.
166 * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58). 169 * In fact, that PID was for ELV's UR 100 USB-RS232 converter (0xFB58).
167 * 170 *
168 * Armin Laeuger originally sent the PID for the UM 100 module. 171 * Armin Laeuger originally sent the PID for the UM 100 module.
169 */ 172 */
173#define FTDI_ELV_USR_PID 0xE000 /* ELV Universal-Sound-Recorder */
174#define FTDI_ELV_MSM1_PID 0xE001 /* ELV Mini-Sound-Modul */
175#define FTDI_ELV_KL100_PID 0xE002 /* ELV Kfz-Leistungsmesser KL 100 */
176#define FTDI_ELV_WS550_PID 0xE004 /* WS 550 */
177#define FTDI_ELV_EC3000_PID 0xE006 /* ENERGY CONTROL 3000 USB */
178#define FTDI_ELV_WS888_PID 0xE008 /* WS 888 */
179#define FTDI_ELV_TWS550_PID 0xE009 /* Technoline WS 550 */
180#define FTDI_ELV_FEM_PID 0xE00A /* Funk Energie Monitor */
170#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */ 181#define FTDI_ELV_FHZ1300PC_PID 0xE0E8 /* FHZ 1300 PC */
171#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */ 182#define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
172#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */ 183#define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */
184#define FTDI_ELV_UMS100_PID 0xE0EB /* ELV USB Master-Slave Schaltsteckdose UMS 100 */
185#define FTDI_ELV_TFD128_PID 0xE0EC /* ELV Temperatur-Feuchte-Datenlogger TFD 128 */
186#define FTDI_ELV_FM3RX_PID 0xE0ED /* ELV Messwertuebertragung FM3 RX */
187#define FTDI_ELV_WS777_PID 0xE0EE /* Conrad WS 777 */
173#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */ 188#define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */
174#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */ 189#define FTDI_ELV_CSI8_PID 0xE0F0 /* Computer-Schalt-Interface (CSI 8) */
175#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */ 190#define FTDI_ELV_EM1000DL_PID 0xE0F1 /* PC-Datenlogger fuer Energiemonitor (EM 1000 DL) */
176#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */ 191#define FTDI_ELV_PCK100_PID 0xE0F2 /* PC-Kabeltester (PCK 100) */
177#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */ 192#define FTDI_ELV_RFP500_PID 0xE0F3 /* HF-Leistungsmesser (RFP 500) */
178#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */ 193#define FTDI_ELV_FS20SIG_PID 0xE0F4 /* Signalgeber (FS 20 SIG) */
194#define FTDI_ELV_UTP8_PID 0xE0F5 /* ELV UTP 8 */
179#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */ 195#define FTDI_ELV_WS300PC_PID 0xE0F6 /* PC-Wetterstation (WS 300 PC) */
196#define FTDI_ELV_WS444PC_PID 0xE0F7 /* Conrad WS 444 PC */
180#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */ 197#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */
181#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */ 198#define FTDI_ELV_UAD8_PID 0xF068 /* USB-AD-Wandler (UAD 8) */
182#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */ 199#define FTDI_ELV_UDA7_PID 0xF069 /* USB-DA-Wandler (UDA 7) */
@@ -968,6 +985,7 @@
968#define PAPOUCH_VID 0x5050 /* Vendor ID */ 985#define PAPOUCH_VID 0x5050 /* Vendor ID */
969#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ 986#define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */
970#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ 987#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */
988#define PAPOUCH_AD4USB_PID 0x8003 /* AD4USB Measurement Module */
971 989
972/* 990/*
973 * Marvell SheevaPlug 991 * Marvell SheevaPlug
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index ac1b6449fb6a..3eb6143bb646 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -298,6 +298,7 @@ static struct usb_device_id id_table [] = {
298 { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */ 298 { USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless Direct IP modems */
299 .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist 299 .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
300 }, 300 },
301 { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */
301 302
302 { } 303 { }
303}; 304};
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index c932f9053188..49575fba3756 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -941,7 +941,7 @@ UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999,
941UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133, 941UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133,
942 "Microtech", 942 "Microtech",
943 "USB-SCSI-DB25", 943 "USB-SCSI-DB25",
944 US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, 944 US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init,
945 US_FL_SCM_MULT_TARG ), 945 US_FL_SCM_MULT_TARG ),
946 946
947UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, 947UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100,
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index eb12182b2059..d25df51bb0d2 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -161,8 +161,17 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
161 return 0; 161 return 0;
162} 162}
163 163
164static void efifb_destroy(struct fb_info *info)
165{
166 if (info->screen_base)
167 iounmap(info->screen_base);
168 release_mem_region(info->aperture_base, info->aperture_size);
169 framebuffer_release(info);
170}
171
164static struct fb_ops efifb_ops = { 172static struct fb_ops efifb_ops = {
165 .owner = THIS_MODULE, 173 .owner = THIS_MODULE,
174 .fb_destroy = efifb_destroy,
166 .fb_setcolreg = efifb_setcolreg, 175 .fb_setcolreg = efifb_setcolreg,
167 .fb_fillrect = cfb_fillrect, 176 .fb_fillrect = cfb_fillrect,
168 .fb_copyarea = cfb_copyarea, 177 .fb_copyarea = cfb_copyarea,
@@ -281,7 +290,7 @@ static int __init efifb_probe(struct platform_device *dev)
281 info->par = NULL; 290 info->par = NULL;
282 291
283 info->aperture_base = efifb_fix.smem_start; 292 info->aperture_base = efifb_fix.smem_start;
284 info->aperture_size = size_total; 293 info->aperture_size = size_remap;
285 294
286 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); 295 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
287 if (!info->screen_base) { 296 if (!info->screen_base) {
diff --git a/drivers/watchdog/bfin_wdt.c b/drivers/watchdog/bfin_wdt.c
index c7b3f9df2317..2159e668751c 100644
--- a/drivers/watchdog/bfin_wdt.c
+++ b/drivers/watchdog/bfin_wdt.c
@@ -1,9 +1,8 @@
1/* 1/*
2 * Blackfin On-Chip Watchdog Driver 2 * Blackfin On-Chip Watchdog Driver
3 * Supports BF53[123]/BF53[467]/BF54[2489]/BF561
4 * 3 *
5 * Originally based on softdog.c 4 * Originally based on softdog.c
6 * Copyright 2006-2007 Analog Devices Inc. 5 * Copyright 2006-2010 Analog Devices Inc.
7 * Copyright 2006-2007 Michele d'Amico 6 * Copyright 2006-2007 Michele d'Amico
8 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk> 7 * Copyright 1996 Alan Cox <alan@lxorguk.ukuu.org.uk>
9 * 8 *
@@ -137,13 +136,15 @@ static int bfin_wdt_running(void)
137 */ 136 */
138static int bfin_wdt_set_timeout(unsigned long t) 137static int bfin_wdt_set_timeout(unsigned long t)
139{ 138{
140 u32 cnt; 139 u32 cnt, max_t, sclk;
141 unsigned long flags; 140 unsigned long flags;
142 141
143 stampit(); 142 sclk = get_sclk();
143 max_t = -1 / sclk;
144 cnt = t * sclk;
145 stamp("maxtimeout=%us newtimeout=%lus (cnt=%#x)", max_t, t, cnt);
144 146
145 cnt = t * get_sclk(); 147 if (t > max_t) {
146 if (cnt < get_sclk()) {
147 printk(KERN_WARNING PFX "timeout value is too large\n"); 148 printk(KERN_WARNING PFX "timeout value is too large\n");
148 return -EINVAL; 149 return -EINVAL;
149 } 150 }
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 9d0809629967..6ed434ac037f 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -720,13 +720,15 @@ again:
720 inode->i_ino, orig_offset); 720 inode->i_ino, orig_offset);
721 BUG_ON(ret); 721 BUG_ON(ret);
722 } 722 }
723 fi = btrfs_item_ptr(leaf, path->slots[0],
724 struct btrfs_file_extent_item);
725 if (del_nr == 0) { 723 if (del_nr == 0) {
724 fi = btrfs_item_ptr(leaf, path->slots[0],
725 struct btrfs_file_extent_item);
726 btrfs_set_file_extent_type(leaf, fi, 726 btrfs_set_file_extent_type(leaf, fi,
727 BTRFS_FILE_EXTENT_REG); 727 BTRFS_FILE_EXTENT_REG);
728 btrfs_mark_buffer_dirty(leaf); 728 btrfs_mark_buffer_dirty(leaf);
729 } else { 729 } else {
730 fi = btrfs_item_ptr(leaf, del_slot - 1,
731 struct btrfs_file_extent_item);
730 btrfs_set_file_extent_type(leaf, fi, 732 btrfs_set_file_extent_type(leaf, fi,
731 BTRFS_FILE_EXTENT_REG); 733 BTRFS_FILE_EXTENT_REG);
732 btrfs_set_file_extent_num_bytes(leaf, fi, 734 btrfs_set_file_extent_num_bytes(leaf, fi,
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index 14ac4806e291..eeb4986ea7db 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -348,7 +348,17 @@ int cachefiles_delete_object(struct cachefiles_cache *cache,
348 dir = dget_parent(object->dentry); 348 dir = dget_parent(object->dentry);
349 349
350 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); 350 mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
351 ret = cachefiles_bury_object(cache, dir, object->dentry); 351
352 /* we need to check that our parent is _still_ our parent - it may have
353 * been renamed */
354 if (dir == object->dentry->d_parent) {
355 ret = cachefiles_bury_object(cache, dir, object->dentry);
356 } else {
357 /* it got moved, presumably by cachefilesd culling it, so it's
358 * no longer in the key path and we can ignore it */
359 mutex_unlock(&dir->d_inode->i_mutex);
360 ret = 0;
361 }
352 362
353 dput(dir); 363 dput(dir);
354 _leave(" = %d", ret); 364 _leave(" = %d", ret);
diff --git a/fs/exec.c b/fs/exec.c
index e95c692ef0e4..cce6bbdbdbb1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -637,7 +637,6 @@ int setup_arg_pages(struct linux_binprm *bprm,
637 * will align it up. 637 * will align it up.
638 */ 638 */
639 rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK; 639 rlim_stack = rlimit(RLIMIT_STACK) & PAGE_MASK;
640 rlim_stack = min(rlim_stack, stack_size);
641#ifdef CONFIG_STACK_GROWSUP 640#ifdef CONFIG_STACK_GROWSUP
642 if (stack_size + stack_expand > rlim_stack) 641 if (stack_size + stack_expand > rlim_stack)
643 stack_base = vma->vm_start + rlim_stack; 642 stack_base = vma->vm_start + rlim_stack;
diff --git a/fs/namei.c b/fs/namei.c
index d62fdc875f22..a4855af776a8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -823,6 +823,17 @@ fail:
823} 823}
824 824
825/* 825/*
826 * This is a temporary kludge to deal with "automount" symlinks; proper
827 * solution is to trigger them on follow_mount(), so that do_lookup()
828 * would DTRT. To be killed before 2.6.34-final.
829 */
830static inline int follow_on_final(struct inode *inode, unsigned lookup_flags)
831{
832 return inode && unlikely(inode->i_op->follow_link) &&
833 ((lookup_flags & LOOKUP_FOLLOW) || S_ISDIR(inode->i_mode));
834}
835
836/*
826 * Name resolution. 837 * Name resolution.
827 * This is the basic name resolution function, turning a pathname into 838 * This is the basic name resolution function, turning a pathname into
828 * the final dentry. We expect 'base' to be positive and a directory. 839 * the final dentry. We expect 'base' to be positive and a directory.
@@ -942,8 +953,7 @@ last_component:
942 if (err) 953 if (err)
943 break; 954 break;
944 inode = next.dentry->d_inode; 955 inode = next.dentry->d_inode;
945 if ((lookup_flags & LOOKUP_FOLLOW) 956 if (follow_on_final(inode, lookup_flags)) {
946 && inode && inode->i_op->follow_link) {
947 err = do_follow_link(&next, nd); 957 err = do_follow_link(&next, nd);
948 if (err) 958 if (err)
949 goto return_err; 959 goto return_err;
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index e1d415e97849..0d289823e856 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -342,6 +342,7 @@ static ssize_t nfs_direct_read_schedule_segment(struct nfs_direct_req *dreq,
342 data->res.fattr = &data->fattr; 342 data->res.fattr = &data->fattr;
343 data->res.eof = 0; 343 data->res.eof = 0;
344 data->res.count = bytes; 344 data->res.count = bytes;
345 nfs_fattr_init(&data->fattr);
345 msg.rpc_argp = &data->args; 346 msg.rpc_argp = &data->args;
346 msg.rpc_resp = &data->res; 347 msg.rpc_resp = &data->res;
347 348
@@ -575,6 +576,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
575 data->res.count = 0; 576 data->res.count = 0;
576 data->res.fattr = &data->fattr; 577 data->res.fattr = &data->fattr;
577 data->res.verf = &data->verf; 578 data->res.verf = &data->verf;
579 nfs_fattr_init(&data->fattr);
578 580
579 NFS_PROTO(data->inode)->commit_setup(data, &msg); 581 NFS_PROTO(data->inode)->commit_setup(data, &msg);
580 582
@@ -766,6 +768,7 @@ static ssize_t nfs_direct_write_schedule_segment(struct nfs_direct_req *dreq,
766 data->res.fattr = &data->fattr; 768 data->res.fattr = &data->fattr;
767 data->res.count = bytes; 769 data->res.count = bytes;
768 data->res.verf = &data->verf; 770 data->res.verf = &data->verf;
771 nfs_fattr_init(&data->fattr);
769 772
770 task_setup_data.task = &data->task; 773 task_setup_data.task = &data->task;
771 task_setup_data.callback_data = data; 774 task_setup_data.callback_data = data;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 97d79eff6b7f..8715d194561a 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -752,7 +752,8 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
752 flags, current_cred()); 752 flags, current_cred());
753 if (IS_ERR(*filp)) 753 if (IS_ERR(*filp))
754 host_err = PTR_ERR(*filp); 754 host_err = PTR_ERR(*filp);
755 host_err = ima_file_check(*filp, access); 755 else
756 host_err = ima_file_check(*filp, access);
756out_nfserr: 757out_nfserr:
757 err = nfserrno(host_err); 758 err = nfserrno(host_err);
758out: 759out:
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e42bbd843ed1..58324c299165 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2369,16 +2369,30 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
2369{ 2369{
2370 struct pid_namespace *ns = dentry->d_sb->s_fs_info; 2370 struct pid_namespace *ns = dentry->d_sb->s_fs_info;
2371 pid_t tgid = task_tgid_nr_ns(current, ns); 2371 pid_t tgid = task_tgid_nr_ns(current, ns);
2372 char tmp[PROC_NUMBUF]; 2372 char *name = ERR_PTR(-ENOENT);
2373 if (!tgid) 2373 if (tgid) {
2374 return ERR_PTR(-ENOENT); 2374 name = __getname();
2375 sprintf(tmp, "%d", task_tgid_nr_ns(current, ns)); 2375 if (!name)
2376 return ERR_PTR(vfs_follow_link(nd,tmp)); 2376 name = ERR_PTR(-ENOMEM);
2377 else
2378 sprintf(name, "%d", tgid);
2379 }
2380 nd_set_link(nd, name);
2381 return NULL;
2382}
2383
2384static void proc_self_put_link(struct dentry *dentry, struct nameidata *nd,
2385 void *cookie)
2386{
2387 char *s = nd_get_link(nd);
2388 if (!IS_ERR(s))
2389 __putname(s);
2377} 2390}
2378 2391
2379static const struct inode_operations proc_self_inode_operations = { 2392static const struct inode_operations proc_self_inode_operations = {
2380 .readlink = proc_self_readlink, 2393 .readlink = proc_self_readlink,
2381 .follow_link = proc_self_follow_link, 2394 .follow_link = proc_self_follow_link,
2395 .put_link = proc_self_put_link,
2382}; 2396};
2383 2397
2384/* 2398/*
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 9087b10209e6..2df0f5c7c60b 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1497,9 +1497,11 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
1497 1497
1498 args.objectid = key->on_disk_key.k_objectid; 1498 args.objectid = key->on_disk_key.k_objectid;
1499 args.dirid = key->on_disk_key.k_dir_id; 1499 args.dirid = key->on_disk_key.k_dir_id;
1500 reiserfs_write_unlock(s);
1500 inode = iget5_locked(s, key->on_disk_key.k_objectid, 1501 inode = iget5_locked(s, key->on_disk_key.k_objectid,
1501 reiserfs_find_actor, reiserfs_init_locked_inode, 1502 reiserfs_find_actor, reiserfs_init_locked_inode,
1502 (void *)(&args)); 1503 (void *)(&args));
1504 reiserfs_write_lock(s);
1503 if (!inode) 1505 if (!inode)
1504 return ERR_PTR(-ENOMEM); 1506 return ERR_PTR(-ENOMEM);
1505 1507
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 220b758523ae..6a06a1d1ea7b 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -81,24 +81,23 @@ int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr)
81 if (!sd_attrs) 81 if (!sd_attrs)
82 return -ENOMEM; 82 return -ENOMEM;
83 sd->s_iattr = sd_attrs; 83 sd->s_iattr = sd_attrs;
84 } else { 84 }
85 /* attributes were changed at least once in past */ 85 /* attributes were changed at least once in past */
86 iattrs = &sd_attrs->ia_iattr; 86 iattrs = &sd_attrs->ia_iattr;
87 87
88 if (ia_valid & ATTR_UID) 88 if (ia_valid & ATTR_UID)
89 iattrs->ia_uid = iattr->ia_uid; 89 iattrs->ia_uid = iattr->ia_uid;
90 if (ia_valid & ATTR_GID) 90 if (ia_valid & ATTR_GID)
91 iattrs->ia_gid = iattr->ia_gid; 91 iattrs->ia_gid = iattr->ia_gid;
92 if (ia_valid & ATTR_ATIME) 92 if (ia_valid & ATTR_ATIME)
93 iattrs->ia_atime = iattr->ia_atime; 93 iattrs->ia_atime = iattr->ia_atime;
94 if (ia_valid & ATTR_MTIME) 94 if (ia_valid & ATTR_MTIME)
95 iattrs->ia_mtime = iattr->ia_mtime; 95 iattrs->ia_mtime = iattr->ia_mtime;
96 if (ia_valid & ATTR_CTIME) 96 if (ia_valid & ATTR_CTIME)
97 iattrs->ia_ctime = iattr->ia_ctime; 97 iattrs->ia_ctime = iattr->ia_ctime;
98 if (ia_valid & ATTR_MODE) { 98 if (ia_valid & ATTR_MODE) {
99 umode_t mode = iattr->ia_mode; 99 umode_t mode = iattr->ia_mode;
100 iattrs->ia_mode = sd->s_mode = mode; 100 iattrs->ia_mode = sd->s_mode = mode;
101 }
102 } 101 }
103 return 0; 102 return 0;
104} 103}
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index ab94335b4bb9..6816be6c3f77 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -1,5 +1,9 @@
1/* 1/*
2 * linux/include/asm-arm/hardware/amba.h 2 * linux/include/amba/bus.h
3 *
4 * This device type deals with ARM PrimeCells and anything else that
5 * presents a proper CID (0xB105F00D) at the end of the I/O register
6 * region or that is derived from a PrimeCell.
3 * 7 *
4 * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved. 8 * Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
5 * 9 *
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5c8018977efa..1896e868854f 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -461,8 +461,7 @@ struct request_queue
461#define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */ 461#define QUEUE_FLAG_NONROT 14 /* non-rotational device (SSD) */
462#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */ 462#define QUEUE_FLAG_VIRT QUEUE_FLAG_NONROT /* paravirt device */
463#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */ 463#define QUEUE_FLAG_IO_STAT 15 /* do IO stats */
464#define QUEUE_FLAG_CQ 16 /* hardware does queuing */ 464#define QUEUE_FLAG_DISCARD 16 /* supports DISCARD */
465#define QUEUE_FLAG_DISCARD 17 /* supports DISCARD */
466 465
467#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ 466#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
468 (1 << QUEUE_FLAG_CLUSTER) | \ 467 (1 << QUEUE_FLAG_CLUSTER) | \
@@ -586,7 +585,6 @@ enum {
586 585
587#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags) 586#define blk_queue_plugged(q) test_bit(QUEUE_FLAG_PLUGGED, &(q)->queue_flags)
588#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags) 587#define blk_queue_tagged(q) test_bit(QUEUE_FLAG_QUEUED, &(q)->queue_flags)
589#define blk_queue_queuing(q) test_bit(QUEUE_FLAG_CQ, &(q)->queue_flags)
590#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags) 588#define blk_queue_stopped(q) test_bit(QUEUE_FLAG_STOPPED, &(q)->queue_flags)
591#define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags) 589#define blk_queue_nomerges(q) test_bit(QUEUE_FLAG_NOMERGES, &(q)->queue_flags)
592#define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags) 590#define blk_queue_nonrot(q) test_bit(QUEUE_FLAG_NONROT, &(q)->queue_flags)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b1bcb275b596..ebb1cd5bc241 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -729,6 +729,7 @@ struct inode {
729 uid_t i_uid; 729 uid_t i_uid;
730 gid_t i_gid; 730 gid_t i_gid;
731 dev_t i_rdev; 731 dev_t i_rdev;
732 unsigned int i_blkbits;
732 u64 i_version; 733 u64 i_version;
733 loff_t i_size; 734 loff_t i_size;
734#ifdef __NEED_I_SIZE_ORDERED 735#ifdef __NEED_I_SIZE_ORDERED
@@ -738,7 +739,6 @@ struct inode {
738 struct timespec i_mtime; 739 struct timespec i_mtime;
739 struct timespec i_ctime; 740 struct timespec i_ctime;
740 blkcnt_t i_blocks; 741 blkcnt_t i_blocks;
741 unsigned int i_blkbits;
742 unsigned short i_bytes; 742 unsigned short i_bytes;
743 umode_t i_mode; 743 umode_t i_mode;
744 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ 744 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h
index 070ba0621738..5977b724f7c6 100644
--- a/include/linux/hw_breakpoint.h
+++ b/include/linux/hw_breakpoint.h
@@ -44,7 +44,7 @@ static inline int hw_breakpoint_type(struct perf_event *bp)
44 return bp->attr.bp_type; 44 return bp->attr.bp_type;
45} 45}
46 46
47static inline int hw_breakpoint_len(struct perf_event *bp) 47static inline unsigned long hw_breakpoint_len(struct perf_event *bp)
48{ 48{
49 return bp->attr.bp_len; 49 return bp->attr.bp_len;
50} 50}
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index bf1c5be1f5b6..7897f3096560 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -547,6 +547,10 @@ struct twl4030_codec_data {
547 unsigned int audio_mclk; 547 unsigned int audio_mclk;
548 struct twl4030_codec_audio_data *audio; 548 struct twl4030_codec_audio_data *audio;
549 struct twl4030_codec_vibra_data *vibra; 549 struct twl4030_codec_vibra_data *vibra;
550
551 /* twl6030 */
552 int audpwron_gpio; /* audio power-on gpio */
553 int naudint_irq; /* audio interrupt */
550}; 554};
551 555
552struct twl4030_platform_data { 556struct twl4030_platform_data {
diff --git a/include/linux/input.h b/include/linux/input.h
index 735ceaf1bc2d..663208afb64c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -376,6 +376,7 @@ struct input_absinfo {
376#define KEY_DISPLAY_OFF 245 /* display device to off state */ 376#define KEY_DISPLAY_OFF 245 /* display device to off state */
377 377
378#define KEY_WIMAX 246 378#define KEY_WIMAX 246
379#define KEY_RFKILL 247 /* Key that controls all radios */
379 380
380/* Range 248 - 255 is reserved for special needs of AT keyboard driver */ 381/* Range 248 - 255 is reserved for special needs of AT keyboard driver */
381 382
diff --git a/include/linux/kfifo.h b/include/linux/kfifo.h
index 6f6c5f300af6..bc0fc795bd35 100644
--- a/include/linux/kfifo.h
+++ b/include/linux/kfifo.h
@@ -124,7 +124,7 @@ extern __must_check unsigned int kfifo_out_peek(struct kfifo *fifo,
124 */ 124 */
125static inline bool kfifo_initialized(struct kfifo *fifo) 125static inline bool kfifo_initialized(struct kfifo *fifo)
126{ 126{
127 return fifo->buffer != 0; 127 return fifo->buffer != NULL;
128} 128}
129 129
130/** 130/**
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 8fa71874113f..a177698d95e2 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -211,11 +211,9 @@ struct perf_event_attr {
211 __u32 wakeup_watermark; /* bytes before wakeup */ 211 __u32 wakeup_watermark; /* bytes before wakeup */
212 }; 212 };
213 213
214 __u32 __reserved_2;
215
216 __u64 bp_addr;
217 __u32 bp_type; 214 __u32 bp_type;
218 __u32 bp_len; 215 __u64 bp_addr;
216 __u64 bp_len;
219}; 217};
220 218
221/* 219/*
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index ca24e7f7a3f5..061f16d4c878 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -16,6 +16,8 @@
16 16
17#include <linux/list.h> 17#include <linux/list.h>
18 18
19#include <sound/soc.h>
20
19struct snd_pcm_substream; 21struct snd_pcm_substream;
20 22
21/* 23/*
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index c5c95e1da65b..c0922a034223 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -95,6 +95,21 @@
95 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ 95 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \
96 .num_kcontrols = 1} 96 .num_kcontrols = 1}
97 97
98/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
99#define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\
100 wcontrols) \
101{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
102 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
103#define SOC_MIXER_ARRAY(wname, wreg, wshift, winvert, \
104 wcontrols)\
105{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
106 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols)}
107#define SOC_MIXER_NAMED_CTL_ARRAY(wname, wreg, wshift, winvert, \
108 wcontrols)\
109{ .id = snd_soc_dapm_mixer_named_ctl, .name = wname, .reg = wreg, \
110 .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \
111 .num_kcontrols = ARRAY_SIZE(wcontrols)}
112
98/* path domain with event - event handler must return 0 for success */ 113/* path domain with event - event handler must return 0 for success */
99#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \ 114#define SND_SOC_DAPM_PGA_E(wname, wreg, wshift, winvert, wcontrols, \
100 wncontrols, wevent, wflags) \ 115 wncontrols, wevent, wflags) \
@@ -126,6 +141,23 @@
126 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ 141 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \
127 .event = wevent, .event_flags = wflags} 142 .event = wevent, .event_flags = wflags}
128 143
144/* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */
145#define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
146 wevent, wflags) \
147{ .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \
148 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
149 .event = wevent, .event_flags = wflags}
150#define SOC_MIXER_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \
151 wevent, wflags) \
152{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
153 .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = ARRAY_SIZE(wcontrols), \
154 .event = wevent, .event_flags = wflags}
155#define SOC_MIXER_NAMED_CTL_E_ARRAY(wname, wreg, wshift, winvert, \
156 wcontrols, wevent, wflags) \
157{ .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \
158 .invert = winvert, .kcontrols = wcontrols, \
159 .num_kcontrols = ARRAY_SIZE(wcontrols), .event = wevent, .event_flags = wflags}
160
129/* events that are pre and post DAPM */ 161/* events that are pre and post DAPM */
130#define SND_SOC_DAPM_PRE(wname, wevent) \ 162#define SND_SOC_DAPM_PRE(wname, wevent) \
131{ .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \ 163{ .id = snd_soc_dapm_pre, .name = wname, .kcontrols = NULL, \
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0d7718f9280d..5d234a8c2506 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -169,6 +169,23 @@
169 .private_value = (unsigned long)&xenum } 169 .private_value = (unsigned long)&xenum }
170 170
171/* 171/*
172 * Simplified versions of above macros, declaring a struct and calculating
173 * ARRAY_SIZE internally
174 */
175#define SOC_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xtexts) \
176 struct soc_enum name = SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, \
177 ARRAY_SIZE(xtexts), xtexts)
178#define SOC_ENUM_SINGLE_DECL(name, xreg, xshift, xtexts) \
179 SOC_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xtexts)
180#define SOC_ENUM_SINGLE_EXT_DECL(name, xtexts) \
181 struct soc_enum name = SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(xtexts), xtexts)
182#define SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift_l, xshift_r, xmask, xtexts, xvalues) \
183 struct soc_enum name = SOC_VALUE_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, \
184 ARRAY_SIZE(xtexts), xtexts, xvalues)
185#define SOC_VALUE_ENUM_SINGLE_DECL(name, xreg, xshift, xmask, xtexts, xvalues) \
186 SOC_VALUE_ENUM_DOUBLE_DECL(name, xreg, xshift, xshift, xmask, xtexts, xvalues)
187
188/*
172 * Bias levels 189 * Bias levels
173 * 190 *
174 * @ON: Bias is fully on for audio playback and capture operations. 191 * @ON: Bias is fully on for audio playback and capture operations.
@@ -253,6 +270,9 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count,
253/* codec register bit access */ 270/* codec register bit access */
254int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, 271int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
255 unsigned int mask, unsigned int value); 272 unsigned int mask, unsigned int value);
273int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
274 unsigned short reg, unsigned int mask,
275 unsigned int value);
256int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, 276int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
257 unsigned int mask, unsigned int value); 277 unsigned int mask, unsigned int value);
258 278
@@ -402,6 +422,10 @@ struct snd_soc_codec {
402 short reg_cache_size; 422 short reg_cache_size;
403 short reg_cache_step; 423 short reg_cache_step;
404 424
425 unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */
426 unsigned int cache_only:1; /* Suppress writes to hardware */
427 unsigned int cache_sync:1; /* Cache needs to be synced to hardware */
428
405 /* dapm */ 429 /* dapm */
406 u32 pop_time; 430 u32 pop_time;
407 struct list_head dapm_widgets; 431 struct list_head dapm_widgets;
@@ -497,6 +521,8 @@ struct snd_soc_card {
497 int (*set_bias_level)(struct snd_soc_card *, 521 int (*set_bias_level)(struct snd_soc_card *,
498 enum snd_soc_bias_level level); 522 enum snd_soc_bias_level level);
499 523
524 long pmdown_time;
525
500 /* CPU <--> Codec DAI links */ 526 /* CPU <--> Codec DAI links */
501 struct snd_soc_dai_link *dai_link; 527 struct snd_soc_dai_link *dai_link;
502 int num_links; 528 int num_links;
diff --git a/include/sound/tlv320dac33-plat.h b/include/sound/tlv320dac33-plat.h
index 5858d06a7ffa..ac0665264bdf 100644
--- a/include/sound/tlv320dac33-plat.h
+++ b/include/sound/tlv320dac33-plat.h
@@ -15,6 +15,7 @@
15 15
16struct tlv320dac33_platform_data { 16struct tlv320dac33_platform_data {
17 int power_gpio; 17 int power_gpio;
18 u8 burst_bclkdiv;
18}; 19};
19 20
20#endif /* __TLV320DAC33_PLAT_H */ 21#endif /* __TLV320DAC33_PLAT_H */
diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h
index e8c901e749d8..e29fde6b5cbe 100644
--- a/include/sound/tpa6130a2-plat.h
+++ b/include/sound/tpa6130a2-plat.h
@@ -23,7 +23,13 @@
23#ifndef TPA6130A2_PLAT_H 23#ifndef TPA6130A2_PLAT_H
24#define TPA6130A2_PLAT_H 24#define TPA6130A2_PLAT_H
25 25
26enum tpa_model {
27 TPA6130A2,
28 TPA6140A2,
29};
30
26struct tpa6130a2_platform_data { 31struct tpa6130a2_platform_data {
32 enum tpa_model id;
27 int power_gpio; 33 int power_gpio;
28}; 34};
29 35
diff --git a/include/sound/wm2000.h b/include/sound/wm2000.h
new file mode 100644
index 000000000000..aa388ca9ec64
--- /dev/null
+++ b/include/sound/wm2000.h
@@ -0,0 +1,26 @@
1/*
2 * linux/sound/wm2000.h -- Platform data for WM2000
3 *
4 * Copyright 2010 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_WM2000_H
12#define __LINUX_SND_WM2000_H
13
14struct wm2000_platform_data {
15 /** Filename for system-specific image to download to device. */
16 const char *download_file;
17
18 /** Divide MCLK by 2 for system clock? */
19 unsigned int mclkdiv2:1;
20
21 /** Disable speech clarity enhancement, for use when an
22 * external algorithm is used. */
23 unsigned int speech_enh_disable:1;
24};
25
26#endif
diff --git a/include/sound/wm8904.h b/include/sound/wm8904.h
new file mode 100644
index 000000000000..d66575a601be
--- /dev/null
+++ b/include/sound/wm8904.h
@@ -0,0 +1,57 @@
1/*
2 * Platform data for WM8904
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
15#ifndef __MFD_WM8994_PDATA_H__
16#define __MFD_WM8994_PDATA_H__
17
18#define WM8904_DRC_REGS 4
19#define WM8904_EQ_REGS 25
20
21/**
22 * DRC configurations are specified with a label and a set of register
23 * values to write (the enable bits will be ignored). At runtime an
24 * enumerated control will be presented for each DRC block allowing
25 * the user to choose the configration to use.
26 *
27 * Configurations may be generated by hand or by using the DRC control
28 * panel provided by the WISCE - see http://www.wolfsonmicro.com/wisce/
29 * for details.
30 */
31struct wm8904_drc_cfg {
32 const char *name;
33 u16 regs[WM8904_DRC_REGS];
34};
35
36/**
37 * ReTune Mobile configurations are specified with a label, sample
38 * rate and set of values to write (the enable bits will be ignored).
39 *
40 * Configurations are expected to be generated using the ReTune Mobile
41 * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/
42 */
43struct wm8904_retune_mobile_cfg {
44 const char *name;
45 unsigned int rate;
46 u16 regs[WM8904_EQ_REGS];
47};
48
49struct wm8904_pdata {
50 int num_drc_cfgs;
51 struct wm8904_drc_cfg *drc_cfgs;
52
53 int num_retune_mobile_cfgs;
54 struct wm8904_retune_mobile_cfg *retune_mobile_cfgs;
55};
56
57#endif
diff --git a/include/sound/wm8955.h b/include/sound/wm8955.h
new file mode 100644
index 000000000000..5074ef499f40
--- /dev/null
+++ b/include/sound/wm8955.h
@@ -0,0 +1,26 @@
1/*
2 * Platform data for WM8955
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
15#ifndef __WM8955_PDATA_H__
16#define __WM8955_PDATA_H__
17
18struct wm8955_pdata {
19 /* Configure LOUT2/ROUT2 to drive a speaker */
20 unsigned int out2_speaker:1;
21
22 /* Configure MONOIN+/- in differential mode */
23 unsigned int monoin_diff:1;
24};
25
26#endif
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c
index 8a5c7d55ac9f..967e66143e11 100644
--- a/kernel/hw_breakpoint.c
+++ b/kernel/hw_breakpoint.c
@@ -360,8 +360,8 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
360int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) 360int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr)
361{ 361{
362 u64 old_addr = bp->attr.bp_addr; 362 u64 old_addr = bp->attr.bp_addr;
363 u64 old_len = bp->attr.bp_len;
363 int old_type = bp->attr.bp_type; 364 int old_type = bp->attr.bp_type;
364 int old_len = bp->attr.bp_len;
365 int err = 0; 365 int err = 0;
366 366
367 perf_event_disable(bp); 367 perf_event_disable(bp);
diff --git a/kernel/kfifo.c b/kernel/kfifo.c
index 498cabba225e..35edbe22e9a9 100644
--- a/kernel/kfifo.c
+++ b/kernel/kfifo.c
@@ -80,7 +80,7 @@ int kfifo_alloc(struct kfifo *fifo, unsigned int size, gfp_t gfp_mask)
80 80
81 buffer = kmalloc(size, gfp_mask); 81 buffer = kmalloc(size, gfp_mask);
82 if (!buffer) { 82 if (!buffer) {
83 _kfifo_init(fifo, 0, 0); 83 _kfifo_init(fifo, NULL, 0);
84 return -ENOMEM; 84 return -ENOMEM;
85 } 85 }
86 86
@@ -97,6 +97,7 @@ EXPORT_SYMBOL(kfifo_alloc);
97void kfifo_free(struct kfifo *fifo) 97void kfifo_free(struct kfifo *fifo)
98{ 98{
99 kfree(fifo->buffer); 99 kfree(fifo->buffer);
100 _kfifo_init(fifo, NULL, 0);
100} 101}
101EXPORT_SYMBOL(kfifo_free); 102EXPORT_SYMBOL(kfifo_free);
102 103
diff --git a/kernel/perf_event.c b/kernel/perf_event.c
index d27746bd3a06..2ae7409bf38f 100644
--- a/kernel/perf_event.c
+++ b/kernel/perf_event.c
@@ -3259,8 +3259,6 @@ static void perf_event_task_output(struct perf_event *event,
3259 task_event->event_id.tid = perf_event_tid(event, task); 3259 task_event->event_id.tid = perf_event_tid(event, task);
3260 task_event->event_id.ptid = perf_event_tid(event, current); 3260 task_event->event_id.ptid = perf_event_tid(event, current);
3261 3261
3262 task_event->event_id.time = perf_clock();
3263
3264 perf_output_put(&handle, task_event->event_id); 3262 perf_output_put(&handle, task_event->event_id);
3265 3263
3266 perf_output_end(&handle); 3264 perf_output_end(&handle);
@@ -3268,7 +3266,7 @@ static void perf_event_task_output(struct perf_event *event,
3268 3266
3269static int perf_event_task_match(struct perf_event *event) 3267static int perf_event_task_match(struct perf_event *event)
3270{ 3268{
3271 if (event->state != PERF_EVENT_STATE_ACTIVE) 3269 if (event->state < PERF_EVENT_STATE_INACTIVE)
3272 return 0; 3270 return 0;
3273 3271
3274 if (event->cpu != -1 && event->cpu != smp_processor_id()) 3272 if (event->cpu != -1 && event->cpu != smp_processor_id())
@@ -3300,7 +3298,7 @@ static void perf_event_task_event(struct perf_task_event *task_event)
3300 cpuctx = &get_cpu_var(perf_cpu_context); 3298 cpuctx = &get_cpu_var(perf_cpu_context);
3301 perf_event_task_ctx(&cpuctx->ctx, task_event); 3299 perf_event_task_ctx(&cpuctx->ctx, task_event);
3302 if (!ctx) 3300 if (!ctx)
3303 ctx = rcu_dereference(task_event->task->perf_event_ctxp); 3301 ctx = rcu_dereference(current->perf_event_ctxp);
3304 if (ctx) 3302 if (ctx)
3305 perf_event_task_ctx(ctx, task_event); 3303 perf_event_task_ctx(ctx, task_event);
3306 put_cpu_var(perf_cpu_context); 3304 put_cpu_var(perf_cpu_context);
@@ -3331,6 +3329,7 @@ static void perf_event_task(struct task_struct *task,
3331 /* .ppid */ 3329 /* .ppid */
3332 /* .tid */ 3330 /* .tid */
3333 /* .ptid */ 3331 /* .ptid */
3332 .time = perf_clock(),
3334 }, 3333 },
3335 }; 3334 };
3336 3335
@@ -3380,7 +3379,7 @@ static void perf_event_comm_output(struct perf_event *event,
3380 3379
3381static int perf_event_comm_match(struct perf_event *event) 3380static int perf_event_comm_match(struct perf_event *event)
3382{ 3381{
3383 if (event->state != PERF_EVENT_STATE_ACTIVE) 3382 if (event->state < PERF_EVENT_STATE_INACTIVE)
3384 return 0; 3383 return 0;
3385 3384
3386 if (event->cpu != -1 && event->cpu != smp_processor_id()) 3385 if (event->cpu != -1 && event->cpu != smp_processor_id())
@@ -3500,7 +3499,7 @@ static void perf_event_mmap_output(struct perf_event *event,
3500static int perf_event_mmap_match(struct perf_event *event, 3499static int perf_event_mmap_match(struct perf_event *event,
3501 struct perf_mmap_event *mmap_event) 3500 struct perf_mmap_event *mmap_event)
3502{ 3501{
3503 if (event->state != PERF_EVENT_STATE_ACTIVE) 3502 if (event->state < PERF_EVENT_STATE_INACTIVE)
3504 return 0; 3503 return 0;
3505 3504
3506 if (event->cpu != -1 && event->cpu != smp_processor_id()) 3505 if (event->cpu != -1 && event->cpu != smp_processor_id())
@@ -4580,7 +4579,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
4580 if (attr->type >= PERF_TYPE_MAX) 4579 if (attr->type >= PERF_TYPE_MAX)
4581 return -EINVAL; 4580 return -EINVAL;
4582 4581
4583 if (attr->__reserved_1 || attr->__reserved_2) 4582 if (attr->__reserved_1)
4584 return -EINVAL; 4583 return -EINVAL;
4585 4584
4586 if (attr->sample_type & ~(PERF_SAMPLE_MAX-1)) 4585 if (attr->sample_type & ~(PERF_SAMPLE_MAX-1))
diff --git a/kernel/softirq.c b/kernel/softirq.c
index a09502e2ef75..7c1a67ef0274 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -500,22 +500,17 @@ EXPORT_SYMBOL(tasklet_kill);
500 */ 500 */
501 501
502/* 502/*
503 * The trampoline is called when the hrtimer expires. If this is 503 * The trampoline is called when the hrtimer expires. It schedules a tasklet
504 * called from the hrtimer interrupt then we schedule the tasklet as 504 * to run __tasklet_hrtimer_trampoline() which in turn will call the intended
505 * the timer callback function expects to run in softirq context. If 505 * hrtimer callback, but from softirq context.
506 * it's called in softirq context anyway (i.e. high resolution timers
507 * disabled) then the hrtimer callback is called right away.
508 */ 506 */
509static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer) 507static enum hrtimer_restart __hrtimer_tasklet_trampoline(struct hrtimer *timer)
510{ 508{
511 struct tasklet_hrtimer *ttimer = 509 struct tasklet_hrtimer *ttimer =
512 container_of(timer, struct tasklet_hrtimer, timer); 510 container_of(timer, struct tasklet_hrtimer, timer);
513 511
514 if (hrtimer_is_hres_active(timer)) { 512 tasklet_hi_schedule(&ttimer->tasklet);
515 tasklet_hi_schedule(&ttimer->tasklet); 513 return HRTIMER_NORESTART;
516 return HRTIMER_NORESTART;
517 }
518 return ttimer->function(timer);
519} 514}
520 515
521/* 516/*
diff --git a/kernel/sys.c b/kernel/sys.c
index 26a6b73a6b85..18bde979f346 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -222,6 +222,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
222 if (which > PRIO_USER || which < PRIO_PROCESS) 222 if (which > PRIO_USER || which < PRIO_PROCESS)
223 return -EINVAL; 223 return -EINVAL;
224 224
225 rcu_read_lock();
225 read_lock(&tasklist_lock); 226 read_lock(&tasklist_lock);
226 switch (which) { 227 switch (which) {
227 case PRIO_PROCESS: 228 case PRIO_PROCESS:
@@ -267,6 +268,7 @@ SYSCALL_DEFINE2(getpriority, int, which, int, who)
267 } 268 }
268out_unlock: 269out_unlock:
269 read_unlock(&tasklist_lock); 270 read_unlock(&tasklist_lock);
271 rcu_read_unlock();
270 272
271 return retval; 273 return retval;
272} 274}
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 6ea90c0e2c96..50b1b8239806 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -689,7 +689,7 @@ static int create_trace_probe(int argc, char **argv)
689 return -EINVAL; 689 return -EINVAL;
690 } 690 }
691 /* an address specified */ 691 /* an address specified */
692 ret = strict_strtoul(&argv[0][2], 0, (unsigned long *)&addr); 692 ret = strict_strtoul(&argv[1][0], 0, (unsigned long *)&addr);
693 if (ret) { 693 if (ret) {
694 pr_info("Failed to parse address.\n"); 694 pr_info("Failed to parse address.\n");
695 return ret; 695 return ret;
diff --git a/kernel/trace/trace_stack.c b/kernel/trace/trace_stack.c
index 678a5120ee30..f4bc9b27de5f 100644
--- a/kernel/trace/trace_stack.c
+++ b/kernel/trace/trace_stack.c
@@ -157,6 +157,7 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
157 unsigned long val, flags; 157 unsigned long val, flags;
158 char buf[64]; 158 char buf[64];
159 int ret; 159 int ret;
160 int cpu;
160 161
161 if (count >= sizeof(buf)) 162 if (count >= sizeof(buf))
162 return -EINVAL; 163 return -EINVAL;
@@ -171,9 +172,20 @@ stack_max_size_write(struct file *filp, const char __user *ubuf,
171 return ret; 172 return ret;
172 173
173 local_irq_save(flags); 174 local_irq_save(flags);
175
176 /*
177 * In case we trace inside arch_spin_lock() or after (NMI),
178 * we will cause circular lock, so we also need to increase
179 * the percpu trace_active here.
180 */
181 cpu = smp_processor_id();
182 per_cpu(trace_active, cpu)++;
183
174 arch_spin_lock(&max_stack_lock); 184 arch_spin_lock(&max_stack_lock);
175 *ptr = val; 185 *ptr = val;
176 arch_spin_unlock(&max_stack_lock); 186 arch_spin_unlock(&max_stack_lock);
187
188 per_cpu(trace_active, cpu)--;
177 local_irq_restore(flags); 189 local_irq_restore(flags);
178 190
179 return count; 191 return count;
@@ -206,7 +218,13 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
206 218
207static void *t_start(struct seq_file *m, loff_t *pos) 219static void *t_start(struct seq_file *m, loff_t *pos)
208{ 220{
221 int cpu;
222
209 local_irq_disable(); 223 local_irq_disable();
224
225 cpu = smp_processor_id();
226 per_cpu(trace_active, cpu)++;
227
210 arch_spin_lock(&max_stack_lock); 228 arch_spin_lock(&max_stack_lock);
211 229
212 if (*pos == 0) 230 if (*pos == 0)
@@ -217,7 +235,13 @@ static void *t_start(struct seq_file *m, loff_t *pos)
217 235
218static void t_stop(struct seq_file *m, void *p) 236static void t_stop(struct seq_file *m, void *p)
219{ 237{
238 int cpu;
239
220 arch_spin_unlock(&max_stack_lock); 240 arch_spin_unlock(&max_stack_lock);
241
242 cpu = smp_processor_id();
243 per_cpu(trace_active, cpu)--;
244
221 local_irq_enable(); 245 local_irq_enable();
222} 246}
223 247
diff --git a/lib/idr.c b/lib/idr.c
index 1cac726c44bc..0dc782216d4b 100644
--- a/lib/idr.c
+++ b/lib/idr.c
@@ -156,10 +156,12 @@ static int sub_alloc(struct idr *idp, int *starting_id, struct idr_layer **pa)
156 id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1; 156 id = (id | ((1 << (IDR_BITS * l)) - 1)) + 1;
157 157
158 /* if already at the top layer, we need to grow */ 158 /* if already at the top layer, we need to grow */
159 if (!(p = pa[l])) { 159 if (id >= 1 << (idp->layers * IDR_BITS)) {
160 *starting_id = id; 160 *starting_id = id;
161 return IDR_NEED_TO_GROW; 161 return IDR_NEED_TO_GROW;
162 } 162 }
163 p = pa[l];
164 BUG_ON(!p);
163 165
164 /* If we need to go up one layer, continue the 166 /* If we need to go up one layer, continue the
165 * loop; otherwise, restart from the top. 167 * loop; otherwise, restart from the top.
diff --git a/mm/migrate.c b/mm/migrate.c
index 9a0db5bbabe4..880bd592d38e 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1002,33 +1002,27 @@ static int do_pages_stat(struct mm_struct *mm, unsigned long nr_pages,
1002#define DO_PAGES_STAT_CHUNK_NR 16 1002#define DO_PAGES_STAT_CHUNK_NR 16
1003 const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR]; 1003 const void __user *chunk_pages[DO_PAGES_STAT_CHUNK_NR];
1004 int chunk_status[DO_PAGES_STAT_CHUNK_NR]; 1004 int chunk_status[DO_PAGES_STAT_CHUNK_NR];
1005 unsigned long i, chunk_nr = DO_PAGES_STAT_CHUNK_NR;
1006 int err;
1007 1005
1008 for (i = 0; i < nr_pages; i += chunk_nr) { 1006 while (nr_pages) {
1009 if (chunk_nr > nr_pages - i) 1007 unsigned long chunk_nr;
1010 chunk_nr = nr_pages - i;
1011 1008
1012 err = copy_from_user(chunk_pages, &pages[i], 1009 chunk_nr = nr_pages;
1013 chunk_nr * sizeof(*chunk_pages)); 1010 if (chunk_nr > DO_PAGES_STAT_CHUNK_NR)
1014 if (err) { 1011 chunk_nr = DO_PAGES_STAT_CHUNK_NR;
1015 err = -EFAULT; 1012
1016 goto out; 1013 if (copy_from_user(chunk_pages, pages, chunk_nr * sizeof(*chunk_pages)))
1017 } 1014 break;
1018 1015
1019 do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status); 1016 do_pages_stat_array(mm, chunk_nr, chunk_pages, chunk_status);
1020 1017
1021 err = copy_to_user(&status[i], chunk_status, 1018 if (copy_to_user(status, chunk_status, chunk_nr * sizeof(*status)))
1022 chunk_nr * sizeof(*chunk_status)); 1019 break;
1023 if (err) {
1024 err = -EFAULT;
1025 goto out;
1026 }
1027 }
1028 err = 0;
1029 1020
1030out: 1021 pages += chunk_nr;
1031 return err; 1022 status += chunk_nr;
1023 nr_pages -= chunk_nr;
1024 }
1025 return nr_pages ? -EFAULT : 0;
1032} 1026}
1033 1027
1034/* 1028/*
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f52481b1c1e5..237050478f28 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -459,6 +459,8 @@ static int oom_kill_process(struct task_struct *p, gfp_t gfp_mask, int order,
459 list_for_each_entry(c, &p->children, sibling) { 459 list_for_each_entry(c, &p->children, sibling) {
460 if (c->mm == p->mm) 460 if (c->mm == p->mm)
461 continue; 461 continue;
462 if (mem && !task_in_mem_cgroup(c, mem))
463 continue;
462 if (!oom_kill_task(c)) 464 if (!oom_kill_task(c))
463 return 0; 465 return 0;
464 } 466 }
diff --git a/net/core/dev.c b/net/core/dev.c
index be9924f60ec3..ec874218b206 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2761,7 +2761,7 @@ gro_result_t napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb,
2761 switch (ret) { 2761 switch (ret) {
2762 case GRO_NORMAL: 2762 case GRO_NORMAL:
2763 case GRO_HELD: 2763 case GRO_HELD:
2764 skb->protocol = eth_type_trans(skb, napi->dev); 2764 skb->protocol = eth_type_trans(skb, skb->dev);
2765 2765
2766 if (ret == GRO_HELD) 2766 if (ret == GRO_HELD)
2767 skb_gro_pull(skb, -ETH_HLEN); 2767 skb_gro_pull(skb, -ETH_HLEN);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index d8aee584e8d1..236a9988ea91 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -927,6 +927,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
927 case ETHTOOL_GPERMADDR: 927 case ETHTOOL_GPERMADDR:
928 case ETHTOOL_GUFO: 928 case ETHTOOL_GUFO:
929 case ETHTOOL_GGSO: 929 case ETHTOOL_GGSO:
930 case ETHTOOL_GGRO:
930 case ETHTOOL_GFLAGS: 931 case ETHTOOL_GFLAGS:
931 case ETHTOOL_GPFLAGS: 932 case ETHTOOL_GPFLAGS:
932 case ETHTOOL_GRXFH: 933 case ETHTOOL_GRXFH:
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index fbc1c7472c5e..099c753c4213 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -410,7 +410,8 @@ static ssize_t wireless_show(struct device *d, char *buf,
410 const struct iw_statistics *iw; 410 const struct iw_statistics *iw;
411 ssize_t ret = -EINVAL; 411 ssize_t ret = -EINVAL;
412 412
413 rtnl_lock(); 413 if (!rtnl_trylock())
414 return restart_syscall();
414 if (dev_isalive(dev)) { 415 if (dev_isalive(dev)) {
415 iw = get_wireless_stats(dev); 416 iw = get_wireless_stats(dev);
416 if (iw) 417 if (iw)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 040c4f05b653..26dec2be9615 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1317,14 +1317,19 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
1317{ 1317{
1318 int *valp = ctl->data; 1318 int *valp = ctl->data;
1319 int val = *valp; 1319 int val = *valp;
1320 loff_t pos = *ppos;
1320 int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 1321 int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
1321 1322
1322 if (write && *valp != val) { 1323 if (write && *valp != val) {
1323 struct net *net = ctl->extra2; 1324 struct net *net = ctl->extra2;
1324 1325
1325 if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) { 1326 if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
1326 if (!rtnl_trylock()) 1327 if (!rtnl_trylock()) {
1328 /* Restore the original values before restarting */
1329 *valp = val;
1330 *ppos = pos;
1327 return restart_syscall(); 1331 return restart_syscall();
1332 }
1328 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) { 1333 if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
1329 inet_forward_change(net); 1334 inet_forward_change(net);
1330 } else if (*valp) { 1335 } else if (*valp) {
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 76c08402c933..a42f658e756a 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -946,7 +946,6 @@ int igmp_rcv(struct sk_buff *skb)
946 break; 946 break;
947 case IGMP_HOST_MEMBERSHIP_REPORT: 947 case IGMP_HOST_MEMBERSHIP_REPORT:
948 case IGMPV2_HOST_MEMBERSHIP_REPORT: 948 case IGMPV2_HOST_MEMBERSHIP_REPORT:
949 case IGMPV3_HOST_MEMBERSHIP_REPORT:
950 /* Is it our report looped back? */ 949 /* Is it our report looped back? */
951 if (skb_rtable(skb)->fl.iif == 0) 950 if (skb_rtable(skb)->fl.iif == 0)
952 break; 951 break;
@@ -960,6 +959,7 @@ int igmp_rcv(struct sk_buff *skb)
960 in_dev_put(in_dev); 959 in_dev_put(in_dev);
961 return pim_rcv_v1(skb); 960 return pim_rcv_v1(skb);
962#endif 961#endif
962 case IGMPV3_HOST_MEMBERSHIP_REPORT:
963 case IGMP_DVMRP: 963 case IGMP_DVMRP:
964 case IGMP_TRACE: 964 case IGMP_TRACE:
965 case IGMP_HOST_LEAVE_MESSAGE: 965 case IGMP_HOST_LEAVE_MESSAGE:
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 38fbf04150ae..544ce0876f12 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -124,16 +124,12 @@ static int ipcomp4_init_state(struct xfrm_state *x)
124 if (x->props.mode == XFRM_MODE_TUNNEL) { 124 if (x->props.mode == XFRM_MODE_TUNNEL) {
125 err = ipcomp_tunnel_attach(x); 125 err = ipcomp_tunnel_attach(x);
126 if (err) 126 if (err)
127 goto error_tunnel; 127 goto out;
128 } 128 }
129 129
130 err = 0; 130 err = 0;
131out: 131out:
132 return err; 132 return err;
133
134error_tunnel:
135 ipcomp_destroy(x);
136 goto out;
137} 133}
138 134
139static const struct xfrm_type ipcomp_type = { 135static const struct xfrm_type ipcomp_type = {
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 28e029632493..3fddc69ccccc 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5783,11 +5783,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5783 5783
5784 /* tcp_ack considers this ACK as duplicate 5784 /* tcp_ack considers this ACK as duplicate
5785 * and does not calculate rtt. 5785 * and does not calculate rtt.
5786 * Fix it at least with timestamps. 5786 * Force it here.
5787 */ 5787 */
5788 if (tp->rx_opt.saw_tstamp && 5788 tcp_ack_update_rtt(sk, 0, 0);
5789 tp->rx_opt.rcv_tsecr && !tp->srtt)
5790 tcp_ack_saw_tstamp(sk, 0);
5791 5789
5792 if (tp->rx_opt.tstamp_ok) 5790 if (tp->rx_opt.tstamp_ok)
5793 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED; 5791 tp->advmss -= TCPOLEN_TSTAMP_ALIGNED;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index de7a194a64ab..143791da062c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -502,8 +502,11 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
502 if (p == &net->ipv6.devconf_dflt->forwarding) 502 if (p == &net->ipv6.devconf_dflt->forwarding)
503 return 0; 503 return 0;
504 504
505 if (!rtnl_trylock()) 505 if (!rtnl_trylock()) {
506 /* Restore the original values before restarting */
507 *p = old;
506 return restart_syscall(); 508 return restart_syscall();
509 }
507 510
508 if (p == &net->ipv6.devconf_all->forwarding) { 511 if (p == &net->ipv6.devconf_all->forwarding) {
509 __s32 newf = net->ipv6.devconf_all->forwarding; 512 __s32 newf = net->ipv6.devconf_all->forwarding;
@@ -4028,12 +4031,15 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write,
4028{ 4031{
4029 int *valp = ctl->data; 4032 int *valp = ctl->data;
4030 int val = *valp; 4033 int val = *valp;
4034 loff_t pos = *ppos;
4031 int ret; 4035 int ret;
4032 4036
4033 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4037 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4034 4038
4035 if (write) 4039 if (write)
4036 ret = addrconf_fixup_forwarding(ctl, valp, val); 4040 ret = addrconf_fixup_forwarding(ctl, valp, val);
4041 if (ret)
4042 *ppos = pos;
4037 return ret; 4043 return ret;
4038} 4044}
4039 4045
@@ -4075,8 +4081,11 @@ static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
4075 if (p == &net->ipv6.devconf_dflt->disable_ipv6) 4081 if (p == &net->ipv6.devconf_dflt->disable_ipv6)
4076 return 0; 4082 return 0;
4077 4083
4078 if (!rtnl_trylock()) 4084 if (!rtnl_trylock()) {
4085 /* Restore the original values before restarting */
4086 *p = old;
4079 return restart_syscall(); 4087 return restart_syscall();
4088 }
4080 4089
4081 if (p == &net->ipv6.devconf_all->disable_ipv6) { 4090 if (p == &net->ipv6.devconf_all->disable_ipv6) {
4082 __s32 newf = net->ipv6.devconf_all->disable_ipv6; 4091 __s32 newf = net->ipv6.devconf_all->disable_ipv6;
@@ -4095,12 +4104,15 @@ int addrconf_sysctl_disable(ctl_table *ctl, int write,
4095{ 4104{
4096 int *valp = ctl->data; 4105 int *valp = ctl->data;
4097 int val = *valp; 4106 int val = *valp;
4107 loff_t pos = *ppos;
4098 int ret; 4108 int ret;
4099 4109
4100 ret = proc_dointvec(ctl, write, buffer, lenp, ppos); 4110 ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
4101 4111
4102 if (write) 4112 if (write)
4103 ret = addrconf_disable_ipv6(ctl, valp, val); 4113 ret = addrconf_disable_ipv6(ctl, valp, val);
4114 if (ret)
4115 *ppos = pos;
4104 return ret; 4116 return ret;
4105} 4117}
4106 4118
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 2f2a5ca2c878..002e6eef9120 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -154,16 +154,12 @@ static int ipcomp6_init_state(struct xfrm_state *x)
154 if (x->props.mode == XFRM_MODE_TUNNEL) { 154 if (x->props.mode == XFRM_MODE_TUNNEL) {
155 err = ipcomp6_tunnel_attach(x); 155 err = ipcomp6_tunnel_attach(x);
156 if (err) 156 if (err)
157 goto error_tunnel; 157 goto out;
158 } 158 }
159 159
160 err = 0; 160 err = 0;
161out: 161out:
162 return err; 162 return err;
163error_tunnel:
164 ipcomp_destroy(x);
165
166 goto out;
167} 163}
168 164
169static const struct xfrm_type ipcomp6_type = 165static const struct xfrm_type ipcomp6_type =
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 1f2db647bb5c..22f0c2aa7a89 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -647,7 +647,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
647 } 647 }
648 if (pos[1] != 0 && 648 if (pos[1] != 0 &&
649 (pos[1] != ifibss->ssid_len || 649 (pos[1] != ifibss->ssid_len ||
650 !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) { 650 memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
651 /* Ignore ProbeReq for foreign SSID */ 651 /* Ignore ProbeReq for foreign SSID */
652 return; 652 return;
653 } 653 }
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index b9007f80cb92..12a2bff7dcdb 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -245,6 +245,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
245 info->control.rates[i].count = 1; 245 info->control.rates[i].count = 1;
246 } 246 }
247 247
248 if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
249 return;
250
248 if (sta && sdata->force_unicast_rateidx > -1) { 251 if (sta && sdata->force_unicast_rateidx > -1) {
249 info->control.rates[0].idx = sdata->force_unicast_rateidx; 252 info->control.rates[0].idx = sdata->force_unicast_rateidx;
250 } else { 253 } else {
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f934c9620b73..bc17cf7d68db 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -439,6 +439,16 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
439 if (local->scan_req) 439 if (local->scan_req)
440 return -EBUSY; 440 return -EBUSY;
441 441
442 if (req != local->int_scan_req &&
443 sdata->vif.type == NL80211_IFTYPE_STATION &&
444 !list_empty(&ifmgd->work_list)) {
445 /* actually wait for the work it's doing to finish/time out */
446 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
447 local->scan_req = req;
448 local->scan_sdata = sdata;
449 return 0;
450 }
451
442 if (local->ops->hw_scan) { 452 if (local->ops->hw_scan) {
443 u8 *ies; 453 u8 *ies;
444 454
@@ -463,14 +473,6 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
463 local->scan_req = req; 473 local->scan_req = req;
464 local->scan_sdata = sdata; 474 local->scan_sdata = sdata;
465 475
466 if (req != local->int_scan_req &&
467 sdata->vif.type == NL80211_IFTYPE_STATION &&
468 !list_empty(&ifmgd->work_list)) {
469 /* actually wait for the work it's doing to finish/time out */
470 set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
471 return 0;
472 }
473
474 if (local->ops->hw_scan) 476 if (local->ops->hw_scan)
475 __set_bit(SCAN_HW_SCANNING, &local->scanning); 477 __set_bit(SCAN_HW_SCANNING, &local->scanning);
476 else 478 else
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index b36cc344474b..f445ea1c5f52 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1102,7 +1102,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
1102 int err = -ENOMEM; 1102 int err = -ENOMEM;
1103 struct xfrm_state *x = xfrm_state_alloc(net); 1103 struct xfrm_state *x = xfrm_state_alloc(net);
1104 if (!x) 1104 if (!x)
1105 goto error; 1105 goto out;
1106 1106
1107 memcpy(&x->id, &orig->id, sizeof(x->id)); 1107 memcpy(&x->id, &orig->id, sizeof(x->id));
1108 memcpy(&x->sel, &orig->sel, sizeof(x->sel)); 1108 memcpy(&x->sel, &orig->sel, sizeof(x->sel));
@@ -1160,16 +1160,10 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
1160 return x; 1160 return x;
1161 1161
1162 error: 1162 error:
1163 xfrm_state_put(x);
1164out:
1163 if (errp) 1165 if (errp)
1164 *errp = err; 1166 *errp = err;
1165 if (x) {
1166 kfree(x->aalg);
1167 kfree(x->ealg);
1168 kfree(x->calg);
1169 kfree(x->encap);
1170 kfree(x->coaddr);
1171 }
1172 kfree(x);
1173 return NULL; 1167 return NULL;
1174} 1168}
1175 1169
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 556cff937be7..567348b05b5a 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -157,7 +157,7 @@ config SND_HDA_CODEC_INTELHDMI
157 157
158config SND_HDA_ELD 158config SND_HDA_ELD
159 def_bool y 159 def_bool y
160 depends on SND_HDA_CODEC_INTELHDMI 160 depends on SND_HDA_CODEC_INTELHDMI || SND_HDA_CODEC_NVHDMI
161 161
162config SND_HDA_CODEC_CIRRUS 162config SND_HDA_CODEC_CIRRUS
163 bool "Build Cirrus Logic codec support" 163 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 315a1c4f8998..24bc195b02da 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -3,7 +3,7 @@ snd-hda-intel-objs := hda_intel.o
3snd-hda-codec-y := hda_codec.o 3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o 4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o 5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o 6snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o 7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o 8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9 9
@@ -18,7 +18,7 @@ snd-hda-codec-ca0110-objs := patch_ca0110.o
18snd-hda-codec-conexant-objs := patch_conexant.o 18snd-hda-codec-conexant-objs := patch_conexant.o
19snd-hda-codec-via-objs := patch_via.o 19snd-hda-codec-via-objs := patch_via.o
20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o 20snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o 21snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o
22 22
23# common driver 23# common driver
24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o 24obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 26ceace88c96..5bd7cf45f3a5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -978,8 +978,9 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
978 * 978 *
979 * Returns 0 if successful, or a negative error code. 979 * Returns 0 if successful, or a negative error code.
980 */ 980 */
981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 981int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus,
982 struct hda_codec **codecp) 982 unsigned int codec_addr,
983 struct hda_codec **codecp)
983{ 984{
984 struct hda_codec *codec; 985 struct hda_codec *codec;
985 char component[31]; 986 char component[31];
@@ -1186,7 +1187,7 @@ EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
1186 */ 1187 */
1187 1188
1188/* FIXME: more better hash key? */ 1189/* FIXME: more better hash key? */
1189#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) 1190#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1190#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24)) 1191#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1191#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24)) 1192#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1192#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24)) 1193#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
@@ -1356,7 +1357,8 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1356 if (!codec->no_trigger_sense) { 1357 if (!codec->no_trigger_sense) {
1357 pincap = snd_hda_query_pin_caps(codec, nid); 1358 pincap = snd_hda_query_pin_caps(codec, nid);
1358 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */ 1359 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1359 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0); 1360 snd_hda_codec_read(codec, nid, 0,
1361 AC_VERB_SET_PIN_SENSE, 0);
1360 } 1362 }
1361 return snd_hda_codec_read(codec, nid, 0, 1363 return snd_hda_codec_read(codec, nid, 0,
1362 AC_VERB_GET_PIN_SENSE, 0); 1364 AC_VERB_GET_PIN_SENSE, 0);
@@ -1372,8 +1374,8 @@ EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1372 */ 1374 */
1373int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 1375int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1374{ 1376{
1375 u32 sense = snd_hda_pin_sense(codec, nid); 1377 u32 sense = snd_hda_pin_sense(codec, nid);
1376 return !!(sense & AC_PINSENSE_PRESENCE); 1378 return !!(sense & AC_PINSENSE_PRESENCE);
1377} 1379}
1378EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 1380EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1379 1381
@@ -1952,7 +1954,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1952 err = snd_hda_ctl_add(codec, 0, kctl); 1954 err = snd_hda_ctl_add(codec, 0, kctl);
1953 if (err < 0) 1955 if (err < 0)
1954 return err; 1956 return err;
1955 1957
1956 for (s = slaves; *s; s++) { 1958 for (s = slaves; *s; s++) {
1957 struct snd_kcontrol *sctl; 1959 struct snd_kcontrol *sctl;
1958 int i = 0; 1960 int i = 0;
@@ -2439,27 +2441,27 @@ static struct snd_kcontrol_new dig_mixes[] = {
2439 { 2441 {
2440 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2442 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2441 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2443 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2442 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), 2444 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
2443 .info = snd_hda_spdif_mask_info, 2445 .info = snd_hda_spdif_mask_info,
2444 .get = snd_hda_spdif_cmask_get, 2446 .get = snd_hda_spdif_cmask_get,
2445 }, 2447 },
2446 { 2448 {
2447 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2449 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2448 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2450 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2449 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), 2451 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
2450 .info = snd_hda_spdif_mask_info, 2452 .info = snd_hda_spdif_mask_info,
2451 .get = snd_hda_spdif_pmask_get, 2453 .get = snd_hda_spdif_pmask_get,
2452 }, 2454 },
2453 { 2455 {
2454 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2456 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2455 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 2457 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
2456 .info = snd_hda_spdif_mask_info, 2458 .info = snd_hda_spdif_mask_info,
2457 .get = snd_hda_spdif_default_get, 2459 .get = snd_hda_spdif_default_get,
2458 .put = snd_hda_spdif_default_put, 2460 .put = snd_hda_spdif_default_put,
2459 }, 2461 },
2460 { 2462 {
2461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2462 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), 2464 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
2463 .info = snd_hda_spdif_out_switch_info, 2465 .info = snd_hda_spdif_out_switch_info,
2464 .get = snd_hda_spdif_out_switch_get, 2466 .get = snd_hda_spdif_out_switch_get,
2465 .put = snd_hda_spdif_out_switch_put, 2467 .put = snd_hda_spdif_out_switch_put,
@@ -2610,7 +2612,7 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2610static struct snd_kcontrol_new dig_in_ctls[] = { 2612static struct snd_kcontrol_new dig_in_ctls[] = {
2611 { 2613 {
2612 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2614 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2613 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 2615 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
2614 .info = snd_hda_spdif_in_switch_info, 2616 .info = snd_hda_spdif_in_switch_info,
2615 .get = snd_hda_spdif_in_switch_get, 2617 .get = snd_hda_spdif_in_switch_get,
2616 .put = snd_hda_spdif_in_switch_put, 2618 .put = snd_hda_spdif_in_switch_put,
@@ -2618,7 +2620,7 @@ static struct snd_kcontrol_new dig_in_ctls[] = {
2618 { 2620 {
2619 .access = SNDRV_CTL_ELEM_ACCESS_READ, 2621 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2620 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2622 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2621 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), 2623 .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
2622 .info = snd_hda_spdif_mask_info, 2624 .info = snd_hda_spdif_mask_info,
2623 .get = snd_hda_spdif_in_status_get, 2625 .get = snd_hda_spdif_in_status_get,
2624 }, 2626 },
@@ -2767,7 +2769,8 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2767 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 2769 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
2768 power_state); 2770 power_state);
2769 /* partial workaround for "azx_get_response timeout" */ 2771 /* partial workaround for "azx_get_response timeout" */
2770 if (power_state == AC_PWRST_D0) 2772 if (power_state == AC_PWRST_D0 &&
2773 (codec->vendor_id & 0xffff0000) == 0x14f10000)
2771 msleep(10); 2774 msleep(10);
2772 2775
2773 nid = codec->start_nid; 2776 nid = codec->start_nid;
@@ -2801,7 +2804,6 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2801 if (power_state == AC_PWRST_D0) { 2804 if (power_state == AC_PWRST_D0) {
2802 unsigned long end_time; 2805 unsigned long end_time;
2803 int state; 2806 int state;
2804 msleep(10);
2805 /* wait until the codec reachs to D0 */ 2807 /* wait until the codec reachs to D0 */
2806 end_time = jiffies + msecs_to_jiffies(500); 2808 end_time = jiffies + msecs_to_jiffies(500);
2807 do { 2809 do {
@@ -2883,7 +2885,7 @@ int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
2883 int err = snd_hda_codec_build_controls(codec); 2885 int err = snd_hda_codec_build_controls(codec);
2884 if (err < 0) { 2886 if (err < 0) {
2885 printk(KERN_ERR "hda_codec: cannot build controls" 2887 printk(KERN_ERR "hda_codec: cannot build controls"
2886 "for #%d (error %d)\n", codec->addr, err); 2888 "for #%d (error %d)\n", codec->addr, err);
2887 err = snd_hda_codec_reset(codec); 2889 err = snd_hda_codec_reset(codec);
2888 if (err < 0) { 2890 if (err < 0) {
2889 printk(KERN_ERR 2891 printk(KERN_ERR
@@ -2979,8 +2981,12 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2979 val |= channels - 1; 2981 val |= channels - 1;
2980 2982
2981 switch (snd_pcm_format_width(format)) { 2983 switch (snd_pcm_format_width(format)) {
2982 case 8: val |= 0x00; break; 2984 case 8:
2983 case 16: val |= 0x10; break; 2985 val |= 0x00;
2986 break;
2987 case 16:
2988 val |= 0x10;
2989 break;
2984 case 20: 2990 case 20:
2985 case 24: 2991 case 24:
2986 case 32: 2992 case 32:
@@ -3275,6 +3281,8 @@ const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3275 3281
3276/* 3282/*
3277 * get the empty PCM device number to assign 3283 * get the empty PCM device number to assign
3284 *
3285 * note the max device number is limited by HDA_MAX_PCMS, currently 10
3278 */ 3286 */
3279static int get_empty_pcm_device(struct hda_bus *bus, int type) 3287static int get_empty_pcm_device(struct hda_bus *bus, int type)
3280{ 3288{
@@ -3296,7 +3304,8 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type)
3296 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) 3304 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3297 return audio_idx[type][i]; 3305 return audio_idx[type][i];
3298 3306
3299 snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); 3307 snd_printk(KERN_WARNING "Too many %s devices\n",
3308 snd_hda_pcm_type_name[type]);
3300 return -EAGAIN; 3309 return -EAGAIN;
3301} 3310}
3302 3311
@@ -3334,7 +3343,7 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
3334 err = codec->patch_ops.build_pcms(codec); 3343 err = codec->patch_ops.build_pcms(codec);
3335 if (err < 0) { 3344 if (err < 0) {
3336 printk(KERN_ERR "hda_codec: cannot build PCMs" 3345 printk(KERN_ERR "hda_codec: cannot build PCMs"
3337 "for #%d (error %d)\n", codec->addr, err); 3346 "for #%d (error %d)\n", codec->addr, err);
3338 err = snd_hda_codec_reset(codec); 3347 err = snd_hda_codec_reset(codec);
3339 if (err < 0) { 3348 if (err < 0) {
3340 printk(KERN_ERR 3349 printk(KERN_ERR
@@ -3464,8 +3473,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3464 3473
3465/** 3474/**
3466 * snd_hda_check_board_codec_sid_config - compare the current codec 3475 * snd_hda_check_board_codec_sid_config - compare the current codec
3467 subsystem ID with the 3476 subsystem ID with the
3468 config table 3477 config table
3469 3478
3470 This is important for Gateway notebooks with SB450 HDA Audio 3479 This is important for Gateway notebooks with SB450 HDA Audio
3471 where the vendor ID of the PCI device is: 3480 where the vendor ID of the PCI device is:
@@ -3605,7 +3614,7 @@ void snd_hda_update_power_acct(struct hda_codec *codec)
3605 * 3614 *
3606 * Increment the power-up counter and power up the hardware really when 3615 * Increment the power-up counter and power up the hardware really when
3607 * not turned on yet. 3616 * not turned on yet.
3608 */ 3617 */
3609void snd_hda_power_up(struct hda_codec *codec) 3618void snd_hda_power_up(struct hda_codec *codec)
3610{ 3619{
3611 struct hda_bus *bus = codec->bus; 3620 struct hda_bus *bus = codec->bus;
@@ -3634,7 +3643,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_up);
3634 * 3643 *
3635 * Decrement the power-up counter and schedules the power-off work if 3644 * Decrement the power-up counter and schedules the power-off work if
3636 * the counter rearches to zero. 3645 * the counter rearches to zero.
3637 */ 3646 */
3638void snd_hda_power_down(struct hda_codec *codec) 3647void snd_hda_power_down(struct hda_codec *codec)
3639{ 3648{
3640 --codec->power_count; 3649 --codec->power_count;
@@ -3660,7 +3669,7 @@ EXPORT_SYMBOL_HDA(snd_hda_power_down);
3660 * 3669 *
3661 * This function is supposed to be set or called from the check_power_status 3670 * This function is supposed to be set or called from the check_power_status
3662 * patch ops. 3671 * patch ops.
3663 */ 3672 */
3664int snd_hda_check_amp_list_power(struct hda_codec *codec, 3673int snd_hda_check_amp_list_power(struct hda_codec *codec,
3665 struct hda_loopback_check *check, 3674 struct hda_loopback_check *check,
3666 hda_nid_t nid) 3675 hda_nid_t nid)
@@ -3828,7 +3837,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3828{ 3837{
3829 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 3838 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
3830 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 3839 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3831 set_dig_out_convert(codec, nid, 3840 set_dig_out_convert(codec, nid,
3832 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, 3841 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3833 -1); 3842 -1);
3834 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 3843 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -4087,13 +4096,13 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
4087/* 4096/*
4088 * Sort an associated group of pins according to their sequence numbers. 4097 * Sort an associated group of pins according to their sequence numbers.
4089 */ 4098 */
4090static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, 4099static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4091 int num_pins) 4100 int num_pins)
4092{ 4101{
4093 int i, j; 4102 int i, j;
4094 short seq; 4103 short seq;
4095 hda_nid_t nid; 4104 hda_nid_t nid;
4096 4105
4097 for (i = 0; i < num_pins; i++) { 4106 for (i = 0; i < num_pins; i++) {
4098 for (j = i + 1; j < num_pins; j++) { 4107 for (j = i + 1; j < num_pins; j++) {
4099 if (sequences[i] > sequences[j]) { 4108 if (sequences[i] > sequences[j]) {
@@ -4121,7 +4130,7 @@ static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
4121 * is detected, one of speaker of HP pins is assigned as the primary 4130 * is detected, one of speaker of HP pins is assigned as the primary
4122 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4131 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4123 * if any analog output exists. 4132 * if any analog output exists.
4124 * 4133 *
4125 * The analog input pins are assigned to input_pins array. 4134 * The analog input pins are assigned to input_pins array.
4126 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4135 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4127 * respectively. 4136 * respectively.
@@ -4184,9 +4193,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4184 case AC_JACK_SPEAKER: 4193 case AC_JACK_SPEAKER:
4185 seq = get_defcfg_sequence(def_conf); 4194 seq = get_defcfg_sequence(def_conf);
4186 assoc = get_defcfg_association(def_conf); 4195 assoc = get_defcfg_association(def_conf);
4187 if (! assoc) 4196 if (!assoc)
4188 continue; 4197 continue;
4189 if (! assoc_speaker) 4198 if (!assoc_speaker)
4190 assoc_speaker = assoc; 4199 assoc_speaker = assoc;
4191 else if (assoc_speaker != assoc) 4200 else if (assoc_speaker != assoc)
4192 continue; 4201 continue;
@@ -4284,7 +4293,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4284 cfg->speaker_outs); 4293 cfg->speaker_outs);
4285 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4294 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4286 cfg->hp_outs); 4295 cfg->hp_outs);
4287 4296
4288 /* if we have only one mic, make it AUTO_PIN_MIC */ 4297 /* if we have only one mic, make it AUTO_PIN_MIC */
4289 if (!cfg->input_pins[AUTO_PIN_MIC] && 4298 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4290 cfg->input_pins[AUTO_PIN_FRONT_MIC]) { 4299 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
@@ -4434,7 +4443,7 @@ EXPORT_SYMBOL_HDA(snd_hda_resume);
4434/** 4443/**
4435 * snd_array_new - get a new element from the given array 4444 * snd_array_new - get a new element from the given array
4436 * @array: the array object 4445 * @array: the array object
4437 * 4446 *
4438 * Get a new element from the given array. If it exceeds the 4447 * Get a new element from the given array. If it exceeds the
4439 * pre-allocated array size, re-allocate the array. 4448 * pre-allocated array size, re-allocate the array.
4440 * 4449 *
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 0c8f05cc56be..b75da47571e6 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -527,6 +527,9 @@ enum {
527/* max. codec address */ 527/* max. codec address */
528#define HDA_MAX_CODEC_ADDRESS 0x0f 528#define HDA_MAX_CODEC_ADDRESS 0x0f
529 529
530/* max number of PCM devics per card */
531#define HDA_MAX_PCMS 10
532
530/* 533/*
531 * generic arrays 534 * generic arrays
532 */ 535 */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index 4228f2fe5956..dcd22446cfc7 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -331,6 +331,7 @@ int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, 331 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
332 AC_DIPSIZE_ELD_BUF); 332 AC_DIPSIZE_ELD_BUF);
333} 333}
334EXPORT_SYMBOL_HDA(snd_hdmi_get_eld_size);
334 335
335int snd_hdmi_get_eld(struct hdmi_eld *eld, 336int snd_hdmi_get_eld(struct hdmi_eld *eld,
336 struct hda_codec *codec, hda_nid_t nid) 337 struct hda_codec *codec, hda_nid_t nid)
@@ -366,6 +367,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
366 kfree(buf); 367 kfree(buf);
367 return ret; 368 return ret;
368} 369}
370EXPORT_SYMBOL_HDA(snd_hdmi_get_eld);
369 371
370static void hdmi_show_short_audio_desc(struct cea_sad *a) 372static void hdmi_show_short_audio_desc(struct cea_sad *a)
371{ 373{
@@ -404,6 +406,7 @@ void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
404 } 406 }
405 buf[j] = '\0'; /* necessary when j == 0 */ 407 buf[j] = '\0'; /* necessary when j == 0 */
406} 408}
409EXPORT_SYMBOL_HDA(snd_print_channel_allocation);
407 410
408void snd_hdmi_show_eld(struct hdmi_eld *e) 411void snd_hdmi_show_eld(struct hdmi_eld *e)
409{ 412{
@@ -422,6 +425,7 @@ void snd_hdmi_show_eld(struct hdmi_eld *e)
422 for (i = 0; i < e->sad_count; i++) 425 for (i = 0; i < e->sad_count; i++)
423 hdmi_show_short_audio_desc(e->sad + i); 426 hdmi_show_short_audio_desc(e->sad + i);
424} 427}
428EXPORT_SYMBOL_HDA(snd_hdmi_show_eld);
425 429
426#ifdef CONFIG_PROC_FS 430#ifdef CONFIG_PROC_FS
427 431
@@ -580,6 +584,7 @@ int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld,
580 584
581 return 0; 585 return 0;
582} 586}
587EXPORT_SYMBOL_HDA(snd_hda_eld_proc_new);
583 588
584void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) 589void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
585{ 590{
@@ -588,5 +593,6 @@ void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
588 eld->proc_entry = NULL; 593 eld->proc_entry = NULL;
589 } 594 }
590} 595}
596EXPORT_SYMBOL_HDA(snd_hda_eld_proc_free);
591 597
592#endif /* CONFIG_PROC_FS */ 598#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index b36919c0d363..a1fc83753cc6 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -625,6 +625,10 @@ enum {
625 LINE_MODE_PINCFG, 625 LINE_MODE_PINCFG,
626 LINE_MODE_VERB, 626 LINE_MODE_VERB,
627 LINE_MODE_HINT, 627 LINE_MODE_HINT,
628 LINE_MODE_VENDOR_ID,
629 LINE_MODE_SUBSYSTEM_ID,
630 LINE_MODE_REVISION_ID,
631 LINE_MODE_CHIP_NAME,
628 NUM_LINE_MODES, 632 NUM_LINE_MODES,
629}; 633};
630 634
@@ -654,53 +658,71 @@ static void parse_codec_mode(char *buf, struct hda_bus *bus,
654} 658}
655 659
656/* parse the contents after the other command tags, [pincfg], [verb], 660/* parse the contents after the other command tags, [pincfg], [verb],
657 * [hint] and [model] 661 * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model]
658 * just pass to the sysfs helper (only when any codec was specified) 662 * just pass to the sysfs helper (only when any codec was specified)
659 */ 663 */
660static void parse_pincfg_mode(char *buf, struct hda_bus *bus, 664static void parse_pincfg_mode(char *buf, struct hda_bus *bus,
661 struct hda_codec **codecp) 665 struct hda_codec **codecp)
662{ 666{
663 if (!*codecp)
664 return;
665 parse_user_pin_configs(*codecp, buf); 667 parse_user_pin_configs(*codecp, buf);
666} 668}
667 669
668static void parse_verb_mode(char *buf, struct hda_bus *bus, 670static void parse_verb_mode(char *buf, struct hda_bus *bus,
669 struct hda_codec **codecp) 671 struct hda_codec **codecp)
670{ 672{
671 if (!*codecp)
672 return;
673 parse_init_verbs(*codecp, buf); 673 parse_init_verbs(*codecp, buf);
674} 674}
675 675
676static void parse_hint_mode(char *buf, struct hda_bus *bus, 676static void parse_hint_mode(char *buf, struct hda_bus *bus,
677 struct hda_codec **codecp) 677 struct hda_codec **codecp)
678{ 678{
679 if (!*codecp)
680 return;
681 parse_hints(*codecp, buf); 679 parse_hints(*codecp, buf);
682} 680}
683 681
684static void parse_model_mode(char *buf, struct hda_bus *bus, 682static void parse_model_mode(char *buf, struct hda_bus *bus,
685 struct hda_codec **codecp) 683 struct hda_codec **codecp)
686{ 684{
687 if (!*codecp)
688 return;
689 kfree((*codecp)->modelname); 685 kfree((*codecp)->modelname);
690 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL); 686 (*codecp)->modelname = kstrdup(buf, GFP_KERNEL);
691} 687}
692 688
689static void parse_chip_name_mode(char *buf, struct hda_bus *bus,
690 struct hda_codec **codecp)
691{
692 kfree((*codecp)->chip_name);
693 (*codecp)->chip_name = kstrdup(buf, GFP_KERNEL);
694}
695
696#define DEFINE_PARSE_ID_MODE(name) \
697static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
698 struct hda_codec **codecp) \
699{ \
700 unsigned long val; \
701 if (!strict_strtoul(buf, 0, &val)) \
702 (*codecp)->name = val; \
703}
704
705DEFINE_PARSE_ID_MODE(vendor_id);
706DEFINE_PARSE_ID_MODE(subsystem_id);
707DEFINE_PARSE_ID_MODE(revision_id);
708
709
693struct hda_patch_item { 710struct hda_patch_item {
694 const char *tag; 711 const char *tag;
695 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc); 712 void (*parser)(char *buf, struct hda_bus *bus, struct hda_codec **retc);
713 int need_codec;
696}; 714};
697 715
698static struct hda_patch_item patch_items[NUM_LINE_MODES] = { 716static struct hda_patch_item patch_items[NUM_LINE_MODES] = {
699 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode }, 717 [LINE_MODE_CODEC] = { "[codec]", parse_codec_mode, 0 },
700 [LINE_MODE_MODEL] = { "[model]", parse_model_mode }, 718 [LINE_MODE_MODEL] = { "[model]", parse_model_mode, 1 },
701 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode }, 719 [LINE_MODE_VERB] = { "[verb]", parse_verb_mode, 1 },
702 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode }, 720 [LINE_MODE_PINCFG] = { "[pincfg]", parse_pincfg_mode, 1 },
703 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode }, 721 [LINE_MODE_HINT] = { "[hint]", parse_hint_mode, 1 },
722 [LINE_MODE_VENDOR_ID] = { "[vendor_id]", parse_vendor_id_mode, 1 },
723 [LINE_MODE_SUBSYSTEM_ID] = { "[subsystem_id]", parse_subsystem_id_mode, 1 },
724 [LINE_MODE_REVISION_ID] = { "[revision_id]", parse_revision_id_mode, 1 },
725 [LINE_MODE_CHIP_NAME] = { "[chip_name]", parse_chip_name_mode, 1 },
704}; 726};
705 727
706/* check the line starting with '[' -- change the parser mode accodingly */ 728/* check the line starting with '[' -- change the parser mode accodingly */
@@ -783,7 +805,8 @@ int snd_hda_load_patch(struct hda_bus *bus, const char *patch)
783 continue; 805 continue;
784 if (*buf == '[') 806 if (*buf == '[')
785 line_mode = parse_line_mode(buf, bus); 807 line_mode = parse_line_mode(buf, bus);
786 else if (patch_items[line_mode].parser) 808 else if (patch_items[line_mode].parser &&
809 (codec || !patch_items[line_mode].need_codec))
787 patch_items[line_mode].parser(buf, bus, &codec); 810 patch_items[line_mode].parser(buf, bus, &codec);
788 } 811 }
789 release_firmware(fw); 812 release_firmware(fw);
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 8d8e0b5aa248..43b7cfb7cffd 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -125,6 +125,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
125 "{Intel, ICH9}," 125 "{Intel, ICH9},"
126 "{Intel, ICH10}," 126 "{Intel, ICH10},"
127 "{Intel, PCH}," 127 "{Intel, PCH},"
128 "{Intel, CPT},"
128 "{Intel, SCH}," 129 "{Intel, SCH},"
129 "{ATI, SB450}," 130 "{ATI, SB450},"
130 "{ATI, SB600}," 131 "{ATI, SB600},"
@@ -259,8 +260,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
259#define AZX_MAX_FRAG 32 260#define AZX_MAX_FRAG 32
260/* max buffer size - no h/w limit, you can increase as you like */ 261/* max buffer size - no h/w limit, you can increase as you like */
261#define AZX_MAX_BUF_SIZE (1024*1024*1024) 262#define AZX_MAX_BUF_SIZE (1024*1024*1024)
262/* max number of PCM devics per card */
263#define AZX_MAX_PCMS 8
264 263
265/* RIRB int mask: overrun[2], response[0] */ 264/* RIRB int mask: overrun[2], response[0] */
266#define RIRB_INT_RESPONSE 0x01 265#define RIRB_INT_RESPONSE 0x01
@@ -268,7 +267,8 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
268#define RIRB_INT_MASK 0x05 267#define RIRB_INT_MASK 0x05
269 268
270/* STATESTS int mask: S3,SD2,SD1,SD0 */ 269/* STATESTS int mask: S3,SD2,SD1,SD0 */
271#define AZX_MAX_CODECS 4 270#define AZX_MAX_CODECS 8
271#define AZX_DEFAULT_CODECS 4
272#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1) 272#define STATESTS_INT_MASK ((1 << AZX_MAX_CODECS) - 1)
273 273
274/* SD_CTL bits */ 274/* SD_CTL bits */
@@ -408,7 +408,7 @@ struct azx {
408 struct azx_dev *azx_dev; 408 struct azx_dev *azx_dev;
409 409
410 /* PCM */ 410 /* PCM */
411 struct snd_pcm *pcm[AZX_MAX_PCMS]; 411 struct snd_pcm *pcm[HDA_MAX_PCMS];
412 412
413 /* HD codec */ 413 /* HD codec */
414 unsigned short codec_mask; 414 unsigned short codec_mask;
@@ -449,6 +449,7 @@ struct azx {
449/* driver types */ 449/* driver types */
450enum { 450enum {
451 AZX_DRIVER_ICH, 451 AZX_DRIVER_ICH,
452 AZX_DRIVER_PCH,
452 AZX_DRIVER_SCH, 453 AZX_DRIVER_SCH,
453 AZX_DRIVER_ATI, 454 AZX_DRIVER_ATI,
454 AZX_DRIVER_ATIHDMI, 455 AZX_DRIVER_ATIHDMI,
@@ -463,6 +464,7 @@ enum {
463 464
464static char *driver_short_names[] __devinitdata = { 465static char *driver_short_names[] __devinitdata = {
465 [AZX_DRIVER_ICH] = "HDA Intel", 466 [AZX_DRIVER_ICH] = "HDA Intel",
467 [AZX_DRIVER_PCH] = "HDA Intel PCH",
466 [AZX_DRIVER_SCH] = "HDA Intel MID", 468 [AZX_DRIVER_SCH] = "HDA Intel MID",
467 [AZX_DRIVER_ATI] = "HDA ATI SB", 469 [AZX_DRIVER_ATI] = "HDA ATI SB",
468 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", 470 [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI",
@@ -968,8 +970,8 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev)
968 azx_dev->insufficient = 1; 970 azx_dev->insufficient = 1;
969 971
970 /* enable SIE */ 972 /* enable SIE */
971 azx_writeb(chip, INTCTL, 973 azx_writel(chip, INTCTL,
972 azx_readb(chip, INTCTL) | (1 << azx_dev->index)); 974 azx_readl(chip, INTCTL) | (1 << azx_dev->index));
973 /* set DMA start and interrupt mask */ 975 /* set DMA start and interrupt mask */
974 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | 976 azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) |
975 SD_CTL_DMA_START | SD_INT_MASK); 977 SD_CTL_DMA_START | SD_INT_MASK);
@@ -988,8 +990,8 @@ static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev)
988{ 990{
989 azx_stream_clear(chip, azx_dev); 991 azx_stream_clear(chip, azx_dev);
990 /* disable SIE */ 992 /* disable SIE */
991 azx_writeb(chip, INTCTL, 993 azx_writel(chip, INTCTL,
992 azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); 994 azx_readl(chip, INTCTL) & ~(1 << azx_dev->index));
993} 995}
994 996
995 997
@@ -1065,6 +1067,7 @@ static void azx_init_pci(struct azx *chip)
1065 0x01, NVIDIA_HDA_ENABLE_COHBIT); 1067 0x01, NVIDIA_HDA_ENABLE_COHBIT);
1066 break; 1068 break;
1067 case AZX_DRIVER_SCH: 1069 case AZX_DRIVER_SCH:
1070 case AZX_DRIVER_PCH:
1068 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); 1071 pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop);
1069 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { 1072 if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) {
1070 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, 1073 pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC,
@@ -1350,7 +1353,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1350 if (chip->initialized) { 1353 if (chip->initialized) {
1351 int i; 1354 int i;
1352 1355
1353 for (i = 0; i < AZX_MAX_PCMS; i++) 1356 for (i = 0; i < HDA_MAX_PCMS; i++)
1354 snd_pcm_suspend_all(chip->pcm[i]); 1357 snd_pcm_suspend_all(chip->pcm[i]);
1355 snd_hda_suspend(chip->bus); 1358 snd_hda_suspend(chip->bus);
1356 snd_hda_resume(chip->bus); 1359 snd_hda_resume(chip->bus);
@@ -1365,6 +1368,7 @@ static void azx_bus_reset(struct hda_bus *bus)
1365 1368
1366/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ 1369/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */
1367static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { 1370static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1371 [AZX_DRIVER_NVIDIA] = 8,
1368 [AZX_DRIVER_TERA] = 1, 1372 [AZX_DRIVER_TERA] = 1,
1369}; 1373};
1370 1374
@@ -1397,7 +1401,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1397 codecs = 0; 1401 codecs = 0;
1398 max_slots = azx_max_codecs[chip->driver_type]; 1402 max_slots = azx_max_codecs[chip->driver_type];
1399 if (!max_slots) 1403 if (!max_slots)
1400 max_slots = AZX_MAX_CODECS; 1404 max_slots = AZX_DEFAULT_CODECS;
1401 1405
1402 /* First try to probe all given codec slots */ 1406 /* First try to probe all given codec slots */
1403 for (c = 0; c < max_slots; c++) { 1407 for (c = 0; c < max_slots; c++) {
@@ -1412,7 +1416,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model)
1412 chip->codec_mask &= ~(1 << c); 1416 chip->codec_mask &= ~(1 << c);
1413 /* More badly, accessing to a non-existing 1417 /* More badly, accessing to a non-existing
1414 * codec often screws up the controller chip, 1418 * codec often screws up the controller chip,
1415 * and distrubs the further communications. 1419 * and disturbs the further communications.
1416 * Thus if an error occurs during probing, 1420 * Thus if an error occurs during probing,
1417 * better to reset the controller chip to 1421 * better to reset the controller chip to
1418 * get back to the sanity state. 1422 * get back to the sanity state.
@@ -1983,7 +1987,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1983 int pcm_dev = cpcm->device; 1987 int pcm_dev = cpcm->device;
1984 int s, err; 1988 int s, err;
1985 1989
1986 if (pcm_dev >= AZX_MAX_PCMS) { 1990 if (pcm_dev >= HDA_MAX_PCMS) {
1987 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", 1991 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1988 pcm_dev); 1992 pcm_dev);
1989 return -EINVAL; 1993 return -EINVAL;
@@ -2139,7 +2143,7 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2139 2143
2140 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2144 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2141 azx_clear_irq_pending(chip); 2145 azx_clear_irq_pending(chip);
2142 for (i = 0; i < AZX_MAX_PCMS; i++) 2146 for (i = 0; i < HDA_MAX_PCMS; i++)
2143 snd_pcm_suspend_all(chip->pcm[i]); 2147 snd_pcm_suspend_all(chip->pcm[i]);
2144 if (chip->initialized) 2148 if (chip->initialized)
2145 snd_hda_suspend(chip->bus); 2149 snd_hda_suspend(chip->bus);
@@ -2261,9 +2265,12 @@ static int azx_dev_free(struct snd_device *device)
2261static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2265static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2262 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2266 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2263 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2267 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2268 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2264 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2269 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2270 SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB),
2265 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2271 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2266 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), 2272 SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB),
2273 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB),
2267 {} 2274 {}
2268}; 2275};
2269 2276
@@ -2350,7 +2357,8 @@ static void __devinit check_probe_mask(struct azx *chip, int dev)
2350 */ 2357 */
2351static struct snd_pci_quirk msi_black_list[] __devinitdata = { 2358static struct snd_pci_quirk msi_black_list[] __devinitdata = {
2352 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ 2359 SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */
2353 SND_PCI_QUIRK(0x1043, 0x829c, "ASUS", 0), /* nvidia */ 2360 SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
2361 SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
2354 {} 2362 {}
2355}; 2363};
2356 2364
@@ -2418,6 +2426,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2418 if (bdl_pos_adj[dev] < 0) { 2426 if (bdl_pos_adj[dev] < 0) {
2419 switch (chip->driver_type) { 2427 switch (chip->driver_type) {
2420 case AZX_DRIVER_ICH: 2428 case AZX_DRIVER_ICH:
2429 case AZX_DRIVER_PCH:
2421 bdl_pos_adj[dev] = 1; 2430 bdl_pos_adj[dev] = 1;
2422 break; 2431 break;
2423 default: 2432 default:
@@ -2696,6 +2705,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2696 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH }, 2705 { PCI_DEVICE(0x8086, 0x3a6e), .driver_data = AZX_DRIVER_ICH },
2697 /* PCH */ 2706 /* PCH */
2698 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH }, 2707 { PCI_DEVICE(0x8086, 0x3b56), .driver_data = AZX_DRIVER_ICH },
2708 /* CPT */
2709 { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH },
2699 /* SCH */ 2710 /* SCH */
2700 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, 2711 { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH },
2701 /* ATI SB 450/600 */ 2712 /* ATI SB 450/600 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 214301d568fa..e6d1bdff1b6e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -1098,7 +1098,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 1098 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 1099 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 1100 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 1101 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 1102 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 1103 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 1104 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 685015a53292..194a28c54992 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -42,10 +42,12 @@
42 42
43/* Conexant 5051 specific */ 43/* Conexant 5051 specific */
44 44
45#define CXT5051_SPDIF_OUT 0x1C 45#define CXT5051_SPDIF_OUT 0x12
46#define CXT5051_PORTB_EVENT 0x38 46#define CXT5051_PORTB_EVENT 0x38
47#define CXT5051_PORTC_EVENT 0x39 47#define CXT5051_PORTC_EVENT 0x39
48 48
49#define AUTO_MIC_PORTB (1 << 1)
50#define AUTO_MIC_PORTC (1 << 2)
49 51
50struct conexant_jack { 52struct conexant_jack {
51 53
@@ -74,7 +76,7 @@ struct conexant_spec {
74 */ 76 */
75 unsigned int cur_eapd; 77 unsigned int cur_eapd;
76 unsigned int hp_present; 78 unsigned int hp_present;
77 unsigned int no_auto_mic; 79 unsigned int auto_mic;
78 unsigned int need_dac_fix; 80 unsigned int need_dac_fix;
79 81
80 /* capture */ 82 /* capture */
@@ -111,7 +113,8 @@ struct conexant_spec {
111 113
112 unsigned int dell_automute; 114 unsigned int dell_automute;
113 unsigned int port_d_mode; 115 unsigned int port_d_mode;
114 unsigned int dell_vostro; 116 unsigned int dell_vostro:1;
117 unsigned int ideapad:1;
115 118
116 unsigned int ext_mic_present; 119 unsigned int ext_mic_present;
117 unsigned int recording; 120 unsigned int recording;
@@ -1603,6 +1606,11 @@ static void cxt5051_update_speaker(struct hda_codec *codec)
1603{ 1606{
1604 struct conexant_spec *spec = codec->spec; 1607 struct conexant_spec *spec = codec->spec;
1605 unsigned int pinctl; 1608 unsigned int pinctl;
1609 /* headphone pin */
1610 pinctl = (spec->hp_present && spec->cur_eapd) ? PIN_HP : 0;
1611 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1612 pinctl);
1613 /* speaker pin */
1606 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 1614 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
1607 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1615 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
1608 pinctl); 1616 pinctl);
@@ -1626,7 +1634,7 @@ static void cxt5051_portb_automic(struct hda_codec *codec)
1626 struct conexant_spec *spec = codec->spec; 1634 struct conexant_spec *spec = codec->spec;
1627 unsigned int present; 1635 unsigned int present;
1628 1636
1629 if (spec->no_auto_mic) 1637 if (!(spec->auto_mic & AUTO_MIC_PORTB))
1630 return; 1638 return;
1631 present = snd_hda_jack_detect(codec, 0x17); 1639 present = snd_hda_jack_detect(codec, 0x17);
1632 snd_hda_codec_write(codec, 0x14, 0, 1640 snd_hda_codec_write(codec, 0x14, 0,
@@ -1641,7 +1649,7 @@ static void cxt5051_portc_automic(struct hda_codec *codec)
1641 unsigned int present; 1649 unsigned int present;
1642 hda_nid_t new_adc; 1650 hda_nid_t new_adc;
1643 1651
1644 if (spec->no_auto_mic) 1652 if (!(spec->auto_mic & AUTO_MIC_PORTC))
1645 return; 1653 return;
1646 present = snd_hda_jack_detect(codec, 0x18); 1654 present = snd_hda_jack_detect(codec, 0x18);
1647 if (present) 1655 if (present)
@@ -1687,13 +1695,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec,
1687 conexant_report_jack(codec, nid); 1695 conexant_report_jack(codec, nid);
1688} 1696}
1689 1697
1690static struct snd_kcontrol_new cxt5051_mixers[] = { 1698static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1691 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1692 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1693 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1694 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1695 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1696 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1697 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1699 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1698 { 1700 {
1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1701 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -1703,7 +1705,16 @@ static struct snd_kcontrol_new cxt5051_mixers[] = {
1703 .put = cxt5051_hp_master_sw_put, 1705 .put = cxt5051_hp_master_sw_put,
1704 .private_value = 0x1a, 1706 .private_value = 0x1a,
1705 }, 1707 },
1708 {}
1709};
1706 1710
1711static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1712 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1714 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1715 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1716 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1717 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1707 {} 1718 {}
1708}; 1719};
1709 1720
@@ -1712,48 +1723,26 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1712 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1723 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1713 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1724 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT),
1714 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1725 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT),
1715 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1716 {
1717 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1718 .name = "Master Playback Switch",
1719 .info = cxt_eapd_info,
1720 .get = cxt_eapd_get,
1721 .put = cxt5051_hp_master_sw_put,
1722 .private_value = 0x1a,
1723 },
1724
1725 {} 1726 {}
1726}; 1727};
1727 1728
1728static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { 1729static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = {
1729 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), 1730 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT),
1730 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), 1731 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT),
1731 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT),
1732 {
1733 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1734 .name = "Master Playback Switch",
1735 .info = cxt_eapd_info,
1736 .get = cxt_eapd_get,
1737 .put = cxt5051_hp_master_sw_put,
1738 .private_value = 0x1a,
1739 },
1740
1741 {} 1732 {}
1742}; 1733};
1743 1734
1744static struct snd_kcontrol_new cxt5051_f700_mixers[] = { 1735static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1745 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), 1736 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT),
1746 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), 1737 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT),
1747 HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), 1738 {}
1748 { 1739};
1749 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1750 .name = "Master Playback Switch",
1751 .info = cxt_eapd_info,
1752 .get = cxt_eapd_get,
1753 .put = cxt5051_hp_master_sw_put,
1754 .private_value = 0x1a,
1755 },
1756 1740
1741static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1742 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1743 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1744 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT),
1745 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT),
1757 {} 1746 {}
1758}; 1747};
1759 1748
@@ -1782,8 +1771,6 @@ static struct hda_verb cxt5051_init_verbs[] = {
1782 /* EAPD */ 1771 /* EAPD */
1783 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1772 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1784 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1773 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1785 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1786 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1787 { } /* end */ 1774 { } /* end */
1788}; 1775};
1789 1776
@@ -1809,7 +1796,6 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1809 /* EAPD */ 1796 /* EAPD */
1810 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1797 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1811 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1798 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1812 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1813 { } /* end */ 1799 { } /* end */
1814}; 1800};
1815 1801
@@ -1841,15 +1827,13 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1841 /* EAPD */ 1827 /* EAPD */
1842 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1828 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1843 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1829 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1844 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1845 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT},
1846 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1830 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1847 { } /* end */ 1831 { } /* end */
1848}; 1832};
1849 1833
1850static struct hda_verb cxt5051_f700_init_verbs[] = { 1834static struct hda_verb cxt5051_f700_init_verbs[] = {
1851 /* Line in, Mic */ 1835 /* Line in, Mic */
1852 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x03}, 1836 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03},
1853 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1837 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1854 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1838 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
1855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, 1839 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0},
@@ -1869,15 +1853,34 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
1869 /* EAPD */ 1853 /* EAPD */
1870 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 1854 {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
1871 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, 1855 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT},
1872 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT},
1873 { } /* end */ 1856 { } /* end */
1874}; 1857};
1875 1858
1859static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid,
1860 unsigned int event)
1861{
1862 snd_hda_codec_write(codec, nid, 0,
1863 AC_VERB_SET_UNSOLICITED_ENABLE,
1864 AC_USRSP_EN | event);
1865#ifdef CONFIG_SND_HDA_INPUT_JACK
1866 conexant_add_jack(codec, nid, SND_JACK_MICROPHONE);
1867 conexant_report_jack(codec, nid);
1868#endif
1869}
1870
1876/* initialize jack-sensing, too */ 1871/* initialize jack-sensing, too */
1877static int cxt5051_init(struct hda_codec *codec) 1872static int cxt5051_init(struct hda_codec *codec)
1878{ 1873{
1874 struct conexant_spec *spec = codec->spec;
1875
1879 conexant_init(codec); 1876 conexant_init(codec);
1880 conexant_init_jacks(codec); 1877 conexant_init_jacks(codec);
1878
1879 if (spec->auto_mic & AUTO_MIC_PORTB)
1880 cxt5051_init_mic_port(codec, 0x17, CXT5051_PORTB_EVENT);
1881 if (spec->auto_mic & AUTO_MIC_PORTC)
1882 cxt5051_init_mic_port(codec, 0x18, CXT5051_PORTC_EVENT);
1883
1881 if (codec->patch_ops.unsol_event) { 1884 if (codec->patch_ops.unsol_event) {
1882 cxt5051_hp_automute(codec); 1885 cxt5051_hp_automute(codec);
1883 cxt5051_portb_automic(codec); 1886 cxt5051_portb_automic(codec);
@@ -1893,6 +1896,7 @@ enum {
1893 CXT5051_HP_DV6736, /* HP without mic switch */ 1896 CXT5051_HP_DV6736, /* HP without mic switch */
1894 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ 1897 CXT5051_LENOVO_X200, /* Lenovo X200 laptop */
1895 CXT5051_F700, /* HP Compaq Presario F700 */ 1898 CXT5051_F700, /* HP Compaq Presario F700 */
1899 CXT5051_TOSHIBA, /* Toshiba M300 & co */
1896 CXT5051_MODELS 1900 CXT5051_MODELS
1897}; 1901};
1898 1902
@@ -1901,17 +1905,19 @@ static const char *cxt5051_models[CXT5051_MODELS] = {
1901 [CXT5051_HP] = "hp", 1905 [CXT5051_HP] = "hp",
1902 [CXT5051_HP_DV6736] = "hp-dv6736", 1906 [CXT5051_HP_DV6736] = "hp-dv6736",
1903 [CXT5051_LENOVO_X200] = "lenovo-x200", 1907 [CXT5051_LENOVO_X200] = "lenovo-x200",
1904 [CXT5051_F700] = "hp 700" 1908 [CXT5051_F700] = "hp-700",
1909 [CXT5051_TOSHIBA] = "toshiba",
1905}; 1910};
1906 1911
1907static struct snd_pci_quirk cxt5051_cfg_tbl[] = { 1912static struct snd_pci_quirk cxt5051_cfg_tbl[] = {
1908 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), 1913 SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736),
1909 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), 1914 SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP),
1915 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1916 SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba M30x", CXT5051_TOSHIBA),
1910 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", 1917 SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board",
1911 CXT5051_LAPTOP), 1918 CXT5051_LAPTOP),
1912 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), 1919 SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP),
1913 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), 1920 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200),
1914 SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700),
1915 {} 1921 {}
1916}; 1922};
1917 1923
@@ -1935,8 +1941,9 @@ static int patch_cxt5051(struct hda_codec *codec)
1935 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT; 1941 spec->multiout.dig_out_nid = CXT5051_SPDIF_OUT;
1936 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */ 1942 spec->num_adc_nids = 1; /* not 2; via auto-mic switch */
1937 spec->adc_nids = cxt5051_adc_nids; 1943 spec->adc_nids = cxt5051_adc_nids;
1938 spec->num_mixers = 1; 1944 spec->num_mixers = 2;
1939 spec->mixers[0] = cxt5051_mixers; 1945 spec->mixers[0] = cxt5051_capture_mixers;
1946 spec->mixers[1] = cxt5051_playback_mixers;
1940 spec->num_init_verbs = 1; 1947 spec->num_init_verbs = 1;
1941 spec->init_verbs[0] = cxt5051_init_verbs; 1948 spec->init_verbs[0] = cxt5051_init_verbs;
1942 spec->spdif_route = 0; 1949 spec->spdif_route = 0;
@@ -1950,6 +1957,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1950 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, 1957 board_config = snd_hda_check_board_config(codec, CXT5051_MODELS,
1951 cxt5051_models, 1958 cxt5051_models,
1952 cxt5051_cfg_tbl); 1959 cxt5051_cfg_tbl);
1960 spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC;
1953 switch (board_config) { 1961 switch (board_config) {
1954 case CXT5051_HP: 1962 case CXT5051_HP:
1955 spec->mixers[0] = cxt5051_hp_mixers; 1963 spec->mixers[0] = cxt5051_hp_mixers;
@@ -1957,7 +1965,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1957 case CXT5051_HP_DV6736: 1965 case CXT5051_HP_DV6736:
1958 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; 1966 spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs;
1959 spec->mixers[0] = cxt5051_hp_dv6736_mixers; 1967 spec->mixers[0] = cxt5051_hp_dv6736_mixers;
1960 spec->no_auto_mic = 1; 1968 spec->auto_mic = 0;
1961 break; 1969 break;
1962 case CXT5051_LENOVO_X200: 1970 case CXT5051_LENOVO_X200:
1963 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; 1971 spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs;
@@ -1965,7 +1973,11 @@ static int patch_cxt5051(struct hda_codec *codec)
1965 case CXT5051_F700: 1973 case CXT5051_F700:
1966 spec->init_verbs[0] = cxt5051_f700_init_verbs; 1974 spec->init_verbs[0] = cxt5051_f700_init_verbs;
1967 spec->mixers[0] = cxt5051_f700_mixers; 1975 spec->mixers[0] = cxt5051_f700_mixers;
1968 spec->no_auto_mic = 1; 1976 spec->auto_mic = 0;
1977 break;
1978 case CXT5051_TOSHIBA:
1979 spec->mixers[0] = cxt5051_toshiba_mixers;
1980 spec->auto_mic = AUTO_MIC_PORTB;
1969 break; 1981 break;
1970 } 1982 }
1971 1983
@@ -2156,6 +2168,34 @@ static void cxt5066_vostro_automic(struct hda_codec *codec)
2156 } 2168 }
2157} 2169}
2158 2170
2171/* toggle input of built-in digital mic and mic jack appropriately */
2172static void cxt5066_ideapad_automic(struct hda_codec *codec)
2173{
2174 unsigned int present;
2175
2176 struct hda_verb ext_mic_present[] = {
2177 {0x14, AC_VERB_SET_CONNECT_SEL, 0},
2178 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2179 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2180 {}
2181 };
2182 static struct hda_verb ext_mic_absent[] = {
2183 {0x14, AC_VERB_SET_CONNECT_SEL, 2},
2184 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2185 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
2186 {}
2187 };
2188
2189 present = snd_hda_jack_detect(codec, 0x1b);
2190 if (present) {
2191 snd_printdd("CXT5066: external microphone detected\n");
2192 snd_hda_sequence_write(codec, ext_mic_present);
2193 } else {
2194 snd_printdd("CXT5066: external microphone absent\n");
2195 snd_hda_sequence_write(codec, ext_mic_absent);
2196 }
2197}
2198
2159/* mute internal speaker if HP is plugged */ 2199/* mute internal speaker if HP is plugged */
2160static void cxt5066_hp_automute(struct hda_codec *codec) 2200static void cxt5066_hp_automute(struct hda_codec *codec)
2161{ 2201{
@@ -2205,6 +2245,20 @@ static void cxt5066_vostro_event(struct hda_codec *codec, unsigned int res)
2205 } 2245 }
2206} 2246}
2207 2247
2248/* unsolicited event for jack sensing */
2249static void cxt5066_ideapad_event(struct hda_codec *codec, unsigned int res)
2250{
2251 snd_printdd("CXT5066_ideapad: unsol event %x (%x)\n", res, res >> 26);
2252 switch (res >> 26) {
2253 case CONEXANT_HP_EVENT:
2254 cxt5066_hp_automute(codec);
2255 break;
2256 case CONEXANT_MIC_EVENT:
2257 cxt5066_ideapad_automic(codec);
2258 break;
2259 }
2260}
2261
2208static const struct hda_input_mux cxt5066_analog_mic_boost = { 2262static const struct hda_input_mux cxt5066_analog_mic_boost = {
2209 .num_items = 5, 2263 .num_items = 5,
2210 .items = { 2264 .items = {
@@ -2216,13 +2270,21 @@ static const struct hda_input_mux cxt5066_analog_mic_boost = {
2216 }, 2270 },
2217}; 2271};
2218 2272
2219static int cxt5066_set_mic_boost(struct hda_codec *codec) 2273static void cxt5066_set_mic_boost(struct hda_codec *codec)
2220{ 2274{
2221 struct conexant_spec *spec = codec->spec; 2275 struct conexant_spec *spec = codec->spec;
2222 return snd_hda_codec_write_cache(codec, 0x17, 0, 2276 snd_hda_codec_write_cache(codec, 0x17, 0,
2223 AC_VERB_SET_AMP_GAIN_MUTE, 2277 AC_VERB_SET_AMP_GAIN_MUTE,
2224 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT | 2278 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_OUTPUT |
2225 cxt5066_analog_mic_boost.items[spec->mic_boost].index); 2279 cxt5066_analog_mic_boost.items[spec->mic_boost].index);
2280 if (spec->ideapad) {
2281 /* adjust the internal mic as well...it is not through 0x17 */
2282 snd_hda_codec_write_cache(codec, 0x23, 0,
2283 AC_VERB_SET_AMP_GAIN_MUTE,
2284 AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | AC_AMP_SET_INPUT |
2285 cxt5066_analog_mic_boost.
2286 items[spec->mic_boost].index);
2287 }
2226} 2288}
2227 2289
2228static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol, 2290static int cxt5066_mic_boost_mux_enum_info(struct snd_kcontrol *kcontrol,
@@ -2653,6 +2715,56 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = {
2653 { } /* end */ 2715 { } /* end */
2654}; 2716};
2655 2717
2718static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2719 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */
2720 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */
2721 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */
2722 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */
2723
2724 /* Speakers */
2725 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2726 {0x1f, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2727
2728 /* HP, Amp */
2729 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2730 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2731
2732 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2733 {0x1c, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */
2734
2735 /* DAC1 */
2736 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2737
2738 /* Node 14 connections: 0x17 0x18 0x23 0x24 0x27 */
2739 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x50},
2740 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2741 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2) | 0x50},
2742 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2743 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2744 {0x14, AC_VERB_SET_CONNECT_SEL, 2}, /* default to internal mic */
2745
2746 /* Audio input selector */
2747 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x2},
2748 {0x17, AC_VERB_SET_CONNECT_SEL, 1}, /* route ext mic */
2749
2750 /* SPDIF route: PCM */
2751 {0x20, AC_VERB_SET_CONNECT_SEL, 0x0},
2752 {0x22, AC_VERB_SET_CONNECT_SEL, 0x0},
2753
2754 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2755 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2756
2757 /* internal microphone */
2758 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */
2759
2760 /* EAPD */
2761 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
2762
2763 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
2764 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
2765 { } /* end */
2766};
2767
2656static struct hda_verb cxt5066_init_verbs_portd_lo[] = { 2768static struct hda_verb cxt5066_init_verbs_portd_lo[] = {
2657 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2769 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2658 { } /* end */ 2770 { } /* end */
@@ -2669,6 +2781,8 @@ static int cxt5066_init(struct hda_codec *codec)
2669 cxt5066_hp_automute(codec); 2781 cxt5066_hp_automute(codec);
2670 if (spec->dell_vostro) 2782 if (spec->dell_vostro)
2671 cxt5066_vostro_automic(codec); 2783 cxt5066_vostro_automic(codec);
2784 else if (spec->ideapad)
2785 cxt5066_ideapad_automic(codec);
2672 } 2786 }
2673 cxt5066_set_mic_boost(codec); 2787 cxt5066_set_mic_boost(codec);
2674 return 0; 2788 return 0;
@@ -2694,6 +2808,7 @@ enum {
2694 CXT5066_DELL_LAPTOP, /* Dell Laptop */ 2808 CXT5066_DELL_LAPTOP, /* Dell Laptop */
2695 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */ 2809 CXT5066_OLPC_XO_1_5, /* OLPC XO 1.5 */
2696 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */ 2810 CXT5066_DELL_VOSTO, /* Dell Vostro 1015i */
2811 CXT5066_IDEAPAD, /* Lenovo IdeaPad U150 */
2697 CXT5066_MODELS 2812 CXT5066_MODELS
2698}; 2813};
2699 2814
@@ -2701,7 +2816,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
2701 [CXT5066_LAPTOP] = "laptop", 2816 [CXT5066_LAPTOP] = "laptop",
2702 [CXT5066_DELL_LAPTOP] = "dell-laptop", 2817 [CXT5066_DELL_LAPTOP] = "dell-laptop",
2703 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 2818 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
2704 [CXT5066_DELL_VOSTO] = "dell-vostro" 2819 [CXT5066_DELL_VOSTO] = "dell-vostro",
2820 [CXT5066_IDEAPAD] = "ideapad",
2705}; 2821};
2706 2822
2707static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 2823static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
@@ -2711,6 +2827,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
2711 CXT5066_DELL_LAPTOP), 2827 CXT5066_DELL_LAPTOP),
2712 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 2828 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
2713 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), 2829 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO),
2830 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
2714 {} 2831 {}
2715}; 2832};
2716 2833
@@ -2802,6 +2919,22 @@ static int patch_cxt5066(struct hda_codec *codec)
2802 /* input source automatically selected */ 2919 /* input source automatically selected */
2803 spec->input_mux = NULL; 2920 spec->input_mux = NULL;
2804 break; 2921 break;
2922 case CXT5066_IDEAPAD:
2923 codec->patch_ops.init = cxt5066_init;
2924 codec->patch_ops.unsol_event = cxt5066_ideapad_event;
2925 spec->mixers[spec->num_mixers++] = cxt5066_mixer_master;
2926 spec->mixers[spec->num_mixers++] = cxt5066_mixers;
2927 spec->init_verbs[0] = cxt5066_init_verbs_ideapad;
2928 spec->port_d_mode = 0;
2929 spec->ideapad = 1;
2930 spec->mic_boost = 2; /* default 20dB gain */
2931
2932 /* no S/PDIF out */
2933 spec->multiout.dig_out_nid = 0;
2934
2935 /* input source automatically selected */
2936 spec->input_mux = NULL;
2937 break;
2805 } 2938 }
2806 2939
2807 return 0; 2940 return 0;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
new file mode 100644
index 000000000000..2c2bafbf0258
--- /dev/null
+++ b/sound/pci/hda/patch_hdmi.c
@@ -0,0 +1,849 @@
1/*
2 *
3 * patch_hdmi.c - routines for HDMI/DisplayPort codecs
4 *
5 * Copyright(c) 2008-2010 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Wu Fengguang <wfg@linux.intel.com>
9 *
10 * Maintained by:
11 * Wu Fengguang <wfg@linux.intel.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the Free
15 * Software Foundation; either version 2 of the License, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28
29struct hdmi_spec {
30 int num_cvts;
31 int num_pins;
32 hda_nid_t cvt[MAX_HDMI_CVTS+1]; /* audio sources */
33 hda_nid_t pin[MAX_HDMI_PINS+1]; /* audio sinks */
34
35 /*
36 * source connection for each pin
37 */
38 hda_nid_t pin_cvt[MAX_HDMI_PINS+1];
39
40 /*
41 * HDMI sink attached to each pin
42 */
43 struct hdmi_eld sink_eld[MAX_HDMI_PINS];
44
45 /*
46 * export one pcm per pipe
47 */
48 struct hda_pcm pcm_rec[MAX_HDMI_CVTS];
49
50 /*
51 * nvhdmi specific
52 */
53 struct hda_multi_out multiout;
54 unsigned int codec_type;
55};
56
57
58struct hdmi_audio_infoframe {
59 u8 type; /* 0x84 */
60 u8 ver; /* 0x01 */
61 u8 len; /* 0x0a */
62
63 u8 checksum; /* PB0 */
64 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
65 u8 SS01_SF24;
66 u8 CXT04;
67 u8 CA;
68 u8 LFEPBL01_LSV36_DM_INH7;
69 u8 reserved[5]; /* PB6 - PB10 */
70};
71
72/*
73 * CEA speaker placement:
74 *
75 * FLH FCH FRH
76 * FLW FL FLC FC FRC FR FRW
77 *
78 * LFE
79 * TC
80 *
81 * RL RLC RC RRC RR
82 *
83 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
84 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
85 */
86enum cea_speaker_placement {
87 FL = (1 << 0), /* Front Left */
88 FC = (1 << 1), /* Front Center */
89 FR = (1 << 2), /* Front Right */
90 FLC = (1 << 3), /* Front Left Center */
91 FRC = (1 << 4), /* Front Right Center */
92 RL = (1 << 5), /* Rear Left */
93 RC = (1 << 6), /* Rear Center */
94 RR = (1 << 7), /* Rear Right */
95 RLC = (1 << 8), /* Rear Left Center */
96 RRC = (1 << 9), /* Rear Right Center */
97 LFE = (1 << 10), /* Low Frequency Effect */
98 FLW = (1 << 11), /* Front Left Wide */
99 FRW = (1 << 12), /* Front Right Wide */
100 FLH = (1 << 13), /* Front Left High */
101 FCH = (1 << 14), /* Front Center High */
102 FRH = (1 << 15), /* Front Right High */
103 TC = (1 << 16), /* Top Center */
104};
105
106/*
107 * ELD SA bits in the CEA Speaker Allocation data block
108 */
109static int eld_speaker_allocation_bits[] = {
110 [0] = FL | FR,
111 [1] = LFE,
112 [2] = FC,
113 [3] = RL | RR,
114 [4] = RC,
115 [5] = FLC | FRC,
116 [6] = RLC | RRC,
117 /* the following are not defined in ELD yet */
118 [7] = FLW | FRW,
119 [8] = FLH | FRH,
120 [9] = TC,
121 [10] = FCH,
122};
123
124struct cea_channel_speaker_allocation {
125 int ca_index;
126 int speakers[8];
127
128 /* derived values, just for convenience */
129 int channels;
130 int spk_mask;
131};
132
133/*
134 * ALSA sequence is:
135 *
136 * surround40 surround41 surround50 surround51 surround71
137 * ch0 front left = = = =
138 * ch1 front right = = = =
139 * ch2 rear left = = = =
140 * ch3 rear right = = = =
141 * ch4 LFE center center center
142 * ch5 LFE LFE
143 * ch6 side left
144 * ch7 side right
145 *
146 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
147 */
148static int hdmi_channel_mapping[0x32][8] = {
149 /* stereo */
150 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
151 /* 2.1 */
152 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
153 /* Dolby Surround */
154 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
155 /* surround40 */
156 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
157 /* 4ch */
158 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
159 /* surround41 */
160 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
161 /* surround50 */
162 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
163 /* surround51 */
164 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
165 /* 7.1 */
166 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
167};
168
169/*
170 * This is an ordered list!
171 *
172 * The preceding ones have better chances to be selected by
173 * hdmi_setup_channel_allocation().
174 */
175static struct cea_channel_speaker_allocation channel_allocations[] = {
176/* channel: 7 6 5 4 3 2 1 0 */
177{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
178 /* 2.1 */
179{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
180 /* Dolby Surround */
181{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
182 /* surround40 */
183{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
184 /* surround41 */
185{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
186 /* surround50 */
187{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
188 /* surround51 */
189{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
190 /* 6.1 */
191{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
192 /* surround71 */
193{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
194
195{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
196{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
197{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
198{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
199{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
200{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
203{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
204{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
205{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
206{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
207{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
208{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
209{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
210{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
211{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
212{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
213{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
214{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
215{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
216{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
217{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
218{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
219{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
220{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
222{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
223{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
224{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
225{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
226{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
227{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
228{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
229{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
230{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
231{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
232{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
233{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
234{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
235{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
236};
237
238
239/*
240 * HDMI routines
241 */
242
243static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
244{
245 int i;
246
247 for (i = 0; nids[i]; i++)
248 if (nids[i] == nid)
249 return i;
250
251 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
252 return -EINVAL;
253}
254
255static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
256 struct hdmi_eld *eld)
257{
258 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
259 snd_hdmi_show_eld(eld);
260}
261
262#ifdef BE_PARANOID
263static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
264 int *packet_index, int *byte_index)
265{
266 int val;
267
268 val = snd_hda_codec_read(codec, pin_nid, 0,
269 AC_VERB_GET_HDMI_DIP_INDEX, 0);
270
271 *packet_index = val >> 5;
272 *byte_index = val & 0x1f;
273}
274#endif
275
276static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
277 int packet_index, int byte_index)
278{
279 int val;
280
281 val = (packet_index << 5) | (byte_index & 0x1f);
282
283 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
284}
285
286static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
287 unsigned char val)
288{
289 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
290}
291
292static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
293{
294 /* Unmute */
295 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
296 snd_hda_codec_write(codec, pin_nid, 0,
297 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
298 /* Enable pin out */
299 snd_hda_codec_write(codec, pin_nid, 0,
300 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
301}
302
303static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
304{
305 return 1 + snd_hda_codec_read(codec, nid, 0,
306 AC_VERB_GET_CVT_CHAN_COUNT, 0);
307}
308
309static void hdmi_set_channel_count(struct hda_codec *codec,
310 hda_nid_t nid, int chs)
311{
312 if (chs != hdmi_get_channel_count(codec, nid))
313 snd_hda_codec_write(codec, nid, 0,
314 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
315}
316
317
318/*
319 * Channel mapping routines
320 */
321
322/*
323 * Compute derived values in channel_allocations[].
324 */
325static void init_channel_allocations(void)
326{
327 int i, j;
328 struct cea_channel_speaker_allocation *p;
329
330 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
331 p = channel_allocations + i;
332 p->channels = 0;
333 p->spk_mask = 0;
334 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
335 if (p->speakers[j]) {
336 p->channels++;
337 p->spk_mask |= p->speakers[j];
338 }
339 }
340}
341
342/*
343 * The transformation takes two steps:
344 *
345 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
346 * spk_mask => (channel_allocations[]) => ai->CA
347 *
348 * TODO: it could select the wrong CA from multiple candidates.
349*/
350static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
351 struct hdmi_audio_infoframe *ai)
352{
353 struct hdmi_spec *spec = codec->spec;
354 struct hdmi_eld *eld;
355 int i;
356 int spk_mask = 0;
357 int channels = 1 + (ai->CC02_CT47 & 0x7);
358 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
359
360 /*
361 * CA defaults to 0 for basic stereo audio
362 */
363 if (channels <= 2)
364 return 0;
365
366 i = hda_node_index(spec->pin_cvt, nid);
367 if (i < 0)
368 return 0;
369 eld = &spec->sink_eld[i];
370
371 /*
372 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
373 * in console or for audio devices. Assume the highest speakers
374 * configuration, to _not_ prohibit multi-channel audio playback.
375 */
376 if (!eld->spk_alloc)
377 eld->spk_alloc = 0xffff;
378
379 /*
380 * expand ELD's speaker allocation mask
381 *
382 * ELD tells the speaker mask in a compact(paired) form,
383 * expand ELD's notions to match the ones used by Audio InfoFrame.
384 */
385 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
386 if (eld->spk_alloc & (1 << i))
387 spk_mask |= eld_speaker_allocation_bits[i];
388 }
389
390 /* search for the first working match in the CA table */
391 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
392 if (channels == channel_allocations[i].channels &&
393 (spk_mask & channel_allocations[i].spk_mask) ==
394 channel_allocations[i].spk_mask) {
395 ai->CA = channel_allocations[i].ca_index;
396 break;
397 }
398 }
399
400 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
401 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
402 ai->CA, channels, buf);
403
404 return ai->CA;
405}
406
407static void hdmi_debug_channel_mapping(struct hda_codec *codec,
408 hda_nid_t pin_nid)
409{
410#ifdef CONFIG_SND_DEBUG_VERBOSE
411 int i;
412 int slot;
413
414 for (i = 0; i < 8; i++) {
415 slot = snd_hda_codec_read(codec, pin_nid, 0,
416 AC_VERB_GET_HDMI_CHAN_SLOT, i);
417 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
418 slot >> 4, slot & 0xf);
419 }
420#endif
421}
422
423
424static void hdmi_setup_channel_mapping(struct hda_codec *codec,
425 hda_nid_t pin_nid,
426 struct hdmi_audio_infoframe *ai)
427{
428 int i;
429 int ca = ai->CA;
430 int err;
431
432 if (hdmi_channel_mapping[ca][1] == 0) {
433 for (i = 0; i < channel_allocations[ca].channels; i++)
434 hdmi_channel_mapping[ca][i] = i | (i << 4);
435 for (; i < 8; i++)
436 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
437 }
438
439 for (i = 0; i < 8; i++) {
440 err = snd_hda_codec_write(codec, pin_nid, 0,
441 AC_VERB_SET_HDMI_CHAN_SLOT,
442 hdmi_channel_mapping[ca][i]);
443 if (err) {
444 snd_printdd(KERN_NOTICE
445 "HDMI: channel mapping failed\n");
446 break;
447 }
448 }
449
450 hdmi_debug_channel_mapping(codec, pin_nid);
451}
452
453
454/*
455 * Audio InfoFrame routines
456 */
457
458/*
459 * Enable Audio InfoFrame Transmission
460 */
461static void hdmi_start_infoframe_trans(struct hda_codec *codec,
462 hda_nid_t pin_nid)
463{
464 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
465 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
466 AC_DIPXMIT_BEST);
467}
468
469/*
470 * Disable Audio InfoFrame Transmission
471 */
472static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
473 hda_nid_t pin_nid)
474{
475 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
476 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
477 AC_DIPXMIT_DISABLE);
478}
479
480static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
481{
482#ifdef CONFIG_SND_DEBUG_VERBOSE
483 int i;
484 int size;
485
486 size = snd_hdmi_get_eld_size(codec, pin_nid);
487 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
488
489 for (i = 0; i < 8; i++) {
490 size = snd_hda_codec_read(codec, pin_nid, 0,
491 AC_VERB_GET_HDMI_DIP_SIZE, i);
492 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
493 }
494#endif
495}
496
497static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
498{
499#ifdef BE_PARANOID
500 int i, j;
501 int size;
502 int pi, bi;
503 for (i = 0; i < 8; i++) {
504 size = snd_hda_codec_read(codec, pin_nid, 0,
505 AC_VERB_GET_HDMI_DIP_SIZE, i);
506 if (size == 0)
507 continue;
508
509 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
510 for (j = 1; j < 1000; j++) {
511 hdmi_write_dip_byte(codec, pin_nid, 0x0);
512 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
513 if (pi != i)
514 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
515 bi, pi, i);
516 if (bi == 0) /* byte index wrapped around */
517 break;
518 }
519 snd_printd(KERN_INFO
520 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
521 i, size, j);
522 }
523#endif
524}
525
526static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
527{
528 u8 *bytes = (u8 *)ai;
529 u8 sum = 0;
530 int i;
531
532 ai->checksum = 0;
533
534 for (i = 0; i < sizeof(*ai); i++)
535 sum += bytes[i];
536
537 ai->checksum = -sum;
538}
539
540static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
541 hda_nid_t pin_nid,
542 struct hdmi_audio_infoframe *ai)
543{
544 u8 *bytes = (u8 *)ai;
545 int i;
546
547 hdmi_debug_dip_size(codec, pin_nid);
548 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
549
550 hdmi_checksum_audio_infoframe(ai);
551
552 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
553 for (i = 0; i < sizeof(*ai); i++)
554 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
555}
556
557static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
558 struct hdmi_audio_infoframe *ai)
559{
560 u8 *bytes = (u8 *)ai;
561 u8 val;
562 int i;
563
564 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
565 != AC_DIPXMIT_BEST)
566 return false;
567
568 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
569 for (i = 0; i < sizeof(*ai); i++) {
570 val = snd_hda_codec_read(codec, pin_nid, 0,
571 AC_VERB_GET_HDMI_DIP_DATA, 0);
572 if (val != bytes[i])
573 return false;
574 }
575
576 return true;
577}
578
579static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
580 struct snd_pcm_substream *substream)
581{
582 struct hdmi_spec *spec = codec->spec;
583 hda_nid_t pin_nid;
584 int i;
585 struct hdmi_audio_infoframe ai = {
586 .type = 0x84,
587 .ver = 0x01,
588 .len = 0x0a,
589 .CC02_CT47 = substream->runtime->channels - 1,
590 };
591
592 hdmi_setup_channel_allocation(codec, nid, &ai);
593
594 for (i = 0; i < spec->num_pins; i++) {
595 if (spec->pin_cvt[i] != nid)
596 continue;
597 if (!spec->sink_eld[i].monitor_present)
598 continue;
599
600 pin_nid = spec->pin[i];
601 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
602 snd_printdd("hdmi_setup_audio_infoframe: "
603 "cvt=%d pin=%d channels=%d\n",
604 nid, pin_nid,
605 substream->runtime->channels);
606 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
607 hdmi_stop_infoframe_trans(codec, pin_nid);
608 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
609 hdmi_start_infoframe_trans(codec, pin_nid);
610 }
611 }
612}
613
614
615/*
616 * Unsolicited events
617 */
618
619static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
620{
621 struct hdmi_spec *spec = codec->spec;
622 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
623 int pind = !!(res & AC_UNSOL_RES_PD);
624 int eldv = !!(res & AC_UNSOL_RES_ELDV);
625 int index;
626
627 printk(KERN_INFO
628 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
629 tag, pind, eldv);
630
631 index = hda_node_index(spec->pin, tag);
632 if (index < 0)
633 return;
634
635 spec->sink_eld[index].monitor_present = pind;
636 spec->sink_eld[index].eld_valid = eldv;
637
638 if (pind && eldv) {
639 hdmi_get_show_eld(codec, spec->pin[index],
640 &spec->sink_eld[index]);
641 /* TODO: do real things about ELD */
642 }
643}
644
645static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
646{
647 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
648 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
649 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
650 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
651
652 printk(KERN_INFO
653 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
654 tag,
655 subtag,
656 cp_state,
657 cp_ready);
658
659 /* TODO */
660 if (cp_state)
661 ;
662 if (cp_ready)
663 ;
664}
665
666
667static void hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
668{
669 struct hdmi_spec *spec = codec->spec;
670 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
671 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
672
673 if (hda_node_index(spec->pin, tag) < 0) {
674 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
675 return;
676 }
677
678 if (subtag == 0)
679 hdmi_intrinsic_event(codec, res);
680 else
681 hdmi_non_intrinsic_event(codec, res);
682}
683
684/*
685 * Callbacks
686 */
687
688static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
689 u32 stream_tag, int format)
690{
691 int tag;
692 int fmt;
693
694 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
695 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
696
697 snd_printdd("hdmi_setup_stream: "
698 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
699 nid,
700 tag == stream_tag ? "" : "new-",
701 stream_tag,
702 fmt == format ? "" : "new-",
703 format);
704
705 if (tag != stream_tag)
706 snd_hda_codec_write(codec, nid, 0,
707 AC_VERB_SET_CHANNEL_STREAMID,
708 stream_tag << 4);
709 if (fmt != format)
710 snd_hda_codec_write(codec, nid, 0,
711 AC_VERB_SET_STREAM_FORMAT, format);
712}
713
714/*
715 * HDA/HDMI auto parsing
716 */
717
718static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
719{
720 struct hdmi_spec *spec = codec->spec;
721 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
722 int conn_len, curr;
723 int index;
724
725 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
726 snd_printk(KERN_WARNING
727 "HDMI: pin %d wcaps %#x "
728 "does not support connection list\n",
729 pin_nid, get_wcaps(codec, pin_nid));
730 return -EINVAL;
731 }
732
733 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
734 HDA_MAX_CONNECTIONS);
735 if (conn_len > 1)
736 curr = snd_hda_codec_read(codec, pin_nid, 0,
737 AC_VERB_GET_CONNECT_SEL, 0);
738 else
739 curr = 0;
740
741 index = hda_node_index(spec->pin, pin_nid);
742 if (index < 0)
743 return -EINVAL;
744
745 spec->pin_cvt[index] = conn_list[curr];
746
747 return 0;
748}
749
750static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
751 struct hdmi_eld *eld)
752{
753 int present = snd_hda_pin_sense(codec, pin_nid);
754
755 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
756 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
757
758 if (present & AC_PINSENSE_ELDV)
759 hdmi_get_show_eld(codec, pin_nid, eld);
760}
761
762static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
763{
764 struct hdmi_spec *spec = codec->spec;
765
766 if (spec->num_pins >= MAX_HDMI_PINS) {
767 snd_printk(KERN_WARNING
768 "HDMI: no space for pin %d\n", pin_nid);
769 return -EINVAL;
770 }
771
772 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
773
774 spec->pin[spec->num_pins] = pin_nid;
775 spec->num_pins++;
776
777 /*
778 * It is assumed that converter nodes come first in the node list and
779 * hence have been registered and usable now.
780 */
781 return hdmi_read_pin_conn(codec, pin_nid);
782}
783
784static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
785{
786 struct hdmi_spec *spec = codec->spec;
787
788 if (spec->num_cvts >= MAX_HDMI_CVTS) {
789 snd_printk(KERN_WARNING
790 "HDMI: no space for converter %d\n", nid);
791 return -EINVAL;
792 }
793
794 spec->cvt[spec->num_cvts] = nid;
795 spec->num_cvts++;
796
797 return 0;
798}
799
800static int hdmi_parse_codec(struct hda_codec *codec)
801{
802 hda_nid_t nid;
803 int i, nodes;
804
805 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
806 if (!nid || nodes < 0) {
807 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
808 return -EINVAL;
809 }
810
811 for (i = 0; i < nodes; i++, nid++) {
812 unsigned int caps;
813 unsigned int type;
814
815 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
816 type = get_wcaps_type(caps);
817
818 if (!(caps & AC_WCAP_DIGITAL))
819 continue;
820
821 switch (type) {
822 case AC_WID_AUD_OUT:
823 if (hdmi_add_cvt(codec, nid) < 0)
824 return -EINVAL;
825 break;
826 case AC_WID_PIN:
827 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
828 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
829 continue;
830 if (hdmi_add_pin(codec, nid) < 0)
831 return -EINVAL;
832 break;
833 }
834 }
835
836 /*
837 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
838 * can be lost and presence sense verb will become inaccurate if the
839 * HDA link is powered off at hot plug or hw initialization time.
840 */
841#ifdef CONFIG_SND_HDA_POWER_SAVE
842 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
843 AC_PWRST_EPSS))
844 codec->bus->power_keep_link_on = 1;
845#endif
846
847 return 0;
848}
849
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
index 918f40378d52..88d035104cc5 100644
--- a/sound/pci/hda/patch_intelhdmi.c
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -40,815 +40,20 @@
40 * 40 *
41 * The HDA correspondence of pipes/ports are converter/pin nodes. 41 * The HDA correspondence of pipes/ports are converter/pin nodes.
42 */ 42 */
43#define INTEL_HDMI_CVTS 2 43#define MAX_HDMI_CVTS 2
44#define INTEL_HDMI_PINS 3 44#define MAX_HDMI_PINS 3
45 45
46static char *intel_hdmi_pcm_names[INTEL_HDMI_CVTS] = { 46#include "patch_hdmi.c"
47
48static char *intel_hdmi_pcm_names[MAX_HDMI_CVTS] = {
47 "INTEL HDMI 0", 49 "INTEL HDMI 0",
48 "INTEL HDMI 1", 50 "INTEL HDMI 1",
49}; 51};
50 52
51struct intel_hdmi_spec {
52 int num_cvts;
53 int num_pins;
54 hda_nid_t cvt[INTEL_HDMI_CVTS+1]; /* audio sources */
55 hda_nid_t pin[INTEL_HDMI_PINS+1]; /* audio sinks */
56
57 /*
58 * source connection for each pin
59 */
60 hda_nid_t pin_cvt[INTEL_HDMI_PINS+1];
61
62 /*
63 * HDMI sink attached to each pin
64 */
65 struct hdmi_eld sink_eld[INTEL_HDMI_PINS];
66
67 /*
68 * export one pcm per pipe
69 */
70 struct hda_pcm pcm_rec[INTEL_HDMI_CVTS];
71};
72
73struct hdmi_audio_infoframe {
74 u8 type; /* 0x84 */
75 u8 ver; /* 0x01 */
76 u8 len; /* 0x0a */
77
78 u8 checksum; /* PB0 */
79 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
80 u8 SS01_SF24;
81 u8 CXT04;
82 u8 CA;
83 u8 LFEPBL01_LSV36_DM_INH7;
84 u8 reserved[5]; /* PB6 - PB10 */
85};
86
87/*
88 * CEA speaker placement:
89 *
90 * FLH FCH FRH
91 * FLW FL FLC FC FRC FR FRW
92 *
93 * LFE
94 * TC
95 *
96 * RL RLC RC RRC RR
97 *
98 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
99 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
100 */
101enum cea_speaker_placement {
102 FL = (1 << 0), /* Front Left */
103 FC = (1 << 1), /* Front Center */
104 FR = (1 << 2), /* Front Right */
105 FLC = (1 << 3), /* Front Left Center */
106 FRC = (1 << 4), /* Front Right Center */
107 RL = (1 << 5), /* Rear Left */
108 RC = (1 << 6), /* Rear Center */
109 RR = (1 << 7), /* Rear Right */
110 RLC = (1 << 8), /* Rear Left Center */
111 RRC = (1 << 9), /* Rear Right Center */
112 LFE = (1 << 10), /* Low Frequency Effect */
113 FLW = (1 << 11), /* Front Left Wide */
114 FRW = (1 << 12), /* Front Right Wide */
115 FLH = (1 << 13), /* Front Left High */
116 FCH = (1 << 14), /* Front Center High */
117 FRH = (1 << 15), /* Front Right High */
118 TC = (1 << 16), /* Top Center */
119};
120
121/*
122 * ELD SA bits in the CEA Speaker Allocation data block
123 */
124static int eld_speaker_allocation_bits[] = {
125 [0] = FL | FR,
126 [1] = LFE,
127 [2] = FC,
128 [3] = RL | RR,
129 [4] = RC,
130 [5] = FLC | FRC,
131 [6] = RLC | RRC,
132 /* the following are not defined in ELD yet */
133 [7] = FLW | FRW,
134 [8] = FLH | FRH,
135 [9] = TC,
136 [10] = FCH,
137};
138
139struct cea_channel_speaker_allocation {
140 int ca_index;
141 int speakers[8];
142
143 /* derived values, just for convenience */
144 int channels;
145 int spk_mask;
146};
147
148/*
149 * ALSA sequence is:
150 *
151 * surround40 surround41 surround50 surround51 surround71
152 * ch0 front left = = = =
153 * ch1 front right = = = =
154 * ch2 rear left = = = =
155 * ch3 rear right = = = =
156 * ch4 LFE center center center
157 * ch5 LFE LFE
158 * ch6 side left
159 * ch7 side right
160 *
161 * surround71 = {FL, FR, RLC, RRC, FC, LFE, RL, RR}
162 */
163static int hdmi_channel_mapping[0x32][8] = {
164 /* stereo */
165 [0x00] = { 0x00, 0x11, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
166 /* 2.1 */
167 [0x01] = { 0x00, 0x11, 0x22, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7 },
168 /* Dolby Surround */
169 [0x02] = { 0x00, 0x11, 0x23, 0xf2, 0xf4, 0xf5, 0xf6, 0xf7 },
170 /* surround40 */
171 [0x08] = { 0x00, 0x11, 0x24, 0x35, 0xf3, 0xf2, 0xf6, 0xf7 },
172 /* 4ch */
173 [0x03] = { 0x00, 0x11, 0x23, 0x32, 0x44, 0xf5, 0xf6, 0xf7 },
174 /* surround41 */
175 [0x09] = { 0x00, 0x11, 0x24, 0x34, 0x43, 0xf2, 0xf6, 0xf7 },
176 /* surround50 */
177 [0x0a] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0xf2, 0xf6, 0xf7 },
178 /* surround51 */
179 [0x0b] = { 0x00, 0x11, 0x24, 0x35, 0x43, 0x52, 0xf6, 0xf7 },
180 /* 7.1 */
181 [0x13] = { 0x00, 0x11, 0x26, 0x37, 0x43, 0x52, 0x64, 0x75 },
182};
183
184/*
185 * This is an ordered list!
186 *
187 * The preceding ones have better chances to be selected by
188 * hdmi_setup_channel_allocation().
189 */
190static struct cea_channel_speaker_allocation channel_allocations[] = {
191/* channel: 7 6 5 4 3 2 1 0 */
192{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
193 /* 2.1 */
194{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
195 /* Dolby Surround */
196{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
197 /* surround40 */
198{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
199 /* surround41 */
200{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
201 /* surround50 */
202{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
203 /* surround51 */
204{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
205 /* 6.1 */
206{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
207 /* surround71 */
208{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
209
210{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
211{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
212{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
213{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
214{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
215{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
216{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
217{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
218{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
219{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
220{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
221{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
222{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
223{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
224{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
225{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
226{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
227{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
228{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
229{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
230{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
231{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
232{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
233{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
234{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
235{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
236{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
237{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
238{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
239{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
240{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
241{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
242{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
243{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
244{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
245{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
246{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
247{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
248{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
249{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
250{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
251};
252
253/*
254 * HDA/HDMI auto parsing
255 */
256
257static int hda_node_index(hda_nid_t *nids, hda_nid_t nid)
258{
259 int i;
260
261 for (i = 0; nids[i]; i++)
262 if (nids[i] == nid)
263 return i;
264
265 snd_printk(KERN_WARNING "HDMI: nid %d not registered\n", nid);
266 return -EINVAL;
267}
268
269static int intel_hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid)
270{
271 struct intel_hdmi_spec *spec = codec->spec;
272 hda_nid_t conn_list[HDA_MAX_CONNECTIONS];
273 int conn_len, curr;
274 int index;
275
276 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
277 snd_printk(KERN_WARNING
278 "HDMI: pin %d wcaps %#x "
279 "does not support connection list\n",
280 pin_nid, get_wcaps(codec, pin_nid));
281 return -EINVAL;
282 }
283
284 conn_len = snd_hda_get_connections(codec, pin_nid, conn_list,
285 HDA_MAX_CONNECTIONS);
286 if (conn_len > 1)
287 curr = snd_hda_codec_read(codec, pin_nid, 0,
288 AC_VERB_GET_CONNECT_SEL, 0);
289 else
290 curr = 0;
291
292 index = hda_node_index(spec->pin, pin_nid);
293 if (index < 0)
294 return -EINVAL;
295
296 spec->pin_cvt[index] = conn_list[curr];
297
298 return 0;
299}
300
301static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid,
302 struct hdmi_eld *eld)
303{
304 if (!snd_hdmi_get_eld(eld, codec, pin_nid))
305 snd_hdmi_show_eld(eld);
306}
307
308static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid,
309 struct hdmi_eld *eld)
310{
311 int present = snd_hda_pin_sense(codec, pin_nid);
312
313 eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE);
314 eld->eld_valid = !!(present & AC_PINSENSE_ELDV);
315
316 if (present & AC_PINSENSE_ELDV)
317 hdmi_get_show_eld(codec, pin_nid, eld);
318}
319
320static int intel_hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
321{
322 struct intel_hdmi_spec *spec = codec->spec;
323
324 if (spec->num_pins >= INTEL_HDMI_PINS) {
325 snd_printk(KERN_WARNING
326 "HDMI: no space for pin %d \n", pin_nid);
327 return -EINVAL;
328 }
329
330 hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]);
331
332 spec->pin[spec->num_pins] = pin_nid;
333 spec->num_pins++;
334
335 /*
336 * It is assumed that converter nodes come first in the node list and
337 * hence have been registered and usable now.
338 */
339 return intel_hdmi_read_pin_conn(codec, pin_nid);
340}
341
342static int intel_hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
343{
344 struct intel_hdmi_spec *spec = codec->spec;
345
346 if (spec->num_cvts >= INTEL_HDMI_CVTS) {
347 snd_printk(KERN_WARNING
348 "HDMI: no space for converter %d \n", nid);
349 return -EINVAL;
350 }
351
352 spec->cvt[spec->num_cvts] = nid;
353 spec->num_cvts++;
354
355 return 0;
356}
357
358static int intel_hdmi_parse_codec(struct hda_codec *codec)
359{
360 hda_nid_t nid;
361 int i, nodes;
362
363 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
364 if (!nid || nodes < 0) {
365 snd_printk(KERN_WARNING "HDMI: failed to get afg sub nodes\n");
366 return -EINVAL;
367 }
368
369 for (i = 0; i < nodes; i++, nid++) {
370 unsigned int caps;
371 unsigned int type;
372
373 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
374 type = get_wcaps_type(caps);
375
376 if (!(caps & AC_WCAP_DIGITAL))
377 continue;
378
379 switch (type) {
380 case AC_WID_AUD_OUT:
381 if (intel_hdmi_add_cvt(codec, nid) < 0)
382 return -EINVAL;
383 break;
384 case AC_WID_PIN:
385 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
386 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
387 continue;
388 if (intel_hdmi_add_pin(codec, nid) < 0)
389 return -EINVAL;
390 break;
391 }
392 }
393
394 /*
395 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
396 * can be lost and presence sense verb will become inaccurate if the
397 * HDA link is powered off at hot plug or hw initialization time.
398 */
399#ifdef CONFIG_SND_HDA_POWER_SAVE
400 if (!(snd_hda_param_read(codec, codec->afg, AC_PAR_POWER_STATE) &
401 AC_PWRST_EPSS))
402 codec->bus->power_keep_link_on = 1;
403#endif
404
405 return 0;
406}
407
408/*
409 * HDMI routines
410 */
411
412#ifdef BE_PARANOID
413static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
414 int *packet_index, int *byte_index)
415{
416 int val;
417
418 val = snd_hda_codec_read(codec, pin_nid, 0,
419 AC_VERB_GET_HDMI_DIP_INDEX, 0);
420
421 *packet_index = val >> 5;
422 *byte_index = val & 0x1f;
423}
424#endif
425
426static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t pin_nid,
427 int packet_index, int byte_index)
428{
429 int val;
430
431 val = (packet_index << 5) | (byte_index & 0x1f);
432
433 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
434}
435
436static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t pin_nid,
437 unsigned char val)
438{
439 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
440}
441
442static void hdmi_enable_output(struct hda_codec *codec, hda_nid_t pin_nid)
443{
444 /* Unmute */
445 if (get_wcaps(codec, pin_nid) & AC_WCAP_OUT_AMP)
446 snd_hda_codec_write(codec, pin_nid, 0,
447 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
448 /* Enable pin out */
449 snd_hda_codec_write(codec, pin_nid, 0,
450 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
451}
452
453/*
454 * Enable Audio InfoFrame Transmission
455 */
456static void hdmi_start_infoframe_trans(struct hda_codec *codec,
457 hda_nid_t pin_nid)
458{
459 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
460 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
461 AC_DIPXMIT_BEST);
462}
463
464/*
465 * Disable Audio InfoFrame Transmission
466 */
467static void hdmi_stop_infoframe_trans(struct hda_codec *codec,
468 hda_nid_t pin_nid)
469{
470 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
471 snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_DIP_XMIT,
472 AC_DIPXMIT_DISABLE);
473}
474
475static int hdmi_get_channel_count(struct hda_codec *codec, hda_nid_t nid)
476{
477 return 1 + snd_hda_codec_read(codec, nid, 0,
478 AC_VERB_GET_CVT_CHAN_COUNT, 0);
479}
480
481static void hdmi_set_channel_count(struct hda_codec *codec,
482 hda_nid_t nid, int chs)
483{
484 if (chs != hdmi_get_channel_count(codec, nid))
485 snd_hda_codec_write(codec, nid, 0,
486 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
487}
488
489static void hdmi_debug_channel_mapping(struct hda_codec *codec,
490 hda_nid_t pin_nid)
491{
492#ifdef CONFIG_SND_DEBUG_VERBOSE
493 int i;
494 int slot;
495
496 for (i = 0; i < 8; i++) {
497 slot = snd_hda_codec_read(codec, pin_nid, 0,
498 AC_VERB_GET_HDMI_CHAN_SLOT, i);
499 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
500 slot >> 4, slot & 0xf);
501 }
502#endif
503}
504
505
506/*
507 * Audio InfoFrame routines
508 */
509
510static void hdmi_debug_dip_size(struct hda_codec *codec, hda_nid_t pin_nid)
511{
512#ifdef CONFIG_SND_DEBUG_VERBOSE
513 int i;
514 int size;
515
516 size = snd_hdmi_get_eld_size(codec, pin_nid);
517 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
518
519 for (i = 0; i < 8; i++) {
520 size = snd_hda_codec_read(codec, pin_nid, 0,
521 AC_VERB_GET_HDMI_DIP_SIZE, i);
522 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
523 }
524#endif
525}
526
527static void hdmi_clear_dip_buffers(struct hda_codec *codec, hda_nid_t pin_nid)
528{
529#ifdef BE_PARANOID
530 int i, j;
531 int size;
532 int pi, bi;
533 for (i = 0; i < 8; i++) {
534 size = snd_hda_codec_read(codec, pin_nid, 0,
535 AC_VERB_GET_HDMI_DIP_SIZE, i);
536 if (size == 0)
537 continue;
538
539 hdmi_set_dip_index(codec, pin_nid, i, 0x0);
540 for (j = 1; j < 1000; j++) {
541 hdmi_write_dip_byte(codec, pin_nid, 0x0);
542 hdmi_get_dip_index(codec, pin_nid, &pi, &bi);
543 if (pi != i)
544 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
545 bi, pi, i);
546 if (bi == 0) /* byte index wrapped around */
547 break;
548 }
549 snd_printd(KERN_INFO
550 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
551 i, size, j);
552 }
553#endif
554}
555
556static void hdmi_checksum_audio_infoframe(struct hdmi_audio_infoframe *ai)
557{
558 u8 *bytes = (u8 *)ai;
559 u8 sum = 0;
560 int i;
561
562 ai->checksum = 0;
563
564 for (i = 0; i < sizeof(*ai); i++)
565 sum += bytes[i];
566
567 ai->checksum = - sum;
568}
569
570static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
571 hda_nid_t pin_nid,
572 struct hdmi_audio_infoframe *ai)
573{
574 u8 *bytes = (u8 *)ai;
575 int i;
576
577 hdmi_debug_dip_size(codec, pin_nid);
578 hdmi_clear_dip_buffers(codec, pin_nid); /* be paranoid */
579
580 hdmi_checksum_audio_infoframe(ai);
581
582 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
583 for (i = 0; i < sizeof(*ai); i++)
584 hdmi_write_dip_byte(codec, pin_nid, bytes[i]);
585}
586
587/*
588 * Compute derived values in channel_allocations[].
589 */
590static void init_channel_allocations(void)
591{
592 int i, j;
593 struct cea_channel_speaker_allocation *p;
594
595 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
596 p = channel_allocations + i;
597 p->channels = 0;
598 p->spk_mask = 0;
599 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
600 if (p->speakers[j]) {
601 p->channels++;
602 p->spk_mask |= p->speakers[j];
603 }
604 }
605}
606
607/*
608 * The transformation takes two steps:
609 *
610 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
611 * spk_mask => (channel_allocations[]) => ai->CA
612 *
613 * TODO: it could select the wrong CA from multiple candidates.
614*/
615static int hdmi_setup_channel_allocation(struct hda_codec *codec, hda_nid_t nid,
616 struct hdmi_audio_infoframe *ai)
617{
618 struct intel_hdmi_spec *spec = codec->spec;
619 struct hdmi_eld *eld;
620 int i;
621 int spk_mask = 0;
622 int channels = 1 + (ai->CC02_CT47 & 0x7);
623 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
624
625 /*
626 * CA defaults to 0 for basic stereo audio
627 */
628 if (channels <= 2)
629 return 0;
630
631 i = hda_node_index(spec->pin_cvt, nid);
632 if (i < 0)
633 return 0;
634 eld = &spec->sink_eld[i];
635
636 /*
637 * HDMI sink's ELD info cannot always be retrieved for now, e.g.
638 * in console or for audio devices. Assume the highest speakers
639 * configuration, to _not_ prohibit multi-channel audio playback.
640 */
641 if (!eld->spk_alloc)
642 eld->spk_alloc = 0xffff;
643
644 /*
645 * expand ELD's speaker allocation mask
646 *
647 * ELD tells the speaker mask in a compact(paired) form,
648 * expand ELD's notions to match the ones used by Audio InfoFrame.
649 */
650 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
651 if (eld->spk_alloc & (1 << i))
652 spk_mask |= eld_speaker_allocation_bits[i];
653 }
654
655 /* search for the first working match in the CA table */
656 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
657 if (channels == channel_allocations[i].channels &&
658 (spk_mask & channel_allocations[i].spk_mask) ==
659 channel_allocations[i].spk_mask) {
660 ai->CA = channel_allocations[i].ca_index;
661 break;
662 }
663 }
664
665 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
666 snd_printdd(KERN_INFO
667 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
668 ai->CA, channels, buf);
669
670 return ai->CA;
671}
672
673static void hdmi_setup_channel_mapping(struct hda_codec *codec,
674 hda_nid_t pin_nid,
675 struct hdmi_audio_infoframe *ai)
676{
677 int i;
678 int ca = ai->CA;
679 int err;
680
681 if (hdmi_channel_mapping[ca][1] == 0) {
682 for (i = 0; i < channel_allocations[ca].channels; i++)
683 hdmi_channel_mapping[ca][i] = i | (i << 4);
684 for (; i < 8; i++)
685 hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
686 }
687
688 for (i = 0; i < 8; i++) {
689 err = snd_hda_codec_write(codec, pin_nid, 0,
690 AC_VERB_SET_HDMI_CHAN_SLOT,
691 hdmi_channel_mapping[ca][i]);
692 if (err) {
693 snd_printdd(KERN_INFO "HDMI: channel mapping failed\n");
694 break;
695 }
696 }
697
698 hdmi_debug_channel_mapping(codec, pin_nid);
699}
700
701static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
702 struct hdmi_audio_infoframe *ai)
703{
704 u8 *bytes = (u8 *)ai;
705 u8 val;
706 int i;
707
708 if (snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_HDMI_DIP_XMIT, 0)
709 != AC_DIPXMIT_BEST)
710 return false;
711
712 hdmi_set_dip_index(codec, pin_nid, 0x0, 0x0);
713 for (i = 0; i < sizeof(*ai); i++) {
714 val = snd_hda_codec_read(codec, pin_nid, 0,
715 AC_VERB_GET_HDMI_DIP_DATA, 0);
716 if (val != bytes[i])
717 return false;
718 }
719
720 return true;
721}
722
723static void hdmi_setup_audio_infoframe(struct hda_codec *codec, hda_nid_t nid,
724 struct snd_pcm_substream *substream)
725{
726 struct intel_hdmi_spec *spec = codec->spec;
727 hda_nid_t pin_nid;
728 int i;
729 struct hdmi_audio_infoframe ai = {
730 .type = 0x84,
731 .ver = 0x01,
732 .len = 0x0a,
733 .CC02_CT47 = substream->runtime->channels - 1,
734 };
735
736 hdmi_setup_channel_allocation(codec, nid, &ai);
737
738 for (i = 0; i < spec->num_pins; i++) {
739 if (spec->pin_cvt[i] != nid)
740 continue;
741 if (!spec->sink_eld[i].monitor_present)
742 continue;
743
744 pin_nid = spec->pin[i];
745 if (!hdmi_infoframe_uptodate(codec, pin_nid, &ai)) {
746 hdmi_setup_channel_mapping(codec, pin_nid, &ai);
747 hdmi_stop_infoframe_trans(codec, pin_nid);
748 hdmi_fill_audio_infoframe(codec, pin_nid, &ai);
749 hdmi_start_infoframe_trans(codec, pin_nid);
750 }
751 }
752}
753
754
755/* 53/*
756 * Unsolicited events 54 * HDMI callbacks
757 */ 55 */
758 56
759static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
760{
761 struct intel_hdmi_spec *spec = codec->spec;
762 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
763 int pind = !!(res & AC_UNSOL_RES_PD);
764 int eldv = !!(res & AC_UNSOL_RES_ELDV);
765 int index;
766
767 printk(KERN_INFO
768 "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n",
769 tag, pind, eldv);
770
771 index = hda_node_index(spec->pin, tag);
772 if (index < 0)
773 return;
774
775 spec->sink_eld[index].monitor_present = pind;
776 spec->sink_eld[index].eld_valid = eldv;
777
778 if (pind && eldv) {
779 hdmi_get_show_eld(codec, spec->pin[index], &spec->sink_eld[index]);
780 /* TODO: do real things about ELD */
781 }
782}
783
784static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
785{
786 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
787 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
788 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
789 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
790
791 printk(KERN_INFO
792 "HDMI CP event: PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
793 tag,
794 subtag,
795 cp_state,
796 cp_ready);
797
798 /* TODO */
799 if (cp_state)
800 ;
801 if (cp_ready)
802 ;
803}
804
805
806static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
807{
808 struct intel_hdmi_spec *spec = codec->spec;
809 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
810 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
811
812 if (hda_node_index(spec->pin, tag) < 0) {
813 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
814 return;
815 }
816
817 if (subtag == 0)
818 hdmi_intrinsic_event(codec, res);
819 else
820 hdmi_non_intrinsic_event(codec, res);
821}
822
823/*
824 * Callbacks
825 */
826
827static void hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
828 u32 stream_tag, int format)
829{
830 int tag;
831 int fmt;
832
833 tag = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0) >> 4;
834 fmt = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_STREAM_FORMAT, 0);
835
836 snd_printdd("hdmi_setup_stream: "
837 "NID=0x%x, %sstream=0x%x, %sformat=0x%x\n",
838 nid,
839 tag == stream_tag ? "" : "new-",
840 stream_tag,
841 fmt == format ? "" : "new-",
842 format);
843
844 if (tag != stream_tag)
845 snd_hda_codec_write(codec, nid, 0,
846 AC_VERB_SET_CHANNEL_STREAMID, stream_tag << 4);
847 if (fmt != format)
848 snd_hda_codec_write(codec, nid, 0,
849 AC_VERB_SET_STREAM_FORMAT, format);
850}
851
852static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 57static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
853 struct hda_codec *codec, 58 struct hda_codec *codec,
854 unsigned int stream_tag, 59 unsigned int stream_tag,
@@ -882,7 +87,7 @@ static struct hda_pcm_stream intel_hdmi_pcm_playback = {
882 87
883static int intel_hdmi_build_pcms(struct hda_codec *codec) 88static int intel_hdmi_build_pcms(struct hda_codec *codec)
884{ 89{
885 struct intel_hdmi_spec *spec = codec->spec; 90 struct hdmi_spec *spec = codec->spec;
886 struct hda_pcm *info = spec->pcm_rec; 91 struct hda_pcm *info = spec->pcm_rec;
887 int i; 92 int i;
888 93
@@ -908,7 +113,7 @@ static int intel_hdmi_build_pcms(struct hda_codec *codec)
908 113
909static int intel_hdmi_build_controls(struct hda_codec *codec) 114static int intel_hdmi_build_controls(struct hda_codec *codec)
910{ 115{
911 struct intel_hdmi_spec *spec = codec->spec; 116 struct hdmi_spec *spec = codec->spec;
912 int err; 117 int err;
913 int i; 118 int i;
914 119
@@ -923,7 +128,7 @@ static int intel_hdmi_build_controls(struct hda_codec *codec)
923 128
924static int intel_hdmi_init(struct hda_codec *codec) 129static int intel_hdmi_init(struct hda_codec *codec)
925{ 130{
926 struct intel_hdmi_spec *spec = codec->spec; 131 struct hdmi_spec *spec = codec->spec;
927 int i; 132 int i;
928 133
929 for (i = 0; spec->pin[i]; i++) { 134 for (i = 0; spec->pin[i]; i++) {
@@ -937,7 +142,7 @@ static int intel_hdmi_init(struct hda_codec *codec)
937 142
938static void intel_hdmi_free(struct hda_codec *codec) 143static void intel_hdmi_free(struct hda_codec *codec)
939{ 144{
940 struct intel_hdmi_spec *spec = codec->spec; 145 struct hdmi_spec *spec = codec->spec;
941 int i; 146 int i;
942 147
943 for (i = 0; i < spec->num_pins; i++) 148 for (i = 0; i < spec->num_pins; i++)
@@ -951,12 +156,12 @@ static struct hda_codec_ops intel_hdmi_patch_ops = {
951 .free = intel_hdmi_free, 156 .free = intel_hdmi_free,
952 .build_pcms = intel_hdmi_build_pcms, 157 .build_pcms = intel_hdmi_build_pcms,
953 .build_controls = intel_hdmi_build_controls, 158 .build_controls = intel_hdmi_build_controls,
954 .unsol_event = intel_hdmi_unsol_event, 159 .unsol_event = hdmi_unsol_event,
955}; 160};
956 161
957static int patch_intel_hdmi(struct hda_codec *codec) 162static int patch_intel_hdmi(struct hda_codec *codec)
958{ 163{
959 struct intel_hdmi_spec *spec; 164 struct hdmi_spec *spec;
960 int i; 165 int i;
961 166
962 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 167 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
@@ -964,7 +169,7 @@ static int patch_intel_hdmi(struct hda_codec *codec)
964 return -ENOMEM; 169 return -ENOMEM;
965 170
966 codec->spec = spec; 171 codec->spec = spec;
967 if (intel_hdmi_parse_codec(codec) < 0) { 172 if (hdmi_parse_codec(codec) < 0) {
968 codec->spec = NULL; 173 codec->spec = NULL;
969 kfree(spec); 174 kfree(spec);
970 return -EINVAL; 175 return -EINVAL;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 6afdab09bab7..70669a246902 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -29,13 +29,23 @@
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31 31
32#define MAX_HDMI_CVTS 1
33#define MAX_HDMI_PINS 1
34
35#include "patch_hdmi.c"
36
37static char *nvhdmi_pcm_names[MAX_HDMI_CVTS] = {
38 "NVIDIA HDMI",
39};
40
32/* define below to restrict the supported rates and formats */ 41/* define below to restrict the supported rates and formats */
33/* #define LIMITED_RATE_FMT_SUPPORT */ 42/* #define LIMITED_RATE_FMT_SUPPORT */
34 43
35struct nvhdmi_spec { 44enum HDACodec {
36 struct hda_multi_out multiout; 45 HDA_CODEC_NVIDIA_MCP7X,
37 46 HDA_CODEC_NVIDIA_MCP89,
38 struct hda_pcm pcm_rec; 47 HDA_CODEC_NVIDIA_GT21X,
48 HDA_CODEC_INVALID
39}; 49};
40 50
41#define Nv_VERB_SET_Channel_Allocation 0xF79 51#define Nv_VERB_SET_Channel_Allocation 0xF79
@@ -43,15 +53,18 @@ struct nvhdmi_spec {
43#define Nv_VERB_SET_Audio_Protection_On 0xF98 53#define Nv_VERB_SET_Audio_Protection_On 0xF98
44#define Nv_VERB_SET_Audio_Protection_Off 0xF99 54#define Nv_VERB_SET_Audio_Protection_Off 0xF99
45 55
46#define Nv_Master_Convert_nid 0x04 56#define nvhdmi_master_con_nid_7x 0x04
47#define Nv_Master_Pin_nid 0x05 57#define nvhdmi_master_pin_nid_7x 0x05
48 58
49static hda_nid_t nvhdmi_convert_nids[4] = { 59#define nvhdmi_master_con_nid_89 0x04
60#define nvhdmi_master_pin_nid_89 0x05
61
62static hda_nid_t nvhdmi_con_nids_7x[4] = {
50 /*front, rear, clfe, rear_surr */ 63 /*front, rear, clfe, rear_surr */
51 0x6, 0x8, 0xa, 0xc, 64 0x6, 0x8, 0xa, 0xc,
52}; 65};
53 66
54static struct hda_verb nvhdmi_basic_init[] = { 67static struct hda_verb nvhdmi_basic_init_7x[] = {
55 /* set audio protect on */ 68 /* set audio protect on */
56 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 69 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
57 /* enable digital output on pin widget */ 70 /* enable digital output on pin widget */
@@ -84,22 +97,60 @@ static struct hda_verb nvhdmi_basic_init[] = {
84 */ 97 */
85static int nvhdmi_build_controls(struct hda_codec *codec) 98static int nvhdmi_build_controls(struct hda_codec *codec)
86{ 99{
87 struct nvhdmi_spec *spec = codec->spec; 100 struct hdmi_spec *spec = codec->spec;
88 int err; 101 int err;
102 int i;
89 103
90 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); 104 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
91 if (err < 0) 105 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
92 return err; 106 for (i = 0; i < codec->num_pcms; i++) {
107 err = snd_hda_create_spdif_out_ctls(codec,
108 spec->cvt[i]);
109 if (err < 0)
110 return err;
111 }
112 } else {
113 err = snd_hda_create_spdif_out_ctls(codec,
114 spec->multiout.dig_out_nid);
115 if (err < 0)
116 return err;
117 }
93 118
94 return 0; 119 return 0;
95} 120}
96 121
97static int nvhdmi_init(struct hda_codec *codec) 122static int nvhdmi_init(struct hda_codec *codec)
98{ 123{
99 snd_hda_sequence_write(codec, nvhdmi_basic_init); 124 struct hdmi_spec *spec = codec->spec;
125 int i;
126 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
127 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
128 for (i = 0; spec->pin[i]; i++) {
129 hdmi_enable_output(codec, spec->pin[i]);
130 snd_hda_codec_write(codec, spec->pin[i], 0,
131 AC_VERB_SET_UNSOLICITED_ENABLE,
132 AC_USRSP_EN | spec->pin[i]);
133 }
134 } else {
135 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x);
136 }
100 return 0; 137 return 0;
101} 138}
102 139
140static void nvhdmi_free(struct hda_codec *codec)
141{
142 struct hdmi_spec *spec = codec->spec;
143 int i;
144
145 if ((spec->codec_type == HDA_CODEC_NVIDIA_MCP89)
146 || (spec->codec_type == HDA_CODEC_NVIDIA_GT21X)) {
147 for (i = 0; i < spec->num_pins; i++)
148 snd_hda_eld_proc_free(codec, &spec->sink_eld[i]);
149 }
150
151 kfree(spec);
152}
153
103/* 154/*
104 * Digital out 155 * Digital out
105 */ 156 */
@@ -107,25 +158,25 @@ static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
107 struct hda_codec *codec, 158 struct hda_codec *codec,
108 struct snd_pcm_substream *substream) 159 struct snd_pcm_substream *substream)
109{ 160{
110 struct nvhdmi_spec *spec = codec->spec; 161 struct hdmi_spec *spec = codec->spec;
111 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 162 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
112} 163}
113 164
114static int nvhdmi_dig_playback_pcm_close_8ch(struct hda_pcm_stream *hinfo, 165static int nvhdmi_dig_playback_pcm_close_8ch_7x(struct hda_pcm_stream *hinfo,
115 struct hda_codec *codec, 166 struct hda_codec *codec,
116 struct snd_pcm_substream *substream) 167 struct snd_pcm_substream *substream)
117{ 168{
118 struct nvhdmi_spec *spec = codec->spec; 169 struct hdmi_spec *spec = codec->spec;
119 int i; 170 int i;
120 171
121 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 172 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x,
122 0, AC_VERB_SET_CHANNEL_STREAMID, 0); 173 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
123 for (i = 0; i < 4; i++) { 174 for (i = 0; i < 4; i++) {
124 /* set the stream id */ 175 /* set the stream id */
125 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 176 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
126 AC_VERB_SET_CHANNEL_STREAMID, 0); 177 AC_VERB_SET_CHANNEL_STREAMID, 0);
127 /* set the stream format */ 178 /* set the stream format */
128 snd_hda_codec_write(codec, nvhdmi_convert_nids[i], 0, 179 snd_hda_codec_write(codec, nvhdmi_con_nids_7x[i], 0,
129 AC_VERB_SET_STREAM_FORMAT, 0); 180 AC_VERB_SET_STREAM_FORMAT, 0);
130 } 181 }
131 182
@@ -136,10 +187,25 @@ static int nvhdmi_dig_playback_pcm_close_2ch(struct hda_pcm_stream *hinfo,
136 struct hda_codec *codec, 187 struct hda_codec *codec,
137 struct snd_pcm_substream *substream) 188 struct snd_pcm_substream *substream)
138{ 189{
139 struct nvhdmi_spec *spec = codec->spec; 190 struct hdmi_spec *spec = codec->spec;
140 return snd_hda_multi_out_dig_close(codec, &spec->multiout); 191 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
141} 192}
142 193
194static int nvhdmi_dig_playback_pcm_prepare_8ch_89(struct hda_pcm_stream *hinfo,
195 struct hda_codec *codec,
196 unsigned int stream_tag,
197 unsigned int format,
198 struct snd_pcm_substream *substream)
199{
200 hdmi_set_channel_count(codec, hinfo->nid,
201 substream->runtime->channels);
202
203 hdmi_setup_audio_infoframe(codec, hinfo->nid, substream);
204
205 hdmi_setup_stream(codec, hinfo->nid, stream_tag, format);
206 return 0;
207}
208
143static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo, 209static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
144 struct hda_codec *codec, 210 struct hda_codec *codec,
145 unsigned int stream_tag, 211 unsigned int stream_tag,
@@ -181,29 +247,29 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
181 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ 247 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
182 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) 248 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
183 snd_hda_codec_write(codec, 249 snd_hda_codec_write(codec,
184 Nv_Master_Convert_nid, 250 nvhdmi_master_con_nid_7x,
185 0, 251 0,
186 AC_VERB_SET_DIGI_CONVERT_1, 252 AC_VERB_SET_DIGI_CONVERT_1,
187 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 253 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
188 254
189 /* set the stream id */ 255 /* set the stream id */
190 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 256 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
191 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0); 257 AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | 0x0);
192 258
193 /* set the stream format */ 259 /* set the stream format */
194 snd_hda_codec_write(codec, Nv_Master_Convert_nid, 0, 260 snd_hda_codec_write(codec, nvhdmi_master_con_nid_7x, 0,
195 AC_VERB_SET_STREAM_FORMAT, format); 261 AC_VERB_SET_STREAM_FORMAT, format);
196 262
197 /* turn on again (if needed) */ 263 /* turn on again (if needed) */
198 /* enable and set the channel status audio/data flag */ 264 /* enable and set the channel status audio/data flag */
199 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { 265 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) {
200 snd_hda_codec_write(codec, 266 snd_hda_codec_write(codec,
201 Nv_Master_Convert_nid, 267 nvhdmi_master_con_nid_7x,
202 0, 268 0,
203 AC_VERB_SET_DIGI_CONVERT_1, 269 AC_VERB_SET_DIGI_CONVERT_1,
204 codec->spdif_ctls & 0xff); 270 codec->spdif_ctls & 0xff);
205 snd_hda_codec_write(codec, 271 snd_hda_codec_write(codec,
206 Nv_Master_Convert_nid, 272 nvhdmi_master_con_nid_7x,
207 0, 273 0,
208 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 274 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
209 } 275 }
@@ -220,19 +286,19 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
220 if (codec->spdif_status_reset && 286 if (codec->spdif_status_reset &&
221 (codec->spdif_ctls & AC_DIG1_ENABLE)) 287 (codec->spdif_ctls & AC_DIG1_ENABLE))
222 snd_hda_codec_write(codec, 288 snd_hda_codec_write(codec,
223 nvhdmi_convert_nids[i], 289 nvhdmi_con_nids_7x[i],
224 0, 290 0,
225 AC_VERB_SET_DIGI_CONVERT_1, 291 AC_VERB_SET_DIGI_CONVERT_1,
226 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); 292 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff);
227 /* set the stream id */ 293 /* set the stream id */
228 snd_hda_codec_write(codec, 294 snd_hda_codec_write(codec,
229 nvhdmi_convert_nids[i], 295 nvhdmi_con_nids_7x[i],
230 0, 296 0,
231 AC_VERB_SET_CHANNEL_STREAMID, 297 AC_VERB_SET_CHANNEL_STREAMID,
232 (stream_tag << 4) | channel_id); 298 (stream_tag << 4) | channel_id);
233 /* set the stream format */ 299 /* set the stream format */
234 snd_hda_codec_write(codec, 300 snd_hda_codec_write(codec,
235 nvhdmi_convert_nids[i], 301 nvhdmi_con_nids_7x[i],
236 0, 302 0,
237 AC_VERB_SET_STREAM_FORMAT, 303 AC_VERB_SET_STREAM_FORMAT,
238 format); 304 format);
@@ -241,12 +307,12 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
241 if (codec->spdif_status_reset && 307 if (codec->spdif_status_reset &&
242 (codec->spdif_ctls & AC_DIG1_ENABLE)) { 308 (codec->spdif_ctls & AC_DIG1_ENABLE)) {
243 snd_hda_codec_write(codec, 309 snd_hda_codec_write(codec,
244 nvhdmi_convert_nids[i], 310 nvhdmi_con_nids_7x[i],
245 0, 311 0,
246 AC_VERB_SET_DIGI_CONVERT_1, 312 AC_VERB_SET_DIGI_CONVERT_1,
247 codec->spdif_ctls & 0xff); 313 codec->spdif_ctls & 0xff);
248 snd_hda_codec_write(codec, 314 snd_hda_codec_write(codec,
249 nvhdmi_convert_nids[i], 315 nvhdmi_con_nids_7x[i],
250 0, 316 0,
251 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2); 317 AC_VERB_SET_DIGI_CONVERT_2, dataDCC2);
252 } 318 }
@@ -261,28 +327,47 @@ static int nvhdmi_dig_playback_pcm_prepare_8ch(struct hda_pcm_stream *hinfo,
261 return 0; 327 return 0;
262} 328}
263 329
330static int nvhdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
331 struct hda_codec *codec,
332 struct snd_pcm_substream *substream)
333{
334 return 0;
335}
336
264static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo, 337static int nvhdmi_dig_playback_pcm_prepare_2ch(struct hda_pcm_stream *hinfo,
265 struct hda_codec *codec, 338 struct hda_codec *codec,
266 unsigned int stream_tag, 339 unsigned int stream_tag,
267 unsigned int format, 340 unsigned int format,
268 struct snd_pcm_substream *substream) 341 struct snd_pcm_substream *substream)
269{ 342{
270 struct nvhdmi_spec *spec = codec->spec; 343 struct hdmi_spec *spec = codec->spec;
271 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 344 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
272 format, substream); 345 format, substream);
273} 346}
274 347
275static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch = { 348static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_89 = {
349 .substreams = 1,
350 .channels_min = 2,
351 .rates = SUPPORTED_RATES,
352 .maxbps = SUPPORTED_MAXBPS,
353 .formats = SUPPORTED_FORMATS,
354 .ops = {
355 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch_89,
356 .cleanup = nvhdmi_playback_pcm_cleanup,
357 },
358};
359
360static struct hda_pcm_stream nvhdmi_pcm_digital_playback_8ch_7x = {
276 .substreams = 1, 361 .substreams = 1,
277 .channels_min = 2, 362 .channels_min = 2,
278 .channels_max = 8, 363 .channels_max = 8,
279 .nid = Nv_Master_Convert_nid, 364 .nid = nvhdmi_master_con_nid_7x,
280 .rates = SUPPORTED_RATES, 365 .rates = SUPPORTED_RATES,
281 .maxbps = SUPPORTED_MAXBPS, 366 .maxbps = SUPPORTED_MAXBPS,
282 .formats = SUPPORTED_FORMATS, 367 .formats = SUPPORTED_FORMATS,
283 .ops = { 368 .ops = {
284 .open = nvhdmi_dig_playback_pcm_open, 369 .open = nvhdmi_dig_playback_pcm_open,
285 .close = nvhdmi_dig_playback_pcm_close_8ch, 370 .close = nvhdmi_dig_playback_pcm_close_8ch_7x,
286 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch 371 .prepare = nvhdmi_dig_playback_pcm_prepare_8ch
287 }, 372 },
288}; 373};
@@ -291,7 +376,7 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
291 .substreams = 1, 376 .substreams = 1,
292 .channels_min = 2, 377 .channels_min = 2,
293 .channels_max = 2, 378 .channels_max = 2,
294 .nid = Nv_Master_Convert_nid, 379 .nid = nvhdmi_master_con_nid_7x,
295 .rates = SUPPORTED_RATES, 380 .rates = SUPPORTED_RATES,
296 .maxbps = SUPPORTED_MAXBPS, 381 .maxbps = SUPPORTED_MAXBPS,
297 .formats = SUPPORTED_FORMATS, 382 .formats = SUPPORTED_FORMATS,
@@ -302,10 +387,36 @@ static struct hda_pcm_stream nvhdmi_pcm_digital_playback_2ch = {
302 }, 387 },
303}; 388};
304 389
305static int nvhdmi_build_pcms_8ch(struct hda_codec *codec) 390static int nvhdmi_build_pcms_8ch_89(struct hda_codec *codec)
391{
392 struct hdmi_spec *spec = codec->spec;
393 struct hda_pcm *info = spec->pcm_rec;
394 int i;
395
396 codec->num_pcms = spec->num_cvts;
397 codec->pcm_info = info;
398
399 for (i = 0; i < codec->num_pcms; i++, info++) {
400 unsigned int chans;
401
402 chans = get_wcaps(codec, spec->cvt[i]);
403 chans = get_wcaps_channels(chans);
404
405 info->name = nvhdmi_pcm_names[i];
406 info->pcm_type = HDA_PCM_TYPE_HDMI;
407 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
408 = nvhdmi_pcm_digital_playback_8ch_89;
409 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->cvt[i];
410 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans;
411 }
412
413 return 0;
414}
415
416static int nvhdmi_build_pcms_8ch_7x(struct hda_codec *codec)
306{ 417{
307 struct nvhdmi_spec *spec = codec->spec; 418 struct hdmi_spec *spec = codec->spec;
308 struct hda_pcm *info = &spec->pcm_rec; 419 struct hda_pcm *info = spec->pcm_rec;
309 420
310 codec->num_pcms = 1; 421 codec->num_pcms = 1;
311 codec->pcm_info = info; 422 codec->pcm_info = info;
@@ -313,15 +424,15 @@ static int nvhdmi_build_pcms_8ch(struct hda_codec *codec)
313 info->name = "NVIDIA HDMI"; 424 info->name = "NVIDIA HDMI";
314 info->pcm_type = HDA_PCM_TYPE_HDMI; 425 info->pcm_type = HDA_PCM_TYPE_HDMI;
315 info->stream[SNDRV_PCM_STREAM_PLAYBACK] 426 info->stream[SNDRV_PCM_STREAM_PLAYBACK]
316 = nvhdmi_pcm_digital_playback_8ch; 427 = nvhdmi_pcm_digital_playback_8ch_7x;
317 428
318 return 0; 429 return 0;
319} 430}
320 431
321static int nvhdmi_build_pcms_2ch(struct hda_codec *codec) 432static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
322{ 433{
323 struct nvhdmi_spec *spec = codec->spec; 434 struct hdmi_spec *spec = codec->spec;
324 struct hda_pcm *info = &spec->pcm_rec; 435 struct hda_pcm *info = spec->pcm_rec;
325 436
326 codec->num_pcms = 1; 437 codec->num_pcms = 1;
327 codec->pcm_info = info; 438 codec->pcm_info = info;
@@ -334,14 +445,17 @@ static int nvhdmi_build_pcms_2ch(struct hda_codec *codec)
334 return 0; 445 return 0;
335} 446}
336 447
337static void nvhdmi_free(struct hda_codec *codec) 448static struct hda_codec_ops nvhdmi_patch_ops_8ch_89 = {
338{ 449 .build_controls = nvhdmi_build_controls,
339 kfree(codec->spec); 450 .build_pcms = nvhdmi_build_pcms_8ch_89,
340} 451 .init = nvhdmi_init,
452 .free = nvhdmi_free,
453 .unsol_event = hdmi_unsol_event,
454};
341 455
342static struct hda_codec_ops nvhdmi_patch_ops_8ch = { 456static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
343 .build_controls = nvhdmi_build_controls, 457 .build_controls = nvhdmi_build_controls,
344 .build_pcms = nvhdmi_build_pcms_8ch, 458 .build_pcms = nvhdmi_build_pcms_8ch_7x,
345 .init = nvhdmi_init, 459 .init = nvhdmi_init,
346 .free = nvhdmi_free, 460 .free = nvhdmi_free,
347}; 461};
@@ -353,9 +467,36 @@ static struct hda_codec_ops nvhdmi_patch_ops_2ch = {
353 .free = nvhdmi_free, 467 .free = nvhdmi_free,
354}; 468};
355 469
356static int patch_nvhdmi_8ch(struct hda_codec *codec) 470static int patch_nvhdmi_8ch_89(struct hda_codec *codec)
471{
472 struct hdmi_spec *spec;
473 int i;
474
475 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
476 if (spec == NULL)
477 return -ENOMEM;
478
479 codec->spec = spec;
480 spec->codec_type = HDA_CODEC_NVIDIA_MCP89;
481
482 if (hdmi_parse_codec(codec) < 0) {
483 codec->spec = NULL;
484 kfree(spec);
485 return -EINVAL;
486 }
487 codec->patch_ops = nvhdmi_patch_ops_8ch_89;
488
489 for (i = 0; i < spec->num_pins; i++)
490 snd_hda_eld_proc_new(codec, &spec->sink_eld[i], i);
491
492 init_channel_allocations();
493
494 return 0;
495}
496
497static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
357{ 498{
358 struct nvhdmi_spec *spec; 499 struct hdmi_spec *spec;
359 500
360 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 501 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
361 if (spec == NULL) 502 if (spec == NULL)
@@ -365,16 +506,17 @@ static int patch_nvhdmi_8ch(struct hda_codec *codec)
365 506
366 spec->multiout.num_dacs = 0; /* no analog */ 507 spec->multiout.num_dacs = 0; /* no analog */
367 spec->multiout.max_channels = 8; 508 spec->multiout.max_channels = 8;
368 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 509 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
510 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
369 511
370 codec->patch_ops = nvhdmi_patch_ops_8ch; 512 codec->patch_ops = nvhdmi_patch_ops_8ch_7x;
371 513
372 return 0; 514 return 0;
373} 515}
374 516
375static int patch_nvhdmi_2ch(struct hda_codec *codec) 517static int patch_nvhdmi_2ch(struct hda_codec *codec)
376{ 518{
377 struct nvhdmi_spec *spec; 519 struct hdmi_spec *spec;
378 520
379 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 521 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
380 if (spec == NULL) 522 if (spec == NULL)
@@ -384,7 +526,8 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
384 526
385 spec->multiout.num_dacs = 0; /* no analog */ 527 spec->multiout.num_dacs = 0; /* no analog */
386 spec->multiout.max_channels = 2; 528 spec->multiout.max_channels = 2;
387 spec->multiout.dig_out_nid = Nv_Master_Convert_nid; 529 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
530 spec->codec_type = HDA_CODEC_NVIDIA_MCP7X;
388 531
389 codec->patch_ops = nvhdmi_patch_ops_2ch; 532 codec->patch_ops = nvhdmi_patch_ops_2ch;
390 533
@@ -395,13 +538,24 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec)
395 * patch entries 538 * patch entries
396 */ 539 */
397static struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 540static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
398 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
399 { .id = 0x10de0003, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
400 { .id = 0x10de0005, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
401 { .id = 0x10de0006, .name = "MCP78 HDMI", .patch = patch_nvhdmi_8ch },
402 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi_8ch },
403 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 541 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
404 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 542 { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
543 { .id = 0x10de0002, .name = "MCP77/78 HDMI",
544 .patch = patch_nvhdmi_8ch_7x },
545 { .id = 0x10de0003, .name = "MCP77/78 HDMI",
546 .patch = patch_nvhdmi_8ch_7x },
547 { .id = 0x10de0005, .name = "MCP77/78 HDMI",
548 .patch = patch_nvhdmi_8ch_7x },
549 { .id = 0x10de0006, .name = "MCP77/78 HDMI",
550 .patch = patch_nvhdmi_8ch_7x },
551 { .id = 0x10de0007, .name = "MCP79/7A HDMI",
552 .patch = patch_nvhdmi_8ch_7x },
553 { .id = 0x10de000c, .name = "MCP89 HDMI",
554 .patch = patch_nvhdmi_8ch_89 },
555 { .id = 0x10de000b, .name = "GT21x HDMI",
556 .patch = patch_nvhdmi_8ch_89 },
557 { .id = 0x10de000d, .name = "GT240 HDMI",
558 .patch = patch_nvhdmi_8ch_89 },
405 {} /* terminator */ 559 {} /* terminator */
406}; 560};
407 561
@@ -412,9 +566,12 @@ MODULE_ALIAS("snd-hda-codec-id:10de0006");
412MODULE_ALIAS("snd-hda-codec-id:10de0007"); 566MODULE_ALIAS("snd-hda-codec-id:10de0007");
413MODULE_ALIAS("snd-hda-codec-id:10de0067"); 567MODULE_ALIAS("snd-hda-codec-id:10de0067");
414MODULE_ALIAS("snd-hda-codec-id:10de8001"); 568MODULE_ALIAS("snd-hda-codec-id:10de8001");
569MODULE_ALIAS("snd-hda-codec-id:10de000c");
570MODULE_ALIAS("snd-hda-codec-id:10de000b");
571MODULE_ALIAS("snd-hda-codec-id:10de000d");
415 572
416MODULE_LICENSE("GPL"); 573MODULE_LICENSE("GPL");
417MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec"); 574MODULE_DESCRIPTION("NVIDIA HDMI HD-audio codec");
418 575
419static struct hda_codec_preset_list nvhdmi_list = { 576static struct hda_codec_preset_list nvhdmi_list = {
420 .preset = snd_hda_preset_nvhdmi, 577 .preset = snd_hda_preset_nvhdmi,
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index f628c33d80b3..5d2fbb87b871 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -131,8 +131,10 @@ enum {
131enum { 131enum {
132 ALC269_BASIC, 132 ALC269_BASIC,
133 ALC269_QUANTA_FL1, 133 ALC269_QUANTA_FL1,
134 ALC269_ASUS_AMIC, 134 ALC269_AMIC,
135 ALC269_ASUS_DMIC, 135 ALC269_DMIC,
136 ALC269VB_AMIC,
137 ALC269VB_DMIC,
136 ALC269_FUJITSU, 138 ALC269_FUJITSU,
137 ALC269_LIFEBOOK, 139 ALC269_LIFEBOOK,
138 ALC269_AUTO, 140 ALC269_AUTO,
@@ -207,8 +209,10 @@ enum {
207 ALC882_ASUS_A7J, 209 ALC882_ASUS_A7J,
208 ALC882_ASUS_A7M, 210 ALC882_ASUS_A7M,
209 ALC885_MACPRO, 211 ALC885_MACPRO,
212 ALC885_MBA21,
210 ALC885_MBP3, 213 ALC885_MBP3,
211 ALC885_MB5, 214 ALC885_MB5,
215 ALC885_MACMINI3,
212 ALC885_IMAC24, 216 ALC885_IMAC24,
213 ALC885_IMAC91, 217 ALC885_IMAC91,
214 ALC883_3ST_2ch_DIG, 218 ALC883_3ST_2ch_DIG,
@@ -841,27 +845,6 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
841 spec->init_verbs[spec->num_init_verbs++] = verb; 845 spec->init_verbs[spec->num_init_verbs++] = verb;
842} 846}
843 847
844#ifdef CONFIG_PROC_FS
845/*
846 * hook for proc
847 */
848static void print_realtek_coef(struct snd_info_buffer *buffer,
849 struct hda_codec *codec, hda_nid_t nid)
850{
851 int coeff;
852
853 if (nid != 0x20)
854 return;
855 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
856 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
857 coeff = snd_hda_codec_read(codec, nid, 0,
858 AC_VERB_GET_COEF_INDEX, 0);
859 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
860}
861#else
862#define print_realtek_coef NULL
863#endif
864
865/* 848/*
866 * set up from the preset table 849 * set up from the preset table
867 */ 850 */
@@ -1166,6 +1149,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1166 case 0x10ec0888: 1149 case 0x10ec0888:
1167 alc888_coef_init(codec); 1150 alc888_coef_init(codec);
1168 break; 1151 break;
1152#if 0 /* XXX: This may cause the silent output on speaker on some machines */
1169 case 0x10ec0267: 1153 case 0x10ec0267:
1170 case 0x10ec0268: 1154 case 0x10ec0268:
1171 snd_hda_codec_write(codec, 0x20, 0, 1155 snd_hda_codec_write(codec, 0x20, 0,
@@ -1178,6 +1162,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1178 AC_VERB_SET_PROC_COEF, 1162 AC_VERB_SET_PROC_COEF,
1179 tmp | 0x3000); 1163 tmp | 0x3000);
1180 break; 1164 break;
1165#endif /* XXX */
1181 } 1166 }
1182 break; 1167 break;
1183 } 1168 }
@@ -1269,7 +1254,7 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1269 */ 1254 */
1270static int alc_subsystem_id(struct hda_codec *codec, 1255static int alc_subsystem_id(struct hda_codec *codec,
1271 hda_nid_t porta, hda_nid_t porte, 1256 hda_nid_t porta, hda_nid_t porte,
1272 hda_nid_t portd) 1257 hda_nid_t portd, hda_nid_t porti)
1273{ 1258{
1274 unsigned int ass, tmp, i; 1259 unsigned int ass, tmp, i;
1275 unsigned nid; 1260 unsigned nid;
@@ -1295,7 +1280,7 @@ static int alc_subsystem_id(struct hda_codec *codec,
1295 snd_printd("realtek: No valid SSID, " 1280 snd_printd("realtek: No valid SSID, "
1296 "checking pincfg 0x%08x for NID 0x%x\n", 1281 "checking pincfg 0x%08x for NID 0x%x\n",
1297 ass, nid); 1282 ass, nid);
1298 if (!(ass & 1) && !(ass & 0x100000)) 1283 if (!(ass & 1))
1299 return 0; 1284 return 0;
1300 if ((ass >> 30) != 1) /* no physical connection */ 1285 if ((ass >> 30) != 1) /* no physical connection */
1301 return 0; 1286 return 0;
@@ -1355,6 +1340,8 @@ do_sku:
1355 nid = porte; 1340 nid = porte;
1356 else if (tmp == 2) 1341 else if (tmp == 2)
1357 nid = portd; 1342 nid = portd;
1343 else if (tmp == 3)
1344 nid = porti;
1358 else 1345 else
1359 return 1; 1346 return 1;
1360 for (i = 0; i < spec->autocfg.line_outs; i++) 1347 for (i = 0; i < spec->autocfg.line_outs; i++)
@@ -1369,9 +1356,10 @@ do_sku:
1369} 1356}
1370 1357
1371static void alc_ssid_check(struct hda_codec *codec, 1358static void alc_ssid_check(struct hda_codec *codec,
1372 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd) 1359 hda_nid_t porta, hda_nid_t porte,
1360 hda_nid_t portd, hda_nid_t porti)
1373{ 1361{
1374 if (!alc_subsystem_id(codec, porta, porte, portd)) { 1362 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1375 struct alc_spec *spec = codec->spec; 1363 struct alc_spec *spec = codec->spec;
1376 snd_printd("realtek: " 1364 snd_printd("realtek: "
1377 "Enable default setup for auto mode as fallback\n"); 1365 "Enable default setup for auto mode as fallback\n");
@@ -3729,25 +3717,22 @@ static void alc_power_eapd(struct hda_codec *codec)
3729 /* We currently only handle front, HP */ 3717 /* We currently only handle front, HP */
3730 switch (codec->vendor_id) { 3718 switch (codec->vendor_id) {
3731 case 0x10ec0260: 3719 case 0x10ec0260:
3732 snd_hda_codec_write(codec, 0x0f, 0, 3720 set_eapd(codec, 0x0f, 0);
3733 AC_VERB_SET_EAPD_BTLENABLE, 0x00); 3721 set_eapd(codec, 0x10, 0);
3734 snd_hda_codec_write(codec, 0x10, 0,
3735 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3736 break; 3722 break;
3737 case 0x10ec0262: 3723 case 0x10ec0262:
3738 case 0x10ec0267: 3724 case 0x10ec0267:
3739 case 0x10ec0268: 3725 case 0x10ec0268:
3740 case 0x10ec0269: 3726 case 0x10ec0269:
3727 case 0x10ec0270:
3741 case 0x10ec0272: 3728 case 0x10ec0272:
3742 case 0x10ec0660: 3729 case 0x10ec0660:
3743 case 0x10ec0662: 3730 case 0x10ec0662:
3744 case 0x10ec0663: 3731 case 0x10ec0663:
3745 case 0x10ec0862: 3732 case 0x10ec0862:
3746 case 0x10ec0889: 3733 case 0x10ec0889:
3747 snd_hda_codec_write(codec, 0x14, 0, 3734 set_eapd(codec, 0x14, 0);
3748 AC_VERB_SET_EAPD_BTLENABLE, 0x00); 3735 set_eapd(codec, 0x15, 0);
3749 snd_hda_codec_write(codec, 0x15, 0,
3750 AC_VERB_SET_EAPD_BTLENABLE, 0x00);
3751 break; 3736 break;
3752 } 3737 }
3753} 3738}
@@ -4877,7 +4862,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4877 spec->num_mux_defs = 1; 4862 spec->num_mux_defs = 1;
4878 spec->input_mux = &spec->private_imux[0]; 4863 spec->input_mux = &spec->private_imux[0];
4879 4864
4880 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 4865 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
4881 4866
4882 return 1; 4867 return 1;
4883} 4868}
@@ -4930,7 +4915,7 @@ static void fixup_automic_adc(struct hda_codec *codec)
4930static void fixup_single_adc(struct hda_codec *codec) 4915static void fixup_single_adc(struct hda_codec *codec)
4931{ 4916{
4932 struct alc_spec *spec = codec->spec; 4917 struct alc_spec *spec = codec->spec;
4933 hda_nid_t pin; 4918 hda_nid_t pin = 0;
4934 int i; 4919 int i;
4935 4920
4936 /* search for the input pin; there must be only one */ 4921 /* search for the input pin; there must be only one */
@@ -5081,7 +5066,6 @@ static int patch_alc880(struct hda_codec *codec)
5081 if (!spec->loopback.amplist) 5066 if (!spec->loopback.amplist)
5082 spec->loopback.amplist = alc880_loopbacks; 5067 spec->loopback.amplist = alc880_loopbacks;
5083#endif 5068#endif
5084 codec->proc_widget_hook = print_realtek_coef;
5085 5069
5086 return 0; 5070 return 0;
5087} 5071}
@@ -6412,7 +6396,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
6412 spec->num_mux_defs = 1; 6396 spec->num_mux_defs = 1;
6413 spec->input_mux = &spec->private_imux[0]; 6397 spec->input_mux = &spec->private_imux[0];
6414 6398
6415 alc_ssid_check(codec, 0x10, 0x15, 0x0f); 6399 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
6416 6400
6417 return 1; 6401 return 1;
6418} 6402}
@@ -6691,7 +6675,6 @@ static int patch_alc260(struct hda_codec *codec)
6691 if (!spec->loopback.amplist) 6675 if (!spec->loopback.amplist)
6692 spec->loopback.amplist = alc260_loopbacks; 6676 spec->loopback.amplist = alc260_loopbacks;
6693#endif 6677#endif
6694 codec->proc_widget_hook = print_realtek_coef;
6695 6678
6696 return 0; 6679 return 0;
6697} 6680}
@@ -6773,6 +6756,14 @@ static struct hda_input_mux mb5_capture_source = {
6773 }, 6756 },
6774}; 6757};
6775 6758
6759static struct hda_input_mux macmini3_capture_source = {
6760 .num_items = 2,
6761 .items = {
6762 { "Line", 0x2 },
6763 { "CD", 0x4 },
6764 },
6765};
6766
6776static struct hda_input_mux alc883_3stack_6ch_intel = { 6767static struct hda_input_mux alc883_3stack_6ch_intel = {
6777 .num_items = 4, 6768 .num_items = 4,
6778 .items = { 6769 .items = {
@@ -6961,6 +6952,13 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = {
6961 { 8, alc882_sixstack_ch8_init }, 6952 { 8, alc882_sixstack_ch8_init },
6962}; 6953};
6963 6954
6955
6956/* Macbook Air 2,1 */
6957
6958static struct hda_channel_mode alc885_mba21_ch_modes[1] = {
6959 { 2, NULL },
6960};
6961
6964/* 6962/*
6965 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic 6963 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
6966 */ 6964 */
@@ -7021,6 +7019,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7021 { 6, alc885_mb5_ch6_init }, 7019 { 6, alc885_mb5_ch6_init },
7022}; 7020};
7023 7021
7022#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7024 7023
7025/* 7024/*
7026 * 2ch mode 7025 * 2ch mode
@@ -7232,6 +7231,15 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7232 { } /* end */ 7231 { } /* end */
7233}; 7232};
7234 7233
7234/* Macbook Air 2,1 same control for HP and internal Speaker */
7235
7236static struct snd_kcontrol_new alc885_mba21_mixer[] = {
7237 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7238 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
7239 { }
7240};
7241
7242
7235static struct snd_kcontrol_new alc885_mbp3_mixer[] = { 7243static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7236 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7244 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7237 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), 7245 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7265,6 +7273,21 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7265 { } /* end */ 7273 { } /* end */
7266}; 7274};
7267 7275
7276static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7277 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7278 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
7279 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
7280 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
7281 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
7282 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
7283 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
7284 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7286 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7287 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT),
7288 { } /* end */
7289};
7290
7268static struct snd_kcontrol_new alc885_imac91_mixer[] = { 7291static struct snd_kcontrol_new alc885_imac91_mixer[] = {
7269 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT), 7292 HDA_CODEC_VOLUME("Line-Out Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
7270 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT), 7293 HDA_BIND_MUTE ("Line-Out Playback Switch", 0x0c, 0x02, HDA_INPUT),
@@ -7356,29 +7379,18 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = {
7356 7379
7357static struct hda_verb alc882_base_init_verbs[] = { 7380static struct hda_verb alc882_base_init_verbs[] = {
7358 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7381 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7359 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7360 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7382 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7361 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7383 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7362 /* Rear mixer */ 7384 /* Rear mixer */
7363 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7364 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7385 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7365 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7386 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7366 /* CLFE mixer */ 7387 /* CLFE mixer */
7367 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7368 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7388 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7369 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7389 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7370 /* Side mixer */ 7390 /* Side mixer */
7371 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7372 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7391 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7373 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 7392 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7374 7393
7375 /* mute analog input loopbacks */
7376 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7377 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7378 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7379 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7380 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7381
7382 /* Front Pin: output 0 (0x0c) */ 7394 /* Front Pin: output 0 (0x0c) */
7383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 7395 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 7396 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
@@ -7415,14 +7427,8 @@ static struct hda_verb alc882_base_init_verbs[] = {
7415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 7427 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
7416 /* Input mixer2 */ 7428 /* Input mixer2 */
7417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7418 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7419 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7420 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7421 /* Input mixer3 */ 7430 /* Input mixer3 */
7422 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7431 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7423 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7424 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7425 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7426 /* ADC2: mute amp left and right */ 7432 /* ADC2: mute amp left and right */
7427 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7433 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7428 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, 7434 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -7466,26 +7472,17 @@ static struct hda_verb alc_hp15_unsol_verbs[] = {
7466 7472
7467static struct hda_verb alc885_init_verbs[] = { 7473static struct hda_verb alc885_init_verbs[] = {
7468 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7474 /* Front mixer: unmute input/output amp left and right (volume = 0) */
7469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7475 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7476 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7471 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7472 /* Rear mixer */ 7477 /* Rear mixer */
7473 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7478 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7474 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7479 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7475 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7476 /* CLFE mixer */ 7480 /* CLFE mixer */
7477 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7481 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7478 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7482 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7479 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7480 /* Side mixer */ 7483 /* Side mixer */
7481 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 7484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7482 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7485 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7483 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7484
7485 /* mute analog input loopbacks */
7486 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7487 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7488 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7489 7486
7490 /* Front HP Pin: output 0 (0x0c) */ 7487 /* Front HP Pin: output 0 (0x0c) */
7491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 7488 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -7519,17 +7516,11 @@ static struct hda_verb alc885_init_verbs[] = {
7519 7516
7520 /* Mixer elements: 0x18, , 0x1a, 0x1b */ 7517 /* Mixer elements: 0x18, , 0x1a, 0x1b */
7521 /* Input mixer1 */ 7518 /* Input mixer1 */
7522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, 7519 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7524 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7525 /* Input mixer2 */ 7520 /* Input mixer2 */
7526 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 7521 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7527 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7528 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7529 /* Input mixer3 */ 7522 /* Input mixer3 */
7530 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, 7523 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7531 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7532 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7533 /* ADC2: mute amp left and right */ 7524 /* ADC2: mute amp left and right */
7534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 7525 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7535 /* ADC3: mute amp left and right */ 7526 /* ADC3: mute amp left and right */
@@ -7671,6 +7662,76 @@ static struct hda_verb alc885_mb5_init_verbs[] = {
7671 { } 7662 { }
7672}; 7663};
7673 7664
7665/* Macmini 3,1 */
7666static struct hda_verb alc885_macmini3_init_verbs[] = {
7667 /* DACs */
7668 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7669 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7670 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7671 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7672 /* Front mixer */
7673 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7674 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7675 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7676 /* Surround mixer */
7677 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7678 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7679 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7680 /* LFE mixer */
7681 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7682 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7684 /* HP mixer */
7685 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7686 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7687 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7688 /* Front Pin (0x0c) */
7689 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7690 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7691 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7692 /* LFE Pin (0x0e) */
7693 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
7694 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7695 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
7696 /* HP Pin (0x0f) */
7697 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7698 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7699 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
7700 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
7701 /* Line In pin */
7702 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7703 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7704
7705 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7706 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7707 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7708 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7709 { }
7710};
7711
7712
7713static struct hda_verb alc885_mba21_init_verbs[] = {
7714 /*Internal and HP Speaker Mixer*/
7715 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7716 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7717 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7718 /*Internal Speaker Pin (0x0c)*/
7719 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
7720 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7721 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
7722 /* HP Pin: output 0 (0x0e) */
7723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
7724 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7725 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
7726 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
7727 /* Line in (is hp when jack connected)*/
7728 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
7729 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7730
7731 { }
7732 };
7733
7734
7674/* Macbook Pro rev3 */ 7735/* Macbook Pro rev3 */
7675static struct hda_verb alc885_mbp3_init_verbs[] = { 7736static struct hda_verb alc885_mbp3_init_verbs[] = {
7676 /* Front mixer: unmute input/output amp left and right (volume = 0) */ 7737 /* Front mixer: unmute input/output amp left and right (volume = 0) */
@@ -7833,54 +7894,35 @@ static void alc885_imac24_setup(struct hda_codec *codec)
7833 spec->autocfg.speaker_pins[1] = 0x1a; 7894 spec->autocfg.speaker_pins[1] = 0x1a;
7834} 7895}
7835 7896
7836static void alc885_mbp3_setup(struct hda_codec *codec) 7897#define alc885_mb5_setup alc885_imac24_setup
7837{ 7898#define alc885_macmini3_setup alc885_imac24_setup
7838 struct alc_spec *spec = codec->spec;
7839
7840 spec->autocfg.hp_pins[0] = 0x15;
7841 spec->autocfg.speaker_pins[0] = 0x14;
7842}
7843 7899
7844static void alc885_mb5_automute(struct hda_codec *codec) 7900/* Macbook Air 2,1 */
7901static void alc885_mba21_setup(struct hda_codec *codec)
7845{ 7902{
7846 unsigned int present; 7903 struct alc_spec *spec = codec->spec;
7847
7848 present = snd_hda_codec_read(codec, 0x14, 0,
7849 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7850 snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0,
7851 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7852 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7853 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7854 7904
7905 spec->autocfg.hp_pins[0] = 0x14;
7906 spec->autocfg.speaker_pins[0] = 0x18;
7855} 7907}
7856 7908
7857static void alc885_mb5_unsol_event(struct hda_codec *codec,
7858 unsigned int res)
7859{
7860 /* Headphone insertion or removal. */
7861 if ((res >> 26) == ALC880_HP_EVENT)
7862 alc885_mb5_automute(codec);
7863}
7864 7909
7865static void alc885_imac91_automute(struct hda_codec *codec)
7866{
7867 unsigned int present;
7868 7910
7869 present = snd_hda_codec_read(codec, 0x14, 0, 7911static void alc885_mbp3_setup(struct hda_codec *codec)
7870 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; 7912{
7871 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, 7913 struct alc_spec *spec = codec->spec;
7872 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7873 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0,
7874 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
7875 7914
7915 spec->autocfg.hp_pins[0] = 0x15;
7916 spec->autocfg.speaker_pins[0] = 0x14;
7876} 7917}
7877 7918
7878static void alc885_imac91_unsol_event(struct hda_codec *codec, 7919static void alc885_imac91_setup(struct hda_codec *codec)
7879 unsigned int res)
7880{ 7920{
7881 /* Headphone insertion or removal. */ 7921 struct alc_spec *spec = codec->spec;
7882 if ((res >> 26) == ALC880_HP_EVENT) 7922
7883 alc885_imac91_automute(codec); 7923 spec->autocfg.hp_pins[0] = 0x14;
7924 spec->autocfg.speaker_pins[0] = 0x15;
7925 spec->autocfg.speaker_pins[1] = 0x1a;
7884} 7926}
7885 7927
7886static struct hda_verb alc882_targa_verbs[] = { 7928static struct hda_verb alc882_targa_verbs[] = {
@@ -8015,18 +8057,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8015 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 8057 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8016 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 8058 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8017 8059
8018 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
8019 * mixer widget
8020 * Note: PASD motherboards uses the Line In 2 as the input for
8021 * front panel mic (mic 2)
8022 */
8023 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8024 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8025 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8026 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8027 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8028 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8029
8030 /* 8060 /*
8031 * Set up output mixers (0x0c - 0x0f) 8061 * Set up output mixers (0x0c - 0x0f)
8032 */ 8062 */
@@ -8051,16 +8081,9 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8051 /* FIXME: use matrix-type input source selection */ 8081 /* FIXME: use matrix-type input source selection */
8052 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ 8082 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8053 /* Input mixer2 */ 8083 /* Input mixer2 */
8054 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8084 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8055 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8056 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8057 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8058 /* Input mixer3 */ 8085 /* Input mixer3 */
8059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, 8086 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
8061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
8062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
8063
8064 { } 8087 { }
8065}; 8088};
8066 8089
@@ -9047,6 +9070,8 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9047 [ALC882_ASUS_A7M] = "asus-a7m", 9070 [ALC882_ASUS_A7M] = "asus-a7m",
9048 [ALC885_MACPRO] = "macpro", 9071 [ALC885_MACPRO] = "macpro",
9049 [ALC885_MB5] = "mb5", 9072 [ALC885_MB5] = "mb5",
9073 [ALC885_MACMINI3] = "macmini3",
9074 [ALC885_MBA21] = "mba21",
9050 [ALC885_MBP3] = "mbp3", 9075 [ALC885_MBP3] = "mbp3",
9051 [ALC885_IMAC24] = "imac24", 9076 [ALC885_IMAC24] = "imac24",
9052 [ALC885_IMAC91] = "imac91", 9077 [ALC885_IMAC91] = "imac91",
@@ -9230,6 +9255,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
9230 */ 9255 */
9231 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5), 9256 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
9232 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5), 9257 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
9258 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
9233 {} /* terminator */ 9259 {} /* terminator */
9234}; 9260};
9235 9261
@@ -9281,6 +9307,18 @@ static struct alc_config_preset alc882_presets[] = {
9281 .input_mux = &alc882_capture_source, 9307 .input_mux = &alc882_capture_source,
9282 .dig_out_nid = ALC882_DIGOUT_NID, 9308 .dig_out_nid = ALC882_DIGOUT_NID,
9283 }, 9309 },
9310 [ALC885_MBA21] = {
9311 .mixers = { alc885_mba21_mixer },
9312 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
9313 .num_dacs = 2,
9314 .dac_nids = alc882_dac_nids,
9315 .channel_mode = alc885_mba21_ch_modes,
9316 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
9317 .input_mux = &alc882_capture_source,
9318 .unsol_event = alc_automute_amp_unsol_event,
9319 .setup = alc885_mba21_setup,
9320 .init_hook = alc_automute_amp,
9321 },
9284 [ALC885_MBP3] = { 9322 [ALC885_MBP3] = {
9285 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, 9323 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
9286 .init_verbs = { alc885_mbp3_init_verbs, 9324 .init_verbs = { alc885_mbp3_init_verbs,
@@ -9308,8 +9346,24 @@ static struct alc_config_preset alc882_presets[] = {
9308 .input_mux = &mb5_capture_source, 9346 .input_mux = &mb5_capture_source,
9309 .dig_out_nid = ALC882_DIGOUT_NID, 9347 .dig_out_nid = ALC882_DIGOUT_NID,
9310 .dig_in_nid = ALC882_DIGIN_NID, 9348 .dig_in_nid = ALC882_DIGIN_NID,
9311 .unsol_event = alc885_mb5_unsol_event, 9349 .unsol_event = alc_automute_amp_unsol_event,
9312 .init_hook = alc885_mb5_automute, 9350 .setup = alc885_mb5_setup,
9351 .init_hook = alc_automute_amp,
9352 },
9353 [ALC885_MACMINI3] = {
9354 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
9355 .init_verbs = { alc885_macmini3_init_verbs,
9356 alc880_gpio1_init_verbs },
9357 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
9358 .dac_nids = alc882_dac_nids,
9359 .channel_mode = alc885_macmini3_6ch_modes,
9360 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
9361 .input_mux = &macmini3_capture_source,
9362 .dig_out_nid = ALC882_DIGOUT_NID,
9363 .dig_in_nid = ALC882_DIGIN_NID,
9364 .unsol_event = alc_automute_amp_unsol_event,
9365 .setup = alc885_macmini3_setup,
9366 .init_hook = alc_automute_amp,
9313 }, 9367 },
9314 [ALC885_MACPRO] = { 9368 [ALC885_MACPRO] = {
9315 .mixers = { alc882_macpro_mixer }, 9369 .mixers = { alc882_macpro_mixer },
@@ -9348,8 +9402,9 @@ static struct alc_config_preset alc882_presets[] = {
9348 .input_mux = &alc882_capture_source, 9402 .input_mux = &alc882_capture_source,
9349 .dig_out_nid = ALC882_DIGOUT_NID, 9403 .dig_out_nid = ALC882_DIGOUT_NID,
9350 .dig_in_nid = ALC882_DIGIN_NID, 9404 .dig_in_nid = ALC882_DIGIN_NID,
9351 .unsol_event = alc885_imac91_unsol_event, 9405 .unsol_event = alc_automute_amp_unsol_event,
9352 .init_hook = alc885_imac91_automute, 9406 .setup = alc885_imac91_setup,
9407 .init_hook = alc_automute_amp,
9353 }, 9408 },
9354 [ALC882_TARGA] = { 9409 [ALC882_TARGA] = {
9355 .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, 9410 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
@@ -10172,7 +10227,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10172 spec->num_mux_defs = 1; 10227 spec->num_mux_defs = 1;
10173 spec->input_mux = &spec->private_imux[0]; 10228 spec->input_mux = &spec->private_imux[0];
10174 10229
10175 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 10230 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
10176 10231
10177 err = alc_auto_add_mic_boost(codec); 10232 err = alc_auto_add_mic_boost(codec);
10178 if (err < 0) 10233 if (err < 0)
@@ -10310,7 +10365,6 @@ static int patch_alc882(struct hda_codec *codec)
10310 if (!spec->loopback.amplist) 10365 if (!spec->loopback.amplist)
10311 spec->loopback.amplist = alc882_loopbacks; 10366 spec->loopback.amplist = alc882_loopbacks;
10312#endif 10367#endif
10313 codec->proc_widget_hook = print_realtek_coef;
10314 10368
10315 return 0; 10369 return 0;
10316} 10370}
@@ -11731,7 +11785,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
11731 if (err < 0) 11785 if (err < 0)
11732 return err; 11786 return err;
11733 11787
11734 alc_ssid_check(codec, 0x15, 0x14, 0x1b); 11788 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11735 11789
11736 return 1; 11790 return 1;
11737} 11791}
@@ -12174,7 +12228,6 @@ static int patch_alc262(struct hda_codec *codec)
12174 if (!spec->loopback.amplist) 12228 if (!spec->loopback.amplist)
12175 spec->loopback.amplist = alc262_loopbacks; 12229 spec->loopback.amplist = alc262_loopbacks;
12176#endif 12230#endif
12177 codec->proc_widget_hook = print_realtek_coef;
12178 12231
12179 return 0; 12232 return 0;
12180} 12233}
@@ -12683,7 +12736,6 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
12683 dac = 0x02; 12736 dac = 0x02;
12684 break; 12737 break;
12685 case 0x15: 12738 case 0x15:
12686 case 0x21:
12687 dac = 0x03; 12739 dac = 0x03;
12688 break; 12740 break;
12689 default: 12741 default:
@@ -12904,7 +12956,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
12904 if (err < 0) 12956 if (err < 0)
12905 return err; 12957 return err;
12906 12958
12907 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 12959 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12908 12960
12909 return 1; 12961 return 1;
12910} 12962}
@@ -13241,8 +13293,6 @@ static int patch_alc268(struct hda_codec *codec)
13241 if (board_config == ALC268_AUTO) 13293 if (board_config == ALC268_AUTO)
13242 spec->init_hook = alc268_auto_init; 13294 spec->init_hook = alc268_auto_init;
13243 13295
13244 codec->proc_widget_hook = print_realtek_coef;
13245
13246 return 0; 13296 return 0;
13247} 13297}
13248 13298
@@ -13262,6 +13312,15 @@ static hda_nid_t alc269_capsrc_nids[1] = {
13262 0x23, 13312 0x23,
13263}; 13313};
13264 13314
13315static hda_nid_t alc269vb_adc_nids[1] = {
13316 /* ADC1 */
13317 0x09,
13318};
13319
13320static hda_nid_t alc269vb_capsrc_nids[1] = {
13321 0x22,
13322};
13323
13265/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), 13324/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24),
13266 * not a mux! 13325 * not a mux!
13267 */ 13326 */
@@ -13330,7 +13389,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13330 { } 13389 { }
13331}; 13390};
13332 13391
13333static struct snd_kcontrol_new alc269_eeepc_mixer[] = { 13392static struct snd_kcontrol_new alc269_laptop_mixer[] = {
13334 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13393 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13335 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 13394 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13336 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13395 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -13338,16 +13397,47 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
13338 { } /* end */ 13397 { } /* end */
13339}; 13398};
13340 13399
13400static struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13401 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13402 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13403 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13404 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13405 { } /* end */
13406};
13407
13341/* capture mixer elements */ 13408/* capture mixer elements */
13342static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 13409static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13410 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13411 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13412 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13413 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13414 { } /* end */
13415};
13416
13417static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13343 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 13418 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13344 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 13419 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13345 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13420 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13346 { } /* end */ 13421 { } /* end */
13347}; 13422};
13348 13423
13424static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13425 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13426 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13427 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13428 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT),
13429 { } /* end */
13430};
13431
13432static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13433 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13434 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13435 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
13436 { } /* end */
13437};
13438
13349/* FSC amilo */ 13439/* FSC amilo */
13350#define alc269_fujitsu_mixer alc269_eeepc_mixer 13440#define alc269_fujitsu_mixer alc269_laptop_mixer
13351 13441
13352static struct hda_verb alc269_quanta_fl1_verbs[] = { 13442static struct hda_verb alc269_quanta_fl1_verbs[] = {
13353 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13443 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
@@ -13471,6 +13561,8 @@ static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13471static void alc269_quanta_fl1_setup(struct hda_codec *codec) 13561static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13472{ 13562{
13473 struct alc_spec *spec = codec->spec; 13563 struct alc_spec *spec = codec->spec;
13564 spec->autocfg.hp_pins[0] = 0x15;
13565 spec->autocfg.speaker_pins[0] = 0x14;
13474 spec->ext_mic.pin = 0x18; 13566 spec->ext_mic.pin = 0x18;
13475 spec->ext_mic.mux_idx = 0; 13567 spec->ext_mic.mux_idx = 0;
13476 spec->int_mic.pin = 0x19; 13568 spec->int_mic.pin = 0x19;
@@ -13490,7 +13582,7 @@ static void alc269_lifebook_init_hook(struct hda_codec *codec)
13490 alc269_lifebook_mic_autoswitch(codec); 13582 alc269_lifebook_mic_autoswitch(codec);
13491} 13583}
13492 13584
13493static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 13585static struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13494 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13586 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13495 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 13587 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13496 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13588 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13501,7 +13593,7 @@ static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
13501 {} 13593 {}
13502}; 13594};
13503 13595
13504static struct hda_verb alc269_eeepc_amic_init_verbs[] = { 13596static struct hda_verb alc269_laptop_amic_init_verbs[] = {
13505 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 13597 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13506 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, 13598 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13507 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, 13599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
@@ -13511,6 +13603,28 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = {
13511 {} 13603 {}
13512}; 13604};
13513 13605
13606static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13607 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13608 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13609 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13611 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13612 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13613 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13614 {}
13615};
13616
13617static struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13618 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13619 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13620 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13621 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13622 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13623 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13624 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13625 {}
13626};
13627
13514/* toggle speaker-output according to the hp-jack state */ 13628/* toggle speaker-output according to the hp-jack state */
13515static void alc269_speaker_automute(struct hda_codec *codec) 13629static void alc269_speaker_automute(struct hda_codec *codec)
13516{ 13630{
@@ -13528,7 +13642,7 @@ static void alc269_speaker_automute(struct hda_codec *codec)
13528} 13642}
13529 13643
13530/* unsolicited event for HP jack sensing */ 13644/* unsolicited event for HP jack sensing */
13531static void alc269_eeepc_unsol_event(struct hda_codec *codec, 13645static void alc269_laptop_unsol_event(struct hda_codec *codec,
13532 unsigned int res) 13646 unsigned int res)
13533{ 13647{
13534 switch (res >> 26) { 13648 switch (res >> 26) {
@@ -13541,9 +13655,11 @@ static void alc269_eeepc_unsol_event(struct hda_codec *codec,
13541 } 13655 }
13542} 13656}
13543 13657
13544static void alc269_eeepc_dmic_setup(struct hda_codec *codec) 13658static void alc269_laptop_dmic_setup(struct hda_codec *codec)
13545{ 13659{
13546 struct alc_spec *spec = codec->spec; 13660 struct alc_spec *spec = codec->spec;
13661 spec->autocfg.hp_pins[0] = 0x15;
13662 spec->autocfg.speaker_pins[0] = 0x14;
13547 spec->ext_mic.pin = 0x18; 13663 spec->ext_mic.pin = 0x18;
13548 spec->ext_mic.mux_idx = 0; 13664 spec->ext_mic.mux_idx = 0;
13549 spec->int_mic.pin = 0x12; 13665 spec->int_mic.pin = 0x12;
@@ -13551,9 +13667,23 @@ static void alc269_eeepc_dmic_setup(struct hda_codec *codec)
13551 spec->auto_mic = 1; 13667 spec->auto_mic = 1;
13552} 13668}
13553 13669
13554static void alc269_eeepc_amic_setup(struct hda_codec *codec) 13670static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
13671{
13672 struct alc_spec *spec = codec->spec;
13673 spec->autocfg.hp_pins[0] = 0x15;
13674 spec->autocfg.speaker_pins[0] = 0x14;
13675 spec->ext_mic.pin = 0x18;
13676 spec->ext_mic.mux_idx = 0;
13677 spec->int_mic.pin = 0x12;
13678 spec->int_mic.mux_idx = 6;
13679 spec->auto_mic = 1;
13680}
13681
13682static void alc269_laptop_amic_setup(struct hda_codec *codec)
13555{ 13683{
13556 struct alc_spec *spec = codec->spec; 13684 struct alc_spec *spec = codec->spec;
13685 spec->autocfg.hp_pins[0] = 0x15;
13686 spec->autocfg.speaker_pins[0] = 0x14;
13557 spec->ext_mic.pin = 0x18; 13687 spec->ext_mic.pin = 0x18;
13558 spec->ext_mic.mux_idx = 0; 13688 spec->ext_mic.mux_idx = 0;
13559 spec->int_mic.pin = 0x19; 13689 spec->int_mic.pin = 0x19;
@@ -13561,7 +13691,7 @@ static void alc269_eeepc_amic_setup(struct hda_codec *codec)
13561 spec->auto_mic = 1; 13691 spec->auto_mic = 1;
13562} 13692}
13563 13693
13564static void alc269_eeepc_inithook(struct hda_codec *codec) 13694static void alc269_laptop_inithook(struct hda_codec *codec)
13565{ 13695{
13566 alc269_speaker_automute(codec); 13696 alc269_speaker_automute(codec);
13567 alc_mic_automute(codec); 13697 alc_mic_automute(codec);
@@ -13574,22 +13704,10 @@ static struct hda_verb alc269_init_verbs[] = {
13574 /* 13704 /*
13575 * Unmute ADC0 and set the default input to mic-in 13705 * Unmute ADC0 and set the default input to mic-in
13576 */ 13706 */
13577 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 13707 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13578
13579 /* Mute input amps (PCBeep, Line In, Mic 1 & Mic 2) of the
13580 * analog-loopback mixer widget
13581 * Note: PASD motherboards uses the Line In 2 as the input for
13582 * front panel mic (mic 2)
13583 */
13584 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
13585 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
13586 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13587 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
13590 13708
13591 /* 13709 /*
13592 * Set up output mixers (0x0c - 0x0e) 13710 * Set up output mixers (0x02 - 0x03)
13593 */ 13711 */
13594 /* set vol=0 to output mixers */ 13712 /* set vol=0 to output mixers */
13595 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 13713 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
@@ -13614,26 +13732,57 @@ static struct hda_verb alc269_init_verbs[] = {
13614 13732
13615 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13733 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13616 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 13734 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13617 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13618 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13619 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13620 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13621 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13622 13735
13623 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, 13736 /* FIXME: use Mux-type input source selection */
13624 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 13737 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13738 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13739 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13625 13740
13626 /* FIXME: use matrix-type input source selection */ 13741 /* set EAPD */
13742 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13743 { }
13744};
13745
13746static struct hda_verb alc269vb_init_verbs[] = {
13747 /*
13748 * Unmute ADC0 and set the default input to mic-in
13749 */
13750 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13751
13752 /*
13753 * Set up output mixers (0x02 - 0x03)
13754 */
13755 /* set vol=0 to output mixers */
13756 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13757 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13758
13759 /* set up input amps for analog loopback */
13760 /* Amp Indices: DAC = 0, mixer = 1 */
13761 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13762 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13763 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13764 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13765 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13766 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13767
13768 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13769 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13770 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13771 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13772 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13774 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13775
13776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13777 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13778
13779 /* FIXME: use Mux-type input source selection */
13627 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ 13780 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
13628 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ 13781 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
13629 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 13782 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
13630 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
13631 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
13632 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
13633 13783
13634 /* set EAPD */ 13784 /* set EAPD */
13635 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, 13785 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13636 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13637 { } 13786 { }
13638}; 13787};
13639 13788
@@ -13681,6 +13830,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13681 struct alc_spec *spec = codec->spec; 13830 struct alc_spec *spec = codec->spec;
13682 int err; 13831 int err;
13683 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; 13832 static hda_nid_t alc269_ignore[] = { 0x1d, 0 };
13833 hda_nid_t real_capsrc_nids;
13684 13834
13685 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 13835 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13686 alc269_ignore); 13836 alc269_ignore);
@@ -13702,11 +13852,20 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13702 if (spec->kctls.list) 13852 if (spec->kctls.list)
13703 add_mixer(spec, spec->kctls.list); 13853 add_mixer(spec, spec->kctls.list);
13704 13854
13705 add_verb(spec, alc269_init_verbs); 13855 if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) {
13856 add_verb(spec, alc269vb_init_verbs);
13857 real_capsrc_nids = alc269vb_capsrc_nids[0];
13858 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
13859 } else {
13860 add_verb(spec, alc269_init_verbs);
13861 real_capsrc_nids = alc269_capsrc_nids[0];
13862 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13863 }
13864
13706 spec->num_mux_defs = 1; 13865 spec->num_mux_defs = 1;
13707 spec->input_mux = &spec->private_imux[0]; 13866 spec->input_mux = &spec->private_imux[0];
13708 /* set default input source */ 13867 /* set default input source */
13709 snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 13868 snd_hda_codec_write_cache(codec, real_capsrc_nids,
13710 0, AC_VERB_SET_CONNECT_SEL, 13869 0, AC_VERB_SET_CONNECT_SEL,
13711 spec->input_mux->items[0].index); 13870 spec->input_mux->items[0].index);
13712 13871
@@ -13717,8 +13876,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
13717 if (!spec->cap_mixer && !spec->no_analog) 13876 if (!spec->cap_mixer && !spec->no_analog)
13718 set_capture_mixer(codec); 13877 set_capture_mixer(codec);
13719 13878
13720 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
13721
13722 return 1; 13879 return 1;
13723} 13880}
13724 13881
@@ -13744,8 +13901,8 @@ static void alc269_auto_init(struct hda_codec *codec)
13744static const char *alc269_models[ALC269_MODEL_LAST] = { 13901static const char *alc269_models[ALC269_MODEL_LAST] = {
13745 [ALC269_BASIC] = "basic", 13902 [ALC269_BASIC] = "basic",
13746 [ALC269_QUANTA_FL1] = "quanta", 13903 [ALC269_QUANTA_FL1] = "quanta",
13747 [ALC269_ASUS_AMIC] = "asus-amic", 13904 [ALC269_AMIC] = "laptop-amic",
13748 [ALC269_ASUS_DMIC] = "asus-dmic", 13905 [ALC269_DMIC] = "laptop-dmic",
13749 [ALC269_FUJITSU] = "fujitsu", 13906 [ALC269_FUJITSU] = "fujitsu",
13750 [ALC269_LIFEBOOK] = "lifebook", 13907 [ALC269_LIFEBOOK] = "lifebook",
13751 [ALC269_AUTO] = "auto", 13908 [ALC269_AUTO] = "auto",
@@ -13754,43 +13911,57 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
13754static struct snd_pci_quirk alc269_cfg_tbl[] = { 13911static struct snd_pci_quirk alc269_cfg_tbl[] = {
13755 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), 13912 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
13756 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", 13913 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
13757 ALC269_ASUS_AMIC), 13914 ALC269_AMIC),
13758 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_ASUS_AMIC), 13915 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
13759 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80JT", ALC269_ASUS_AMIC), 13916 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
13760 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_ASUS_AMIC), 13917 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
13761 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_ASUS_AMIC), 13918 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
13762 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_ASUS_AMIC), 13919 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
13763 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_ASUS_AMIC), 13920 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
13764 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_ASUS_AMIC), 13921 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
13765 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_ASUS_AMIC), 13922 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
13766 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_ASUS_AMIC), 13923 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
13767 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_ASUS_AMIC), 13924 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82Jv", ALC269_AMIC),
13768 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_ASUS_AMIC), 13925 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
13769 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_ASUS_AMIC), 13926 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
13770 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_ASUS_AMIC), 13927 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
13771 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_ASUS_AMIC), 13928 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
13772 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_ASUS_AMIC), 13929 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
13773 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_ASUS_AMIC), 13930 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
13774 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_ASUS_AMIC), 13931 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
13775 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_ASUS_AMIC), 13932 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
13776 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_ASUS_AMIC), 13933 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
13777 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_ASUS_AMIC), 13934 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
13778 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_ASUS_AMIC), 13935 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
13779 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_ASUS_AMIC), 13936 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
13780 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_ASUS_AMIC), 13937 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
13781 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_ASUS_DMIC), 13938 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
13782 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_ASUS_AMIC), 13939 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
13783 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_ASUS_AMIC), 13940 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
13784 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_ASUS_AMIC), 13941 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
13785 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_ASUS_AMIC), 13942 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
13943 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
13944 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
13945 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
13946 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
13947 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
13948 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
13949 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
13950 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
13786 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", 13951 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
13787 ALC269_ASUS_DMIC), 13952 ALC269_DMIC),
13788 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 13953 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
13789 ALC269_ASUS_DMIC), 13954 ALC269_DMIC),
13790 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_ASUS_DMIC), 13955 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
13791 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_ASUS_DMIC), 13956 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
13792 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), 13957 SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC),
13793 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), 13958 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
13959 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
13960 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
13961 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
13962 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
13963 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
13964 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
13794 {} 13965 {}
13795}; 13966};
13796 13967
@@ -13818,47 +13989,75 @@ static struct alc_config_preset alc269_presets[] = {
13818 .setup = alc269_quanta_fl1_setup, 13989 .setup = alc269_quanta_fl1_setup,
13819 .init_hook = alc269_quanta_fl1_init_hook, 13990 .init_hook = alc269_quanta_fl1_init_hook,
13820 }, 13991 },
13821 [ALC269_ASUS_AMIC] = { 13992 [ALC269_AMIC] = {
13822 .mixers = { alc269_eeepc_mixer }, 13993 .mixers = { alc269_laptop_mixer },
13823 .cap_mixer = alc269_epc_capture_mixer, 13994 .cap_mixer = alc269_laptop_analog_capture_mixer,
13824 .init_verbs = { alc269_init_verbs, 13995 .init_verbs = { alc269_init_verbs,
13825 alc269_eeepc_amic_init_verbs }, 13996 alc269_laptop_amic_init_verbs },
13826 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 13997 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13827 .dac_nids = alc269_dac_nids, 13998 .dac_nids = alc269_dac_nids,
13828 .hp_nid = 0x03, 13999 .hp_nid = 0x03,
13829 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14000 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13830 .channel_mode = alc269_modes, 14001 .channel_mode = alc269_modes,
13831 .unsol_event = alc269_eeepc_unsol_event, 14002 .unsol_event = alc269_laptop_unsol_event,
13832 .setup = alc269_eeepc_amic_setup, 14003 .setup = alc269_laptop_amic_setup,
13833 .init_hook = alc269_eeepc_inithook, 14004 .init_hook = alc269_laptop_inithook,
13834 }, 14005 },
13835 [ALC269_ASUS_DMIC] = { 14006 [ALC269_DMIC] = {
13836 .mixers = { alc269_eeepc_mixer }, 14007 .mixers = { alc269_laptop_mixer },
13837 .cap_mixer = alc269_epc_capture_mixer, 14008 .cap_mixer = alc269_laptop_digital_capture_mixer,
13838 .init_verbs = { alc269_init_verbs, 14009 .init_verbs = { alc269_init_verbs,
13839 alc269_eeepc_dmic_init_verbs }, 14010 alc269_laptop_dmic_init_verbs },
14011 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14012 .dac_nids = alc269_dac_nids,
14013 .hp_nid = 0x03,
14014 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14015 .channel_mode = alc269_modes,
14016 .unsol_event = alc269_laptop_unsol_event,
14017 .setup = alc269_laptop_dmic_setup,
14018 .init_hook = alc269_laptop_inithook,
14019 },
14020 [ALC269VB_AMIC] = {
14021 .mixers = { alc269vb_laptop_mixer },
14022 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14023 .init_verbs = { alc269vb_init_verbs,
14024 alc269vb_laptop_amic_init_verbs },
13840 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14025 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13841 .dac_nids = alc269_dac_nids, 14026 .dac_nids = alc269_dac_nids,
13842 .hp_nid = 0x03, 14027 .hp_nid = 0x03,
13843 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14028 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13844 .channel_mode = alc269_modes, 14029 .channel_mode = alc269_modes,
13845 .unsol_event = alc269_eeepc_unsol_event, 14030 .unsol_event = alc269_laptop_unsol_event,
13846 .setup = alc269_eeepc_dmic_setup, 14031 .setup = alc269_laptop_amic_setup,
13847 .init_hook = alc269_eeepc_inithook, 14032 .init_hook = alc269_laptop_inithook,
14033 },
14034 [ALC269VB_DMIC] = {
14035 .mixers = { alc269vb_laptop_mixer },
14036 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14037 .init_verbs = { alc269vb_init_verbs,
14038 alc269vb_laptop_dmic_init_verbs },
14039 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14040 .dac_nids = alc269_dac_nids,
14041 .hp_nid = 0x03,
14042 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14043 .channel_mode = alc269_modes,
14044 .unsol_event = alc269_laptop_unsol_event,
14045 .setup = alc269vb_laptop_dmic_setup,
14046 .init_hook = alc269_laptop_inithook,
13848 }, 14047 },
13849 [ALC269_FUJITSU] = { 14048 [ALC269_FUJITSU] = {
13850 .mixers = { alc269_fujitsu_mixer }, 14049 .mixers = { alc269_fujitsu_mixer },
13851 .cap_mixer = alc269_epc_capture_mixer, 14050 .cap_mixer = alc269_laptop_digital_capture_mixer,
13852 .init_verbs = { alc269_init_verbs, 14051 .init_verbs = { alc269_init_verbs,
13853 alc269_eeepc_dmic_init_verbs }, 14052 alc269_laptop_dmic_init_verbs },
13854 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 14053 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
13855 .dac_nids = alc269_dac_nids, 14054 .dac_nids = alc269_dac_nids,
13856 .hp_nid = 0x03, 14055 .hp_nid = 0x03,
13857 .num_channel_mode = ARRAY_SIZE(alc269_modes), 14056 .num_channel_mode = ARRAY_SIZE(alc269_modes),
13858 .channel_mode = alc269_modes, 14057 .channel_mode = alc269_modes,
13859 .unsol_event = alc269_eeepc_unsol_event, 14058 .unsol_event = alc269_laptop_unsol_event,
13860 .setup = alc269_eeepc_dmic_setup, 14059 .setup = alc269_laptop_dmic_setup,
13861 .init_hook = alc269_eeepc_inithook, 14060 .init_hook = alc269_laptop_inithook,
13862 }, 14061 },
13863 [ALC269_LIFEBOOK] = { 14062 [ALC269_LIFEBOOK] = {
13864 .mixers = { alc269_lifebook_mixer }, 14063 .mixers = { alc269_lifebook_mixer },
@@ -13879,6 +14078,7 @@ static int patch_alc269(struct hda_codec *codec)
13879 struct alc_spec *spec; 14078 struct alc_spec *spec;
13880 int board_config; 14079 int board_config;
13881 int err; 14080 int err;
14081 int is_alc269vb = 0;
13882 14082
13883 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 14083 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13884 if (spec == NULL) 14084 if (spec == NULL)
@@ -13895,6 +14095,7 @@ static int patch_alc269(struct hda_codec *codec)
13895 alc_free(codec); 14095 alc_free(codec);
13896 return -ENOMEM; 14096 return -ENOMEM;
13897 } 14097 }
14098 is_alc269vb = 1;
13898 } 14099 }
13899 14100
13900 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 14101 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
@@ -13930,7 +14131,7 @@ static int patch_alc269(struct hda_codec *codec)
13930 if (board_config != ALC269_AUTO) 14131 if (board_config != ALC269_AUTO)
13931 setup_preset(codec, &alc269_presets[board_config]); 14132 setup_preset(codec, &alc269_presets[board_config]);
13932 14133
13933 if (codec->subsystem_id == 0x17aa3bf8) { 14134 if (board_config == ALC269_QUANTA_FL1) {
13934 /* Due to a hardware problem on Lenovo Ideadpad, we need to 14135 /* Due to a hardware problem on Lenovo Ideadpad, we need to
13935 * fix the sample rate of analog I/O to 44.1kHz 14136 * fix the sample rate of analog I/O to 44.1kHz
13936 */ 14137 */
@@ -13943,9 +14144,16 @@ static int patch_alc269(struct hda_codec *codec)
13943 spec->stream_digital_playback = &alc269_pcm_digital_playback; 14144 spec->stream_digital_playback = &alc269_pcm_digital_playback;
13944 spec->stream_digital_capture = &alc269_pcm_digital_capture; 14145 spec->stream_digital_capture = &alc269_pcm_digital_capture;
13945 14146
13946 spec->adc_nids = alc269_adc_nids; 14147 if (!is_alc269vb) {
13947 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 14148 spec->adc_nids = alc269_adc_nids;
13948 spec->capsrc_nids = alc269_capsrc_nids; 14149 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
14150 spec->capsrc_nids = alc269_capsrc_nids;
14151 } else {
14152 spec->adc_nids = alc269vb_adc_nids;
14153 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
14154 spec->capsrc_nids = alc269vb_capsrc_nids;
14155 }
14156
13949 if (!spec->cap_mixer) 14157 if (!spec->cap_mixer)
13950 set_capture_mixer(codec); 14158 set_capture_mixer(codec);
13951 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 14159 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
@@ -13959,7 +14167,6 @@ static int patch_alc269(struct hda_codec *codec)
13959 if (!spec->loopback.amplist) 14167 if (!spec->loopback.amplist)
13960 spec->loopback.amplist = alc269_loopbacks; 14168 spec->loopback.amplist = alc269_loopbacks;
13961#endif 14169#endif
13962 codec->proc_widget_hook = print_realtek_coef;
13963 14170
13964 return 0; 14171 return 0;
13965} 14172}
@@ -14822,7 +15029,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14822 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 15029 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14823 set_capture_mixer(codec); 15030 set_capture_mixer(codec);
14824 15031
14825 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b); 15032 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
14826 15033
14827 return 1; 15034 return 1;
14828} 15035}
@@ -15087,7 +15294,6 @@ static int patch_alc861(struct hda_codec *codec)
15087 if (!spec->loopback.amplist) 15294 if (!spec->loopback.amplist)
15088 spec->loopback.amplist = alc861_loopbacks; 15295 spec->loopback.amplist = alc861_loopbacks;
15089#endif 15296#endif
15090 codec->proc_widget_hook = print_realtek_coef;
15091 15297
15092 return 0; 15298 return 0;
15093} 15299}
@@ -15714,7 +15920,7 @@ static struct alc_config_preset alc861vd_presets[] = {
15714static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, 15920static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
15715 const struct auto_pin_cfg *cfg) 15921 const struct auto_pin_cfg *cfg)
15716{ 15922{
15717 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x22, 0); 15923 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x09, 0);
15718} 15924}
15719 15925
15720 15926
@@ -15950,7 +16156,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15950 if (err < 0) 16156 if (err < 0)
15951 return err; 16157 return err;
15952 16158
15953 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 16159 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
15954 16160
15955 return 1; 16161 return 1;
15956} 16162}
@@ -16067,7 +16273,6 @@ static int patch_alc861vd(struct hda_codec *codec)
16067 if (!spec->loopback.amplist) 16273 if (!spec->loopback.amplist)
16068 spec->loopback.amplist = alc861vd_loopbacks; 16274 spec->loopback.amplist = alc861vd_loopbacks;
16069#endif 16275#endif
16070 codec->proc_widget_hook = print_realtek_coef;
16071 16276
16072 return 0; 16277 return 0;
16073} 16278}
@@ -16534,13 +16739,6 @@ static struct hda_verb alc662_init_verbs[] = {
16534 /* ADC: mute amp left and right */ 16739 /* ADC: mute amp left and right */
16535 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 16740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16536 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, 16741 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16537 /* Front mixer: unmute input/output amp left and right (volume = 0) */
16538
16539 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16540 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16544 16742
16545 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 16743 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16546 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
@@ -16590,6 +16788,28 @@ static struct hda_verb alc662_init_verbs[] = {
16590 { } 16788 { }
16591}; 16789};
16592 16790
16791static struct hda_verb alc663_init_verbs[] = {
16792 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16793 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16794 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16795 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16796 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16797 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16798 { }
16799};
16800
16801static struct hda_verb alc272_init_verbs[] = {
16802 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16803 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16804 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16805 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16806 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16807 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16808 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16809 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16810 { }
16811};
16812
16593static struct hda_verb alc662_sue_init_verbs[] = { 16813static struct hda_verb alc662_sue_init_verbs[] = {
16594 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, 16814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
16595 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, 16815 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
@@ -16609,61 +16829,6 @@ static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
16609 {} 16829 {}
16610}; 16830};
16611 16831
16612/*
16613 * generic initialization of ADC, input mixers and output mixers
16614 */
16615static struct hda_verb alc662_auto_init_verbs[] = {
16616 /*
16617 * Unmute ADC and set the default input to mic-in
16618 */
16619 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16621
16622 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
16623 * mixer widget
16624 * Note: PASD motherboards uses the Line In 2 as the input for front
16625 * panel mic (mic 2)
16626 */
16627 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16628 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16629 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16630 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16631 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16632 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16633
16634 /*
16635 * Set up output mixers (0x0c - 0x0f)
16636 */
16637 /* set vol=0 to output mixers */
16638 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16639 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16640 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16641
16642 /* set up input amps for analog loopback */
16643 /* Amp Indices: DAC = 0, mixer = 1 */
16644 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16645 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16646 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16647 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16648 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16649 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16650
16651
16652 /* FIXME: use matrix-type input source selection */
16653 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
16654 /* Input mixer */
16655 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16656 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16657 { }
16658};
16659
16660/* additional verbs for ALC663 */
16661static struct hda_verb alc663_auto_init_verbs[] = {
16662 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16663 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16664 { }
16665};
16666
16667static struct hda_verb alc663_m51va_init_verbs[] = { 16832static struct hda_verb alc663_m51va_init_verbs[] = {
16668 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16833 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16669 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 16834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
@@ -17414,6 +17579,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17414 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), 17579 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17415 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), 17580 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17416 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), 17581 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17582 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17417 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), 17583 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17418 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), 17584 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17419 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), 17585 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
@@ -17449,6 +17615,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17449 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), 17615 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17450 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), 17616 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17451 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), 17617 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17618 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17452 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), 17619 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17453 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), 17620 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17454 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), 17621 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
@@ -17476,6 +17643,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
17476 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), 17643 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17477 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", 17644 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17478 ALC662_3ST_6ch_DIG), 17645 ALC662_3ST_6ch_DIG),
17646 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17479 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), 17647 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17480 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), 17648 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17481 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 17649 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
@@ -18094,15 +18262,23 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
18094 spec->num_mux_defs = 1; 18262 spec->num_mux_defs = 1;
18095 spec->input_mux = &spec->private_imux[0]; 18263 spec->input_mux = &spec->private_imux[0];
18096 18264
18097 add_verb(spec, alc662_auto_init_verbs); 18265 add_verb(spec, alc662_init_verbs);
18098 if (codec->vendor_id == 0x10ec0663) 18266 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18099 add_verb(spec, alc663_auto_init_verbs); 18267 codec->vendor_id == 0x10ec0665)
18268 add_verb(spec, alc663_init_verbs);
18269
18270 if (codec->vendor_id == 0x10ec0272)
18271 add_verb(spec, alc272_init_verbs);
18100 18272
18101 err = alc_auto_add_mic_boost(codec); 18273 err = alc_auto_add_mic_boost(codec);
18102 if (err < 0) 18274 if (err < 0)
18103 return err; 18275 return err;
18104 18276
18105 alc_ssid_check(codec, 0x15, 0x1b, 0x14); 18277 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
18278 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
18279 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
18280 else
18281 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
18106 18282
18107 return 1; 18283 return 1;
18108} 18284}
@@ -18188,11 +18364,20 @@ static int patch_alc662(struct hda_codec *codec)
18188 18364
18189 if (!spec->cap_mixer) 18365 if (!spec->cap_mixer)
18190 set_capture_mixer(codec); 18366 set_capture_mixer(codec);
18191 if (codec->vendor_id == 0x10ec0662) 18367
18368 switch (codec->vendor_id) {
18369 case 0x10ec0662:
18192 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 18370 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
18193 else 18371 break;
18372 case 0x10ec0272:
18373 case 0x10ec0663:
18374 case 0x10ec0665:
18194 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 18375 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
18195 18376 break;
18377 case 0x10ec0273:
18378 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
18379 break;
18380 }
18196 spec->vmaster_nid = 0x02; 18381 spec->vmaster_nid = 0x02;
18197 18382
18198 codec->patch_ops = alc_patch_ops; 18383 codec->patch_ops = alc_patch_ops;
@@ -18202,7 +18387,6 @@ static int patch_alc662(struct hda_codec *codec)
18202 if (!spec->loopback.amplist) 18387 if (!spec->loopback.amplist)
18203 spec->loopback.amplist = alc662_loopbacks; 18388 spec->loopback.amplist = alc662_loopbacks;
18204#endif 18389#endif
18205 codec->proc_widget_hook = print_realtek_coef;
18206 18390
18207 return 0; 18391 return 0;
18208} 18392}
@@ -18243,6 +18427,8 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = {
18243 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", 18427 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
18244 .patch = patch_alc662 }, 18428 .patch = patch_alc662 },
18245 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, 18429 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
18430 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
18431 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
18246 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 18432 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
18247 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 18433 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
18248 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, 18434 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index dbffb5b5c69d..8c416bb18a57 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -568,6 +568,11 @@ static hda_nid_t stac92hd83xxx_pin_nids[10] = {
568 0x0f, 0x10, 0x11, 0x1f, 0x20, 568 0x0f, 0x10, 0x11, 0x1f, 0x20,
569}; 569};
570 570
571static hda_nid_t stac92hd88xxx_pin_nids[10] = {
572 0x0a, 0x0b, 0x0c, 0x0d,
573 0x0f, 0x11, 0x1f, 0x20,
574};
575
571#define STAC92HD71BXX_NUM_PINS 13 576#define STAC92HD71BXX_NUM_PINS 13
572static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 577static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = {
573 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 578 0x0a, 0x0b, 0x0c, 0x0d, 0x00,
@@ -2873,6 +2878,13 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2873 2878
2874 conn_len = snd_hda_get_connections(codec, nid, conn, 2879 conn_len = snd_hda_get_connections(codec, nid, conn,
2875 HDA_MAX_CONNECTIONS); 2880 HDA_MAX_CONNECTIONS);
2881 /* 92HD88: trace back up the link of nids to find the DAC */
2882 while (conn_len == 1 && (get_wcaps_type(get_wcaps(codec, conn[0]))
2883 != AC_WID_AUD_OUT)) {
2884 nid = conn[0];
2885 conn_len = snd_hda_get_connections(codec, nid, conn,
2886 HDA_MAX_CONNECTIONS);
2887 }
2876 for (j = 0; j < conn_len; j++) { 2888 for (j = 0; j < conn_len; j++) {
2877 wcaps = get_wcaps(codec, conn[j]); 2889 wcaps = get_wcaps(codec, conn[j]);
2878 wtype = get_wcaps_type(wcaps); 2890 wtype = get_wcaps_type(wcaps);
@@ -4351,6 +4363,12 @@ static int stac92xx_init(struct hda_codec *codec)
4351 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT)) 4363 if (enable_pin_detect(codec, nid, STAC_PWR_EVENT))
4352 stac_issue_unsol_event(codec, nid); 4364 stac_issue_unsol_event(codec, nid);
4353 } 4365 }
4366
4367#ifdef CONFIG_SND_HDA_POWER_SAVE
4368 /* sync mute LED */
4369 if (spec->gpio_led && codec->patch_ops.check_power_status)
4370 codec->patch_ops.check_power_status(codec, 0x01);
4371#endif
4354 if (spec->dac_list) 4372 if (spec->dac_list)
4355 stac92xx_power_down(codec); 4373 stac92xx_power_down(codec);
4356 return 0; 4374 return 0;
@@ -4742,19 +4760,14 @@ static int hp_blike_system(u32 subsystem_id);
4742static void set_hp_led_gpio(struct hda_codec *codec) 4760static void set_hp_led_gpio(struct hda_codec *codec)
4743{ 4761{
4744 struct sigmatel_spec *spec = codec->spec; 4762 struct sigmatel_spec *spec = codec->spec;
4745 switch (codec->vendor_id) { 4763 unsigned int gpio;
4746 case 0x111d7608: 4764
4747 /* GPIO 0 */ 4765 gpio = snd_hda_param_read(codec, codec->afg, AC_PAR_GPIO_CAP);
4748 spec->gpio_led = 0x01; 4766 gpio &= AC_GPIO_IO_COUNT;
4749 break; 4767 if (gpio > 3)
4750 case 0x111d7600: 4768 spec->gpio_led = 0x08; /* GPIO 3 */
4751 case 0x111d7601: 4769 else
4752 case 0x111d7602: 4770 spec->gpio_led = 0x01; /* GPIO 0 */
4753 case 0x111d7603:
4754 /* GPIO 3 */
4755 spec->gpio_led = 0x08;
4756 break;
4757 }
4758} 4771}
4759 4772
4760/* 4773/*
@@ -4777,7 +4790,7 @@ static void set_hp_led_gpio(struct hda_codec *codec)
4777 * Need more information on whether it is true across the entire series. 4790 * Need more information on whether it is true across the entire series.
4778 * -- kunal 4791 * -- kunal
4779 */ 4792 */
4780static int find_mute_led_gpio(struct hda_codec *codec) 4793static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity)
4781{ 4794{
4782 struct sigmatel_spec *spec = codec->spec; 4795 struct sigmatel_spec *spec = codec->spec;
4783 const struct dmi_device *dev = NULL; 4796 const struct dmi_device *dev = NULL;
@@ -4804,7 +4817,7 @@ static int find_mute_led_gpio(struct hda_codec *codec)
4804 */ 4817 */
4805 if (!hp_blike_system(codec->subsystem_id)) { 4818 if (!hp_blike_system(codec->subsystem_id)) {
4806 set_hp_led_gpio(codec); 4819 set_hp_led_gpio(codec);
4807 spec->gpio_led_polarity = 1; 4820 spec->gpio_led_polarity = default_polarity;
4808 return 1; 4821 return 1;
4809 } 4822 }
4810 } 4823 }
@@ -4902,6 +4915,11 @@ static int stac92xx_resume(struct hda_codec *codec)
4902 stac_issue_unsol_event(codec, 4915 stac_issue_unsol_event(codec,
4903 spec->autocfg.line_out_pins[0]); 4916 spec->autocfg.line_out_pins[0]);
4904 } 4917 }
4918#ifdef CONFIG_SND_HDA_POWER_SAVE
4919 /* sync mute LED */
4920 if (spec->gpio_led && codec->patch_ops.check_power_status)
4921 codec->patch_ops.check_power_status(codec, 0x01);
4922#endif
4905 return 0; 4923 return 0;
4906} 4924}
4907 4925
@@ -4921,43 +4939,29 @@ static int stac92xx_hp_check_power_status(struct hda_codec *codec,
4921 hda_nid_t nid) 4939 hda_nid_t nid)
4922{ 4940{
4923 struct sigmatel_spec *spec = codec->spec; 4941 struct sigmatel_spec *spec = codec->spec;
4942 int i, muted = 1;
4924 4943
4925 if (nid == 0x10) { 4944 for (i = 0; i < spec->multiout.num_dacs; i++) {
4926 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & 4945 nid = spec->multiout.dac_nids[i];
4927 HDA_AMP_MUTE) 4946 if (!(snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) &
4928 spec->gpio_data &= ~spec->gpio_led; /* orange */ 4947 HDA_AMP_MUTE)) {
4929 else 4948 muted = 0; /* something heard */
4930 spec->gpio_data |= spec->gpio_led; /* white */ 4949 break;
4931
4932 if (!spec->gpio_led_polarity) {
4933 /* LED state is inverted on these systems */
4934 spec->gpio_data ^= spec->gpio_led;
4935 } 4950 }
4936
4937 stac_gpio_set(codec, spec->gpio_mask,
4938 spec->gpio_dir,
4939 spec->gpio_data);
4940 } 4951 }
4952 if (muted)
4953 spec->gpio_data &= ~spec->gpio_led; /* orange */
4954 else
4955 spec->gpio_data |= spec->gpio_led; /* white */
4941 4956
4942 return 0; 4957 if (!spec->gpio_led_polarity) {
4943} 4958 /* LED state is inverted on these systems */
4944 4959 spec->gpio_data ^= spec->gpio_led;
4945static int idt92hd83xxx_hp_check_power_status(struct hda_codec *codec, 4960 }
4946 hda_nid_t nid)
4947{
4948 struct sigmatel_spec *spec = codec->spec;
4949 4961
4950 if (nid != 0x13)
4951 return 0;
4952 if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & HDA_AMP_MUTE)
4953 spec->gpio_data |= spec->gpio_led; /* mute LED on */
4954 else
4955 spec->gpio_data &= ~spec->gpio_led; /* mute LED off */
4956 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data); 4962 stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
4957
4958 return 0; 4963 return 0;
4959} 4964}
4960
4961#endif 4965#endif
4962 4966
4963static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 4967static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
@@ -5279,7 +5283,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5279 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; 5283 hda_nid_t conn[STAC92HD83_DAC_COUNT + 1];
5280 int err; 5284 int err;
5281 int num_dacs; 5285 int num_dacs;
5282 hda_nid_t nid;
5283 5286
5284 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 5287 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5285 if (spec == NULL) 5288 if (spec == NULL)
@@ -5318,7 +5321,18 @@ again:
5318 stac92hd83xxx_brd_tbl[spec->board_config]); 5321 stac92hd83xxx_brd_tbl[spec->board_config]);
5319 5322
5320 switch (codec->vendor_id) { 5323 switch (codec->vendor_id) {
5324 case 0x111d7666:
5325 case 0x111d7667:
5326 case 0x111d7668:
5327 case 0x111d7669:
5328 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5329 spec->pin_nids = stac92hd88xxx_pin_nids;
5330 spec->mono_nid = 0;
5331 spec->digbeep_nid = 0;
5332 spec->num_pwrs = 0;
5333 break;
5321 case 0x111d7604: 5334 case 0x111d7604:
5335 case 0x111d76d4:
5322 case 0x111d7605: 5336 case 0x111d7605:
5323 case 0x111d76d5: 5337 case 0x111d76d5:
5324 if (spec->board_config == STAC_92HD83XXX_PWR_REF) 5338 if (spec->board_config == STAC_92HD83XXX_PWR_REF)
@@ -5329,8 +5343,10 @@ again:
5329 5343
5330 codec->patch_ops = stac92xx_patch_ops; 5344 codec->patch_ops = stac92xx_patch_ops;
5331 5345
5332 if (spec->board_config == STAC_92HD83XXX_HP) 5346 if (find_mute_led_gpio(codec, 0))
5333 spec->gpio_led = 0x01; 5347 snd_printd("mute LED gpio %d polarity %d\n",
5348 spec->gpio_led,
5349 spec->gpio_led_polarity);
5334 5350
5335#ifdef CONFIG_SND_HDA_POWER_SAVE 5351#ifdef CONFIG_SND_HDA_POWER_SAVE
5336 if (spec->gpio_led) { 5352 if (spec->gpio_led) {
@@ -5339,7 +5355,7 @@ again:
5339 spec->gpio_data |= spec->gpio_led; 5355 spec->gpio_data |= spec->gpio_led;
5340 /* register check_power_status callback. */ 5356 /* register check_power_status callback. */
5341 codec->patch_ops.check_power_status = 5357 codec->patch_ops.check_power_status =
5342 idt92hd83xxx_hp_check_power_status; 5358 stac92xx_hp_check_power_status;
5343 } 5359 }
5344#endif 5360#endif
5345 5361
@@ -5359,24 +5375,21 @@ again:
5359 return err; 5375 return err;
5360 } 5376 }
5361 5377
5362 switch (spec->board_config) { 5378 /* docking output support */
5363 case STAC_DELL_S14: 5379 num_dacs = snd_hda_get_connections(codec, 0xF,
5364 nid = 0xf;
5365 break;
5366 default:
5367 nid = 0xe;
5368 break;
5369 }
5370
5371 num_dacs = snd_hda_get_connections(codec, nid,
5372 conn, STAC92HD83_DAC_COUNT + 1) - 1; 5380 conn, STAC92HD83_DAC_COUNT + 1) - 1;
5373 if (num_dacs < 0) 5381 /* skip non-DAC connections */
5374 num_dacs = STAC92HD83_DAC_COUNT; 5382 while (num_dacs >= 0 &&
5375 5383 (get_wcaps_type(get_wcaps(codec, conn[num_dacs]))
5376 /* set port X to select the last DAC 5384 != AC_WID_AUD_OUT))
5377 */ 5385 num_dacs--;
5378 snd_hda_codec_write_cache(codec, nid, 0, 5386 /* set port E and F to select the last DAC */
5387 if (num_dacs >= 0) {
5388 snd_hda_codec_write_cache(codec, 0xE, 0,
5389 AC_VERB_SET_CONNECT_SEL, num_dacs);
5390 snd_hda_codec_write_cache(codec, 0xF, 0,
5379 AC_VERB_SET_CONNECT_SEL, num_dacs); 5391 AC_VERB_SET_CONNECT_SEL, num_dacs);
5392 }
5380 5393
5381 codec->proc_widget_hook = stac92hd_proc_hook; 5394 codec->proc_widget_hook = stac92hd_proc_hook;
5382 5395
@@ -5657,7 +5670,6 @@ again:
5657 */ 5670 */
5658 spec->num_smuxes = 1; 5671 spec->num_smuxes = 1;
5659 spec->num_dmuxes = 1; 5672 spec->num_dmuxes = 1;
5660 spec->gpio_led = 0x01;
5661 /* fallthrough */ 5673 /* fallthrough */
5662 case STAC_HP_DV5: 5674 case STAC_HP_DV5:
5663 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); 5675 snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010);
@@ -5672,8 +5684,6 @@ again:
5672 spec->num_dmics = 1; 5684 spec->num_dmics = 1;
5673 spec->num_dmuxes = 1; 5685 spec->num_dmuxes = 1;
5674 spec->num_smuxes = 1; 5686 spec->num_smuxes = 1;
5675 /* orange/white mute led on GPIO3, orange=0, white=1 */
5676 spec->gpio_led = 0x08;
5677 break; 5687 break;
5678 } 5688 }
5679 5689
@@ -5695,7 +5705,7 @@ again:
5695 } 5705 }
5696 } 5706 }
5697 5707
5698 if (find_mute_led_gpio(codec)) 5708 if (find_mute_led_gpio(codec, 1))
5699 snd_printd("mute LED gpio %d polarity %d\n", 5709 snd_printd("mute LED gpio %d polarity %d\n",
5700 spec->gpio_led, 5710 spec->gpio_led,
5701 spec->gpio_led_polarity); 5711 spec->gpio_led_polarity);
@@ -6236,8 +6246,13 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
6236 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, 6246 { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 },
6237 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, 6247 { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx},
6238 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, 6248 { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx},
6249 { .id = 0x111d76d4, .name = "92HD83C1C5", .patch = patch_stac92hd83xxx},
6239 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, 6250 { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx},
6240 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, 6251 { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx},
6252 { .id = 0x111d7666, .name = "92HD88B3", .patch = patch_stac92hd83xxx},
6253 { .id = 0x111d7667, .name = "92HD88B1", .patch = patch_stac92hd83xxx},
6254 { .id = 0x111d7668, .name = "92HD88B2", .patch = patch_stac92hd83xxx},
6255 { .id = 0x111d7669, .name = "92HD88B4", .patch = patch_stac92hd83xxx},
6241 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, 6256 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx},
6242 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, 6257 { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx },
6243 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, 6258 { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx },
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 9595b5b535f3..7e494b6a1d0e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1791,6 +1791,12 @@ static struct ac97_quirk ac97_quirks[] = {
1791 .type = AC97_TUNE_HP_ONLY 1791 .type = AC97_TUNE_HP_ONLY
1792 }, 1792 },
1793 { 1793 {
1794 .subvendor = 0x110a,
1795 .subdevice = 0x0079,
1796 .name = "Fujitsu Siemens D1289",
1797 .type = AC97_TUNE_HP_ONLY
1798 },
1799 {
1794 .subvendor = 0x1019, 1800 .subvendor = 0x1019,
1795 .subdevice = 0x0a81, 1801 .subdevice = 0x0a81,
1796 .name = "ECS K7VTA3", 1802 .name = "ECS K7VTA3",
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index cf0dfb7ca221..67cbfe7283da 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -349,9 +349,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
350 size, &sport_handle->tx_dma_phy, GFP_KERNEL); 350 size, &sport_handle->tx_dma_phy, GFP_KERNEL);
351 if (!sport_handle->tx_dma_buf) { 351 if (!sport_handle->tx_dma_buf) {
352 pr_err("Failed to allocate memory for tx dma \ 352 pr_err("Failed to allocate memory for tx dma buf - Please increase uncached DMA memory region\n");
353 buf - Please increase uncached DMA \
354 memory region\n");
355 return -ENOMEM; 353 return -ENOMEM;
356 } else 354 } else
357 memset(sport_handle->tx_dma_buf, 0, size); 355 memset(sport_handle->tx_dma_buf, 0, size);
@@ -362,9 +360,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
362 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \ 360 sport_handle->rx_dma_buf = dma_alloc_coherent(NULL, \
363 size, &sport_handle->rx_dma_phy, GFP_KERNEL); 361 size, &sport_handle->rx_dma_phy, GFP_KERNEL);
364 if (!sport_handle->rx_dma_buf) { 362 if (!sport_handle->rx_dma_buf) {
365 pr_err("Failed to allocate memory for rx dma \ 363 pr_err("Failed to allocate memory for rx dma buf - Please increase uncached DMA memory region\n");
366 buf - Please increase uncached DMA \
367 memory region\n");
368 return -ENOMEM; 364 return -ENOMEM;
369 } else 365 } else
370 memset(sport_handle->rx_dma_buf, 0, size); 366 memset(sport_handle->rx_dma_buf, 0, size);
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 62fbb8459569..c6c6a4a7d948 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -207,8 +207,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
207 buf->area = dma_alloc_coherent(pcm->card->dev, size, 207 buf->area = dma_alloc_coherent(pcm->card->dev, size,
208 &buf->addr, GFP_KERNEL); 208 &buf->addr, GFP_KERNEL);
209 if (!buf->area) { 209 if (!buf->area) {
210 pr_err("Failed to allocate dma memory \ 210 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
211 Please increase uncached DMA memory region\n");
212 return -ENOMEM; 211 return -ENOMEM;
213 } 212 }
214 buf->bytes = size; 213 buf->bytes = size;
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index a8c73cbbd685..5e03bb2f3cd7 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -244,8 +244,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
244 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4, 244 buf->area = dma_alloc_coherent(pcm->card->dev, size * 4,
245 &buf->addr, GFP_KERNEL); 245 &buf->addr, GFP_KERNEL);
246 if (!buf->area) { 246 if (!buf->area) {
247 pr_err("Failed to allocate dma memory \ 247 pr_err("Failed to allocate dma memory - Please increase uncached DMA memory region\n");
248 Please increase uncached DMA memory region\n");
249 return -ENOMEM; 248 return -ENOMEM;
250 } 249 }
251 buf->bytes = size; 250 buf->bytes = size;
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 52b005f8fed4..1743d565e996 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -23,6 +23,7 @@ config SND_SOC_ALL_CODECS
23 select SND_SOC_AK4671 if I2C 23 select SND_SOC_AK4671 if I2C
24 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
25 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
26 select SND_SOC_DA7210 if I2C
26 select SND_SOC_PCM3008 27 select SND_SOC_PCM3008
27 select SND_SOC_SPDIF 28 select SND_SOC_SPDIF
28 select SND_SOC_SSM2602 if I2C 29 select SND_SOC_SSM2602 if I2C
@@ -35,6 +36,7 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_TWL4030 if TWL4030_CORE 36 select SND_SOC_TWL4030 if TWL4030_CORE
36 select SND_SOC_UDA134X 37 select SND_SOC_UDA134X
37 select SND_SOC_UDA1380 if I2C 38 select SND_SOC_UDA1380 if I2C
39 select SND_SOC_WM2000 if I2C
38 select SND_SOC_WM8350 if MFD_WM8350 40 select SND_SOC_WM8350 if MFD_WM8350
39 select SND_SOC_WM8400 if MFD_WM8400 41 select SND_SOC_WM8400 if MFD_WM8400
40 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 42 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -49,14 +51,18 @@ config SND_SOC_ALL_CODECS
49 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 51 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
50 select SND_SOC_WM8900 if I2C 52 select SND_SOC_WM8900 if I2C
51 select SND_SOC_WM8903 if I2C 53 select SND_SOC_WM8903 if I2C
54 select SND_SOC_WM8904 if I2C
52 select SND_SOC_WM8940 if I2C 55 select SND_SOC_WM8940 if I2C
56 select SND_SOC_WM8955 if I2C
53 select SND_SOC_WM8960 if I2C 57 select SND_SOC_WM8960 if I2C
54 select SND_SOC_WM8961 if I2C 58 select SND_SOC_WM8961 if I2C
55 select SND_SOC_WM8971 if I2C 59 select SND_SOC_WM8971 if I2C
56 select SND_SOC_WM8974 if I2C 60 select SND_SOC_WM8974 if I2C
61 select SND_SOC_WM8978 if I2C
57 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI 62 select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI
58 select SND_SOC_WM8990 if I2C 63 select SND_SOC_WM8990 if I2C
59 select SND_SOC_WM8993 if I2C 64 select SND_SOC_WM8993 if I2C
65 select SND_SOC_WM8994 if MFD_WM8994
60 select SND_SOC_WM9081 if I2C 66 select SND_SOC_WM9081 if I2C
61 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 67 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
62 select SND_SOC_WM9712 if SND_SOC_AC97_BUS 68 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
@@ -112,6 +118,9 @@ config SND_SOC_AK4671
112config SND_SOC_CS4270 118config SND_SOC_CS4270
113 tristate 119 tristate
114 120
121config SND_SOC_DA7210
122 tristate
123
115# Cirrus Logic CS4270 Codec VD = 3.3V Errata 124# Cirrus Logic CS4270 Codec VD = 3.3V Errata
116# Select if you are affected by the errata where the part will not function 125# Select if you are affected by the errata where the part will not function
117# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will 126# if MCLK divide-by-1.5 is selected and VD is set to 3.3V. The driver will
@@ -203,9 +212,15 @@ config SND_SOC_WM8900
203config SND_SOC_WM8903 212config SND_SOC_WM8903
204 tristate 213 tristate
205 214
215config SND_SOC_WM8904
216 tristate
217
206config SND_SOC_WM8940 218config SND_SOC_WM8940
207 tristate 219 tristate
208 220
221config SND_SOC_WM8955
222 tristate
223
209config SND_SOC_WM8960 224config SND_SOC_WM8960
210 tristate 225 tristate
211 226
@@ -218,6 +233,9 @@ config SND_SOC_WM8971
218config SND_SOC_WM8974 233config SND_SOC_WM8974
219 tristate 234 tristate
220 235
236config SND_SOC_WM8978
237 tristate
238
221config SND_SOC_WM8988 239config SND_SOC_WM8988
222 tristate 240 tristate
223 241
@@ -227,6 +245,9 @@ config SND_SOC_WM8990
227config SND_SOC_WM8993 245config SND_SOC_WM8993
228 tristate 246 tristate
229 247
248config SND_SOC_WM8994
249 tristate
250
230config SND_SOC_WM9081 251config SND_SOC_WM9081
231 tristate 252 tristate
232 253
@@ -245,3 +266,6 @@ config SND_SOC_MAX9877
245 266
246config SND_SOC_TPA6130A2 267config SND_SOC_TPA6130A2
247 tristate 268 tristate
269
270config SND_SOC_WM2000
271 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index dbaecb133ac7..dd5ce6df6292 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -10,6 +10,7 @@ snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o 10snd-soc-ak4671-objs := ak4671.o
11snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
12snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
13snd-soc-da7210-objs := da7210.o
13snd-soc-l3-objs := l3.o 14snd-soc-l3-objs := l3.o
14snd-soc-pcm3008-objs := pcm3008.o 15snd-soc-pcm3008-objs := pcm3008.o
15snd-soc-spdif-objs := spdif_transciever.o 16snd-soc-spdif-objs := spdif_transciever.o
@@ -36,14 +37,18 @@ snd-soc-wm8753-objs := wm8753.o
36snd-soc-wm8776-objs := wm8776.o 37snd-soc-wm8776-objs := wm8776.o
37snd-soc-wm8900-objs := wm8900.o 38snd-soc-wm8900-objs := wm8900.o
38snd-soc-wm8903-objs := wm8903.o 39snd-soc-wm8903-objs := wm8903.o
40snd-soc-wm8904-objs := wm8904.o
39snd-soc-wm8940-objs := wm8940.o 41snd-soc-wm8940-objs := wm8940.o
42snd-soc-wm8955-objs := wm8955.o
40snd-soc-wm8960-objs := wm8960.o 43snd-soc-wm8960-objs := wm8960.o
41snd-soc-wm8961-objs := wm8961.o 44snd-soc-wm8961-objs := wm8961.o
42snd-soc-wm8971-objs := wm8971.o 45snd-soc-wm8971-objs := wm8971.o
43snd-soc-wm8974-objs := wm8974.o 46snd-soc-wm8974-objs := wm8974.o
47snd-soc-wm8978-objs := wm8978.o
44snd-soc-wm8988-objs := wm8988.o 48snd-soc-wm8988-objs := wm8988.o
45snd-soc-wm8990-objs := wm8990.o 49snd-soc-wm8990-objs := wm8990.o
46snd-soc-wm8993-objs := wm8993.o 50snd-soc-wm8993-objs := wm8993.o
51snd-soc-wm8994-objs := wm8994.o
47snd-soc-wm9081-objs := wm9081.o 52snd-soc-wm9081-objs := wm9081.o
48snd-soc-wm9705-objs := wm9705.o 53snd-soc-wm9705-objs := wm9705.o
49snd-soc-wm9712-objs := wm9712.o 54snd-soc-wm9712-objs := wm9712.o
@@ -53,6 +58,7 @@ snd-soc-wm-hubs-objs := wm_hubs.o
53# Amp 58# Amp
54snd-soc-max9877-objs := max9877.o 59snd-soc-max9877-objs := max9877.o
55snd-soc-tpa6130a2-objs := tpa6130a2.o 60snd-soc-tpa6130a2-objs := tpa6130a2.o
61snd-soc-wm2000-objs := wm2000.o
56 62
57obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 63obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
58obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 64obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
@@ -66,6 +72,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
66obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 72obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
67obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 73obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
68obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 74obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
75obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
69obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 76obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
70obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 77obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
71obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 78obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
@@ -92,14 +99,18 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
92obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 99obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
93obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 100obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
94obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o 101obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o
95obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o 102obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o
96obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
97obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o 103obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o
104obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o
98obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o 105obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o
99obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o 106obj-$(CONFIG_SND_SOC_WM8961) += snd-soc-wm8961.o
107obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o
108obj-$(CONFIG_SND_SOC_WM8974) += snd-soc-wm8974.o
109obj-$(CONFIG_SND_SOC_WM8978) += snd-soc-wm8978.o
100obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o 110obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
101obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 111obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
102obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 112obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
113obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
103obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 114obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
104obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 115obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
105obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 116obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
@@ -109,3 +120,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
109# Amp 120# Amp
110obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 121obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
111obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o 122obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
123obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index 2c18e3d1b71e..3c80137d5938 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -171,57 +171,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream,
171 return 0; 171 return 0;
172} 172}
173 173
174 174#ifdef CONFIG_PM
175/* 175static int ad1836_soc_suspend(struct platform_device *pdev,
176 * interface to read/write ad1836 register 176 pm_message_t state)
177 */
178#define AD1836_SPI_REG_SHFT 12
179#define AD1836_SPI_READ (1 << 11)
180#define AD1836_SPI_VAL_MSK 0x3FF
181
182/*
183 * write to the ad1836 register space
184 */
185
186static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg,
187 unsigned int value)
188{ 177{
189 u16 *reg_cache = codec->reg_cache; 178 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
190 int ret = 0; 179 struct snd_soc_codec *codec = socdev->card->codec;
191 180
192 if (value != reg_cache[reg]) { 181 /* reset clock control mode */
193 unsigned short buf; 182 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
194 struct spi_transfer t = { 183 adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK;
195 .tx_buf = &buf,
196 .len = 2,
197 };
198 struct spi_message m;
199
200 buf = (reg << AD1836_SPI_REG_SHFT) |
201 (value & AD1836_SPI_VAL_MSK);
202 spi_message_init(&m);
203 spi_message_add_tail(&t, &m);
204 ret = spi_sync(codec->control_data, &m);
205 if (ret == 0)
206 reg_cache[reg] = value;
207 }
208 184
209 return ret; 185 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
210} 186}
211 187
212/* 188static int ad1836_soc_resume(struct platform_device *pdev)
213 * read from the ad1836 register space cache
214 */
215static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec,
216 unsigned int reg)
217{ 189{
218 u16 *reg_cache = codec->reg_cache; 190 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
191 struct snd_soc_codec *codec = socdev->card->codec;
219 192
220 if (reg >= codec->reg_cache_size) 193 /* restore clock control mode */
221 return -EINVAL; 194 u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2);
195 adc_ctrl2 |= AD1836_ADC_AUX;
222 196
223 return reg_cache[reg]; 197 return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2);
224} 198}
199#else
200#define ad1836_soc_suspend NULL
201#define ad1836_soc_resume NULL
202#endif
225 203
226static int __devinit ad1836_spi_probe(struct spi_device *spi) 204static int __devinit ad1836_spi_probe(struct spi_device *spi)
227{ 205{
@@ -306,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836)
306 codec->owner = THIS_MODULE; 284 codec->owner = THIS_MODULE;
307 codec->dai = &ad1836_dai; 285 codec->dai = &ad1836_dai;
308 codec->num_dai = 1; 286 codec->num_dai = 1;
309 codec->write = ad1836_write_reg;
310 codec->read = ad1836_read_reg_cache;
311 INIT_LIST_HEAD(&codec->dapm_widgets); 287 INIT_LIST_HEAD(&codec->dapm_widgets);
312 INIT_LIST_HEAD(&codec->dapm_paths); 288 INIT_LIST_HEAD(&codec->dapm_paths);
313 289
314 ad1836_dai.dev = codec->dev; 290 ad1836_dai.dev = codec->dev;
315 ad1836_codec = codec; 291 ad1836_codec = codec;
316 292
293 ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI);
294 if (ret < 0) {
295 dev_err(codec->dev, "failed to set cache I/O: %d\n",
296 ret);
297 kfree(ad1836);
298 return ret;
299 }
300
317 /* default setting for ad1836 */ 301 /* default setting for ad1836 */
318 /* de-emphasis: 48kHz, power-on dac */ 302 /* de-emphasis: 48kHz, power-on dac */
319 codec->write(codec, AD1836_DAC_CTRL1, 0x300); 303 snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300);
320 /* unmute dac channels */ 304 /* unmute dac channels */
321 codec->write(codec, AD1836_DAC_CTRL2, 0x0); 305 snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0);
322 /* high-pass filter enable, power-on adc */ 306 /* high-pass filter enable, power-on adc */
323 codec->write(codec, AD1836_ADC_CTRL1, 0x100); 307 snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100);
324 /* unmute adc channles, adc aux mode */ 308 /* unmute adc channles, adc aux mode */
325 codec->write(codec, AD1836_ADC_CTRL2, 0x180); 309 snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180);
326 /* left/right diff:PGA/MUX */ 310 /* left/right diff:PGA/MUX */
327 codec->write(codec, AD1836_ADC_CTRL3, 0x3A); 311 snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A);
328 /* volume */ 312 /* volume */
329 codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); 313 snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF);
330 codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); 314 snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF);
331 codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); 315 snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF);
332 codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); 316 snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF);
333 codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); 317 snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF);
334 codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); 318 snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF);
335 319
336 ret = snd_soc_register_codec(codec); 320 ret = snd_soc_register_codec(codec);
337 if (ret != 0) { 321 if (ret != 0) {
@@ -404,6 +388,8 @@ static int ad1836_remove(struct platform_device *pdev)
404struct snd_soc_codec_device soc_codec_dev_ad1836 = { 388struct snd_soc_codec_device soc_codec_dev_ad1836 = {
405 .probe = ad1836_probe, 389 .probe = ad1836_probe,
406 .remove = ad1836_remove, 390 .remove = ad1836_remove,
391 .suspend = ad1836_soc_suspend,
392 .resume = ad1836_soc_resume,
407}; 393};
408EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); 394EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836);
409 395
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h
index 7660ee6973c0..e9d90d3951c5 100644
--- a/sound/soc/codecs/ad1836.h
+++ b/sound/soc/codecs/ad1836.h
@@ -54,6 +54,7 @@
54#define AD1836_ADC_SERFMT_MASK (7 << 6) 54#define AD1836_ADC_SERFMT_MASK (7 << 6)
55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) 55#define AD1836_ADC_SERFMT_PCK256 (0x4 << 6)
56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) 56#define AD1836_ADC_SERFMT_PCK128 (0x5 << 6)
57#define AD1836_ADC_AUX (0x6 << 6)
57 58
58#define AD1836_ADC_CTRL3 14 59#define AD1836_ADC_CTRL3 14
59 60
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 5d489186c05b..c233810d463d 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -46,6 +46,11 @@ struct ad1938_priv {
46 u8 reg_cache[AD1938_NUM_REGS]; 46 u8 reg_cache[AD1938_NUM_REGS];
47}; 47};
48 48
49/* ad1938 register cache & default register settings */
50static const u8 ad1938_reg[AD1938_NUM_REGS] = {
51 0, 0, 0, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0, 0,
52};
53
49static struct snd_soc_codec *ad1938_codec; 54static struct snd_soc_codec *ad1938_codec;
50struct snd_soc_codec_device soc_codec_dev_ad1938; 55struct snd_soc_codec_device soc_codec_dev_ad1938;
51static int ad1938_register(struct ad1938_priv *ad1938); 56static int ad1938_register(struct ad1938_priv *ad1938);
@@ -97,6 +102,7 @@ static const struct snd_kcontrol_new ad1938_snd_controls[] = {
97static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = { 102static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
98 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1), 103 SND_SOC_DAPM_DAC("DAC", "Playback", AD1938_DAC_CTRL0, 0, 1),
99 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), 104 SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0),
105 SND_SOC_DAPM_SUPPLY("PLL_PWR", AD1938_PLL_CLK_CTRL0, 0, 1, NULL, 0),
100 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0), 106 SND_SOC_DAPM_SUPPLY("ADC_PWR", AD1938_ADC_CTRL0, 0, 1, NULL, 0),
101 SND_SOC_DAPM_OUTPUT("DAC1OUT"), 107 SND_SOC_DAPM_OUTPUT("DAC1OUT"),
102 SND_SOC_DAPM_OUTPUT("DAC2OUT"), 108 SND_SOC_DAPM_OUTPUT("DAC2OUT"),
@@ -107,6 +113,8 @@ static const struct snd_soc_dapm_widget ad1938_dapm_widgets[] = {
107}; 113};
108 114
109static const struct snd_soc_dapm_route audio_paths[] = { 115static const struct snd_soc_dapm_route audio_paths[] = {
116 { "DAC", NULL, "PLL_PWR" },
117 { "ADC", NULL, "PLL_PWR" },
110 { "DAC", NULL, "ADC_PWR" }, 118 { "DAC", NULL, "ADC_PWR" },
111 { "ADC", NULL, "ADC_PWR" }, 119 { "ADC", NULL, "ADC_PWR" },
112 { "DAC1OUT", "DAC1 Switch", "DAC" }, 120 { "DAC1OUT", "DAC1 Switch", "DAC" },
@@ -126,30 +134,20 @@ static int ad1938_mute(struct snd_soc_dai *dai, int mute)
126 struct snd_soc_codec *codec = dai->codec; 134 struct snd_soc_codec *codec = dai->codec;
127 int reg; 135 int reg;
128 136
129 reg = codec->read(codec, AD1938_DAC_CTRL2); 137 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
130 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg & 138 reg = (mute > 0) ? reg | AD1938_DAC_MASTER_MUTE : reg &
131 (~AD1938_DAC_MASTER_MUTE); 139 (~AD1938_DAC_MASTER_MUTE);
132 codec->write(codec, AD1938_DAC_CTRL2, reg); 140 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
133
134 return 0;
135}
136
137static inline int ad1938_pll_powerctrl(struct snd_soc_codec *codec, int cmd)
138{
139 int reg = codec->read(codec, AD1938_PLL_CLK_CTRL0);
140 reg = (cmd > 0) ? reg & (~AD1938_PLL_POWERDOWN) : reg |
141 AD1938_PLL_POWERDOWN;
142 codec->write(codec, AD1938_PLL_CLK_CTRL0, reg);
143 141
144 return 0; 142 return 0;
145} 143}
146 144
147static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 145static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
148 unsigned int mask, int slots, int width) 146 unsigned int rx_mask, int slots, int width)
149{ 147{
150 struct snd_soc_codec *codec = dai->codec; 148 struct snd_soc_codec *codec = dai->codec;
151 int dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 149 int dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
152 int adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 150 int adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
153 151
154 dac_reg &= ~AD1938_DAC_CHAN_MASK; 152 dac_reg &= ~AD1938_DAC_CHAN_MASK;
155 adc_reg &= ~AD1938_ADC_CHAN_MASK; 153 adc_reg &= ~AD1938_ADC_CHAN_MASK;
@@ -175,8 +173,8 @@ static int ad1938_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
175 return -EINVAL; 173 return -EINVAL;
176 } 174 }
177 175
178 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 176 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
179 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 177 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
180 178
181 return 0; 179 return 0;
182} 180}
@@ -187,8 +185,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
187 struct snd_soc_codec *codec = codec_dai->codec; 185 struct snd_soc_codec *codec = codec_dai->codec;
188 int adc_reg, dac_reg; 186 int adc_reg, dac_reg;
189 187
190 adc_reg = codec->read(codec, AD1938_ADC_CTRL2); 188 adc_reg = snd_soc_read(codec, AD1938_ADC_CTRL2);
191 dac_reg = codec->read(codec, AD1938_DAC_CTRL1); 189 dac_reg = snd_soc_read(codec, AD1938_DAC_CTRL1);
192 190
193 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S 191 /* At present, the driver only support AUX ADC mode(SND_SOC_DAIFMT_I2S
194 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A) 192 * with TDM) and ADC&DAC TDM mode(SND_SOC_DAIFMT_DSP_A)
@@ -265,8 +263,8 @@ static int ad1938_set_dai_fmt(struct snd_soc_dai *codec_dai,
265 return -EINVAL; 263 return -EINVAL;
266 } 264 }
267 265
268 codec->write(codec, AD1938_ADC_CTRL2, adc_reg); 266 snd_soc_write(codec, AD1938_ADC_CTRL2, adc_reg);
269 codec->write(codec, AD1938_DAC_CTRL1, dac_reg); 267 snd_soc_write(codec, AD1938_DAC_CTRL1, dac_reg);
270 268
271 return 0; 269 return 0;
272} 270}
@@ -295,134 +293,13 @@ static int ad1938_hw_params(struct snd_pcm_substream *substream,
295 break; 293 break;
296 } 294 }
297 295
298 reg = codec->read(codec, AD1938_DAC_CTRL2); 296 reg = snd_soc_read(codec, AD1938_DAC_CTRL2);
299 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len; 297 reg = (reg & (~AD1938_DAC_WORD_LEN_MASK)) | word_len;
300 codec->write(codec, AD1938_DAC_CTRL2, reg); 298 snd_soc_write(codec, AD1938_DAC_CTRL2, reg);
301 299
302 reg = codec->read(codec, AD1938_ADC_CTRL1); 300 reg = snd_soc_read(codec, AD1938_ADC_CTRL1);
303 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len; 301 reg = (reg & (~AD1938_ADC_WORD_LEN_MASK)) | word_len;
304 codec->write(codec, AD1938_ADC_CTRL1, reg); 302 snd_soc_write(codec, AD1938_ADC_CTRL1, reg);
305
306 return 0;
307}
308
309static int ad1938_set_bias_level(struct snd_soc_codec *codec,
310 enum snd_soc_bias_level level)
311{
312 switch (level) {
313 case SND_SOC_BIAS_ON:
314 ad1938_pll_powerctrl(codec, 1);
315 break;
316 case SND_SOC_BIAS_PREPARE:
317 break;
318 case SND_SOC_BIAS_STANDBY:
319 case SND_SOC_BIAS_OFF:
320 ad1938_pll_powerctrl(codec, 0);
321 break;
322 }
323 codec->bias_level = level;
324 return 0;
325}
326
327/*
328 * interface to read/write ad1938 register
329 */
330
331#define AD1938_SPI_ADDR 0x4
332#define AD1938_SPI_READ 0x1
333#define AD1938_SPI_BUFLEN 3
334
335/*
336 * write to the ad1938 register space
337 */
338
339static int ad1938_write_reg(struct snd_soc_codec *codec, unsigned int reg,
340 unsigned int value)
341{
342 u8 *reg_cache = codec->reg_cache;
343 int ret = 0;
344
345 if (value != reg_cache[reg]) {
346 uint8_t buf[AD1938_SPI_BUFLEN];
347 struct spi_transfer t = {
348 .tx_buf = buf,
349 .len = AD1938_SPI_BUFLEN,
350 };
351 struct spi_message m;
352
353 buf[0] = AD1938_SPI_ADDR << 1;
354 buf[1] = reg;
355 buf[2] = value;
356 spi_message_init(&m);
357 spi_message_add_tail(&t, &m);
358 ret = spi_sync(codec->control_data, &m);
359 if (ret == 0)
360 reg_cache[reg] = value;
361 }
362
363 return ret;
364}
365
366/*
367 * read from the ad1938 register space cache
368 */
369
370static unsigned int ad1938_read_reg_cache(struct snd_soc_codec *codec,
371 unsigned int reg)
372{
373 u8 *reg_cache = codec->reg_cache;
374
375 if (reg >= codec->reg_cache_size)
376 return -EINVAL;
377
378 return reg_cache[reg];
379}
380
381/*
382 * read from the ad1938 register space
383 */
384
385static unsigned int ad1938_read_reg(struct snd_soc_codec *codec,
386 unsigned int reg)
387{
388 char w_buf[AD1938_SPI_BUFLEN];
389 char r_buf[AD1938_SPI_BUFLEN];
390 int ret;
391
392 struct spi_transfer t = {
393 .tx_buf = w_buf,
394 .rx_buf = r_buf,
395 .len = AD1938_SPI_BUFLEN,
396 };
397 struct spi_message m;
398
399 w_buf[0] = (AD1938_SPI_ADDR << 1) | AD1938_SPI_READ;
400 w_buf[1] = reg;
401 w_buf[2] = 0;
402
403 spi_message_init(&m);
404 spi_message_add_tail(&t, &m);
405 ret = spi_sync(codec->control_data, &m);
406 if (ret == 0)
407 return r_buf[2];
408 else
409 return -EIO;
410}
411
412static int ad1938_fill_cache(struct snd_soc_codec *codec)
413{
414 int i;
415 u8 *reg_cache = codec->reg_cache;
416 struct spi_device *spi = codec->control_data;
417
418 for (i = 0; i < codec->reg_cache_size; i++) {
419 int ret = ad1938_read_reg(codec, i);
420 if (ret == -EIO) {
421 dev_err(&spi->dev, "AD1938 SPI read failure\n");
422 return ret;
423 }
424 reg_cache[i] = ret;
425 }
426 303
427 return 0; 304 return 0;
428} 305}
@@ -512,32 +389,37 @@ static int ad1938_register(struct ad1938_priv *ad1938)
512 codec->owner = THIS_MODULE; 389 codec->owner = THIS_MODULE;
513 codec->dai = &ad1938_dai; 390 codec->dai = &ad1938_dai;
514 codec->num_dai = 1; 391 codec->num_dai = 1;
515 codec->write = ad1938_write_reg;
516 codec->read = ad1938_read_reg_cache;
517 codec->set_bias_level = ad1938_set_bias_level;
518 INIT_LIST_HEAD(&codec->dapm_widgets); 392 INIT_LIST_HEAD(&codec->dapm_widgets);
519 INIT_LIST_HEAD(&codec->dapm_paths); 393 INIT_LIST_HEAD(&codec->dapm_paths);
520 394
521 ad1938_dai.dev = codec->dev; 395 ad1938_dai.dev = codec->dev;
522 ad1938_codec = codec; 396 ad1938_codec = codec;
523 397
398 memcpy(codec->reg_cache, ad1938_reg, AD1938_NUM_REGS);
399
400 ret = snd_soc_codec_set_cache_io(codec, 16, 8, SND_SOC_SPI);
401 if (ret < 0) {
402 dev_err(codec->dev, "failed to set cache I/O: %d\n",
403 ret);
404 kfree(ad1938);
405 return ret;
406 }
407
524 /* default setting for ad1938 */ 408 /* default setting for ad1938 */
525 409
526 /* unmute dac channels */ 410 /* unmute dac channels */
527 codec->write(codec, AD1938_DAC_CHNL_MUTE, 0x0); 411 snd_soc_write(codec, AD1938_DAC_CHNL_MUTE, 0x0);
528 /* de-emphasis: 48kHz, powedown dac */ 412 /* de-emphasis: 48kHz, powedown dac */
529 codec->write(codec, AD1938_DAC_CTRL2, 0x1A); 413 snd_soc_write(codec, AD1938_DAC_CTRL2, 0x1A);
530 /* powerdown dac, dac in tdm mode */ 414 /* powerdown dac, dac in tdm mode */
531 codec->write(codec, AD1938_DAC_CTRL0, 0x41); 415 snd_soc_write(codec, AD1938_DAC_CTRL0, 0x41);
532 /* high-pass filter enable */ 416 /* high-pass filter enable */
533 codec->write(codec, AD1938_ADC_CTRL0, 0x3); 417 snd_soc_write(codec, AD1938_ADC_CTRL0, 0x3);
534 /* sata delay=1, adc aux mode */ 418 /* sata delay=1, adc aux mode */
535 codec->write(codec, AD1938_ADC_CTRL1, 0x43); 419 snd_soc_write(codec, AD1938_ADC_CTRL1, 0x43);
536 /* pll input: mclki/xi */ 420 /* pll input: mclki/xi */
537 codec->write(codec, AD1938_PLL_CLK_CTRL0, 0x9D); 421 snd_soc_write(codec, AD1938_PLL_CLK_CTRL0, 0x9D);
538 codec->write(codec, AD1938_PLL_CLK_CTRL1, 0x04); 422 snd_soc_write(codec, AD1938_PLL_CLK_CTRL1, 0x04);
539
540 ad1938_fill_cache(codec);
541 423
542 ret = snd_soc_register_codec(codec); 424 ret = snd_soc_register_codec(codec);
543 if (ret != 0) { 425 if (ret != 0) {
@@ -559,7 +441,6 @@ static int ad1938_register(struct ad1938_priv *ad1938)
559 441
560static void ad1938_unregister(struct ad1938_priv *ad1938) 442static void ad1938_unregister(struct ad1938_priv *ad1938)
561{ 443{
562 ad1938_set_bias_level(&ad1938->codec, SND_SOC_BIAS_OFF);
563 snd_soc_unregister_dai(&ad1938_dai); 444 snd_soc_unregister_dai(&ad1938_dai);
564 snd_soc_unregister_codec(&ad1938->codec); 445 snd_soc_unregister_codec(&ad1938->codec);
565 kfree(ad1938); 446 kfree(ad1938);
@@ -593,7 +474,6 @@ static int ad1938_probe(struct platform_device *pdev)
593 ARRAY_SIZE(ad1938_dapm_widgets)); 474 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 475 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 476
596 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
597 477
598pcm_err: 478pcm_err:
599 return ret; 479 return ret;
@@ -610,37 +490,9 @@ static int ad1938_remove(struct platform_device *pdev)
610 return 0; 490 return 0;
611} 491}
612 492
613#ifdef CONFIG_PM
614static int ad1938_suspend(struct platform_device *pdev,
615 pm_message_t state)
616{
617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
618 struct snd_soc_codec *codec = socdev->card->codec;
619
620 ad1938_set_bias_level(codec, SND_SOC_BIAS_OFF);
621 return 0;
622}
623
624static int ad1938_resume(struct platform_device *pdev)
625{
626 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
627 struct snd_soc_codec *codec = socdev->card->codec;
628
629 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
630 ad1938_set_bias_level(codec, SND_SOC_BIAS_ON);
631
632 return 0;
633}
634#else
635#define ad1938_suspend NULL
636#define ad1938_resume NULL
637#endif
638
639struct snd_soc_codec_device soc_codec_dev_ad1938 = { 493struct snd_soc_codec_device soc_codec_dev_ad1938 = {
640 .probe = ad1938_probe, 494 .probe = ad1938_probe,
641 .remove = ad1938_remove, 495 .remove = ad1938_remove,
642 .suspend = ad1938_suspend,
643 .resume = ad1938_resume,
644}; 496};
645EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938); 497EXPORT_SYMBOL_GPL(soc_codec_dev_ad1938);
646 498
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 3a14c6fc4f5e..b68d99fb6af0 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -90,12 +90,10 @@ static int ak4104_spi_write(struct snd_soc_codec *codec, unsigned int reg,
90 if (reg >= codec->reg_cache_size) 90 if (reg >= codec->reg_cache_size)
91 return -EINVAL; 91 return -EINVAL;
92 92
93 reg &= AK4104_REG_MASK;
94 reg |= AK4104_WRITE;
95
96 /* only write to the hardware if value has changed */ 93 /* only write to the hardware if value has changed */
97 if (cache[reg] != value) { 94 if (cache[reg] != value) {
98 u8 tmp[2] = { reg, value }; 95 u8 tmp[2] = { (reg & AK4104_REG_MASK) | AK4104_WRITE, value };
96
99 if (spi_write(spi, tmp, sizeof(tmp))) { 97 if (spi_write(spi, tmp, sizeof(tmp))) {
100 dev_err(&spi->dev, "SPI write failed\n"); 98 dev_err(&spi->dev, "SPI write failed\n");
101 return -EIO; 99 return -EIO;
@@ -185,9 +183,7 @@ struct snd_soc_dai ak4104_dai = {
185 .stream_name = "Playback", 183 .stream_name = "Playback",
186 .channels_min = 2, 184 .channels_min = 2,
187 .channels_max = 2, 185 .channels_max = 2,
188 .rates = SNDRV_PCM_RATE_44100 | 186 .rates = SNDRV_PCM_RATE_8000_192000,
189 SNDRV_PCM_RATE_48000 |
190 SNDRV_PCM_RATE_32000,
191 .formats = SNDRV_PCM_FMTBIT_S16_LE | 187 .formats = SNDRV_PCM_FMTBIT_S16_LE |
192 SNDRV_PCM_FMTBIT_S24_3LE | 188 SNDRV_PCM_FMTBIT_S24_3LE |
193 SNDRV_PCM_FMTBIT_S24_LE 189 SNDRV_PCM_FMTBIT_S24_LE
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ffe122d1cd76..dfbeb2db61b3 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -28,6 +28,7 @@
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <linux/regulator/consumer.h>
31 32
32#include "cs4270.h" 33#include "cs4270.h"
33 34
@@ -106,6 +107,10 @@
106#define CS4270_MUTE_DAC_A 0x01 107#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 108#define CS4270_MUTE_DAC_B 0x02
108 109
110static const char *supply_names[] = {
111 "va", "vd", "vlc"
112};
113
109/* Private data for the CS4270 */ 114/* Private data for the CS4270 */
110struct cs4270_private { 115struct cs4270_private {
111 struct snd_soc_codec codec; 116 struct snd_soc_codec codec;
@@ -114,6 +119,9 @@ struct cs4270_private {
114 unsigned int mode; /* The mode (I2S or left-justified) */ 119 unsigned int mode; /* The mode (I2S or left-justified) */
115 unsigned int slave_mode; 120 unsigned int slave_mode;
116 unsigned int manual_mute; 121 unsigned int manual_mute;
122
123 /* power domain regulators */
124 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
117}; 125};
118 126
119/** 127/**
@@ -192,6 +200,11 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
192 * This function must be called by the machine driver's 'startup' function, 200 * This function must be called by the machine driver's 'startup' function,
193 * otherwise the list of supported sample rates will not be available in 201 * otherwise the list of supported sample rates will not be available in
194 * time for ALSA. 202 * time for ALSA.
203 *
204 * For setups with variable MCLKs, pass 0 as 'freq' argument. This will cause
205 * theoretically possible sample rates to be enabled. Call it again with a
206 * proper value set one the external clock is set (most probably you would do
207 * that from a machine's driver 'hw_param' hook.
195 */ 208 */
196static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai, 209static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
197 int clk_id, unsigned int freq, int dir) 210 int clk_id, unsigned int freq, int dir)
@@ -205,20 +218,27 @@ static int cs4270_set_dai_sysclk(struct snd_soc_dai *codec_dai,
205 218
206 cs4270->mclk = freq; 219 cs4270->mclk = freq;
207 220
208 for (i = 0; i < NUM_MCLK_RATIOS; i++) { 221 if (cs4270->mclk) {
209 unsigned int rate = freq / cs4270_mode_ratios[i].ratio; 222 for (i = 0; i < NUM_MCLK_RATIOS; i++) {
210 rates |= snd_pcm_rate_to_rate_bit(rate); 223 unsigned int rate = freq / cs4270_mode_ratios[i].ratio;
211 if (rate < rate_min) 224 rates |= snd_pcm_rate_to_rate_bit(rate);
212 rate_min = rate; 225 if (rate < rate_min)
213 if (rate > rate_max) 226 rate_min = rate;
214 rate_max = rate; 227 if (rate > rate_max)
215 } 228 rate_max = rate;
216 /* FIXME: soc should support a rate list */ 229 }
217 rates &= ~SNDRV_PCM_RATE_KNOT; 230 /* FIXME: soc should support a rate list */
231 rates &= ~SNDRV_PCM_RATE_KNOT;
218 232
219 if (!rates) { 233 if (!rates) {
220 dev_err(codec->dev, "could not find a valid sample rate\n"); 234 dev_err(codec->dev, "could not find a valid sample rate\n");
221 return -EINVAL; 235 return -EINVAL;
236 }
237 } else {
238 /* enable all possible rates */
239 rates = SNDRV_PCM_RATE_8000_192000;
240 rate_min = 8000;
241 rate_max = 192000;
222 } 242 }
223 243
224 codec_dai->playback.rates = rates; 244 codec_dai->playback.rates = rates;
@@ -579,7 +599,8 @@ static int cs4270_probe(struct platform_device *pdev)
579{ 599{
580 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 600 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
581 struct snd_soc_codec *codec = cs4270_codec; 601 struct snd_soc_codec *codec = cs4270_codec;
582 int ret; 602 struct cs4270_private *cs4270 = codec->private_data;
603 int i, ret;
583 604
584 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */ 605 /* Connect the codec to the socdev. snd_soc_new_pcms() needs this. */
585 socdev->card->codec = codec; 606 socdev->card->codec = codec;
@@ -599,8 +620,26 @@ static int cs4270_probe(struct platform_device *pdev)
599 goto error_free_pcms; 620 goto error_free_pcms;
600 } 621 }
601 622
623 /* get the power supply regulators */
624 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
625 cs4270->supplies[i].supply = supply_names[i];
626
627 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(cs4270->supplies),
628 cs4270->supplies);
629 if (ret < 0)
630 goto error_free_pcms;
631
632 ret = regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
633 cs4270->supplies);
634 if (ret < 0)
635 goto error_free_regulators;
636
602 return 0; 637 return 0;
603 638
639error_free_regulators:
640 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies),
641 cs4270->supplies);
642
604error_free_pcms: 643error_free_pcms:
605 snd_soc_free_pcms(socdev); 644 snd_soc_free_pcms(socdev);
606 645
@@ -616,8 +655,12 @@ error_free_pcms:
616static int cs4270_remove(struct platform_device *pdev) 655static int cs4270_remove(struct platform_device *pdev)
617{ 656{
618 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 657 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
658 struct snd_soc_codec *codec = cs4270_codec;
659 struct cs4270_private *cs4270 = codec->private_data;
619 660
620 snd_soc_free_pcms(socdev); 661 snd_soc_free_pcms(socdev);
662 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
663 regulator_bulk_free(ARRAY_SIZE(cs4270->supplies), cs4270->supplies);
621 664
622 return 0; 665 return 0;
623}; 666};
@@ -799,17 +842,33 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 842static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
800{ 843{
801 struct snd_soc_codec *codec = cs4270_codec; 844 struct snd_soc_codec *codec = cs4270_codec;
802 int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; 845 struct cs4270_private *cs4270 = codec->private_data;
846 int reg, ret;
803 847
804 return snd_soc_write(codec, CS4270_PWRCTL, reg); 848 reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL;
849 if (reg < 0)
850 return reg;
851
852 ret = snd_soc_write(codec, CS4270_PWRCTL, reg);
853 if (ret < 0)
854 return ret;
855
856 regulator_bulk_disable(ARRAY_SIZE(cs4270->supplies),
857 cs4270->supplies);
858
859 return 0;
805} 860}
806 861
807static int cs4270_soc_resume(struct platform_device *pdev) 862static int cs4270_soc_resume(struct platform_device *pdev)
808{ 863{
809 struct snd_soc_codec *codec = cs4270_codec; 864 struct snd_soc_codec *codec = cs4270_codec;
865 struct cs4270_private *cs4270 = codec->private_data;
810 struct i2c_client *i2c_client = codec->control_data; 866 struct i2c_client *i2c_client = codec->control_data;
811 int reg; 867 int reg;
812 868
869 regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies),
870 cs4270->supplies);
871
813 /* In case the device was put to hard reset during sleep, we need to 872 /* In case the device was put to hard reset during sleep, we need to
814 * wait 500ns here before any I2C communication. */ 873 * wait 500ns here before any I2C communication. */
815 ndelay(500); 874 ndelay(500);
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
new file mode 100644
index 000000000000..cf2975a7294a
--- /dev/null
+++ b/sound/soc/codecs/da7210.c
@@ -0,0 +1,589 @@
1/*
2 * DA7210 ALSA Soc codec driver
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * Tested on SuperH Ecovec24 board with S16/S24 LE in 48KHz using I2S
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/kernel.h>
21#include <linux/init.h>
22#include <linux/delay.h>
23#include <linux/pm.h>
24#include <linux/i2c.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32#include <sound/initval.h>
33#include <asm/div64.h>
34
35#include "da7210.h"
36
37/* DA7210 register space */
38#define DA7210_STATUS 0x02
39#define DA7210_STARTUP1 0x03
40#define DA7210_MIC_L 0x07
41#define DA7210_MIC_R 0x08
42#define DA7210_INMIX_L 0x0D
43#define DA7210_INMIX_R 0x0E
44#define DA7210_ADC_HPF 0x0F
45#define DA7210_ADC 0x10
46#define DA7210_DAC_HPF 0x14
47#define DA7210_DAC_L 0x15
48#define DA7210_DAC_R 0x16
49#define DA7210_DAC_SEL 0x17
50#define DA7210_OUTMIX_L 0x1C
51#define DA7210_OUTMIX_R 0x1D
52#define DA7210_HP_L_VOL 0x21
53#define DA7210_HP_R_VOL 0x22
54#define DA7210_HP_CFG 0x23
55#define DA7210_DAI_SRC_SEL 0x25
56#define DA7210_DAI_CFG1 0x26
57#define DA7210_DAI_CFG3 0x28
58#define DA7210_PLL_DIV3 0x2B
59#define DA7210_PLL 0x2C
60
61/* STARTUP1 bit fields */
62#define DA7210_SC_MST_EN (1 << 0)
63
64/* MIC_L bit fields */
65#define DA7210_MICBIAS_EN (1 << 6)
66#define DA7210_MIC_L_EN (1 << 7)
67
68/* MIC_R bit fields */
69#define DA7210_MIC_R_EN (1 << 7)
70
71/* INMIX_L bit fields */
72#define DA7210_IN_L_EN (1 << 7)
73
74/* INMIX_R bit fields */
75#define DA7210_IN_R_EN (1 << 7)
76
77/* ADC_HPF bit fields */
78#define DA7210_ADC_VOICE_EN (1 << 7)
79
80/* ADC bit fields */
81#define DA7210_ADC_L_EN (1 << 3)
82#define DA7210_ADC_R_EN (1 << 7)
83
84/* DAC_HPF fields */
85#define DA7210_DAC_VOICE_EN (1 << 7)
86
87/* DAC_SEL bit fields */
88#define DA7210_DAC_L_SRC_DAI_L (4 << 0)
89#define DA7210_DAC_L_EN (1 << 3)
90#define DA7210_DAC_R_SRC_DAI_R (5 << 4)
91#define DA7210_DAC_R_EN (1 << 7)
92
93/* OUTMIX_L bit fields */
94#define DA7210_OUT_L_EN (1 << 7)
95
96/* OUTMIX_R bit fields */
97#define DA7210_OUT_R_EN (1 << 7)
98
99/* HP_CFG bit fields */
100#define DA7210_HP_2CAP_MODE (1 << 1)
101#define DA7210_HP_SENSE_EN (1 << 2)
102#define DA7210_HP_L_EN (1 << 3)
103#define DA7210_HP_MODE (1 << 6)
104#define DA7210_HP_R_EN (1 << 7)
105
106/* DAI_SRC_SEL bit fields */
107#define DA7210_DAI_OUT_L_SRC (6 << 0)
108#define DA7210_DAI_OUT_R_SRC (7 << 4)
109
110/* DAI_CFG1 bit fields */
111#define DA7210_DAI_WORD_S16_LE (0 << 0)
112#define DA7210_DAI_WORD_S24_LE (2 << 0)
113#define DA7210_DAI_FLEN_64BIT (1 << 2)
114#define DA7210_DAI_MODE_MASTER (1 << 7)
115
116/* DAI_CFG3 bit fields */
117#define DA7210_DAI_FORMAT_I2SMODE (0 << 0)
118#define DA7210_DAI_OE (1 << 3)
119#define DA7210_DAI_EN (1 << 7)
120
121/*PLL_DIV3 bit fields */
122#define DA7210_MCLK_RANGE_10_20_MHZ (1 << 4)
123#define DA7210_PLL_BYP (1 << 6)
124
125/* PLL bit fields */
126#define DA7210_PLL_FS_48000 (11 << 0)
127
128#define DA7210_VERSION "0.0.1"
129
130/* Codec private data */
131struct da7210_priv {
132 struct snd_soc_codec codec;
133};
134
135static struct snd_soc_codec *da7210_codec;
136
137/*
138 * Register cache
139 */
140static const u8 da7210_reg[] = {
141 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R0 - R7 */
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, /* R8 - RF */
143 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x54, /* R10 - R17 */
144 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R18 - R1F */
145 0x00, 0x00, 0x00, 0x02, 0x00, 0x76, 0x00, 0x00, /* R20 - R27 */
146 0x04, 0x00, 0x00, 0x30, 0x2A, 0x00, 0x40, 0x00, /* R28 - R2F */
147 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, /* R30 - R37 */
148 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* R38 - R3F */
149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R40 - R4F */
150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R48 - R4F */
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R50 - R57 */
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R58 - R5F */
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R60 - R67 */
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R68 - R6F */
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* R70 - R77 */
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x00, /* R78 - R7F */
157 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, /* R80 - R87 */
158 0x00, /* R88 */
159};
160
161/*
162 * Read da7210 register cache
163 */
164static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg)
165{
166 u8 *cache = codec->reg_cache;
167 BUG_ON(reg > ARRAY_SIZE(da7210_reg));
168 return cache[reg];
169}
170
171/*
172 * Write to the da7210 register space
173 */
174static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value)
175{
176 u8 *cache = codec->reg_cache;
177 u8 data[2];
178
179 BUG_ON(codec->volatile_register);
180
181 data[0] = reg & 0xff;
182 data[1] = value & 0xff;
183
184 if (reg >= codec->reg_cache_size)
185 return -EIO;
186
187 if (2 != codec->hw_write(codec->control_data, data, 2))
188 return -EIO;
189
190 cache[reg] = value;
191 return 0;
192}
193
194/*
195 * Read from the da7210 register space.
196 */
197static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg)
198{
199 if (DA7210_STATUS == reg)
200 return i2c_smbus_read_byte_data(codec->control_data, reg);
201
202 return da7210_read_reg_cache(codec, reg);
203}
204
205static int da7210_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
209 struct snd_soc_codec *codec = dai->codec;
210
211 if (is_play) {
212 /* PlayBack Volume 40 */
213 snd_soc_update_bits(codec, DA7210_HP_L_VOL, 0x3F, 40);
214 snd_soc_update_bits(codec, DA7210_HP_R_VOL, 0x3F, 40);
215
216 /* Enable Out */
217 snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10);
218 snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10);
219
220 } else {
221 /* Volume 7 */
222 snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7);
223 snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7);
224
225 /* Enable Mic */
226 snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1);
227 snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1);
228 }
229
230 return 0;
231}
232
233/*
234 * Set PCM DAI word length.
235 */
236static int da7210_hw_params(struct snd_pcm_substream *substream,
237 struct snd_pcm_hw_params *params,
238 struct snd_soc_dai *dai)
239{
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct snd_soc_device *socdev = rtd->socdev;
242 struct snd_soc_codec *codec = socdev->card->codec;
243 u32 dai_cfg1;
244 u32 reg, mask;
245
246 /* set DAI source to Left and Right ADC */
247 da7210_write(codec, DA7210_DAI_SRC_SEL,
248 DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC);
249
250 /* Enable DAI */
251 da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN);
252
253 dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1);
254
255 switch (params_format(params)) {
256 case SNDRV_PCM_FORMAT_S16_LE:
257 dai_cfg1 |= DA7210_DAI_WORD_S16_LE;
258 break;
259 case SNDRV_PCM_FORMAT_S24_LE:
260 dai_cfg1 |= DA7210_DAI_WORD_S24_LE;
261 break;
262 default:
263 return -EINVAL;
264 }
265
266 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
267
268 /* FIXME
269 *
270 * It support 48K only now
271 */
272 switch (params_rate(params)) {
273 case 48000:
274 if (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) {
275 reg = DA7210_DAC_HPF;
276 mask = DA7210_DAC_VOICE_EN;
277 } else {
278 reg = DA7210_ADC_HPF;
279 mask = DA7210_ADC_VOICE_EN;
280 }
281 break;
282 default:
283 return -EINVAL;
284 }
285
286 snd_soc_update_bits(codec, reg, mask, 0);
287
288 return 0;
289}
290
291/*
292 * Set DAI mode and Format
293 */
294static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 u32 dai_cfg1;
298 u32 dai_cfg3;
299
300 dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1);
301 dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3);
302
303 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
304 case SND_SOC_DAIFMT_CBM_CFM:
305 dai_cfg1 |= DA7210_DAI_MODE_MASTER;
306 break;
307 default:
308 return -EINVAL;
309 }
310
311 /* FIXME
312 *
313 * It support I2S only now
314 */
315 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
316 case SND_SOC_DAIFMT_I2S:
317 dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE;
318 break;
319 default:
320 return -EINVAL;
321 }
322
323 /* FIXME
324 *
325 * It support 64bit data transmission only now
326 */
327 dai_cfg1 |= DA7210_DAI_FLEN_64BIT;
328
329 da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1);
330 da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3);
331
332 return 0;
333}
334
335#define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)
336
337/* DAI operations */
338static struct snd_soc_dai_ops da7210_dai_ops = {
339 .startup = da7210_startup,
340 .hw_params = da7210_hw_params,
341 .set_fmt = da7210_set_dai_fmt,
342};
343
344struct snd_soc_dai da7210_dai = {
345 .name = "DA7210 IIS",
346 .id = 0,
347 /* playback capabilities */
348 .playback = {
349 .stream_name = "Playback",
350 .channels_min = 1,
351 .channels_max = 2,
352 .rates = SNDRV_PCM_RATE_8000_96000,
353 .formats = DA7210_FORMATS,
354 },
355 /* capture capabilities */
356 .capture = {
357 .stream_name = "Capture",
358 .channels_min = 1,
359 .channels_max = 2,
360 .rates = SNDRV_PCM_RATE_8000_96000,
361 .formats = DA7210_FORMATS,
362 },
363 .ops = &da7210_dai_ops,
364};
365EXPORT_SYMBOL_GPL(da7210_dai);
366
367/*
368 * Initialize the DA7210 driver
369 * register the mixer and dsp interfaces with the kernel
370 */
371static int da7210_init(struct da7210_priv *da7210)
372{
373 struct snd_soc_codec *codec = &da7210->codec;
374 int ret = 0;
375
376 if (da7210_codec) {
377 dev_err(codec->dev, "Another da7210 is registered\n");
378 return -EINVAL;
379 }
380
381 mutex_init(&codec->mutex);
382 INIT_LIST_HEAD(&codec->dapm_widgets);
383 INIT_LIST_HEAD(&codec->dapm_paths);
384
385 codec->private_data = da7210;
386 codec->name = "DA7210";
387 codec->owner = THIS_MODULE;
388 codec->read = da7210_read;
389 codec->write = da7210_write;
390 codec->dai = &da7210_dai;
391 codec->num_dai = 1;
392 codec->hw_write = (hw_write_t)i2c_master_send;
393 codec->reg_cache_size = ARRAY_SIZE(da7210_reg);
394 codec->reg_cache = kmemdup(da7210_reg,
395 sizeof(da7210_reg), GFP_KERNEL);
396
397 if (!codec->reg_cache)
398 return -ENOMEM;
399
400 da7210_dai.dev = codec->dev;
401 da7210_codec = codec;
402
403 ret = snd_soc_register_codec(codec);
404 if (ret) {
405 dev_err(codec->dev, "Failed to register CODEC: %d\n", ret);
406 goto init_err;
407 }
408
409 ret = snd_soc_register_dai(&da7210_dai);
410 if (ret) {
411 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
412 goto init_err;
413 }
414
415 /* FIXME
416 *
417 * This driver use fixed value here
418 */
419
420 /*
421 * ADC settings
422 */
423
424 /* Enable Left & Right MIC PGA and Mic Bias */
425 da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN);
426 da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN);
427
428 /* Enable Left and Right input PGA */
429 da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN);
430 da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN);
431
432 /* Enable Left and Right ADC */
433 da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN);
434
435 /*
436 * DAC settings
437 */
438
439 /* Enable Left and Right DAC */
440 da7210_write(codec, DA7210_DAC_SEL,
441 DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN |
442 DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN);
443
444 /* Enable Left and Right out PGA */
445 da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN);
446 da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN);
447
448 /* Enable Left and Right HeadPhone PGA */
449 da7210_write(codec, DA7210_HP_CFG,
450 DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN |
451 DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN);
452
453 /* Diable PLL and bypass it */
454 da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000);
455
456 /* Bypass PLL and set MCLK freq rang to 10-20MHz */
457 da7210_write(codec, DA7210_PLL_DIV3,
458 DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP);
459
460 /* Activate all enabled subsystem */
461 da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN);
462
463 return ret;
464
465init_err:
466 kfree(codec->reg_cache);
467 codec->reg_cache = NULL;
468
469 return ret;
470
471}
472
473#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
474static int __devinit da7210_i2c_probe(struct i2c_client *i2c,
475 const struct i2c_device_id *id)
476{
477 struct da7210_priv *da7210;
478 struct snd_soc_codec *codec;
479 int ret;
480
481 da7210 = kzalloc(sizeof(struct da7210_priv), GFP_KERNEL);
482 if (!da7210)
483 return -ENOMEM;
484
485 codec = &da7210->codec;
486 codec->dev = &i2c->dev;
487
488 i2c_set_clientdata(i2c, da7210);
489 codec->control_data = i2c;
490
491 ret = da7210_init(da7210);
492 if (ret < 0)
493 pr_err("Failed to initialise da7210 audio codec\n");
494
495 return ret;
496}
497
498static int __devexit da7210_i2c_remove(struct i2c_client *client)
499{
500 struct da7210_priv *da7210 = i2c_get_clientdata(client);
501
502 snd_soc_unregister_dai(&da7210_dai);
503 kfree(da7210->codec.reg_cache);
504 kfree(da7210);
505 da7210_codec = NULL;
506
507 return 0;
508}
509
510static const struct i2c_device_id da7210_i2c_id[] = {
511 { "da7210", 0 },
512 { }
513};
514MODULE_DEVICE_TABLE(i2c, da7210_i2c_id);
515
516/* I2C codec control layer */
517static struct i2c_driver da7210_i2c_driver = {
518 .driver = {
519 .name = "DA7210 I2C Codec",
520 .owner = THIS_MODULE,
521 },
522 .probe = da7210_i2c_probe,
523 .remove = __devexit_p(da7210_i2c_remove),
524 .id_table = da7210_i2c_id,
525};
526#endif
527
528static int da7210_probe(struct platform_device *pdev)
529{
530 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
531 struct snd_soc_codec *codec;
532 int ret;
533
534 if (!da7210_codec) {
535 dev_err(&pdev->dev, "Codec device not registered\n");
536 return -ENODEV;
537 }
538
539 socdev->card->codec = da7210_codec;
540 codec = da7210_codec;
541
542 /* Register pcms */
543 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
544 if (ret < 0)
545 goto pcm_err;
546
547 dev_info(&pdev->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION);
548
549pcm_err:
550 return ret;
551}
552
553static int da7210_remove(struct platform_device *pdev)
554{
555 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
556
557 snd_soc_free_pcms(socdev);
558 snd_soc_dapm_free(socdev);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_da7210 = {
564 .probe = da7210_probe,
565 .remove = da7210_remove,
566};
567EXPORT_SYMBOL_GPL(soc_codec_dev_da7210);
568
569static int __init da7210_modinit(void)
570{
571 int ret = 0;
572#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
573 ret = i2c_add_driver(&da7210_i2c_driver);
574#endif
575 return ret;
576}
577module_init(da7210_modinit);
578
579static void __exit da7210_exit(void)
580{
581#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
582 i2c_del_driver(&da7210_i2c_driver);
583#endif
584}
585module_exit(da7210_exit);
586
587MODULE_DESCRIPTION("ASoC DA7210 driver");
588MODULE_AUTHOR("David Chen, Kuninori Morimoto");
589MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da7210.h b/sound/soc/codecs/da7210.h
new file mode 100644
index 000000000000..390d621eb742
--- /dev/null
+++ b/sound/soc/codecs/da7210.h
@@ -0,0 +1,24 @@
1/*
2 * da7210.h -- audio driver for da7210
3 *
4 * Copyright (c) 2009 Dialog Semiconductor
5 * Written by David Chen <Dajun.chen@diasemi.com>
6 *
7 * Copyright (C) 2009 Renesas Solutions Corp.
8 * Cleanups by Kuninori Morimoto <morimoto.kuninori@renesas.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 *
15 */
16
17#ifndef _DA7210_H
18#define _DA7210_H
19
20extern struct snd_soc_dai da7210_dai;
21extern struct snd_soc_codec_device soc_codec_dev_da7210;
22
23#endif
24
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 2b4dc2b0b017..e4b946a19ea3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -765,9 +765,10 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
765 struct snd_soc_codec *codec = socdev->card->codec; 765 struct snd_soc_codec *codec = socdev->card->codec;
766 struct aic3x_priv *aic3x = codec->private_data; 766 struct aic3x_priv *aic3x = codec->private_data;
767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0; 767 int codec_clk = 0, bypass_pll = 0, fsref, last_clk = 0;
768 u8 data, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1; 768 u8 data, j, r, p, pll_q, pll_p = 1, pll_r = 1, pll_j = 1;
769 u16 pll_d = 1; 769 u16 d, pll_d = 1;
770 u8 reg; 770 u8 reg;
771 int clk;
771 772
772 /* select data word length */ 773 /* select data word length */
773 data = 774 data =
@@ -833,48 +834,70 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream,
833 if (bypass_pll) 834 if (bypass_pll)
834 return 0; 835 return 0;
835 836
836 /* Use PLL 837 /* Use PLL, compute apropriate setup for j, d, r and p, the closest
837 * find an apropriate setup for j, d, r and p by iterating over 838 * one wins the game. Try with d==0 first, next with d!=0.
838 * p and r - j and d are calculated for each fraction. 839 * Constraints for j are according to the datasheet.
839 * Up to 128 values are probed, the closest one wins the game.
840 * The sysclk is divided by 1000 to prevent integer overflows. 840 * The sysclk is divided by 1000 to prevent integer overflows.
841 */ 841 */
842
842 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000); 843 codec_clk = (2048 * fsref) / (aic3x->sysclk / 1000);
843 844
844 for (r = 1; r <= 16; r++) 845 for (r = 1; r <= 16; r++)
845 for (p = 1; p <= 8; p++) { 846 for (p = 1; p <= 8; p++) {
846 int clk, tmp = (codec_clk * pll_r * 10) / pll_p; 847 for (j = 4; j <= 55; j++) {
847 u8 j = tmp / 10000; 848 /* This is actually 1000*((j+(d/10000))*r)/p
848 u16 d = tmp % 10000; 849 * The term had to be converted to get
850 * rid of the division by 10000; d = 0 here
851 */
852 int tmp_clk = (1000 * j * r) / p;
853
854 /* Check whether this values get closer than
855 * the best ones we had before
856 */
857 if (abs(codec_clk - tmp_clk) <
858 abs(codec_clk - last_clk)) {
859 pll_j = j; pll_d = 0;
860 pll_r = r; pll_p = p;
861 last_clk = tmp_clk;
862 }
863
864 /* Early exit for exact matches */
865 if (tmp_clk == codec_clk)
866 goto found;
867 }
868 }
849 869
850 if (j > 63) 870 /* try with d != 0 */
851 continue; 871 for (p = 1; p <= 8; p++) {
872 j = codec_clk * p / 1000;
852 873
853 if (d != 0 && aic3x->sysclk < 10000000) 874 if (j < 4 || j > 11)
854 continue; 875 continue;
855 876
856 /* This is actually 1000 * ((j + (d/10000)) * r) / p 877 /* do not use codec_clk here since we'd loose precision */
857 * The term had to be converted to get rid of the 878 d = ((2048 * p * fsref) - j * aic3x->sysclk)
858 * division by 10000 */ 879 * 100 / (aic3x->sysclk/100);
859 clk = ((10000 * j * r) + (d * r)) / (10 * p);
860 880
861 /* check whether this values get closer than the best 881 clk = (10000 * j + d) / (10 * p);
862 * ones we had before */
863 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
864 pll_j = j; pll_d = d; pll_r = r; pll_p = p;
865 last_clk = clk;
866 }
867 882
868 /* Early exit for exact matches */ 883 /* check whether this values get closer than the best
869 if (clk == codec_clk) 884 * ones we had before */
870 break; 885 if (abs(codec_clk - clk) < abs(codec_clk - last_clk)) {
886 pll_j = j; pll_d = d; pll_r = 1; pll_p = p;
887 last_clk = clk;
871 } 888 }
872 889
890 /* Early exit for exact matches */
891 if (clk == codec_clk)
892 goto found;
893 }
894
873 if (last_clk == 0) { 895 if (last_clk == 0) {
874 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__); 896 printk(KERN_ERR "%s(): unable to setup PLL\n", __func__);
875 return -EINVAL; 897 return -EINVAL;
876 } 898 }
877 899
900found:
878 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG); 901 data = aic3x_read_reg_cache(codec, AIC3X_PLL_PROGA_REG);
879 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT)); 902 aic3x_write(codec, AIC3X_PLL_PROGA_REG, data | (pll_p << PLLP_SHIFT));
880 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT); 903 aic3x_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, pll_r << PLLR_SHIFT);
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index 9c8903dbe647..f9f367d29a90 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -30,6 +30,7 @@
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/gpio.h> 32#include <linux/gpio.h>
33#include <linux/regulator/consumer.h>
33#include <sound/core.h> 34#include <sound/core.h>
34#include <sound/pcm.h> 35#include <sound/pcm.h>
35#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
@@ -58,11 +59,26 @@ enum dac33_state {
58 DAC33_FLUSH, 59 DAC33_FLUSH,
59}; 60};
60 61
62enum dac33_fifo_modes {
63 DAC33_FIFO_BYPASS = 0,
64 DAC33_FIFO_MODE1,
65 DAC33_FIFO_MODE7,
66 DAC33_FIFO_LAST_MODE,
67};
68
69#define DAC33_NUM_SUPPLIES 3
70static const char *dac33_supply_names[DAC33_NUM_SUPPLIES] = {
71 "AVDD",
72 "DVDD",
73 "IOVDD",
74};
75
61struct tlv320dac33_priv { 76struct tlv320dac33_priv {
62 struct mutex mutex; 77 struct mutex mutex;
63 struct workqueue_struct *dac33_wq; 78 struct workqueue_struct *dac33_wq;
64 struct work_struct work; 79 struct work_struct work;
65 struct snd_soc_codec codec; 80 struct snd_soc_codec codec;
81 struct regulator_bulk_data supplies[DAC33_NUM_SUPPLIES];
66 int power_gpio; 82 int power_gpio;
67 int chip_power; 83 int chip_power;
68 int irq; 84 int irq;
@@ -73,8 +89,9 @@ struct tlv320dac33_priv {
73 * this */ 89 * this */
74 unsigned int nsample_max; /* nsample should not be higher than 90 unsigned int nsample_max; /* nsample should not be higher than
75 * this */ 91 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */ 92 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
77 unsigned int nsample; /* burst read amount from host */ 93 unsigned int nsample; /* burst read amount from host */
94 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
78 95
79 enum dac33_state state; 96 enum dac33_state state;
80}; 97};
@@ -297,28 +314,49 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
297 dac33_write(codec, DAC33_PWR_CTRL, reg); 314 dac33_write(codec, DAC33_PWR_CTRL, reg);
298} 315}
299 316
300static void dac33_hard_power(struct snd_soc_codec *codec, int power) 317static int dac33_hard_power(struct snd_soc_codec *codec, int power)
301{ 318{
302 struct tlv320dac33_priv *dac33 = codec->private_data; 319 struct tlv320dac33_priv *dac33 = codec->private_data;
320 int ret;
303 321
304 mutex_lock(&dac33->mutex); 322 mutex_lock(&dac33->mutex);
305 if (power) { 323 if (power) {
306 if (dac33->power_gpio >= 0) { 324 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
307 gpio_set_value(dac33->power_gpio, 1); 325 dac33->supplies);
308 dac33->chip_power = 1; 326 if (ret != 0) {
309 /* Restore registers */ 327 dev_err(codec->dev,
310 dac33_restore_regs(codec); 328 "Failed to enable supplies: %d\n", ret);
329 goto exit;
311 } 330 }
331
332 if (dac33->power_gpio >= 0)
333 gpio_set_value(dac33->power_gpio, 1);
334
335 dac33->chip_power = 1;
336
337 /* Restore registers */
338 dac33_restore_regs(codec);
339
312 dac33_soft_power(codec, 1); 340 dac33_soft_power(codec, 1);
313 } else { 341 } else {
314 dac33_soft_power(codec, 0); 342 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) { 343 if (dac33->power_gpio >= 0)
316 gpio_set_value(dac33->power_gpio, 0); 344 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0; 345
346 ret = regulator_bulk_disable(ARRAY_SIZE(dac33->supplies),
347 dac33->supplies);
348 if (ret != 0) {
349 dev_err(codec->dev,
350 "Failed to disable supplies: %d\n", ret);
351 goto exit;
318 } 352 }
353
354 dac33->chip_power = 0;
319 } 355 }
320 mutex_unlock(&dac33->mutex);
321 356
357exit:
358 mutex_unlock(&dac33->mutex);
359 return ret;
322} 360}
323 361
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol, 362static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
@@ -351,39 +389,48 @@ static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
351 return ret; 389 return ret;
352} 390}
353 391
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol, 392static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol) 393 struct snd_ctl_elem_value *ucontrol)
356{ 394{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 395 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data; 396 struct tlv320dac33_priv *dac33 = codec->private_data;
359 397
360 ucontrol->value.integer.value[0] = dac33->nsample_switch; 398 ucontrol->value.integer.value[0] = dac33->fifo_mode;
361 399
362 return 0; 400 return 0;
363} 401}
364 402
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol, 403static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol) 404 struct snd_ctl_elem_value *ucontrol)
367{ 405{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 406 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data; 407 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0; 408 int ret = 0;
371 409
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0]) 410 if (dac33->fifo_mode == ucontrol->value.integer.value[0])
373 return 0; 411 return 0;
374 /* Do not allow changes while stream is running*/ 412 /* Do not allow changes while stream is running*/
375 if (codec->active) 413 if (codec->active)
376 return -EPERM; 414 return -EPERM;
377 415
378 if (ucontrol->value.integer.value[0] < 0 || 416 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1) 417 ucontrol->value.integer.value[0] >= DAC33_FIFO_LAST_MODE)
380 ret = -EINVAL; 418 ret = -EINVAL;
381 else 419 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0]; 420 dac33->fifo_mode = ucontrol->value.integer.value[0];
383 421
384 return ret; 422 return ret;
385} 423}
386 424
425/* Codec operation modes */
426static const char *dac33_fifo_mode_texts[] = {
427 "Bypass", "Mode 1", "Mode 7"
428};
429
430static const struct soc_enum dac33_fifo_mode_enum =
431 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dac33_fifo_mode_texts),
432 dac33_fifo_mode_texts);
433
387/* 434/*
388 * DACL/R digital volume control: 435 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps 436 * from 0 dB to -63.5 in 0.5 dB steps
@@ -406,8 +453,8 @@ static const struct snd_kcontrol_new dac33_snd_controls[] = {
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = { 453static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, 454 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample), 455 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0, 456 SOC_ENUM_EXT("FIFO Mode", dac33_fifo_mode_enum,
410 dac33_get_nsample_switch, dac33_set_nsample_switch), 457 dac33_get_fifo_mode, dac33_set_fifo_mode),
411}; 458};
412 459
413/* Analog bypass */ 460/* Analog bypass */
@@ -469,6 +516,8 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
469static int dac33_set_bias_level(struct snd_soc_codec *codec, 516static int dac33_set_bias_level(struct snd_soc_codec *codec,
470 enum snd_soc_bias_level level) 517 enum snd_soc_bias_level level)
471{ 518{
519 int ret;
520
472 switch (level) { 521 switch (level) {
473 case SND_SOC_BIAS_ON: 522 case SND_SOC_BIAS_ON:
474 dac33_soft_power(codec, 1); 523 dac33_soft_power(codec, 1);
@@ -476,12 +525,19 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
476 case SND_SOC_BIAS_PREPARE: 525 case SND_SOC_BIAS_PREPARE:
477 break; 526 break;
478 case SND_SOC_BIAS_STANDBY: 527 case SND_SOC_BIAS_STANDBY:
479 if (codec->bias_level == SND_SOC_BIAS_OFF) 528 if (codec->bias_level == SND_SOC_BIAS_OFF) {
480 dac33_hard_power(codec, 1); 529 ret = dac33_hard_power(codec, 1);
530 if (ret != 0)
531 return ret;
532 }
533
481 dac33_soft_power(codec, 0); 534 dac33_soft_power(codec, 0);
482 break; 535 break;
483 case SND_SOC_BIAS_OFF: 536 case SND_SOC_BIAS_OFF:
484 dac33_hard_power(codec, 0); 537 ret = dac33_hard_power(codec, 0);
538 if (ret != 0)
539 return ret;
540
485 break; 541 break;
486 } 542 }
487 codec->bias_level = level; 543 codec->bias_level = level;
@@ -489,6 +545,51 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
489 return 0; 545 return 0;
490} 546}
491 547
548static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
549{
550 struct snd_soc_codec *codec;
551
552 codec = &dac33->codec;
553
554 switch (dac33->fifo_mode) {
555 case DAC33_FIFO_MODE1:
556 dac33_write16(codec, DAC33_NSAMPLE_MSB,
557 DAC33_THRREG(dac33->nsample));
558 dac33_write16(codec, DAC33_PREFILL_MSB,
559 DAC33_THRREG(dac33->alarm_threshold));
560 break;
561 case DAC33_FIFO_MODE7:
562 dac33_write16(codec, DAC33_PREFILL_MSB,
563 DAC33_THRREG(10));
564 break;
565 default:
566 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
567 dac33->fifo_mode);
568 break;
569 }
570}
571
572static inline void dac33_playback_handler(struct tlv320dac33_priv *dac33)
573{
574 struct snd_soc_codec *codec;
575
576 codec = &dac33->codec;
577
578 switch (dac33->fifo_mode) {
579 case DAC33_FIFO_MODE1:
580 dac33_write16(codec, DAC33_NSAMPLE_MSB,
581 DAC33_THRREG(dac33->nsample));
582 break;
583 case DAC33_FIFO_MODE7:
584 /* At the moment we are not using interrupts in mode7 */
585 break;
586 default:
587 dev_warn(codec->dev, "Unhandled FIFO mode: %d\n",
588 dac33->fifo_mode);
589 break;
590 }
591}
592
492static void dac33_work(struct work_struct *work) 593static void dac33_work(struct work_struct *work)
493{ 594{
494 struct snd_soc_codec *codec; 595 struct snd_soc_codec *codec;
@@ -502,14 +603,10 @@ static void dac33_work(struct work_struct *work)
502 switch (dac33->state) { 603 switch (dac33->state) {
503 case DAC33_PREFILL: 604 case DAC33_PREFILL:
504 dac33->state = DAC33_PLAYBACK; 605 dac33->state = DAC33_PLAYBACK;
505 dac33_write16(codec, DAC33_NSAMPLE_MSB, 606 dac33_prefill_handler(dac33);
506 DAC33_THRREG(dac33->nsample));
507 dac33_write16(codec, DAC33_PREFILL_MSB,
508 DAC33_THRREG(dac33->alarm_threshold));
509 break; 607 break;
510 case DAC33_PLAYBACK: 608 case DAC33_PLAYBACK:
511 dac33_write16(codec, DAC33_NSAMPLE_MSB, 609 dac33_playback_handler(dac33);
512 DAC33_THRREG(dac33->nsample));
513 break; 610 break;
514 case DAC33_IDLE: 611 case DAC33_IDLE:
515 break; 612 break;
@@ -547,7 +644,7 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
547 unsigned int pwr_ctrl; 644 unsigned int pwr_ctrl;
548 645
549 /* Stop pending workqueue */ 646 /* Stop pending workqueue */
550 if (dac33->nsample_switch) 647 if (dac33->fifo_mode)
551 cancel_work_sync(&dac33->work); 648 cancel_work_sync(&dac33->work);
552 649
553 mutex_lock(&dac33->mutex); 650 mutex_lock(&dac33->mutex);
@@ -603,7 +700,7 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
603} 700}
604 701
605#define CALC_OSCSET(rate, refclk) ( \ 702#define CALC_OSCSET(rate, refclk) ( \
606 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000) 703 ((((rate * 10000) / refclk) * 4096) + 7000) / 10000)
607#define CALC_RATIOSET(rate, refclk) ( \ 704#define CALC_RATIOSET(rate, refclk) ( \
608 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000) 705 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
609 706
@@ -619,7 +716,7 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
619 struct snd_soc_codec *codec = socdev->card->codec; 716 struct snd_soc_codec *codec = socdev->card->codec;
620 struct tlv320dac33_priv *dac33 = codec->private_data; 717 struct tlv320dac33_priv *dac33 = codec->private_data;
621 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp; 718 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
622 u8 aictrl_a, fifoctrl_a; 719 u8 aictrl_a, aictrl_b, fifoctrl_a;
623 720
624 switch (substream->runtime->rate) { 721 switch (substream->runtime->rate) {
625 case 44100: 722 case 44100:
@@ -637,7 +734,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
637 734
638 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 735 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
639 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK); 736 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
737 /* Read FIFO control A, and clear FIFO flush bit */
640 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A); 738 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
739 fifoctrl_a &= ~DAC33_FIFOFLUSH;
740
641 fifoctrl_a &= ~DAC33_WIDTH; 741 fifoctrl_a &= ~DAC33_WIDTH;
642 switch (substream->runtime->format) { 742 switch (substream->runtime->format) {
643 case SNDRV_PCM_FORMAT_S16_LE: 743 case SNDRV_PCM_FORMAT_S16_LE:
@@ -675,7 +775,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
675 775
676 dac33_oscwait(codec); 776 dac33_oscwait(codec);
677 777
678 if (dac33->nsample_switch) { 778 if (dac33->fifo_mode) {
779 /* Generic for all FIFO modes */
679 /* 50-51 : ASRC Control registers */ 780 /* 50-51 : ASRC Control registers */
680 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */ 781 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
681 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */ 782 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
@@ -685,38 +786,101 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
685 786
686 /* Set interrupts to high active */ 787 /* Set interrupts to high active */
687 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH); 788 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
688
689 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
690 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
691 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
692 } else { 789 } else {
790 /* FIFO bypass mode */
693 /* 50-51 : ASRC Control registers */ 791 /* 50-51 : ASRC Control registers */
694 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP); 792 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
695 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */ 793 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
696 } 794 }
697 795
698 if (dac33->nsample_switch) 796 /* Interrupt behaviour configuration */
797 switch (dac33->fifo_mode) {
798 case DAC33_FIFO_MODE1:
799 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
800 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
801 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
802 break;
803 case DAC33_FIFO_MODE7:
804 /* Disable all interrupts */
805 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
806 break;
807 default:
808 /* in FIFO bypass mode, the interrupts are not used */
809 break;
810 }
811
812 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
813
814 switch (dac33->fifo_mode) {
815 case DAC33_FIFO_MODE1:
816 /*
817 * For mode1:
818 * Disable the FIFO bypass (Enable the use of FIFO)
819 * Select nSample mode
820 * BCLK is only running when data is needed by DAC33
821 */
699 fifoctrl_a &= ~DAC33_FBYPAS; 822 fifoctrl_a &= ~DAC33_FBYPAS;
700 else 823 fifoctrl_a &= ~DAC33_FAUTO;
824 aictrl_b &= ~DAC33_BCLKON;
825 break;
826 case DAC33_FIFO_MODE7:
827 /*
828 * For mode1:
829 * Disable the FIFO bypass (Enable the use of FIFO)
830 * Select Threshold mode
831 * BCLK is only running when data is needed by DAC33
832 */
833 fifoctrl_a &= ~DAC33_FBYPAS;
834 fifoctrl_a |= DAC33_FAUTO;
835 aictrl_b &= ~DAC33_BCLKON;
836 break;
837 default:
838 /*
839 * For FIFO bypass mode:
840 * Enable the FIFO bypass (Disable the FIFO use)
841 * Set the BCLK as continous
842 */
701 fifoctrl_a |= DAC33_FBYPAS; 843 fifoctrl_a |= DAC33_FBYPAS;
702 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a); 844 aictrl_b |= DAC33_BCLKON;
845 break;
846 }
703 847
848 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
704 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a); 849 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
705 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B); 850 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
706 if (dac33->nsample_switch)
707 reg_tmp &= ~DAC33_BCLKON;
708 else
709 reg_tmp |= DAC33_BCLKON;
710 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
711 851
712 if (dac33->nsample_switch) { 852 /*
713 /* 20: BCLK divide ratio */ 853 * BCLK divide ratio
714 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3); 854 * 0: 1.5
855 * 1: 1
856 * 2: 2
857 * ...
858 * 254: 254
859 * 255: 255
860 */
861 if (dac33->fifo_mode)
862 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
863 dac33->burst_bclkdiv);
864 else
865 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
715 866
867 switch (dac33->fifo_mode) {
868 case DAC33_FIFO_MODE1:
716 dac33_write16(codec, DAC33_ATHR_MSB, 869 dac33_write16(codec, DAC33_ATHR_MSB,
717 DAC33_THRREG(dac33->alarm_threshold)); 870 DAC33_THRREG(dac33->alarm_threshold));
718 } else { 871 break;
719 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); 872 case DAC33_FIFO_MODE7:
873 /*
874 * Configure the threshold levels, and leave 10 sample space
875 * at the bottom, and also at the top of the FIFO
876 */
877 dac33_write16(codec, DAC33_UTHR_MSB,
878 DAC33_THRREG(DAC33_BUFFER_SIZE_SAMPLES - 10));
879 dac33_write16(codec, DAC33_LTHR_MSB,
880 DAC33_THRREG(10));
881 break;
882 default:
883 break;
720 } 884 }
721 885
722 mutex_unlock(&dac33->mutex); 886 mutex_unlock(&dac33->mutex);
@@ -789,7 +953,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
789 case SNDRV_PCM_TRIGGER_START: 953 case SNDRV_PCM_TRIGGER_START:
790 case SNDRV_PCM_TRIGGER_RESUME: 954 case SNDRV_PCM_TRIGGER_RESUME:
791 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 955 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
792 if (dac33->nsample_switch) { 956 if (dac33->fifo_mode) {
793 dac33->state = DAC33_PREFILL; 957 dac33->state = DAC33_PREFILL;
794 queue_work(dac33->dac33_wq, &dac33->work); 958 queue_work(dac33->dac33_wq, &dac33->work);
795 } 959 }
@@ -797,7 +961,7 @@ static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
797 case SNDRV_PCM_TRIGGER_STOP: 961 case SNDRV_PCM_TRIGGER_STOP:
798 case SNDRV_PCM_TRIGGER_SUSPEND: 962 case SNDRV_PCM_TRIGGER_SUSPEND:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 963 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (dac33->nsample_switch) { 964 if (dac33->fifo_mode) {
801 dac33->state = DAC33_FLUSH; 965 dac33->state = DAC33_FLUSH;
802 queue_work(dac33->dac33_wq, &dac33->work); 966 queue_work(dac33->dac33_wq, &dac33->work);
803 } 967 }
@@ -843,6 +1007,7 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
843 unsigned int fmt) 1007 unsigned int fmt)
844{ 1008{
845 struct snd_soc_codec *codec = codec_dai->codec; 1009 struct snd_soc_codec *codec = codec_dai->codec;
1010 struct tlv320dac33_priv *dac33 = codec->private_data;
846 u8 aictrl_a, aictrl_b; 1011 u8 aictrl_a, aictrl_b;
847 1012
848 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A); 1013 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
@@ -855,7 +1020,11 @@ static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
855 break; 1020 break;
856 case SND_SOC_DAIFMT_CBS_CFS: 1021 case SND_SOC_DAIFMT_CBS_CFS:
857 /* Codec Slave */ 1022 /* Codec Slave */
858 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK); 1023 if (dac33->fifo_mode) {
1024 dev_err(codec->dev, "FIFO mode requires master mode\n");
1025 return -EINVAL;
1026 } else
1027 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
859 break; 1028 break;
860 default: 1029 default:
861 return -EINVAL; 1030 return -EINVAL;
@@ -959,6 +1128,9 @@ static int dac33_soc_probe(struct platform_device *pdev)
959 /* power on device */ 1128 /* power on device */
960 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1129 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
961 1130
1131 /* Bias level configuration has enabled regulator an extra time */
1132 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1133
962 return 0; 1134 return 0;
963 1135
964pcm_err: 1136pcm_err:
@@ -1033,13 +1205,13 @@ struct snd_soc_dai dac33_dai = {
1033}; 1205};
1034EXPORT_SYMBOL_GPL(dac33_dai); 1206EXPORT_SYMBOL_GPL(dac33_dai);
1035 1207
1036static int dac33_i2c_probe(struct i2c_client *client, 1208static int __devinit dac33_i2c_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id) 1209 const struct i2c_device_id *id)
1038{ 1210{
1039 struct tlv320dac33_platform_data *pdata; 1211 struct tlv320dac33_platform_data *pdata;
1040 struct tlv320dac33_priv *dac33; 1212 struct tlv320dac33_priv *dac33;
1041 struct snd_soc_codec *codec; 1213 struct snd_soc_codec *codec;
1042 int ret = 0; 1214 int ret, i;
1043 1215
1044 if (client->dev.platform_data == NULL) { 1216 if (client->dev.platform_data == NULL) {
1045 dev_err(&client->dev, "Platform data not set\n"); 1217 dev_err(&client->dev, "Platform data not set\n");
@@ -1080,10 +1252,11 @@ static int dac33_i2c_probe(struct i2c_client *client,
1080 i2c_set_clientdata(client, dac33); 1252 i2c_set_clientdata(client, dac33);
1081 1253
1082 dac33->power_gpio = pdata->power_gpio; 1254 dac33->power_gpio = pdata->power_gpio;
1255 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1083 dac33->irq = client->irq; 1256 dac33->irq = client->irq;
1084 dac33->nsample = NSAMPLE_MAX; 1257 dac33->nsample = NSAMPLE_MAX;
1085 /* Disable FIFO use by default */ 1258 /* Disable FIFO use by default */
1086 dac33->nsample_switch = 0; 1259 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1087 1260
1088 tlv320dac33_codec = codec; 1261 tlv320dac33_codec = codec;
1089 1262
@@ -1130,6 +1303,24 @@ static int dac33_i2c_probe(struct i2c_client *client,
1130 } 1303 }
1131 } 1304 }
1132 1305
1306 for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
1307 dac33->supplies[i].supply = dac33_supply_names[i];
1308
1309 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(dac33->supplies),
1310 dac33->supplies);
1311
1312 if (ret != 0) {
1313 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1314 goto err_get;
1315 }
1316
1317 ret = regulator_bulk_enable(ARRAY_SIZE(dac33->supplies),
1318 dac33->supplies);
1319 if (ret != 0) {
1320 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1321 goto err_enable;
1322 }
1323
1133 ret = snd_soc_register_codec(codec); 1324 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) { 1325 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 1326 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
@@ -1149,6 +1340,10 @@ static int dac33_i2c_probe(struct i2c_client *client,
1149 return ret; 1340 return ret;
1150 1341
1151error_codec: 1342error_codec:
1343 regulator_bulk_disable(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1344err_enable:
1345 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1346err_get:
1152 if (dac33->irq >= 0) { 1347 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec); 1348 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq); 1349 destroy_workqueue(dac33->dac33_wq);
@@ -1165,7 +1360,7 @@ error_reg:
1165 return ret; 1360 return ret;
1166} 1361}
1167 1362
1168static int dac33_i2c_remove(struct i2c_client *client) 1363static int __devexit dac33_i2c_remove(struct i2c_client *client)
1169{ 1364{
1170 struct tlv320dac33_priv *dac33; 1365 struct tlv320dac33_priv *dac33;
1171 1366
@@ -1177,6 +1372,8 @@ static int dac33_i2c_remove(struct i2c_client *client)
1177 if (dac33->irq >= 0) 1372 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec); 1373 free_irq(dac33->irq, &dac33->codec);
1179 1374
1375 regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
1376
1180 destroy_workqueue(dac33->dac33_wq); 1377 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai); 1378 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec); 1379 snd_soc_unregister_codec(&dac33->codec);
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index 6b650c1aa3d1..958d49c969ac 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -25,6 +25,7 @@
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/gpio.h> 27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>
28#include <sound/tpa6130a2-plat.h> 29#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h> 30#include <sound/soc.h>
30#include <sound/soc-dapm.h> 31#include <sound/soc-dapm.h>
@@ -34,10 +35,22 @@
34 35
35static struct i2c_client *tpa6130a2_client; 36static struct i2c_client *tpa6130a2_client;
36 37
38#define TPA6130A2_NUM_SUPPLIES 2
39static const char *tpa6130a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
40 "CPVSS",
41 "Vdd",
42};
43
44static const char *tpa6140a2_supply_names[TPA6130A2_NUM_SUPPLIES] = {
45 "HPVdd",
46 "AVdd",
47};
48
37/* This struct is used to save the context */ 49/* This struct is used to save the context */
38struct tpa6130a2_data { 50struct tpa6130a2_data {
39 struct mutex mutex; 51 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM]; 52 unsigned char regs[TPA6130A2_CACHEREGNUM];
53 struct regulator_bulk_data supplies[TPA6130A2_NUM_SUPPLIES];
41 int power_gpio; 54 int power_gpio;
42 unsigned char power_state; 55 unsigned char power_state;
43}; 56};
@@ -106,10 +119,11 @@ static void tpa6130a2_initialize(void)
106 tpa6130a2_i2c_write(i, data->regs[i]); 119 tpa6130a2_i2c_write(i, data->regs[i]);
107} 120}
108 121
109static void tpa6130a2_power(int power) 122static int tpa6130a2_power(int power)
110{ 123{
111 struct tpa6130a2_data *data; 124 struct tpa6130a2_data *data;
112 u8 val; 125 u8 val;
126 int ret;
113 127
114 BUG_ON(tpa6130a2_client == NULL); 128 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client); 129 data = i2c_get_clientdata(tpa6130a2_client);
@@ -117,11 +131,20 @@ static void tpa6130a2_power(int power)
117 mutex_lock(&data->mutex); 131 mutex_lock(&data->mutex);
118 if (power) { 132 if (power) {
119 /* Power on */ 133 /* Power on */
120 if (data->power_gpio >= 0) { 134 if (data->power_gpio >= 0)
121 gpio_set_value(data->power_gpio, 1); 135 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1; 136
123 tpa6130a2_initialize(); 137 ret = regulator_bulk_enable(ARRAY_SIZE(data->supplies),
138 data->supplies);
139 if (ret != 0) {
140 dev_err(&tpa6130a2_client->dev,
141 "Failed to enable supplies: %d\n", ret);
142 goto exit;
124 } 143 }
144
145 data->power_state = 1;
146 tpa6130a2_initialize();
147
125 /* Clear SWS */ 148 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 149 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS; 150 val &= ~TPA6130A2_SWS;
@@ -131,13 +154,25 @@ static void tpa6130a2_power(int power)
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 154 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS; 155 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 156 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
157
134 /* Power off */ 158 /* Power off */
135 if (data->power_gpio >= 0) { 159 if (data->power_gpio >= 0)
136 gpio_set_value(data->power_gpio, 0); 160 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0; 161
162 ret = regulator_bulk_disable(ARRAY_SIZE(data->supplies),
163 data->supplies);
164 if (ret != 0) {
165 dev_err(&tpa6130a2_client->dev,
166 "Failed to disable supplies: %d\n", ret);
167 goto exit;
138 } 168 }
169
170 data->power_state = 0;
139 } 171 }
172
173exit:
140 mutex_unlock(&data->mutex); 174 mutex_unlock(&data->mutex);
175 return ret;
141} 176}
142 177
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol, 178static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
@@ -237,12 +272,8 @@ static const struct snd_kcontrol_new tpa6130a2_controls[] = {
237 */ 272 */
238static void tpa6130a2_channel_enable(u8 channel, int enable) 273static void tpa6130a2_channel_enable(u8 channel, int enable)
239{ 274{
240 struct tpa6130a2_data *data;
241 u8 val; 275 u8 val;
242 276
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) { 277 if (enable) {
247 /* Enable channel */ 278 /* Enable channel */
248 /* Enable amplifier */ 279 /* Enable amplifier */
@@ -299,15 +330,17 @@ static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, 330static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event) 331 struct snd_kcontrol *kcontrol, int event)
301{ 332{
333 int ret = 0;
334
302 switch (event) { 335 switch (event) {
303 case SND_SOC_DAPM_POST_PMU: 336 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1); 337 ret = tpa6130a2_power(1);
305 break; 338 break;
306 case SND_SOC_DAPM_POST_PMD: 339 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0); 340 ret = tpa6130a2_power(0);
308 break; 341 break;
309 } 342 }
310 return 0; 343 return ret;
311} 344}
312 345
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { 346static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
@@ -346,13 +379,13 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
346} 379}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 380EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348 381
349static int tpa6130a2_probe(struct i2c_client *client, 382static int __devinit tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id) 383 const struct i2c_device_id *id)
351{ 384{
352 struct device *dev; 385 struct device *dev;
353 struct tpa6130a2_data *data; 386 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata; 387 struct tpa6130a2_platform_data *pdata;
355 int ret; 388 int i, ret;
356 389
357 dev = &client->dev; 390 dev = &client->dev;
358 391
@@ -387,15 +420,38 @@ static int tpa6130a2_probe(struct i2c_client *client,
387 if (ret < 0) { 420 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n", 421 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio); 422 data->power_gpio);
390 goto fail; 423 goto err_gpio;
391 } 424 }
392 gpio_direction_output(data->power_gpio, 0); 425 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 } 426 }
397 427
398 tpa6130a2_power(1); 428 switch (pdata->id) {
429 case TPA6130A2:
430 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
431 data->supplies[i].supply = tpa6130a2_supply_names[i];
432 break;
433 case TPA6140A2:
434 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
435 data->supplies[i].supply = tpa6140a2_supply_names[i];;
436 break;
437 default:
438 dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n",
439 pdata->id);
440 for (i = 0; i < ARRAY_SIZE(data->supplies); i++)
441 data->supplies[i].supply = tpa6130a2_supply_names[i];
442 }
443
444 ret = regulator_bulk_get(dev, ARRAY_SIZE(data->supplies),
445 data->supplies);
446 if (ret != 0) {
447 dev_err(dev, "Failed to request supplies: %d\n", ret);
448 goto err_regulator;
449 }
450
451 ret = tpa6130a2_power(1);
452 if (ret != 0)
453 goto err_power;
454
399 455
400 /* Read version */ 456 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) & 457 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
@@ -404,10 +460,18 @@ static int tpa6130a2_probe(struct i2c_client *client,
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret); 460 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405 461
406 /* Disable the chip */ 462 /* Disable the chip */
407 tpa6130a2_power(0); 463 ret = tpa6130a2_power(0);
464 if (ret != 0)
465 goto err_power;
408 466
409 return 0; 467 return 0;
410fail: 468
469err_power:
470 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
471err_regulator:
472 if (data->power_gpio >= 0)
473 gpio_free(data->power_gpio);
474err_gpio:
411 kfree(data); 475 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL); 476 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL; 477 tpa6130a2_client = NULL;
@@ -415,7 +479,7 @@ fail:
415 return ret; 479 return ret;
416} 480}
417 481
418static int tpa6130a2_remove(struct i2c_client *client) 482static int __devexit tpa6130a2_remove(struct i2c_client *client)
419{ 483{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client); 484 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421 485
@@ -423,6 +487,9 @@ static int tpa6130a2_remove(struct i2c_client *client)
423 487
424 if (data->power_gpio >= 0) 488 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio); 489 gpio_free(data->power_gpio);
490
491 regulator_bulk_free(ARRAY_SIZE(data->supplies), data->supplies);
492
426 kfree(data); 493 kfree(data);
427 tpa6130a2_client = NULL; 494 tpa6130a2_client = NULL;
428 495
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 2a27f7b56726..6f5d4af20052 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -55,7 +55,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
55 0x0c, /* REG_ATXR1PGA (0xB) */ 55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */ 56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */ 57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */ 58 0x00, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */ 59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */ 60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */ 61 0x00, /* REG_ARXL1PGA (0x11) */
@@ -64,19 +64,19 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
64 0x00, /* REG_VRXPGA (0x14) */ 64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */ 65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */ 66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */ 67 0x00, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */ 68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */ 69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */ 70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */ 71 0x4a, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */ 72 0x4a, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */ 73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */ 74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */ 75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */ 76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */ 77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */ 78 0x00, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */ 79 0x00, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */ 80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */ 81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */ 82 0x00, /* REG_PREDR_CTL (0x26) */
@@ -99,7 +99,7 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */ 99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */ 100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */ 101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */ 102 0x06, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */ 103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */ 104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */ 105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
@@ -1203,6 +1203,8 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event, 1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD), 1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1205 1205
1206 SND_SOC_DAPM_SUPPLY("AIF Enable", TWL4030_REG_AUDIO_IF, 0, 0, NULL, 0),
1207
1206 /* Output MIXER controls */ 1208 /* Output MIXER controls */
1207 /* Earpiece */ 1209 /* Earpiece */
1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1210 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1337,6 +1339,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1337 {"Digital L2 Playback Mixer", NULL, "APLL Enable"}, 1339 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital Voice Playback Mixer", NULL, "APLL Enable"}, 1340 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1339 1341
1342 {"Digital R1 Playback Mixer", NULL, "AIF Enable"},
1343 {"Digital L1 Playback Mixer", NULL, "AIF Enable"},
1344 {"Digital R2 Playback Mixer", NULL, "AIF Enable"},
1345 {"Digital L2 Playback Mixer", NULL, "AIF Enable"},
1346
1340 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1347 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1341 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1348 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1342 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1349 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1455,6 +1462,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1455 {"ADC Virtual Left2", NULL, "APLL Enable"}, 1462 {"ADC Virtual Left2", NULL, "APLL Enable"},
1456 {"ADC Virtual Right2", NULL, "APLL Enable"}, 1463 {"ADC Virtual Right2", NULL, "APLL Enable"},
1457 1464
1465 {"ADC Virtual Left1", NULL, "AIF Enable"},
1466 {"ADC Virtual Right1", NULL, "AIF Enable"},
1467 {"ADC Virtual Left2", NULL, "AIF Enable"},
1468 {"ADC Virtual Right2", NULL, "AIF Enable"},
1469
1458 /* Analog bypass routes */ 1470 /* Analog bypass routes */
1459 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1471 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1460 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1472 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -2152,8 +2164,6 @@ static int twl4030_soc_remove(struct platform_device *pdev)
2152 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2164 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2153 snd_soc_free_pcms(socdev); 2165 snd_soc_free_pcms(socdev);
2154 snd_soc_dapm_free(socdev); 2166 snd_soc_dapm_free(socdev);
2155 kfree(codec->private_data);
2156 kfree(codec);
2157 2167
2158 return 0; 2168 return 0;
2159} 2169}
@@ -2192,7 +2202,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2192 codec->write = twl4030_write; 2202 codec->write = twl4030_write;
2193 codec->set_bias_level = twl4030_set_bias_level; 2203 codec->set_bias_level = twl4030_set_bias_level;
2194 codec->dai = twl4030_dai; 2204 codec->dai = twl4030_dai;
2195 codec->num_dai = ARRAY_SIZE(twl4030_dai), 2205 codec->num_dai = ARRAY_SIZE(twl4030_dai);
2196 codec->reg_cache_size = sizeof(twl4030_reg); 2206 codec->reg_cache_size = sizeof(twl4030_reg);
2197 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg), 2207 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2198 GFP_KERNEL); 2208 GFP_KERNEL);
@@ -2237,6 +2247,9 @@ static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2237{ 2247{
2238 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev); 2248 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2239 2249
2250 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2251 snd_soc_unregister_codec(&twl4030->codec);
2252 kfree(twl4030->codec.reg_cache);
2240 kfree(twl4030); 2253 kfree(twl4030);
2241 2254
2242 twl4030_codec = NULL; 2255 twl4030_codec = NULL;
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index dd6396ec9c79..f206d242ca31 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -25,7 +25,7 @@
25/* Register descriptions are here */ 25/* Register descriptions are here */
26#include <linux/mfd/twl4030-codec.h> 26#include <linux/mfd/twl4030-codec.h>
27 27
28/* Sgadow register used by the audio driver */ 28/* Shadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A 29#define TWL4030_REG_SW_SHADOW 0x4A
30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
31 31
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
new file mode 100644
index 000000000000..217b02680597
--- /dev/null
+++ b/sound/soc/codecs/wm2000.c
@@ -0,0 +1,888 @@
1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 *
4 * Copyright 2008-2010 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 * The download image for the WM2000 will be requested as
13 * 'wm2000_anc.bin' by default (overridable via platform data) at
14 * runtime and is expected to be in flat binary format. This is
15 * generated by Wolfson configuration tools and includes
16 * system-specific callibration information. If supplied as a
17 * sequence of ASCII-encoded hexidecimal bytes this can be converted
18 * into a flat binary with a command such as this on the command line:
19 *
20 * perl -e 'while (<>) { s/[\r\n]+// ; printf("%c", hex($_)); }'
21 * < file > wm2000_anc.bin
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/version.h>
27#include <linux/kernel.h>
28#include <linux/init.h>
29#include <linux/firmware.h>
30#include <linux/delay.h>
31#include <linux/pm.h>
32#include <linux/i2c.h>
33#include <linux/platform_device.h>
34#include <linux/debugfs.h>
35#include <sound/core.h>
36#include <sound/pcm.h>
37#include <sound/pcm_params.h>
38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h>
41#include <sound/tlv.h>
42
43#include <sound/wm2000.h>
44
45#include "wm2000.h"
46
47enum wm2000_anc_mode {
48 ANC_ACTIVE = 0,
49 ANC_BYPASS = 1,
50 ANC_STANDBY = 2,
51 ANC_OFF = 3,
52};
53
54struct wm2000_priv {
55 struct i2c_client *i2c;
56
57 enum wm2000_anc_mode anc_mode;
58
59 unsigned int anc_active:1;
60 unsigned int anc_eng_ena:1;
61 unsigned int spk_ena:1;
62
63 unsigned int mclk_div:1;
64 unsigned int speech_clarity:1;
65
66 int anc_download_size;
67 char *anc_download;
68};
69
70static struct i2c_client *wm2000_i2c;
71
72static int wm2000_write(struct i2c_client *i2c, unsigned int reg,
73 unsigned int value)
74{
75 u8 data[3];
76 int ret;
77
78 data[0] = (reg >> 8) & 0xff;
79 data[1] = reg & 0xff;
80 data[2] = value & 0xff;
81
82 dev_vdbg(&i2c->dev, "write %x = %x\n", reg, value);
83
84 ret = i2c_master_send(i2c, data, 3);
85 if (ret == 3)
86 return 0;
87 if (ret < 0)
88 return ret;
89 else
90 return -EIO;
91}
92
93static unsigned int wm2000_read(struct i2c_client *i2c, unsigned int r)
94{
95 struct i2c_msg xfer[2];
96 u8 reg[2];
97 u8 data;
98 int ret;
99
100 /* Write register */
101 reg[0] = (r >> 8) & 0xff;
102 reg[1] = r & 0xff;
103 xfer[0].addr = i2c->addr;
104 xfer[0].flags = 0;
105 xfer[0].len = sizeof(reg);
106 xfer[0].buf = &reg[0];
107
108 /* Read data */
109 xfer[1].addr = i2c->addr;
110 xfer[1].flags = I2C_M_RD;
111 xfer[1].len = 1;
112 xfer[1].buf = &data;
113
114 ret = i2c_transfer(i2c->adapter, xfer, 2);
115 if (ret != 2) {
116 dev_err(&i2c->dev, "i2c_transfer() returned %d\n", ret);
117 return 0;
118 }
119
120 dev_vdbg(&i2c->dev, "read %x from %x\n", data, r);
121
122 return data;
123}
124
125static void wm2000_reset(struct wm2000_priv *wm2000)
126{
127 struct i2c_client *i2c = wm2000->i2c;
128
129 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
130 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
131 wm2000_write(i2c, WM2000_REG_ID1, 0);
132
133 wm2000->anc_mode = ANC_OFF;
134}
135
136static int wm2000_poll_bit(struct i2c_client *i2c,
137 unsigned int reg, u8 mask, int timeout)
138{
139 int val;
140
141 val = wm2000_read(i2c, reg);
142
143 while (!(val & mask) && --timeout) {
144 msleep(1);
145 val = wm2000_read(i2c, reg);
146 }
147
148 if (timeout == 0)
149 return 0;
150 else
151 return 1;
152}
153
154static int wm2000_power_up(struct i2c_client *i2c, int analogue)
155{
156 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
157 int ret, timeout;
158
159 BUG_ON(wm2000->anc_mode != ANC_OFF);
160
161 dev_dbg(&i2c->dev, "Beginning power up\n");
162
163 if (!wm2000->mclk_div) {
164 dev_dbg(&i2c->dev, "Disabling MCLK divider\n");
165 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
166 WM2000_MCLK_DIV2_ENA_CLR);
167 } else {
168 dev_dbg(&i2c->dev, "Enabling MCLK divider\n");
169 wm2000_write(i2c, WM2000_REG_SYS_CTL2,
170 WM2000_MCLK_DIV2_ENA_SET);
171 }
172
173 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_CLR);
174 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_ENG_SET);
175
176 /* Wait for ANC engine to become ready */
177 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
178 WM2000_ANC_ENG_IDLE, 1)) {
179 dev_err(&i2c->dev, "ANC engine failed to reset\n");
180 return -ETIMEDOUT;
181 }
182
183 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
184 WM2000_STATUS_BOOT_COMPLETE, 1)) {
185 dev_err(&i2c->dev, "ANC engine failed to initialise\n");
186 return -ETIMEDOUT;
187 }
188
189 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
190
191 /* Open code download of the data since it is the only bulk
192 * write we do. */
193 dev_dbg(&i2c->dev, "Downloading %d bytes\n",
194 wm2000->anc_download_size - 2);
195
196 ret = i2c_master_send(i2c, wm2000->anc_download,
197 wm2000->anc_download_size);
198 if (ret < 0) {
199 dev_err(&i2c->dev, "i2c_transfer() failed: %d\n", ret);
200 return ret;
201 }
202 if (ret != wm2000->anc_download_size) {
203 dev_err(&i2c->dev, "i2c_transfer() failed, %d != %d\n",
204 ret, wm2000->anc_download_size);
205 return -EIO;
206 }
207
208 dev_dbg(&i2c->dev, "Download complete\n");
209
210 if (analogue) {
211 timeout = 248;
212 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
213
214 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
215 WM2000_MODE_ANA_SEQ_INCLUDE |
216 WM2000_MODE_MOUSE_ENABLE |
217 WM2000_MODE_THERMAL_ENABLE);
218 } else {
219 timeout = 10;
220
221 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
222 WM2000_MODE_MOUSE_ENABLE |
223 WM2000_MODE_THERMAL_ENABLE);
224 }
225
226 ret = wm2000_read(i2c, WM2000_REG_SPEECH_CLARITY);
227 if (wm2000->speech_clarity)
228 ret &= ~WM2000_SPEECH_CLARITY;
229 else
230 ret |= WM2000_SPEECH_CLARITY;
231 wm2000_write(i2c, WM2000_REG_SPEECH_CLARITY, ret);
232
233 wm2000_write(i2c, WM2000_REG_SYS_START0, 0x33);
234 wm2000_write(i2c, WM2000_REG_SYS_START1, 0x02);
235
236 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
237
238 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
239 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
240 dev_err(&i2c->dev, "Timed out waiting for device after %dms\n",
241 timeout * 10);
242 return -ETIMEDOUT;
243 }
244
245 dev_dbg(&i2c->dev, "ANC active\n");
246 if (analogue)
247 dev_dbg(&i2c->dev, "Analogue active\n");
248 wm2000->anc_mode = ANC_ACTIVE;
249
250 return 0;
251}
252
253static int wm2000_power_down(struct i2c_client *i2c, int analogue)
254{
255 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
256 int timeout;
257
258 if (analogue) {
259 timeout = 248;
260 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
261 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
262 WM2000_MODE_ANA_SEQ_INCLUDE |
263 WM2000_MODE_POWER_DOWN);
264 } else {
265 timeout = 10;
266 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
267 WM2000_MODE_POWER_DOWN);
268 }
269
270 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
271 WM2000_STATUS_POWER_DOWN_COMPLETE, timeout)) {
272 dev_err(&i2c->dev, "Timeout waiting for ANC power down\n");
273 return -ETIMEDOUT;
274 }
275
276 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
277 WM2000_ANC_ENG_IDLE, 1)) {
278 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
279 return -ETIMEDOUT;
280 }
281
282 dev_dbg(&i2c->dev, "powered off\n");
283 wm2000->anc_mode = ANC_OFF;
284
285 return 0;
286}
287
288static int wm2000_enter_bypass(struct i2c_client *i2c, int analogue)
289{
290 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
291
292 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
293
294 if (analogue) {
295 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
296 WM2000_MODE_ANA_SEQ_INCLUDE |
297 WM2000_MODE_THERMAL_ENABLE |
298 WM2000_MODE_BYPASS_ENTRY);
299 } else {
300 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
301 WM2000_MODE_THERMAL_ENABLE |
302 WM2000_MODE_BYPASS_ENTRY);
303 }
304
305 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
306 WM2000_STATUS_ANC_DISABLED, 10)) {
307 dev_err(&i2c->dev, "Timeout waiting for ANC disable\n");
308 return -ETIMEDOUT;
309 }
310
311 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT,
312 WM2000_ANC_ENG_IDLE, 1)) {
313 dev_err(&i2c->dev, "Timeout waiting for ANC engine idle\n");
314 return -ETIMEDOUT;
315 }
316
317 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
318 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
319
320 wm2000->anc_mode = ANC_BYPASS;
321 dev_dbg(&i2c->dev, "bypass enabled\n");
322
323 return 0;
324}
325
326static int wm2000_exit_bypass(struct i2c_client *i2c, int analogue)
327{
328 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
329
330 BUG_ON(wm2000->anc_mode != ANC_BYPASS);
331
332 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
333
334 if (analogue) {
335 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
336 WM2000_MODE_ANA_SEQ_INCLUDE |
337 WM2000_MODE_MOUSE_ENABLE |
338 WM2000_MODE_THERMAL_ENABLE);
339 } else {
340 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
341 WM2000_MODE_MOUSE_ENABLE |
342 WM2000_MODE_THERMAL_ENABLE);
343 }
344
345 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
346 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
347
348 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
349 WM2000_STATUS_MOUSE_ACTIVE, 10)) {
350 dev_err(&i2c->dev, "Timed out waiting for MOUSE\n");
351 return -ETIMEDOUT;
352 }
353
354 wm2000->anc_mode = ANC_ACTIVE;
355 dev_dbg(&i2c->dev, "MOUSE active\n");
356
357 return 0;
358}
359
360static int wm2000_enter_standby(struct i2c_client *i2c, int analogue)
361{
362 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
363 int timeout;
364
365 BUG_ON(wm2000->anc_mode != ANC_ACTIVE);
366
367 if (analogue) {
368 timeout = 248;
369 wm2000_write(i2c, WM2000_REG_ANA_VMID_PD_TIME, timeout / 4);
370
371 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
372 WM2000_MODE_ANA_SEQ_INCLUDE |
373 WM2000_MODE_THERMAL_ENABLE |
374 WM2000_MODE_STANDBY_ENTRY);
375 } else {
376 timeout = 10;
377
378 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
379 WM2000_MODE_THERMAL_ENABLE |
380 WM2000_MODE_STANDBY_ENTRY);
381 }
382
383 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
384 WM2000_STATUS_ANC_DISABLED, timeout)) {
385 dev_err(&i2c->dev,
386 "Timed out waiting for ANC disable after 1ms\n");
387 return -ETIMEDOUT;
388 }
389
390 if (!wm2000_poll_bit(i2c, WM2000_REG_ANC_STAT, WM2000_ANC_ENG_IDLE,
391 1)) {
392 dev_err(&i2c->dev,
393 "Timed out waiting for standby after %dms\n",
394 timeout * 10);
395 return -ETIMEDOUT;
396 }
397
398 wm2000_write(i2c, WM2000_REG_SYS_CTL1, WM2000_SYS_STBY);
399 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_CLR);
400
401 wm2000->anc_mode = ANC_STANDBY;
402 dev_dbg(&i2c->dev, "standby\n");
403 if (analogue)
404 dev_dbg(&i2c->dev, "Analogue disabled\n");
405
406 return 0;
407}
408
409static int wm2000_exit_standby(struct i2c_client *i2c, int analogue)
410{
411 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
412 int timeout;
413
414 BUG_ON(wm2000->anc_mode != ANC_STANDBY);
415
416 wm2000_write(i2c, WM2000_REG_SYS_CTL1, 0);
417
418 if (analogue) {
419 timeout = 248;
420 wm2000_write(i2c, WM2000_REG_ANA_VMID_PU_TIME, timeout / 4);
421
422 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
423 WM2000_MODE_ANA_SEQ_INCLUDE |
424 WM2000_MODE_THERMAL_ENABLE |
425 WM2000_MODE_MOUSE_ENABLE);
426 } else {
427 timeout = 10;
428
429 wm2000_write(i2c, WM2000_REG_SYS_MODE_CNTRL,
430 WM2000_MODE_THERMAL_ENABLE |
431 WM2000_MODE_MOUSE_ENABLE);
432 }
433
434 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_RAM_SET);
435 wm2000_write(i2c, WM2000_REG_SYS_CTL2, WM2000_ANC_INT_N_CLR);
436
437 if (!wm2000_poll_bit(i2c, WM2000_REG_SYS_STATUS,
438 WM2000_STATUS_MOUSE_ACTIVE, timeout)) {
439 dev_err(&i2c->dev, "Timed out waiting for MOUSE after %dms\n",
440 timeout * 10);
441 return -ETIMEDOUT;
442 }
443
444 wm2000->anc_mode = ANC_ACTIVE;
445 dev_dbg(&i2c->dev, "MOUSE active\n");
446 if (analogue)
447 dev_dbg(&i2c->dev, "Analogue enabled\n");
448
449 return 0;
450}
451
452typedef int (*wm2000_mode_fn)(struct i2c_client *i2c, int analogue);
453
454static struct {
455 enum wm2000_anc_mode source;
456 enum wm2000_anc_mode dest;
457 int analogue;
458 wm2000_mode_fn step[2];
459} anc_transitions[] = {
460 {
461 .source = ANC_OFF,
462 .dest = ANC_ACTIVE,
463 .analogue = 1,
464 .step = {
465 wm2000_power_up,
466 },
467 },
468 {
469 .source = ANC_OFF,
470 .dest = ANC_STANDBY,
471 .step = {
472 wm2000_power_up,
473 wm2000_enter_standby,
474 },
475 },
476 {
477 .source = ANC_OFF,
478 .dest = ANC_BYPASS,
479 .analogue = 1,
480 .step = {
481 wm2000_power_up,
482 wm2000_enter_bypass,
483 },
484 },
485 {
486 .source = ANC_ACTIVE,
487 .dest = ANC_BYPASS,
488 .analogue = 1,
489 .step = {
490 wm2000_enter_bypass,
491 },
492 },
493 {
494 .source = ANC_ACTIVE,
495 .dest = ANC_STANDBY,
496 .analogue = 1,
497 .step = {
498 wm2000_enter_standby,
499 },
500 },
501 {
502 .source = ANC_ACTIVE,
503 .dest = ANC_OFF,
504 .analogue = 1,
505 .step = {
506 wm2000_power_down,
507 },
508 },
509 {
510 .source = ANC_BYPASS,
511 .dest = ANC_ACTIVE,
512 .analogue = 1,
513 .step = {
514 wm2000_exit_bypass,
515 },
516 },
517 {
518 .source = ANC_BYPASS,
519 .dest = ANC_STANDBY,
520 .analogue = 1,
521 .step = {
522 wm2000_exit_bypass,
523 wm2000_enter_standby,
524 },
525 },
526 {
527 .source = ANC_BYPASS,
528 .dest = ANC_OFF,
529 .step = {
530 wm2000_exit_bypass,
531 wm2000_power_down,
532 },
533 },
534 {
535 .source = ANC_STANDBY,
536 .dest = ANC_ACTIVE,
537 .analogue = 1,
538 .step = {
539 wm2000_exit_standby,
540 },
541 },
542 {
543 .source = ANC_STANDBY,
544 .dest = ANC_BYPASS,
545 .analogue = 1,
546 .step = {
547 wm2000_exit_standby,
548 wm2000_enter_bypass,
549 },
550 },
551 {
552 .source = ANC_STANDBY,
553 .dest = ANC_OFF,
554 .step = {
555 wm2000_exit_standby,
556 wm2000_power_down,
557 },
558 },
559};
560
561static int wm2000_anc_transition(struct wm2000_priv *wm2000,
562 enum wm2000_anc_mode mode)
563{
564 struct i2c_client *i2c = wm2000->i2c;
565 int i, j;
566 int ret;
567
568 if (wm2000->anc_mode == mode)
569 return 0;
570
571 for (i = 0; i < ARRAY_SIZE(anc_transitions); i++)
572 if (anc_transitions[i].source == wm2000->anc_mode &&
573 anc_transitions[i].dest == mode)
574 break;
575 if (i == ARRAY_SIZE(anc_transitions)) {
576 dev_err(&i2c->dev, "No transition for %d->%d\n",
577 wm2000->anc_mode, mode);
578 return -EINVAL;
579 }
580
581 for (j = 0; j < ARRAY_SIZE(anc_transitions[j].step); j++) {
582 if (!anc_transitions[i].step[j])
583 break;
584 ret = anc_transitions[i].step[j](i2c,
585 anc_transitions[i].analogue);
586 if (ret != 0)
587 return ret;
588 }
589
590 return 0;
591}
592
593static int wm2000_anc_set_mode(struct wm2000_priv *wm2000)
594{
595 struct i2c_client *i2c = wm2000->i2c;
596 enum wm2000_anc_mode mode;
597
598 if (wm2000->anc_eng_ena && wm2000->spk_ena)
599 if (wm2000->anc_active)
600 mode = ANC_ACTIVE;
601 else
602 mode = ANC_BYPASS;
603 else
604 mode = ANC_STANDBY;
605
606 dev_dbg(&i2c->dev, "Set mode %d (enabled %d, mute %d, active %d)\n",
607 mode, wm2000->anc_eng_ena, !wm2000->spk_ena,
608 wm2000->anc_active);
609
610 return wm2000_anc_transition(wm2000, mode);
611}
612
613static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol,
614 struct snd_ctl_elem_value *ucontrol)
615{
616 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
617
618 ucontrol->value.enumerated.item[0] = wm2000->anc_active;
619
620 return 0;
621}
622
623static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol,
624 struct snd_ctl_elem_value *ucontrol)
625{
626 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
627 int anc_active = ucontrol->value.enumerated.item[0];
628
629 if (anc_active > 1)
630 return -EINVAL;
631
632 wm2000->anc_active = anc_active;
633
634 return wm2000_anc_set_mode(wm2000);
635}
636
637static int wm2000_speaker_get(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_value *ucontrol)
639{
640 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
641
642 ucontrol->value.enumerated.item[0] = wm2000->spk_ena;
643
644 return 0;
645}
646
647static int wm2000_speaker_put(struct snd_kcontrol *kcontrol,
648 struct snd_ctl_elem_value *ucontrol)
649{
650 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
651 int val = ucontrol->value.enumerated.item[0];
652
653 if (val > 1)
654 return -EINVAL;
655
656 wm2000->spk_ena = val;
657
658 return wm2000_anc_set_mode(wm2000);
659}
660
661static const struct snd_kcontrol_new wm2000_controls[] = {
662 SOC_SINGLE_BOOL_EXT("WM2000 ANC Switch", 0,
663 wm2000_anc_mode_get,
664 wm2000_anc_mode_put),
665 SOC_SINGLE_BOOL_EXT("WM2000 Switch", 0,
666 wm2000_speaker_get,
667 wm2000_speaker_put),
668};
669
670static int wm2000_anc_power_event(struct snd_soc_dapm_widget *w,
671 struct snd_kcontrol *kcontrol, int event)
672{
673 struct wm2000_priv *wm2000 = dev_get_drvdata(&wm2000_i2c->dev);
674
675 if (SND_SOC_DAPM_EVENT_ON(event))
676 wm2000->anc_eng_ena = 1;
677
678 if (SND_SOC_DAPM_EVENT_OFF(event))
679 wm2000->anc_eng_ena = 0;
680
681 return wm2000_anc_set_mode(wm2000);
682}
683
684static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
685/* Externally visible pins */
686SND_SOC_DAPM_OUTPUT("WM2000 SPKN"),
687SND_SOC_DAPM_OUTPUT("WM2000 SPKP"),
688
689SND_SOC_DAPM_INPUT("WM2000 LINN"),
690SND_SOC_DAPM_INPUT("WM2000 LINP"),
691
692SND_SOC_DAPM_PGA_E("ANC Engine", SND_SOC_NOPM, 0, 0, NULL, 0,
693 wm2000_anc_power_event,
694 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
695};
696
697/* Target, Path, Source */
698static const struct snd_soc_dapm_route audio_map[] = {
699 { "WM2000 SPKN", NULL, "ANC Engine" },
700 { "WM2000 SPKP", NULL, "ANC Engine" },
701 { "ANC Engine", NULL, "WM2000 LINN" },
702 { "ANC Engine", NULL, "WM2000 LINP" },
703};
704
705/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec)
707{
708 int ret;
709
710 if (!wm2000_i2c) {
711 pr_err("WM2000 not yet probed\n");
712 return -ENODEV;
713 }
714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0)
718 return ret;
719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0)
722 return ret;
723
724 return snd_soc_add_controls(codec, wm2000_controls,
725 ARRAY_SIZE(wm2000_controls));
726}
727EXPORT_SYMBOL_GPL(wm2000_add_controls);
728
729static int __devinit wm2000_i2c_probe(struct i2c_client *i2c,
730 const struct i2c_device_id *i2c_id)
731{
732 struct wm2000_priv *wm2000;
733 struct wm2000_platform_data *pdata;
734 const char *filename;
735 const struct firmware *fw;
736 int reg, ret;
737 u16 id;
738
739 if (wm2000_i2c) {
740 dev_err(&i2c->dev, "Another WM2000 is already registered\n");
741 return -EINVAL;
742 }
743
744 wm2000 = kzalloc(sizeof(struct wm2000_priv), GFP_KERNEL);
745 if (wm2000 == NULL) {
746 dev_err(&i2c->dev, "Unable to allocate private data\n");
747 return -ENOMEM;
748 }
749
750 /* Verify that this is a WM2000 */
751 reg = wm2000_read(i2c, WM2000_REG_ID1);
752 id = reg << 8;
753 reg = wm2000_read(i2c, WM2000_REG_ID2);
754 id |= reg & 0xff;
755
756 if (id != 0x2000) {
757 dev_err(&i2c->dev, "Device is not a WM2000 - ID %x\n", id);
758 ret = -ENODEV;
759 goto err;
760 }
761
762 reg = wm2000_read(i2c, WM2000_REG_REVISON);
763 dev_info(&i2c->dev, "revision %c\n", reg + 'A');
764
765 filename = "wm2000_anc.bin";
766 pdata = dev_get_platdata(&i2c->dev);
767 if (pdata) {
768 wm2000->mclk_div = pdata->mclkdiv2;
769 wm2000->speech_clarity = !pdata->speech_enh_disable;
770
771 if (pdata->download_file)
772 filename = pdata->download_file;
773 }
774
775 ret = request_firmware(&fw, filename, &i2c->dev);
776 if (ret != 0) {
777 dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret);
778 goto err;
779 }
780
781 /* Pre-cook the concatenation of the register address onto the image */
782 wm2000->anc_download_size = fw->size + 2;
783 wm2000->anc_download = kmalloc(wm2000->anc_download_size, GFP_KERNEL);
784 if (wm2000->anc_download == NULL) {
785 dev_err(&i2c->dev, "Out of memory\n");
786 ret = -ENOMEM;
787 goto err_fw;
788 }
789
790 wm2000->anc_download[0] = 0x80;
791 wm2000->anc_download[1] = 0x00;
792 memcpy(wm2000->anc_download + 2, fw->data, fw->size);
793
794 release_firmware(fw);
795
796 dev_set_drvdata(&i2c->dev, wm2000);
797 wm2000->anc_eng_ena = 1;
798 wm2000->i2c = i2c;
799
800 wm2000_reset(wm2000);
801
802 /* This will trigger a transition to standby mode by default */
803 wm2000_anc_set_mode(wm2000);
804
805 wm2000_i2c = i2c;
806
807 return 0;
808
809err_fw:
810 release_firmware(fw);
811err:
812 kfree(wm2000);
813 return ret;
814}
815
816static __devexit int wm2000_i2c_remove(struct i2c_client *i2c)
817{
818 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
819
820 wm2000_anc_transition(wm2000, ANC_OFF);
821
822 wm2000_i2c = NULL;
823 kfree(wm2000->anc_download);
824 kfree(wm2000);
825
826 return 0;
827}
828
829static void wm2000_i2c_shutdown(struct i2c_client *i2c)
830{
831 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
832
833 wm2000_anc_transition(wm2000, ANC_OFF);
834}
835
836#ifdef CONFIG_PM
837static int wm2000_i2c_suspend(struct i2c_client *i2c, pm_message_t mesg)
838{
839 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
840
841 return wm2000_anc_transition(wm2000, ANC_OFF);
842}
843
844static int wm2000_i2c_resume(struct i2c_client *i2c)
845{
846 struct wm2000_priv *wm2000 = dev_get_drvdata(&i2c->dev);
847
848 return wm2000_anc_set_mode(wm2000);
849}
850#else
851#define wm2000_i2c_suspend NULL
852#define wm2000_i2c_resume NULL
853#endif
854
855static const struct i2c_device_id wm2000_i2c_id[] = {
856 { "wm2000", 0 },
857 { }
858};
859MODULE_DEVICE_TABLE(i2c, wm2000_i2c_id);
860
861static struct i2c_driver wm2000_i2c_driver = {
862 .driver = {
863 .name = "wm2000",
864 .owner = THIS_MODULE,
865 },
866 .probe = wm2000_i2c_probe,
867 .remove = __devexit_p(wm2000_i2c_remove),
868 .suspend = wm2000_i2c_suspend,
869 .resume = wm2000_i2c_resume,
870 .shutdown = wm2000_i2c_shutdown,
871 .id_table = wm2000_i2c_id,
872};
873
874static int __init wm2000_init(void)
875{
876 return i2c_add_driver(&wm2000_i2c_driver);
877}
878module_init(wm2000_init);
879
880static void __exit wm2000_exit(void)
881{
882 i2c_del_driver(&wm2000_i2c_driver);
883}
884module_exit(wm2000_exit);
885
886MODULE_DESCRIPTION("ASoC WM2000 driver");
887MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
888MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm2000.h b/sound/soc/codecs/wm2000.h
new file mode 100644
index 000000000000..c18e261c3c7f
--- /dev/null
+++ b/sound/soc/codecs/wm2000.h
@@ -0,0 +1,79 @@
1/*
2 * wm2000.h -- WM2000 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 _WM2000_H
10#define _WM2000_H
11
12struct wm2000_setup_data {
13 unsigned short i2c_address;
14 int mclk_div; /* Set to a non-zero value if MCLK_DIV_2 required */
15};
16
17extern int wm2000_add_controls(struct snd_soc_codec *codec);
18
19extern struct snd_soc_dai wm2000_dai;
20extern struct snd_soc_codec_device soc_codec_dev_wm2000;
21
22#define WM2000_REG_SYS_START 0x8000
23#define WM2000_REG_SPEECH_CLARITY 0x8fef
24#define WM2000_REG_SYS_WATCHDOG 0x8ff6
25#define WM2000_REG_ANA_VMID_PD_TIME 0x8ff7
26#define WM2000_REG_ANA_VMID_PU_TIME 0x8ff8
27#define WM2000_REG_CAT_FLTR_INDX 0x8ff9
28#define WM2000_REG_CAT_GAIN_0 0x8ffa
29#define WM2000_REG_SYS_STATUS 0x8ffc
30#define WM2000_REG_SYS_MODE_CNTRL 0x8ffd
31#define WM2000_REG_SYS_START0 0x8ffe
32#define WM2000_REG_SYS_START1 0x8fff
33#define WM2000_REG_ID1 0xf000
34#define WM2000_REG_ID2 0xf001
35#define WM2000_REG_REVISON 0xf002
36#define WM2000_REG_SYS_CTL1 0xf003
37#define WM2000_REG_SYS_CTL2 0xf004
38#define WM2000_REG_ANC_STAT 0xf005
39#define WM2000_REG_IF_CTL 0xf006
40
41/* SPEECH_CLARITY */
42#define WM2000_SPEECH_CLARITY 0x01
43
44/* SYS_STATUS */
45#define WM2000_STATUS_MOUSE_ACTIVE 0x40
46#define WM2000_STATUS_CAT_FREQ_COMPLETE 0x20
47#define WM2000_STATUS_CAT_GAIN_COMPLETE 0x10
48#define WM2000_STATUS_THERMAL_SHUTDOWN_COMPLETE 0x08
49#define WM2000_STATUS_ANC_DISABLED 0x04
50#define WM2000_STATUS_POWER_DOWN_COMPLETE 0x02
51#define WM2000_STATUS_BOOT_COMPLETE 0x01
52
53/* SYS_MODE_CNTRL */
54#define WM2000_MODE_ANA_SEQ_INCLUDE 0x80
55#define WM2000_MODE_MOUSE_ENABLE 0x40
56#define WM2000_MODE_CAT_FREQ_ENABLE 0x20
57#define WM2000_MODE_CAT_GAIN_ENABLE 0x10
58#define WM2000_MODE_BYPASS_ENTRY 0x08
59#define WM2000_MODE_STANDBY_ENTRY 0x04
60#define WM2000_MODE_THERMAL_ENABLE 0x02
61#define WM2000_MODE_POWER_DOWN 0x01
62
63/* SYS_CTL1 */
64#define WM2000_SYS_STBY 0x01
65
66/* SYS_CTL2 */
67#define WM2000_MCLK_DIV2_ENA_CLR 0x80
68#define WM2000_MCLK_DIV2_ENA_SET 0x40
69#define WM2000_ANC_ENG_CLR 0x20
70#define WM2000_ANC_ENG_SET 0x10
71#define WM2000_ANC_INT_N_CLR 0x08
72#define WM2000_ANC_INT_N_SET 0x04
73#define WM2000_RAM_CLR 0x02
74#define WM2000_RAM_SET 0x01
75
76/* ANC_STAT */
77#define WM2000_ANC_ENG_IDLE 0x01
78
79#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
index d8ffbd641d71..63a254e293ca 100644
--- a/sound/soc/codecs/wm8727.c
+++ b/sound/soc/codecs/wm8727.c
@@ -44,23 +44,16 @@ struct snd_soc_dai wm8727_dai = {
44}; 44};
45EXPORT_SYMBOL_GPL(wm8727_dai); 45EXPORT_SYMBOL_GPL(wm8727_dai);
46 46
47static struct snd_soc_codec *wm8727_codec;
48
47static int wm8727_soc_probe(struct platform_device *pdev) 49static int wm8727_soc_probe(struct platform_device *pdev)
48{ 50{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 51 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0; 52 int ret = 0;
52 53
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 54 BUG_ON(!wm8727_codec);
54 if (codec == NULL) 55
55 return -ENOMEM; 56 socdev->card->codec = wm8727_codec;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64 57
65 /* register pcms */ 58 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 59 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -80,12 +73,9 @@ pcm_err:
80static int wm8727_soc_remove(struct platform_device *pdev) 73static int wm8727_soc_remove(struct platform_device *pdev)
81{ 74{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 75 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84 76
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev); 77 snd_soc_free_pcms(socdev);
88 kfree(codec); 78
89 return 0; 79 return 0;
90} 80}
91 81
@@ -98,13 +88,55 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
98 88
99static __devinit int wm8727_platform_probe(struct platform_device *pdev) 89static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{ 90{
91 struct snd_soc_codec *codec;
92 int ret;
93
94 if (wm8727_codec) {
95 dev_err(&pdev->dev, "Another WM8727 is registered\n");
96 return -EBUSY;
97 }
98
99 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
100 if (codec == NULL)
101 return -ENOMEM;
102 wm8727_codec = codec;
103
104 platform_set_drvdata(pdev, codec);
105
106 mutex_init(&codec->mutex);
107 codec->dev = &pdev->dev;
108 codec->name = "WM8727";
109 codec->owner = THIS_MODULE;
110 codec->dai = &wm8727_dai;
111 codec->num_dai = 1;
112 INIT_LIST_HEAD(&codec->dapm_widgets);
113 INIT_LIST_HEAD(&codec->dapm_paths);
114
101 wm8727_dai.dev = &pdev->dev; 115 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai); 116
117 ret = snd_soc_register_codec(codec);
118 if (ret != 0) {
119 dev_err(&pdev->dev, "Failed to register CODEC: %d\n", ret);
120 goto err;
121 }
122
123 ret = snd_soc_register_dai(&wm8727_dai);
124 if (ret != 0) {
125 dev_err(&pdev->dev, "Failed to register DAI: %d\n", ret);
126 goto err_codec;
127 }
128
129err_codec:
130 snd_soc_unregister_codec(codec);
131err:
132 kfree(codec);
133 return ret;
103} 134}
104 135
105static int __devexit wm8727_platform_remove(struct platform_device *pdev) 136static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{ 137{
107 snd_soc_unregister_dai(&wm8727_dai); 138 snd_soc_unregister_dai(&wm8727_dai);
139 snd_soc_unregister_codec(platform_get_drvdata(pdev));
108 return 0; 140 return 0;
109} 141}
110 142
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 3a497810f939..5a2619dbf283 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -456,6 +456,9 @@ static int wm8731_resume(struct platform_device *pdev)
456 456
457 /* Sync reg_cache with the hardware */ 457 /* Sync reg_cache with the hardware */
458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
459 if (cache[i] == wm8731_reg[i])
460 continue;
461
459 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 462 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
460 data[1] = cache[i] & 0x00ff; 463 data[1] = cache[i] & 0x00ff;
461 codec->hw_write(codec->control_data, data, 2); 464 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d6850dacda29..c2444e7c8480 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1507,10 +1507,6 @@ static int wm8753_suspend(struct platform_device *pdev, pm_message_t state)
1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1507 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1508 struct snd_soc_codec *codec = socdev->card->codec; 1508 struct snd_soc_codec *codec = socdev->card->codec;
1509 1509
1510 /* we only need to suspend if we are a valid card */
1511 if (!codec->card)
1512 return 0;
1513
1514 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1510 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1515 return 0; 1511 return 0;
1516} 1512}
@@ -1523,10 +1519,6 @@ static int wm8753_resume(struct platform_device *pdev)
1523 u8 data[2]; 1519 u8 data[2];
1524 u16 *cache = codec->reg_cache; 1520 u16 *cache = codec->reg_cache;
1525 1521
1526 /* we only need to resume if we are a valid card */
1527 if (!codec->card)
1528 return 0;
1529
1530 /* Sync reg_cache with the hardware */ 1522 /* Sync reg_cache with the hardware */
1531 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { 1523 for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) {
1532 if (i + 1 == WM8753_RESET) 1524 if (i + 1 == WM8753_RESET)
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index ab2c0da18091..44e7d9d82f87 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -406,6 +406,8 @@ static int wm8776_resume(struct platform_device *pdev)
406 406
407 /* Sync reg_cache with the hardware */ 407 /* Sync reg_cache with the hardware */
408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { 408 for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) {
409 if (cache[i] == wm8776_reg[i])
410 continue;
409 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 411 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
410 data[1] = cache[i] & 0x00ff; 412 data[1] = cache[i] & 0x00ff;
411 codec->hw_write(codec->control_data, data, 2); 413 codec->hw_write(codec->control_data, data, 2);
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
new file mode 100644
index 000000000000..593e47d0e0eb
--- /dev/null
+++ b/sound/soc/codecs/wm8904.c
@@ -0,0 +1,2656 @@
1/*
2 * wm8904.c -- WM8904 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#include <sound/wm8904.h>
30
31#include "wm8904.h"
32
33static struct snd_soc_codec *wm8904_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8904;
35
36enum wm8904_type {
37 WM8904,
38 WM8912,
39};
40
41#define WM8904_NUM_DCS_CHANNELS 4
42
43#define WM8904_NUM_SUPPLIES 5
44static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
45 "DCVDD",
46 "DBVDD",
47 "AVDD",
48 "CPVDD",
49 "MICVDD",
50};
51
52/* codec private data */
53struct wm8904_priv {
54 struct snd_soc_codec codec;
55 u16 reg_cache[WM8904_MAX_REGISTER + 1];
56
57 enum wm8904_type devtype;
58
59 struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES];
60
61 struct wm8904_pdata *pdata;
62
63 int deemph;
64
65 /* Platform provided DRC configuration */
66 const char **drc_texts;
67 int drc_cfg;
68 struct soc_enum drc_enum;
69
70 /* Platform provided ReTune mobile configuration */
71 int num_retune_mobile_texts;
72 const char **retune_mobile_texts;
73 int retune_mobile_cfg;
74 struct soc_enum retune_mobile_enum;
75
76 /* FLL setup */
77 int fll_src;
78 int fll_fref;
79 int fll_fout;
80
81 /* Clocking configuration */
82 unsigned int mclk_rate;
83 int sysclk_src;
84 unsigned int sysclk_rate;
85
86 int tdm_width;
87 int tdm_slots;
88 int bclk;
89 int fs;
90
91 /* DC servo configuration - cached offset values */
92 int dcs_state[WM8904_NUM_DCS_CHANNELS];
93};
94
95static const u16 wm8904_reg[WM8904_MAX_REGISTER + 1] = {
96 0x8904, /* R0 - SW Reset and ID */
97 0x0000, /* R1 - Revision */
98 0x0000, /* R2 */
99 0x0000, /* R3 */
100 0x0018, /* R4 - Bias Control 0 */
101 0x0000, /* R5 - VMID Control 0 */
102 0x0000, /* R6 - Mic Bias Control 0 */
103 0x0000, /* R7 - Mic Bias Control 1 */
104 0x0001, /* R8 - Analogue DAC 0 */
105 0x9696, /* R9 - mic Filter Control */
106 0x0001, /* R10 - Analogue ADC 0 */
107 0x0000, /* R11 */
108 0x0000, /* R12 - Power Management 0 */
109 0x0000, /* R13 */
110 0x0000, /* R14 - Power Management 2 */
111 0x0000, /* R15 - Power Management 3 */
112 0x0000, /* R16 */
113 0x0000, /* R17 */
114 0x0000, /* R18 - Power Management 6 */
115 0x0000, /* R19 */
116 0x945E, /* R20 - Clock Rates 0 */
117 0x0C05, /* R21 - Clock Rates 1 */
118 0x0006, /* R22 - Clock Rates 2 */
119 0x0000, /* R23 */
120 0x0050, /* R24 - Audio Interface 0 */
121 0x000A, /* R25 - Audio Interface 1 */
122 0x00E4, /* R26 - Audio Interface 2 */
123 0x0040, /* R27 - Audio Interface 3 */
124 0x0000, /* R28 */
125 0x0000, /* R29 */
126 0x00C0, /* R30 - DAC Digital Volume Left */
127 0x00C0, /* R31 - DAC Digital Volume Right */
128 0x0000, /* R32 - DAC Digital 0 */
129 0x0008, /* R33 - DAC Digital 1 */
130 0x0000, /* R34 */
131 0x0000, /* R35 */
132 0x00C0, /* R36 - ADC Digital Volume Left */
133 0x00C0, /* R37 - ADC Digital Volume Right */
134 0x0010, /* R38 - ADC Digital 0 */
135 0x0000, /* R39 - Digital Microphone 0 */
136 0x01AF, /* R40 - DRC 0 */
137 0x3248, /* R41 - DRC 1 */
138 0x0000, /* R42 - DRC 2 */
139 0x0000, /* R43 - DRC 3 */
140 0x0085, /* R44 - Analogue Left Input 0 */
141 0x0085, /* R45 - Analogue Right Input 0 */
142 0x0044, /* R46 - Analogue Left Input 1 */
143 0x0044, /* R47 - Analogue Right Input 1 */
144 0x0000, /* R48 */
145 0x0000, /* R49 */
146 0x0000, /* R50 */
147 0x0000, /* R51 */
148 0x0000, /* R52 */
149 0x0000, /* R53 */
150 0x0000, /* R54 */
151 0x0000, /* R55 */
152 0x0000, /* R56 */
153 0x002D, /* R57 - Analogue OUT1 Left */
154 0x002D, /* R58 - Analogue OUT1 Right */
155 0x0039, /* R59 - Analogue OUT2 Left */
156 0x0039, /* R60 - Analogue OUT2 Right */
157 0x0000, /* R61 - Analogue OUT12 ZC */
158 0x0000, /* R62 */
159 0x0000, /* R63 */
160 0x0000, /* R64 */
161 0x0000, /* R65 */
162 0x0000, /* R66 */
163 0x0000, /* R67 - DC Servo 0 */
164 0x0000, /* R68 - DC Servo 1 */
165 0xAAAA, /* R69 - DC Servo 2 */
166 0x0000, /* R70 */
167 0xAAAA, /* R71 - DC Servo 4 */
168 0xAAAA, /* R72 - DC Servo 5 */
169 0x0000, /* R73 - DC Servo 6 */
170 0x0000, /* R74 - DC Servo 7 */
171 0x0000, /* R75 - DC Servo 8 */
172 0x0000, /* R76 - DC Servo 9 */
173 0x0000, /* R77 - DC Servo Readback 0 */
174 0x0000, /* R78 */
175 0x0000, /* R79 */
176 0x0000, /* R80 */
177 0x0000, /* R81 */
178 0x0000, /* R82 */
179 0x0000, /* R83 */
180 0x0000, /* R84 */
181 0x0000, /* R85 */
182 0x0000, /* R86 */
183 0x0000, /* R87 */
184 0x0000, /* R88 */
185 0x0000, /* R89 */
186 0x0000, /* R90 - Analogue HP 0 */
187 0x0000, /* R91 */
188 0x0000, /* R92 */
189 0x0000, /* R93 */
190 0x0000, /* R94 - Analogue Lineout 0 */
191 0x0000, /* R95 */
192 0x0000, /* R96 */
193 0x0000, /* R97 */
194 0x0000, /* R98 - Charge Pump 0 */
195 0x0000, /* R99 */
196 0x0000, /* R100 */
197 0x0000, /* R101 */
198 0x0000, /* R102 */
199 0x0000, /* R103 */
200 0x0004, /* R104 - Class W 0 */
201 0x0000, /* R105 */
202 0x0000, /* R106 */
203 0x0000, /* R107 */
204 0x0000, /* R108 - Write Sequencer 0 */
205 0x0000, /* R109 - Write Sequencer 1 */
206 0x0000, /* R110 - Write Sequencer 2 */
207 0x0000, /* R111 - Write Sequencer 3 */
208 0x0000, /* R112 - Write Sequencer 4 */
209 0x0000, /* R113 */
210 0x0000, /* R114 */
211 0x0000, /* R115 */
212 0x0000, /* R116 - FLL Control 1 */
213 0x0007, /* R117 - FLL Control 2 */
214 0x0000, /* R118 - FLL Control 3 */
215 0x2EE0, /* R119 - FLL Control 4 */
216 0x0004, /* R120 - FLL Control 5 */
217 0x0014, /* R121 - GPIO Control 1 */
218 0x0010, /* R122 - GPIO Control 2 */
219 0x0010, /* R123 - GPIO Control 3 */
220 0x0000, /* R124 - GPIO Control 4 */
221 0x0000, /* R125 */
222 0x0000, /* R126 - Digital Pulls */
223 0x0000, /* R127 - Interrupt Status */
224 0xFFFF, /* R128 - Interrupt Status Mask */
225 0x0000, /* R129 - Interrupt Polarity */
226 0x0000, /* R130 - Interrupt Debounce */
227 0x0000, /* R131 */
228 0x0000, /* R132 */
229 0x0000, /* R133 */
230 0x0000, /* R134 - EQ1 */
231 0x000C, /* R135 - EQ2 */
232 0x000C, /* R136 - EQ3 */
233 0x000C, /* R137 - EQ4 */
234 0x000C, /* R138 - EQ5 */
235 0x000C, /* R139 - EQ6 */
236 0x0FCA, /* R140 - EQ7 */
237 0x0400, /* R141 - EQ8 */
238 0x00D8, /* R142 - EQ9 */
239 0x1EB5, /* R143 - EQ10 */
240 0xF145, /* R144 - EQ11 */
241 0x0B75, /* R145 - EQ12 */
242 0x01C5, /* R146 - EQ13 */
243 0x1C58, /* R147 - EQ14 */
244 0xF373, /* R148 - EQ15 */
245 0x0A54, /* R149 - EQ16 */
246 0x0558, /* R150 - EQ17 */
247 0x168E, /* R151 - EQ18 */
248 0xF829, /* R152 - EQ19 */
249 0x07AD, /* R153 - EQ20 */
250 0x1103, /* R154 - EQ21 */
251 0x0564, /* R155 - EQ22 */
252 0x0559, /* R156 - EQ23 */
253 0x4000, /* R157 - EQ24 */
254 0x0000, /* R158 */
255 0x0000, /* R159 */
256 0x0000, /* R160 */
257 0x0000, /* R161 - Control Interface Test 1 */
258 0x0000, /* R162 */
259 0x0000, /* R163 */
260 0x0000, /* R164 */
261 0x0000, /* R165 */
262 0x0000, /* R166 */
263 0x0000, /* R167 */
264 0x0000, /* R168 */
265 0x0000, /* R169 */
266 0x0000, /* R170 */
267 0x0000, /* R171 */
268 0x0000, /* R172 */
269 0x0000, /* R173 */
270 0x0000, /* R174 */
271 0x0000, /* R175 */
272 0x0000, /* R176 */
273 0x0000, /* R177 */
274 0x0000, /* R178 */
275 0x0000, /* R179 */
276 0x0000, /* R180 */
277 0x0000, /* R181 */
278 0x0000, /* R182 */
279 0x0000, /* R183 */
280 0x0000, /* R184 */
281 0x0000, /* R185 */
282 0x0000, /* R186 */
283 0x0000, /* R187 */
284 0x0000, /* R188 */
285 0x0000, /* R189 */
286 0x0000, /* R190 */
287 0x0000, /* R191 */
288 0x0000, /* R192 */
289 0x0000, /* R193 */
290 0x0000, /* R194 */
291 0x0000, /* R195 */
292 0x0000, /* R196 */
293 0x0000, /* R197 */
294 0x0000, /* R198 */
295 0x0000, /* R199 */
296 0x0000, /* R200 */
297 0x0000, /* R201 */
298 0x0000, /* R202 */
299 0x0000, /* R203 */
300 0x0000, /* R204 - Analogue Output Bias 0 */
301 0x0000, /* R205 */
302 0x0000, /* R206 */
303 0x0000, /* R207 */
304 0x0000, /* R208 */
305 0x0000, /* R209 */
306 0x0000, /* R210 */
307 0x0000, /* R211 */
308 0x0000, /* R212 */
309 0x0000, /* R213 */
310 0x0000, /* R214 */
311 0x0000, /* R215 */
312 0x0000, /* R216 */
313 0x0000, /* R217 */
314 0x0000, /* R218 */
315 0x0000, /* R219 */
316 0x0000, /* R220 */
317 0x0000, /* R221 */
318 0x0000, /* R222 */
319 0x0000, /* R223 */
320 0x0000, /* R224 */
321 0x0000, /* R225 */
322 0x0000, /* R226 */
323 0x0000, /* R227 */
324 0x0000, /* R228 */
325 0x0000, /* R229 */
326 0x0000, /* R230 */
327 0x0000, /* R231 */
328 0x0000, /* R232 */
329 0x0000, /* R233 */
330 0x0000, /* R234 */
331 0x0000, /* R235 */
332 0x0000, /* R236 */
333 0x0000, /* R237 */
334 0x0000, /* R238 */
335 0x0000, /* R239 */
336 0x0000, /* R240 */
337 0x0000, /* R241 */
338 0x0000, /* R242 */
339 0x0000, /* R243 */
340 0x0000, /* R244 */
341 0x0000, /* R245 */
342 0x0000, /* R246 */
343 0x0000, /* R247 - FLL NCO Test 0 */
344 0x0019, /* R248 - FLL NCO Test 1 */
345};
346
347static struct {
348 int readable;
349 int writable;
350 int vol;
351} wm8904_access[] = {
352 { 0xFFFF, 0xFFFF, 1 }, /* R0 - SW Reset and ID */
353 { 0x0000, 0x0000, 0 }, /* R1 - Revision */
354 { 0x0000, 0x0000, 0 }, /* R2 */
355 { 0x0000, 0x0000, 0 }, /* R3 */
356 { 0x001F, 0x001F, 0 }, /* R4 - Bias Control 0 */
357 { 0x0047, 0x0047, 0 }, /* R5 - VMID Control 0 */
358 { 0x007F, 0x007F, 0 }, /* R6 - Mic Bias Control 0 */
359 { 0xC007, 0xC007, 0 }, /* R7 - Mic Bias Control 1 */
360 { 0x001E, 0x001E, 0 }, /* R8 - Analogue DAC 0 */
361 { 0xFFFF, 0xFFFF, 0 }, /* R9 - mic Filter Control */
362 { 0x0001, 0x0001, 0 }, /* R10 - Analogue ADC 0 */
363 { 0x0000, 0x0000, 0 }, /* R11 */
364 { 0x0003, 0x0003, 0 }, /* R12 - Power Management 0 */
365 { 0x0000, 0x0000, 0 }, /* R13 */
366 { 0x0003, 0x0003, 0 }, /* R14 - Power Management 2 */
367 { 0x0003, 0x0003, 0 }, /* R15 - Power Management 3 */
368 { 0x0000, 0x0000, 0 }, /* R16 */
369 { 0x0000, 0x0000, 0 }, /* R17 */
370 { 0x000F, 0x000F, 0 }, /* R18 - Power Management 6 */
371 { 0x0000, 0x0000, 0 }, /* R19 */
372 { 0x7001, 0x7001, 0 }, /* R20 - Clock Rates 0 */
373 { 0x3C07, 0x3C07, 0 }, /* R21 - Clock Rates 1 */
374 { 0xD00F, 0xD00F, 0 }, /* R22 - Clock Rates 2 */
375 { 0x0000, 0x0000, 0 }, /* R23 */
376 { 0x1FFF, 0x1FFF, 0 }, /* R24 - Audio Interface 0 */
377 { 0x3DDF, 0x3DDF, 0 }, /* R25 - Audio Interface 1 */
378 { 0x0F1F, 0x0F1F, 0 }, /* R26 - Audio Interface 2 */
379 { 0x0FFF, 0x0FFF, 0 }, /* R27 - Audio Interface 3 */
380 { 0x0000, 0x0000, 0 }, /* R28 */
381 { 0x0000, 0x0000, 0 }, /* R29 */
382 { 0x00FF, 0x01FF, 0 }, /* R30 - DAC Digital Volume Left */
383 { 0x00FF, 0x01FF, 0 }, /* R31 - DAC Digital Volume Right */
384 { 0x0FFF, 0x0FFF, 0 }, /* R32 - DAC Digital 0 */
385 { 0x1E4E, 0x1E4E, 0 }, /* R33 - DAC Digital 1 */
386 { 0x0000, 0x0000, 0 }, /* R34 */
387 { 0x0000, 0x0000, 0 }, /* R35 */
388 { 0x00FF, 0x01FF, 0 }, /* R36 - ADC Digital Volume Left */
389 { 0x00FF, 0x01FF, 0 }, /* R37 - ADC Digital Volume Right */
390 { 0x0073, 0x0073, 0 }, /* R38 - ADC Digital 0 */
391 { 0x1800, 0x1800, 0 }, /* R39 - Digital Microphone 0 */
392 { 0xDFEF, 0xDFEF, 0 }, /* R40 - DRC 0 */
393 { 0xFFFF, 0xFFFF, 0 }, /* R41 - DRC 1 */
394 { 0x003F, 0x003F, 0 }, /* R42 - DRC 2 */
395 { 0x07FF, 0x07FF, 0 }, /* R43 - DRC 3 */
396 { 0x009F, 0x009F, 0 }, /* R44 - Analogue Left Input 0 */
397 { 0x009F, 0x009F, 0 }, /* R45 - Analogue Right Input 0 */
398 { 0x007F, 0x007F, 0 }, /* R46 - Analogue Left Input 1 */
399 { 0x007F, 0x007F, 0 }, /* R47 - Analogue Right Input 1 */
400 { 0x0000, 0x0000, 0 }, /* R48 */
401 { 0x0000, 0x0000, 0 }, /* R49 */
402 { 0x0000, 0x0000, 0 }, /* R50 */
403 { 0x0000, 0x0000, 0 }, /* R51 */
404 { 0x0000, 0x0000, 0 }, /* R52 */
405 { 0x0000, 0x0000, 0 }, /* R53 */
406 { 0x0000, 0x0000, 0 }, /* R54 */
407 { 0x0000, 0x0000, 0 }, /* R55 */
408 { 0x0000, 0x0000, 0 }, /* R56 */
409 { 0x017F, 0x01FF, 0 }, /* R57 - Analogue OUT1 Left */
410 { 0x017F, 0x01FF, 0 }, /* R58 - Analogue OUT1 Right */
411 { 0x017F, 0x01FF, 0 }, /* R59 - Analogue OUT2 Left */
412 { 0x017F, 0x01FF, 0 }, /* R60 - Analogue OUT2 Right */
413 { 0x000F, 0x000F, 0 }, /* R61 - Analogue OUT12 ZC */
414 { 0x0000, 0x0000, 0 }, /* R62 */
415 { 0x0000, 0x0000, 0 }, /* R63 */
416 { 0x0000, 0x0000, 0 }, /* R64 */
417 { 0x0000, 0x0000, 0 }, /* R65 */
418 { 0x0000, 0x0000, 0 }, /* R66 */
419 { 0x000F, 0x000F, 0 }, /* R67 - DC Servo 0 */
420 { 0xFFFF, 0xFFFF, 1 }, /* R68 - DC Servo 1 */
421 { 0x0F0F, 0x0F0F, 0 }, /* R69 - DC Servo 2 */
422 { 0x0000, 0x0000, 0 }, /* R70 */
423 { 0x007F, 0x007F, 0 }, /* R71 - DC Servo 4 */
424 { 0x007F, 0x007F, 0 }, /* R72 - DC Servo 5 */
425 { 0x00FF, 0x00FF, 1 }, /* R73 - DC Servo 6 */
426 { 0x00FF, 0x00FF, 1 }, /* R74 - DC Servo 7 */
427 { 0x00FF, 0x00FF, 1 }, /* R75 - DC Servo 8 */
428 { 0x00FF, 0x00FF, 1 }, /* R76 - DC Servo 9 */
429 { 0x0FFF, 0x0000, 1 }, /* R77 - DC Servo Readback 0 */
430 { 0x0000, 0x0000, 0 }, /* R78 */
431 { 0x0000, 0x0000, 0 }, /* R79 */
432 { 0x0000, 0x0000, 0 }, /* R80 */
433 { 0x0000, 0x0000, 0 }, /* R81 */
434 { 0x0000, 0x0000, 0 }, /* R82 */
435 { 0x0000, 0x0000, 0 }, /* R83 */
436 { 0x0000, 0x0000, 0 }, /* R84 */
437 { 0x0000, 0x0000, 0 }, /* R85 */
438 { 0x0000, 0x0000, 0 }, /* R86 */
439 { 0x0000, 0x0000, 0 }, /* R87 */
440 { 0x0000, 0x0000, 0 }, /* R88 */
441 { 0x0000, 0x0000, 0 }, /* R89 */
442 { 0x00FF, 0x00FF, 0 }, /* R90 - Analogue HP 0 */
443 { 0x0000, 0x0000, 0 }, /* R91 */
444 { 0x0000, 0x0000, 0 }, /* R92 */
445 { 0x0000, 0x0000, 0 }, /* R93 */
446 { 0x00FF, 0x00FF, 0 }, /* R94 - Analogue Lineout 0 */
447 { 0x0000, 0x0000, 0 }, /* R95 */
448 { 0x0000, 0x0000, 0 }, /* R96 */
449 { 0x0000, 0x0000, 0 }, /* R97 */
450 { 0x0001, 0x0001, 0 }, /* R98 - Charge Pump 0 */
451 { 0x0000, 0x0000, 0 }, /* R99 */
452 { 0x0000, 0x0000, 0 }, /* R100 */
453 { 0x0000, 0x0000, 0 }, /* R101 */
454 { 0x0000, 0x0000, 0 }, /* R102 */
455 { 0x0000, 0x0000, 0 }, /* R103 */
456 { 0x0001, 0x0001, 0 }, /* R104 - Class W 0 */
457 { 0x0000, 0x0000, 0 }, /* R105 */
458 { 0x0000, 0x0000, 0 }, /* R106 */
459 { 0x0000, 0x0000, 0 }, /* R107 */
460 { 0x011F, 0x011F, 0 }, /* R108 - Write Sequencer 0 */
461 { 0x7FFF, 0x7FFF, 0 }, /* R109 - Write Sequencer 1 */
462 { 0x4FFF, 0x4FFF, 0 }, /* R110 - Write Sequencer 2 */
463 { 0x003F, 0x033F, 0 }, /* R111 - Write Sequencer 3 */
464 { 0x03F1, 0x0000, 0 }, /* R112 - Write Sequencer 4 */
465 { 0x0000, 0x0000, 0 }, /* R113 */
466 { 0x0000, 0x0000, 0 }, /* R114 */
467 { 0x0000, 0x0000, 0 }, /* R115 */
468 { 0x0007, 0x0007, 0 }, /* R116 - FLL Control 1 */
469 { 0x3F77, 0x3F77, 0 }, /* R117 - FLL Control 2 */
470 { 0xFFFF, 0xFFFF, 0 }, /* R118 - FLL Control 3 */
471 { 0x7FEF, 0x7FEF, 0 }, /* R119 - FLL Control 4 */
472 { 0x001B, 0x001B, 0 }, /* R120 - FLL Control 5 */
473 { 0x003F, 0x003F, 0 }, /* R121 - GPIO Control 1 */
474 { 0x003F, 0x003F, 0 }, /* R122 - GPIO Control 2 */
475 { 0x003F, 0x003F, 0 }, /* R123 - GPIO Control 3 */
476 { 0x038F, 0x038F, 0 }, /* R124 - GPIO Control 4 */
477 { 0x0000, 0x0000, 0 }, /* R125 */
478 { 0x00FF, 0x00FF, 0 }, /* R126 - Digital Pulls */
479 { 0x07FF, 0x03FF, 1 }, /* R127 - Interrupt Status */
480 { 0x03FF, 0x03FF, 0 }, /* R128 - Interrupt Status Mask */
481 { 0x03FF, 0x03FF, 0 }, /* R129 - Interrupt Polarity */
482 { 0x03FF, 0x03FF, 0 }, /* R130 - Interrupt Debounce */
483 { 0x0000, 0x0000, 0 }, /* R131 */
484 { 0x0000, 0x0000, 0 }, /* R132 */
485 { 0x0000, 0x0000, 0 }, /* R133 */
486 { 0x0001, 0x0001, 0 }, /* R134 - EQ1 */
487 { 0x001F, 0x001F, 0 }, /* R135 - EQ2 */
488 { 0x001F, 0x001F, 0 }, /* R136 - EQ3 */
489 { 0x001F, 0x001F, 0 }, /* R137 - EQ4 */
490 { 0x001F, 0x001F, 0 }, /* R138 - EQ5 */
491 { 0x001F, 0x001F, 0 }, /* R139 - EQ6 */
492 { 0xFFFF, 0xFFFF, 0 }, /* R140 - EQ7 */
493 { 0xFFFF, 0xFFFF, 0 }, /* R141 - EQ8 */
494 { 0xFFFF, 0xFFFF, 0 }, /* R142 - EQ9 */
495 { 0xFFFF, 0xFFFF, 0 }, /* R143 - EQ10 */
496 { 0xFFFF, 0xFFFF, 0 }, /* R144 - EQ11 */
497 { 0xFFFF, 0xFFFF, 0 }, /* R145 - EQ12 */
498 { 0xFFFF, 0xFFFF, 0 }, /* R146 - EQ13 */
499 { 0xFFFF, 0xFFFF, 0 }, /* R147 - EQ14 */
500 { 0xFFFF, 0xFFFF, 0 }, /* R148 - EQ15 */
501 { 0xFFFF, 0xFFFF, 0 }, /* R149 - EQ16 */
502 { 0xFFFF, 0xFFFF, 0 }, /* R150 - EQ17 */
503 { 0xFFFF, 0xFFFF, 0 }, /* R151wm8523_dai - EQ18 */
504 { 0xFFFF, 0xFFFF, 0 }, /* R152 - EQ19 */
505 { 0xFFFF, 0xFFFF, 0 }, /* R153 - EQ20 */
506 { 0xFFFF, 0xFFFF, 0 }, /* R154 - EQ21 */
507 { 0xFFFF, 0xFFFF, 0 }, /* R155 - EQ22 */
508 { 0xFFFF, 0xFFFF, 0 }, /* R156 - EQ23 */
509 { 0xFFFF, 0xFFFF, 0 }, /* R157 - EQ24 */
510 { 0x0000, 0x0000, 0 }, /* R158 */
511 { 0x0000, 0x0000, 0 }, /* R159 */
512 { 0x0000, 0x0000, 0 }, /* R160 */
513 { 0x0002, 0x0002, 0 }, /* R161 - Control Interface Test 1 */
514 { 0x0000, 0x0000, 0 }, /* R162 */
515 { 0x0000, 0x0000, 0 }, /* R163 */
516 { 0x0000, 0x0000, 0 }, /* R164 */
517 { 0x0000, 0x0000, 0 }, /* R165 */
518 { 0x0000, 0x0000, 0 }, /* R166 */
519 { 0x0000, 0x0000, 0 }, /* R167 */
520 { 0x0000, 0x0000, 0 }, /* R168 */
521 { 0x0000, 0x0000, 0 }, /* R169 */
522 { 0x0000, 0x0000, 0 }, /* R170 */
523 { 0x0000, 0x0000, 0 }, /* R171 */
524 { 0x0000, 0x0000, 0 }, /* R172 */
525 { 0x0000, 0x0000, 0 }, /* R173 */
526 { 0x0000, 0x0000, 0 }, /* R174 */
527 { 0x0000, 0x0000, 0 }, /* R175 */
528 { 0x0000, 0x0000, 0 }, /* R176 */
529 { 0x0000, 0x0000, 0 }, /* R177 */
530 { 0x0000, 0x0000, 0 }, /* R178 */
531 { 0x0000, 0x0000, 0 }, /* R179 */
532 { 0x0000, 0x0000, 0 }, /* R180 */
533 { 0x0000, 0x0000, 0 }, /* R181 */
534 { 0x0000, 0x0000, 0 }, /* R182 */
535 { 0x0000, 0x0000, 0 }, /* R183 */
536 { 0x0000, 0x0000, 0 }, /* R184 */
537 { 0x0000, 0x0000, 0 }, /* R185 */
538 { 0x0000, 0x0000, 0 }, /* R186 */
539 { 0x0000, 0x0000, 0 }, /* R187 */
540 { 0x0000, 0x0000, 0 }, /* R188 */
541 { 0x0000, 0x0000, 0 }, /* R189 */
542 { 0x0000, 0x0000, 0 }, /* R190 */
543 { 0x0000, 0x0000, 0 }, /* R191 */
544 { 0x0000, 0x0000, 0 }, /* R192 */
545 { 0x0000, 0x0000, 0 }, /* R193 */
546 { 0x0000, 0x0000, 0 }, /* R194 */
547 { 0x0000, 0x0000, 0 }, /* R195 */
548 { 0x0000, 0x0000, 0 }, /* R196 */
549 { 0x0000, 0x0000, 0 }, /* R197 */
550 { 0x0000, 0x0000, 0 }, /* R198 */
551 { 0x0000, 0x0000, 0 }, /* R199 */
552 { 0x0000, 0x0000, 0 }, /* R200 */
553 { 0x0000, 0x0000, 0 }, /* R201 */
554 { 0x0000, 0x0000, 0 }, /* R202 */
555 { 0x0000, 0x0000, 0 }, /* R203 */
556 { 0x0070, 0x0070, 0 }, /* R204 - Analogue Output Bias 0 */
557 { 0x0000, 0x0000, 0 }, /* R205 */
558 { 0x0000, 0x0000, 0 }, /* R206 */
559 { 0x0000, 0x0000, 0 }, /* R207 */
560 { 0x0000, 0x0000, 0 }, /* R208 */
561 { 0x0000, 0x0000, 0 }, /* R209 */
562 { 0x0000, 0x0000, 0 }, /* R210 */
563 { 0x0000, 0x0000, 0 }, /* R211 */
564 { 0x0000, 0x0000, 0 }, /* R212 */
565 { 0x0000, 0x0000, 0 }, /* R213 */
566 { 0x0000, 0x0000, 0 }, /* R214 */
567 { 0x0000, 0x0000, 0 }, /* R215 */
568 { 0x0000, 0x0000, 0 }, /* R216 */
569 { 0x0000, 0x0000, 0 }, /* R217 */
570 { 0x0000, 0x0000, 0 }, /* R218 */
571 { 0x0000, 0x0000, 0 }, /* R219 */
572 { 0x0000, 0x0000, 0 }, /* R220 */
573 { 0x0000, 0x0000, 0 }, /* R221 */
574 { 0x0000, 0x0000, 0 }, /* R222 */
575 { 0x0000, 0x0000, 0 }, /* R223 */
576 { 0x0000, 0x0000, 0 }, /* R224 */
577 { 0x0000, 0x0000, 0 }, /* R225 */
578 { 0x0000, 0x0000, 0 }, /* R226 */
579 { 0x0000, 0x0000, 0 }, /* R227 */
580 { 0x0000, 0x0000, 0 }, /* R228 */
581 { 0x0000, 0x0000, 0 }, /* R229 */
582 { 0x0000, 0x0000, 0 }, /* R230 */
583 { 0x0000, 0x0000, 0 }, /* R231 */
584 { 0x0000, 0x0000, 0 }, /* R232 */
585 { 0x0000, 0x0000, 0 }, /* R233 */
586 { 0x0000, 0x0000, 0 }, /* R234 */
587 { 0x0000, 0x0000, 0 }, /* R235 */
588 { 0x0000, 0x0000, 0 }, /* R236 */
589 { 0x0000, 0x0000, 0 }, /* R237 */
590 { 0x0000, 0x0000, 0 }, /* R238 */
591 { 0x0000, 0x0000, 0 }, /* R239 */
592 { 0x0000, 0x0000, 0 }, /* R240 */
593 { 0x0000, 0x0000, 0 }, /* R241 */
594 { 0x0000, 0x0000, 0 }, /* R242 */
595 { 0x0000, 0x0000, 0 }, /* R243 */
596 { 0x0000, 0x0000, 0 }, /* R244 */
597 { 0x0000, 0x0000, 0 }, /* R245 */
598 { 0x0000, 0x0000, 0 }, /* R246 */
599 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */
600 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */
601};
602
603static int wm8904_volatile_register(unsigned int reg)
604{
605 return wm8904_access[reg].vol;
606}
607
608static int wm8904_reset(struct snd_soc_codec *codec)
609{
610 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
611}
612
613static int wm8904_configure_clocking(struct snd_soc_codec *codec)
614{
615 struct wm8904_priv *wm8904 = codec->private_data;
616 unsigned int clock0, clock2, rate;
617
618 /* Gate the clock while we're updating to avoid misclocking */
619 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
620 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
621 WM8904_SYSCLK_SRC, 0);
622
623 /* This should be done on init() for bypass paths */
624 switch (wm8904->sysclk_src) {
625 case WM8904_CLK_MCLK:
626 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8904->mclk_rate);
627
628 clock2 &= ~WM8904_SYSCLK_SRC;
629 rate = wm8904->mclk_rate;
630
631 /* Ensure the FLL is stopped */
632 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
633 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
634 break;
635
636 case WM8904_CLK_FLL:
637 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
638 wm8904->fll_fout);
639
640 clock2 |= WM8904_SYSCLK_SRC;
641 rate = wm8904->fll_fout;
642 break;
643
644 default:
645 dev_err(codec->dev, "System clock not configured\n");
646 return -EINVAL;
647 }
648
649 /* SYSCLK shouldn't be over 13.5MHz */
650 if (rate > 13500000) {
651 clock0 = WM8904_MCLK_DIV;
652 wm8904->sysclk_rate = rate / 2;
653 } else {
654 clock0 = 0;
655 wm8904->sysclk_rate = rate;
656 }
657
658 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, WM8904_MCLK_DIV,
659 clock0);
660
661 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
662 WM8904_CLK_SYS_ENA | WM8904_SYSCLK_SRC, clock2);
663
664 dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm8904->sysclk_rate);
665
666 return 0;
667}
668
669static void wm8904_set_drc(struct snd_soc_codec *codec)
670{
671 struct wm8904_priv *wm8904 = codec->private_data;
672 struct wm8904_pdata *pdata = wm8904->pdata;
673 int save, i;
674
675 /* Save any enables; the configuration should clear them. */
676 save = snd_soc_read(codec, WM8904_DRC_0);
677
678 for (i = 0; i < WM8904_DRC_REGS; i++)
679 snd_soc_update_bits(codec, WM8904_DRC_0 + i, 0xffff,
680 pdata->drc_cfgs[wm8904->drc_cfg].regs[i]);
681
682 /* Reenable the DRC */
683 snd_soc_update_bits(codec, WM8904_DRC_0,
684 WM8904_DRC_ENA | WM8904_DRC_DAC_PATH, save);
685}
686
687static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol,
688 struct snd_ctl_elem_value *ucontrol)
689{
690 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
691 struct wm8904_priv *wm8904 = codec->private_data;
692 struct wm8904_pdata *pdata = wm8904->pdata;
693 int value = ucontrol->value.integer.value[0];
694
695 if (value >= pdata->num_drc_cfgs)
696 return -EINVAL;
697
698 wm8904->drc_cfg = value;
699
700 wm8904_set_drc(codec);
701
702 return 0;
703}
704
705static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol,
706 struct snd_ctl_elem_value *ucontrol)
707{
708 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
709 struct wm8904_priv *wm8904 = codec->private_data;
710
711 ucontrol->value.enumerated.item[0] = wm8904->drc_cfg;
712
713 return 0;
714}
715
716static void wm8904_set_retune_mobile(struct snd_soc_codec *codec)
717{
718 struct wm8904_priv *wm8904 = codec->private_data;
719 struct wm8904_pdata *pdata = wm8904->pdata;
720 int best, best_val, save, i, cfg;
721
722 if (!pdata || !wm8904->num_retune_mobile_texts)
723 return;
724
725 /* Find the version of the currently selected configuration
726 * with the nearest sample rate. */
727 cfg = wm8904->retune_mobile_cfg;
728 best = 0;
729 best_val = INT_MAX;
730 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
731 if (strcmp(pdata->retune_mobile_cfgs[i].name,
732 wm8904->retune_mobile_texts[cfg]) == 0 &&
733 abs(pdata->retune_mobile_cfgs[i].rate
734 - wm8904->fs) < best_val) {
735 best = i;
736 best_val = abs(pdata->retune_mobile_cfgs[i].rate
737 - wm8904->fs);
738 }
739 }
740
741 dev_dbg(codec->dev, "ReTune Mobile %s/%dHz for %dHz sample rate\n",
742 pdata->retune_mobile_cfgs[best].name,
743 pdata->retune_mobile_cfgs[best].rate,
744 wm8904->fs);
745
746 /* The EQ will be disabled while reconfiguring it, remember the
747 * current configuration.
748 */
749 save = snd_soc_read(codec, WM8904_EQ1);
750
751 for (i = 0; i < WM8904_EQ_REGS; i++)
752 snd_soc_update_bits(codec, WM8904_EQ1 + i, 0xffff,
753 pdata->retune_mobile_cfgs[best].regs[i]);
754
755 snd_soc_update_bits(codec, WM8904_EQ1, WM8904_EQ_ENA, save);
756}
757
758static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
759 struct snd_ctl_elem_value *ucontrol)
760{
761 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
762 struct wm8904_priv *wm8904 = codec->private_data;
763 struct wm8904_pdata *pdata = wm8904->pdata;
764 int value = ucontrol->value.integer.value[0];
765
766 if (value >= pdata->num_retune_mobile_cfgs)
767 return -EINVAL;
768
769 wm8904->retune_mobile_cfg = value;
770
771 wm8904_set_retune_mobile(codec);
772
773 return 0;
774}
775
776static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
777 struct snd_ctl_elem_value *ucontrol)
778{
779 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
780 struct wm8904_priv *wm8904 = codec->private_data;
781
782 ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg;
783
784 return 0;
785}
786
787static int deemph_settings[] = { 0, 32000, 44100, 48000 };
788
789static int wm8904_set_deemph(struct snd_soc_codec *codec)
790{
791 struct wm8904_priv *wm8904 = codec->private_data;
792 int val, i, best;
793
794 /* If we're using deemphasis select the nearest available sample
795 * rate.
796 */
797 if (wm8904->deemph) {
798 best = 1;
799 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
800 if (abs(deemph_settings[i] - wm8904->fs) <
801 abs(deemph_settings[best] - wm8904->fs))
802 best = i;
803 }
804
805 val = best << WM8904_DEEMPH_SHIFT;
806 } else {
807 val = 0;
808 }
809
810 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
811
812 return snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
813 WM8904_DEEMPH_MASK, val);
814}
815
816static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
817 struct snd_ctl_elem_value *ucontrol)
818{
819 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
820 struct wm8904_priv *wm8904 = codec->private_data;
821
822 return wm8904->deemph;
823}
824
825static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
826 struct snd_ctl_elem_value *ucontrol)
827{
828 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
829 struct wm8904_priv *wm8904 = codec->private_data;
830 int deemph = ucontrol->value.enumerated.item[0];
831
832 if (deemph > 1)
833 return -EINVAL;
834
835 wm8904->deemph = deemph;
836
837 return wm8904_set_deemph(codec);
838}
839
840static const DECLARE_TLV_DB_SCALE(dac_boost_tlv, 0, 600, 0);
841static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
842static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
843static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 300, 0);
844static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
845
846static const char *input_mode_text[] = {
847 "Single-Ended", "Differential Line", "Differential Mic"
848};
849
850static const struct soc_enum lin_mode =
851 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 0, 3, input_mode_text);
852
853static const struct soc_enum rin_mode =
854 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 0, 3, input_mode_text);
855
856static const char *hpf_mode_text[] = {
857 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
858};
859
860static const struct soc_enum hpf_mode =
861 SOC_ENUM_SINGLE(WM8904_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
862
863static const struct snd_kcontrol_new wm8904_adc_snd_controls[] = {
864SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8904_ADC_DIGITAL_VOLUME_LEFT,
865 WM8904_ADC_DIGITAL_VOLUME_RIGHT, 1, 119, 0, digital_tlv),
866
867SOC_ENUM("Left Caputure Mode", lin_mode),
868SOC_ENUM("Right Capture Mode", rin_mode),
869
870/* No TLV since it depends on mode */
871SOC_DOUBLE_R("Capture Volume", WM8904_ANALOGUE_LEFT_INPUT_0,
872 WM8904_ANALOGUE_RIGHT_INPUT_0, 0, 31, 0),
873SOC_DOUBLE_R("Capture Switch", WM8904_ANALOGUE_LEFT_INPUT_0,
874 WM8904_ANALOGUE_RIGHT_INPUT_0, 7, 1, 0),
875
876SOC_SINGLE("High Pass Filter Switch", WM8904_ADC_DIGITAL_0, 4, 1, 0),
877SOC_ENUM("High Pass Filter Mode", hpf_mode),
878
879SOC_SINGLE("ADC 128x OSR Switch", WM8904_ANALOGUE_ADC_0, 0, 1, 0),
880};
881
882static const char *drc_path_text[] = {
883 "ADC", "DAC"
884};
885
886static const struct soc_enum drc_path =
887 SOC_ENUM_SINGLE(WM8904_DRC_0, 14, 2, drc_path_text);
888
889static const struct snd_kcontrol_new wm8904_dac_snd_controls[] = {
890SOC_SINGLE_TLV("Digital Playback Boost Volume",
891 WM8904_AUDIO_INTERFACE_0, 9, 3, 0, dac_boost_tlv),
892SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8904_DAC_DIGITAL_VOLUME_LEFT,
893 WM8904_DAC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv),
894
895SOC_DOUBLE_R_TLV("Headphone Volume", WM8904_ANALOGUE_OUT1_LEFT,
896 WM8904_ANALOGUE_OUT1_RIGHT, 0, 63, 0, out_tlv),
897SOC_DOUBLE_R("Headphone Switch", WM8904_ANALOGUE_OUT1_LEFT,
898 WM8904_ANALOGUE_OUT1_RIGHT, 8, 1, 1),
899SOC_DOUBLE_R("Headphone ZC Switch", WM8904_ANALOGUE_OUT1_LEFT,
900 WM8904_ANALOGUE_OUT1_RIGHT, 6, 1, 0),
901
902SOC_DOUBLE_R_TLV("Line Output Volume", WM8904_ANALOGUE_OUT2_LEFT,
903 WM8904_ANALOGUE_OUT2_RIGHT, 0, 63, 0, out_tlv),
904SOC_DOUBLE_R("Line Output Switch", WM8904_ANALOGUE_OUT2_LEFT,
905 WM8904_ANALOGUE_OUT2_RIGHT, 8, 1, 1),
906SOC_DOUBLE_R("Line Output ZC Switch", WM8904_ANALOGUE_OUT2_LEFT,
907 WM8904_ANALOGUE_OUT2_RIGHT, 6, 1, 0),
908
909SOC_SINGLE("EQ Switch", WM8904_EQ1, 0, 1, 0),
910SOC_SINGLE("DRC Switch", WM8904_DRC_0, 15, 1, 0),
911SOC_ENUM("DRC Path", drc_path),
912SOC_SINGLE("DAC OSRx2 Switch", WM8904_DAC_DIGITAL_1, 6, 1, 0),
913SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
914 wm8904_get_deemph, wm8904_put_deemph),
915};
916
917static const struct snd_kcontrol_new wm8904_snd_controls[] = {
918SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8904_DAC_DIGITAL_0, 4, 8, 15, 0,
919 sidetone_tlv),
920};
921
922static const struct snd_kcontrol_new wm8904_eq_controls[] = {
923SOC_SINGLE_TLV("EQ1 Volume", WM8904_EQ2, 0, 24, 0, eq_tlv),
924SOC_SINGLE_TLV("EQ2 Volume", WM8904_EQ3, 0, 24, 0, eq_tlv),
925SOC_SINGLE_TLV("EQ3 Volume", WM8904_EQ4, 0, 24, 0, eq_tlv),
926SOC_SINGLE_TLV("EQ4 Volume", WM8904_EQ5, 0, 24, 0, eq_tlv),
927SOC_SINGLE_TLV("EQ5 Volume", WM8904_EQ6, 0, 24, 0, eq_tlv),
928};
929
930static int cp_event(struct snd_soc_dapm_widget *w,
931 struct snd_kcontrol *kcontrol, int event)
932{
933 BUG_ON(event != SND_SOC_DAPM_POST_PMU);
934
935 /* Maximum startup time */
936 udelay(500);
937
938 return 0;
939}
940
941static int sysclk_event(struct snd_soc_dapm_widget *w,
942 struct snd_kcontrol *kcontrol, int event)
943{
944 struct snd_soc_codec *codec = w->codec;
945 struct wm8904_priv *wm8904 = codec->private_data;
946
947 switch (event) {
948 case SND_SOC_DAPM_PRE_PMU:
949 /* If we're using the FLL then we only start it when
950 * required; we assume that the configuration has been
951 * done previously and all we need to do is kick it
952 * off.
953 */
954 switch (wm8904->sysclk_src) {
955 case WM8904_CLK_FLL:
956 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
957 WM8904_FLL_OSC_ENA,
958 WM8904_FLL_OSC_ENA);
959
960 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
961 WM8904_FLL_ENA,
962 WM8904_FLL_ENA);
963 break;
964
965 default:
966 break;
967 }
968 break;
969
970 case SND_SOC_DAPM_POST_PMD:
971 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
972 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
973 break;
974 }
975
976 return 0;
977}
978
979static int out_pga_event(struct snd_soc_dapm_widget *w,
980 struct snd_kcontrol *kcontrol, int event)
981{
982 struct snd_soc_codec *codec = w->codec;
983 struct wm8904_priv *wm8904 = codec->private_data;
984 int reg, val;
985 int dcs_mask;
986 int dcs_l, dcs_r;
987 int dcs_l_reg, dcs_r_reg;
988 int timeout;
989 int pwr_reg;
990
991 /* This code is shared between HP and LINEOUT; we do all our
992 * power management in stereo pairs to avoid latency issues so
993 * we reuse shift to identify which rather than strcmp() the
994 * name. */
995 reg = w->shift;
996
997 switch (reg) {
998 case WM8904_ANALOGUE_HP_0:
999 pwr_reg = WM8904_POWER_MANAGEMENT_2;
1000 dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1;
1001 dcs_r_reg = WM8904_DC_SERVO_8;
1002 dcs_l_reg = WM8904_DC_SERVO_9;
1003 dcs_l = 0;
1004 dcs_r = 1;
1005 break;
1006 case WM8904_ANALOGUE_LINEOUT_0:
1007 pwr_reg = WM8904_POWER_MANAGEMENT_3;
1008 dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3;
1009 dcs_r_reg = WM8904_DC_SERVO_6;
1010 dcs_l_reg = WM8904_DC_SERVO_7;
1011 dcs_l = 2;
1012 dcs_r = 3;
1013 break;
1014 default:
1015 BUG();
1016 return -EINVAL;
1017 }
1018
1019 switch (event) {
1020 case SND_SOC_DAPM_PRE_PMU:
1021 /* Power on the PGAs */
1022 snd_soc_update_bits(codec, pwr_reg,
1023 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1024 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA);
1025
1026 /* Power on the amplifier */
1027 snd_soc_update_bits(codec, reg,
1028 WM8904_HPL_ENA | WM8904_HPR_ENA,
1029 WM8904_HPL_ENA | WM8904_HPR_ENA);
1030
1031
1032 /* Enable the first stage */
1033 snd_soc_update_bits(codec, reg,
1034 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY,
1035 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY);
1036
1037 /* Power up the DC servo */
1038 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1039 dcs_mask, dcs_mask);
1040
1041 /* Either calibrate the DC servo or restore cached state
1042 * if we have that.
1043 */
1044 if (wm8904->dcs_state[dcs_l] || wm8904->dcs_state[dcs_r]) {
1045 dev_dbg(codec->dev, "Restoring DC servo state\n");
1046
1047 snd_soc_write(codec, dcs_l_reg,
1048 wm8904->dcs_state[dcs_l]);
1049 snd_soc_write(codec, dcs_r_reg,
1050 wm8904->dcs_state[dcs_r]);
1051
1052 snd_soc_write(codec, WM8904_DC_SERVO_1, dcs_mask);
1053
1054 timeout = 20;
1055 } else {
1056 dev_dbg(codec->dev, "Calibrating DC servo\n");
1057
1058 snd_soc_write(codec, WM8904_DC_SERVO_1,
1059 dcs_mask << WM8904_DCS_TRIG_STARTUP_0_SHIFT);
1060
1061 timeout = 500;
1062 }
1063
1064 /* Wait for DC servo to complete */
1065 dcs_mask <<= WM8904_DCS_CAL_COMPLETE_SHIFT;
1066 do {
1067 val = snd_soc_read(codec, WM8904_DC_SERVO_READBACK_0);
1068 if ((val & dcs_mask) == dcs_mask)
1069 break;
1070
1071 msleep(1);
1072 } while (--timeout);
1073
1074 if ((val & dcs_mask) != dcs_mask)
1075 dev_warn(codec->dev, "DC servo timed out\n");
1076 else
1077 dev_dbg(codec->dev, "DC servo ready\n");
1078
1079 /* Enable the output stage */
1080 snd_soc_update_bits(codec, reg,
1081 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1082 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP);
1083 break;
1084
1085 case SND_SOC_DAPM_POST_PMU:
1086 /* Unshort the output itself */
1087 snd_soc_update_bits(codec, reg,
1088 WM8904_HPL_RMV_SHORT |
1089 WM8904_HPR_RMV_SHORT,
1090 WM8904_HPL_RMV_SHORT |
1091 WM8904_HPR_RMV_SHORT);
1092
1093 break;
1094
1095 case SND_SOC_DAPM_PRE_PMD:
1096 /* Short the output */
1097 snd_soc_update_bits(codec, reg,
1098 WM8904_HPL_RMV_SHORT |
1099 WM8904_HPR_RMV_SHORT, 0);
1100 break;
1101
1102 case SND_SOC_DAPM_POST_PMD:
1103 /* Cache the DC servo configuration; this will be
1104 * invalidated if we change the configuration. */
1105 wm8904->dcs_state[dcs_l] = snd_soc_read(codec, dcs_l_reg);
1106 wm8904->dcs_state[dcs_r] = snd_soc_read(codec, dcs_r_reg);
1107
1108 snd_soc_update_bits(codec, WM8904_DC_SERVO_0,
1109 dcs_mask, 0);
1110
1111 /* Disable the amplifier input and output stages */
1112 snd_soc_update_bits(codec, reg,
1113 WM8904_HPL_ENA | WM8904_HPR_ENA |
1114 WM8904_HPL_ENA_DLY | WM8904_HPR_ENA_DLY |
1115 WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP,
1116 0);
1117
1118 /* PGAs too */
1119 snd_soc_update_bits(codec, pwr_reg,
1120 WM8904_HPL_PGA_ENA | WM8904_HPR_PGA_ENA,
1121 0);
1122 break;
1123 }
1124
1125 return 0;
1126}
1127
1128static const char *lin_text[] = {
1129 "IN1L", "IN2L", "IN3L"
1130};
1131
1132static const struct soc_enum lin_enum =
1133 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 2, 3, lin_text);
1134
1135static const struct snd_kcontrol_new lin_mux =
1136 SOC_DAPM_ENUM("Left Capture Mux", lin_enum);
1137
1138static const struct soc_enum lin_inv_enum =
1139 SOC_ENUM_SINGLE(WM8904_ANALOGUE_LEFT_INPUT_1, 4, 3, lin_text);
1140
1141static const struct snd_kcontrol_new lin_inv_mux =
1142 SOC_DAPM_ENUM("Left Capture Inveting Mux", lin_inv_enum);
1143
1144static const char *rin_text[] = {
1145 "IN1R", "IN2R", "IN3R"
1146};
1147
1148static const struct soc_enum rin_enum =
1149 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 2, 3, rin_text);
1150
1151static const struct snd_kcontrol_new rin_mux =
1152 SOC_DAPM_ENUM("Right Capture Mux", rin_enum);
1153
1154static const struct soc_enum rin_inv_enum =
1155 SOC_ENUM_SINGLE(WM8904_ANALOGUE_RIGHT_INPUT_1, 4, 3, rin_text);
1156
1157static const struct snd_kcontrol_new rin_inv_mux =
1158 SOC_DAPM_ENUM("Right Capture Inveting Mux", rin_inv_enum);
1159
1160static const char *aif_text[] = {
1161 "Left", "Right"
1162};
1163
1164static const struct soc_enum aifoutl_enum =
1165 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 7, 2, aif_text);
1166
1167static const struct snd_kcontrol_new aifoutl_mux =
1168 SOC_DAPM_ENUM("AIFOUTL Mux", aifoutl_enum);
1169
1170static const struct soc_enum aifoutr_enum =
1171 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 6, 2, aif_text);
1172
1173static const struct snd_kcontrol_new aifoutr_mux =
1174 SOC_DAPM_ENUM("AIFOUTR Mux", aifoutr_enum);
1175
1176static const struct soc_enum aifinl_enum =
1177 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 5, 2, aif_text);
1178
1179static const struct snd_kcontrol_new aifinl_mux =
1180 SOC_DAPM_ENUM("AIFINL Mux", aifinl_enum);
1181
1182static const struct soc_enum aifinr_enum =
1183 SOC_ENUM_SINGLE(WM8904_AUDIO_INTERFACE_0, 4, 2, aif_text);
1184
1185static const struct snd_kcontrol_new aifinr_mux =
1186 SOC_DAPM_ENUM("AIFINR Mux", aifinr_enum);
1187
1188static const struct snd_soc_dapm_widget wm8904_core_dapm_widgets[] = {
1189SND_SOC_DAPM_SUPPLY("SYSCLK", WM8904_CLOCK_RATES_2, 2, 0, sysclk_event,
1190 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
1191SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8904_CLOCK_RATES_2, 1, 0, NULL, 0),
1192SND_SOC_DAPM_SUPPLY("TOCLK", WM8904_CLOCK_RATES_2, 0, 0, NULL, 0),
1193};
1194
1195static const struct snd_soc_dapm_widget wm8904_adc_dapm_widgets[] = {
1196SND_SOC_DAPM_INPUT("IN1L"),
1197SND_SOC_DAPM_INPUT("IN1R"),
1198SND_SOC_DAPM_INPUT("IN2L"),
1199SND_SOC_DAPM_INPUT("IN2R"),
1200SND_SOC_DAPM_INPUT("IN3L"),
1201SND_SOC_DAPM_INPUT("IN3R"),
1202
1203SND_SOC_DAPM_MICBIAS("MICBIAS", WM8904_MIC_BIAS_CONTROL_0, 0, 0),
1204
1205SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lin_mux),
1206SND_SOC_DAPM_MUX("Left Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1207 &lin_inv_mux),
1208SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rin_mux),
1209SND_SOC_DAPM_MUX("Right Capture Inverting Mux", SND_SOC_NOPM, 0, 0,
1210 &rin_inv_mux),
1211
1212SND_SOC_DAPM_PGA("Left Capture PGA", WM8904_POWER_MANAGEMENT_0, 1, 0,
1213 NULL, 0),
1214SND_SOC_DAPM_PGA("Right Capture PGA", WM8904_POWER_MANAGEMENT_0, 0, 0,
1215 NULL, 0),
1216
1217SND_SOC_DAPM_ADC("ADCL", NULL, WM8904_POWER_MANAGEMENT_6, 1, 0),
1218SND_SOC_DAPM_ADC("ADCR", NULL, WM8904_POWER_MANAGEMENT_6, 0, 0),
1219
1220SND_SOC_DAPM_MUX("AIFOUTL Mux", SND_SOC_NOPM, 0, 0, &aifoutl_mux),
1221SND_SOC_DAPM_MUX("AIFOUTR Mux", SND_SOC_NOPM, 0, 0, &aifoutr_mux),
1222
1223SND_SOC_DAPM_AIF_OUT("AIFOUTL", "Capture", 0, SND_SOC_NOPM, 0, 0),
1224SND_SOC_DAPM_AIF_OUT("AIFOUTR", "Capture", 1, SND_SOC_NOPM, 0, 0),
1225};
1226
1227static const struct snd_soc_dapm_widget wm8904_dac_dapm_widgets[] = {
1228SND_SOC_DAPM_AIF_IN("AIFINL", "Playback", 0, SND_SOC_NOPM, 0, 0),
1229SND_SOC_DAPM_AIF_IN("AIFINR", "Playback", 1, SND_SOC_NOPM, 0, 0),
1230
1231SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &aifinl_mux),
1232SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &aifinr_mux),
1233
1234SND_SOC_DAPM_DAC("DACL", NULL, WM8904_POWER_MANAGEMENT_6, 3, 0),
1235SND_SOC_DAPM_DAC("DACR", NULL, WM8904_POWER_MANAGEMENT_6, 2, 0),
1236
1237SND_SOC_DAPM_SUPPLY("Charge pump", WM8904_CHARGE_PUMP_0, 0, 0, cp_event,
1238 SND_SOC_DAPM_POST_PMU),
1239
1240SND_SOC_DAPM_PGA("HPL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1241SND_SOC_DAPM_PGA("HPR PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1242
1243SND_SOC_DAPM_PGA("LINEL PGA", SND_SOC_NOPM, 1, 0, NULL, 0),
1244SND_SOC_DAPM_PGA("LINER PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
1245
1246SND_SOC_DAPM_PGA_E("Headphone Output", SND_SOC_NOPM, WM8904_ANALOGUE_HP_0,
1247 0, NULL, 0, out_pga_event,
1248 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1249 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1250SND_SOC_DAPM_PGA_E("Line Output", SND_SOC_NOPM, WM8904_ANALOGUE_LINEOUT_0,
1251 0, NULL, 0, out_pga_event,
1252 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
1253 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
1254
1255SND_SOC_DAPM_OUTPUT("HPOUTL"),
1256SND_SOC_DAPM_OUTPUT("HPOUTR"),
1257SND_SOC_DAPM_OUTPUT("LINEOUTL"),
1258SND_SOC_DAPM_OUTPUT("LINEOUTR"),
1259};
1260
1261static const char *out_mux_text[] = {
1262 "DAC", "Bypass"
1263};
1264
1265static const struct soc_enum hpl_enum =
1266 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 3, 2, out_mux_text);
1267
1268static const struct snd_kcontrol_new hpl_mux =
1269 SOC_DAPM_ENUM("HPL Mux", hpl_enum);
1270
1271static const struct soc_enum hpr_enum =
1272 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 2, 2, out_mux_text);
1273
1274static const struct snd_kcontrol_new hpr_mux =
1275 SOC_DAPM_ENUM("HPR Mux", hpr_enum);
1276
1277static const struct soc_enum linel_enum =
1278 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 1, 2, out_mux_text);
1279
1280static const struct snd_kcontrol_new linel_mux =
1281 SOC_DAPM_ENUM("LINEL Mux", linel_enum);
1282
1283static const struct soc_enum liner_enum =
1284 SOC_ENUM_SINGLE(WM8904_ANALOGUE_OUT12_ZC, 0, 2, out_mux_text);
1285
1286static const struct snd_kcontrol_new liner_mux =
1287 SOC_DAPM_ENUM("LINEL Mux", liner_enum);
1288
1289static const char *sidetone_text[] = {
1290 "None", "Left", "Right"
1291};
1292
1293static const struct soc_enum dacl_sidetone_enum =
1294 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 2, 3, sidetone_text);
1295
1296static const struct snd_kcontrol_new dacl_sidetone_mux =
1297 SOC_DAPM_ENUM("Left Sidetone Mux", dacl_sidetone_enum);
1298
1299static const struct soc_enum dacr_sidetone_enum =
1300 SOC_ENUM_SINGLE(WM8904_DAC_DIGITAL_0, 0, 3, sidetone_text);
1301
1302static const struct snd_kcontrol_new dacr_sidetone_mux =
1303 SOC_DAPM_ENUM("Right Sidetone Mux", dacr_sidetone_enum);
1304
1305static const struct snd_soc_dapm_widget wm8904_dapm_widgets[] = {
1306SND_SOC_DAPM_SUPPLY("Class G", WM8904_CLASS_W_0, 0, 1, NULL, 0),
1307SND_SOC_DAPM_PGA("Left Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1308SND_SOC_DAPM_PGA("Right Bypass", SND_SOC_NOPM, 0, 0, NULL, 0),
1309
1310SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &dacl_sidetone_mux),
1311SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &dacr_sidetone_mux),
1312
1313SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
1314SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
1315SND_SOC_DAPM_MUX("LINEL Mux", SND_SOC_NOPM, 0, 0, &linel_mux),
1316SND_SOC_DAPM_MUX("LINER Mux", SND_SOC_NOPM, 0, 0, &liner_mux),
1317};
1318
1319static const struct snd_soc_dapm_route core_intercon[] = {
1320 { "CLK_DSP", NULL, "SYSCLK" },
1321 { "TOCLK", NULL, "SYSCLK" },
1322};
1323
1324static const struct snd_soc_dapm_route adc_intercon[] = {
1325 { "Left Capture Mux", "IN1L", "IN1L" },
1326 { "Left Capture Mux", "IN2L", "IN2L" },
1327 { "Left Capture Mux", "IN3L", "IN3L" },
1328
1329 { "Left Capture Inverting Mux", "IN1L", "IN1L" },
1330 { "Left Capture Inverting Mux", "IN2L", "IN2L" },
1331 { "Left Capture Inverting Mux", "IN3L", "IN3L" },
1332
1333 { "Right Capture Mux", "IN1R", "IN1R" },
1334 { "Right Capture Mux", "IN2R", "IN2R" },
1335 { "Right Capture Mux", "IN3R", "IN3R" },
1336
1337 { "Right Capture Inverting Mux", "IN1R", "IN1R" },
1338 { "Right Capture Inverting Mux", "IN2R", "IN2R" },
1339 { "Right Capture Inverting Mux", "IN3R", "IN3R" },
1340
1341 { "Left Capture PGA", NULL, "Left Capture Mux" },
1342 { "Left Capture PGA", NULL, "Left Capture Inverting Mux" },
1343
1344 { "Right Capture PGA", NULL, "Right Capture Mux" },
1345 { "Right Capture PGA", NULL, "Right Capture Inverting Mux" },
1346
1347 { "AIFOUTL", "Left", "ADCL" },
1348 { "AIFOUTL", "Right", "ADCR" },
1349 { "AIFOUTR", "Left", "ADCL" },
1350 { "AIFOUTR", "Right", "ADCR" },
1351
1352 { "ADCL", NULL, "CLK_DSP" },
1353 { "ADCL", NULL, "Left Capture PGA" },
1354
1355 { "ADCR", NULL, "CLK_DSP" },
1356 { "ADCR", NULL, "Right Capture PGA" },
1357};
1358
1359static const struct snd_soc_dapm_route dac_intercon[] = {
1360 { "DACL", "Right", "AIFINR" },
1361 { "DACL", "Left", "AIFINL" },
1362 { "DACL", NULL, "CLK_DSP" },
1363
1364 { "DACR", "Right", "AIFINR" },
1365 { "DACR", "Left", "AIFINL" },
1366 { "DACR", NULL, "CLK_DSP" },
1367
1368 { "Charge pump", NULL, "SYSCLK" },
1369
1370 { "Headphone Output", NULL, "HPL PGA" },
1371 { "Headphone Output", NULL, "HPR PGA" },
1372 { "Headphone Output", NULL, "Charge pump" },
1373 { "Headphone Output", NULL, "TOCLK" },
1374
1375 { "Line Output", NULL, "LINEL PGA" },
1376 { "Line Output", NULL, "LINER PGA" },
1377 { "Line Output", NULL, "Charge pump" },
1378 { "Line Output", NULL, "TOCLK" },
1379
1380 { "HPOUTL", NULL, "Headphone Output" },
1381 { "HPOUTR", NULL, "Headphone Output" },
1382
1383 { "LINEOUTL", NULL, "Line Output" },
1384 { "LINEOUTR", NULL, "Line Output" },
1385};
1386
1387static const struct snd_soc_dapm_route wm8904_intercon[] = {
1388 { "Left Sidetone", "Left", "ADCL" },
1389 { "Left Sidetone", "Right", "ADCR" },
1390 { "DACL", NULL, "Left Sidetone" },
1391
1392 { "Right Sidetone", "Left", "ADCL" },
1393 { "Right Sidetone", "Right", "ADCR" },
1394 { "DACR", NULL, "Right Sidetone" },
1395
1396 { "Left Bypass", NULL, "Class G" },
1397 { "Left Bypass", NULL, "Left Capture PGA" },
1398
1399 { "Right Bypass", NULL, "Class G" },
1400 { "Right Bypass", NULL, "Right Capture PGA" },
1401
1402 { "HPL Mux", "DAC", "DACL" },
1403 { "HPL Mux", "Bypass", "Left Bypass" },
1404
1405 { "HPR Mux", "DAC", "DACR" },
1406 { "HPR Mux", "Bypass", "Right Bypass" },
1407
1408 { "LINEL Mux", "DAC", "DACL" },
1409 { "LINEL Mux", "Bypass", "Left Bypass" },
1410
1411 { "LINER Mux", "DAC", "DACR" },
1412 { "LINER Mux", "Bypass", "Right Bypass" },
1413
1414 { "HPL PGA", NULL, "HPL Mux" },
1415 { "HPR PGA", NULL, "HPR Mux" },
1416
1417 { "LINEL PGA", NULL, "LINEL Mux" },
1418 { "LINER PGA", NULL, "LINER Mux" },
1419};
1420
1421static const struct snd_soc_dapm_route wm8912_intercon[] = {
1422 { "HPL PGA", NULL, "DACL" },
1423 { "HPR PGA", NULL, "DACR" },
1424
1425 { "LINEL PGA", NULL, "DACL" },
1426 { "LINER PGA", NULL, "DACR" },
1427};
1428
1429static int wm8904_add_widgets(struct snd_soc_codec *codec)
1430{
1431 struct wm8904_priv *wm8904 = codec->private_data;
1432
1433 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets,
1434 ARRAY_SIZE(wm8904_core_dapm_widgets));
1435 snd_soc_dapm_add_routes(codec, core_intercon,
1436 ARRAY_SIZE(core_intercon));
1437
1438 switch (wm8904->devtype) {
1439 case WM8904:
1440 snd_soc_add_controls(codec, wm8904_adc_snd_controls,
1441 ARRAY_SIZE(wm8904_adc_snd_controls));
1442 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1443 ARRAY_SIZE(wm8904_dac_snd_controls));
1444 snd_soc_add_controls(codec, wm8904_snd_controls,
1445 ARRAY_SIZE(wm8904_snd_controls));
1446
1447 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets,
1448 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1449 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1450 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1451 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets,
1452 ARRAY_SIZE(wm8904_dapm_widgets));
1453
1454 snd_soc_dapm_add_routes(codec, core_intercon,
1455 ARRAY_SIZE(core_intercon));
1456 snd_soc_dapm_add_routes(codec, adc_intercon,
1457 ARRAY_SIZE(adc_intercon));
1458 snd_soc_dapm_add_routes(codec, dac_intercon,
1459 ARRAY_SIZE(dac_intercon));
1460 snd_soc_dapm_add_routes(codec, wm8904_intercon,
1461 ARRAY_SIZE(wm8904_intercon));
1462 break;
1463
1464 case WM8912:
1465 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1466 ARRAY_SIZE(wm8904_dac_snd_controls));
1467
1468 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets,
1469 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1470
1471 snd_soc_dapm_add_routes(codec, dac_intercon,
1472 ARRAY_SIZE(dac_intercon));
1473 snd_soc_dapm_add_routes(codec, wm8912_intercon,
1474 ARRAY_SIZE(wm8912_intercon));
1475 break;
1476 }
1477
1478 snd_soc_dapm_new_widgets(codec);
1479 return 0;
1480}
1481
1482static struct {
1483 int ratio;
1484 unsigned int clk_sys_rate;
1485} clk_sys_rates[] = {
1486 { 64, 0 },
1487 { 128, 1 },
1488 { 192, 2 },
1489 { 256, 3 },
1490 { 384, 4 },
1491 { 512, 5 },
1492 { 786, 6 },
1493 { 1024, 7 },
1494 { 1408, 8 },
1495 { 1536, 9 },
1496};
1497
1498static struct {
1499 int rate;
1500 int sample_rate;
1501} sample_rates[] = {
1502 { 8000, 0 },
1503 { 11025, 1 },
1504 { 12000, 1 },
1505 { 16000, 2 },
1506 { 22050, 3 },
1507 { 24000, 3 },
1508 { 32000, 4 },
1509 { 44100, 5 },
1510 { 48000, 5 },
1511};
1512
1513static struct {
1514 int div; /* *10 due to .5s */
1515 int bclk_div;
1516} bclk_divs[] = {
1517 { 10, 0 },
1518 { 15, 1 },
1519 { 20, 2 },
1520 { 30, 3 },
1521 { 40, 4 },
1522 { 50, 5 },
1523 { 55, 6 },
1524 { 60, 7 },
1525 { 80, 8 },
1526 { 100, 9 },
1527 { 110, 10 },
1528 { 120, 11 },
1529 { 160, 12 },
1530 { 200, 13 },
1531 { 220, 14 },
1532 { 240, 16 },
1533 { 200, 17 },
1534 { 320, 18 },
1535 { 440, 19 },
1536 { 480, 20 },
1537};
1538
1539
1540static int wm8904_hw_params(struct snd_pcm_substream *substream,
1541 struct snd_pcm_hw_params *params,
1542 struct snd_soc_dai *dai)
1543{
1544 struct snd_soc_codec *codec = dai->codec;
1545 struct wm8904_priv *wm8904 = codec->private_data;
1546 int ret, i, best, best_val, cur_val;
1547 unsigned int aif1 = 0;
1548 unsigned int aif2 = 0;
1549 unsigned int aif3 = 0;
1550 unsigned int clock1 = 0;
1551 unsigned int dac_digital1 = 0;
1552
1553 /* What BCLK do we need? */
1554 wm8904->fs = params_rate(params);
1555 if (wm8904->tdm_slots) {
1556 dev_dbg(codec->dev, "Configuring for %d %d bit TDM slots\n",
1557 wm8904->tdm_slots, wm8904->tdm_width);
1558 wm8904->bclk = snd_soc_calc_bclk(wm8904->fs,
1559 wm8904->tdm_width, 2,
1560 wm8904->tdm_slots);
1561 } else {
1562 wm8904->bclk = snd_soc_params_to_bclk(params);
1563 }
1564
1565 switch (params_format(params)) {
1566 case SNDRV_PCM_FORMAT_S16_LE:
1567 break;
1568 case SNDRV_PCM_FORMAT_S20_3LE:
1569 aif1 |= 0x40;
1570 break;
1571 case SNDRV_PCM_FORMAT_S24_LE:
1572 aif1 |= 0x80;
1573 break;
1574 case SNDRV_PCM_FORMAT_S32_LE:
1575 aif1 |= 0xc0;
1576 break;
1577 default:
1578 return -EINVAL;
1579 }
1580
1581
1582 dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm8904->bclk);
1583
1584 ret = wm8904_configure_clocking(codec);
1585 if (ret != 0)
1586 return ret;
1587
1588 /* Select nearest CLK_SYS_RATE */
1589 best = 0;
1590 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio)
1591 - wm8904->fs);
1592 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1593 cur_val = abs((wm8904->sysclk_rate /
1594 clk_sys_rates[i].ratio) - wm8904->fs);;
1595 if (cur_val < best_val) {
1596 best = i;
1597 best_val = cur_val;
1598 }
1599 }
1600 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n",
1601 clk_sys_rates[best].ratio);
1602 clock1 |= (clk_sys_rates[best].clk_sys_rate
1603 << WM8904_CLK_SYS_RATE_SHIFT);
1604
1605 /* SAMPLE_RATE */
1606 best = 0;
1607 best_val = abs(wm8904->fs - sample_rates[0].rate);
1608 for (i = 1; i < ARRAY_SIZE(sample_rates); i++) {
1609 /* Closest match */
1610 cur_val = abs(wm8904->fs - sample_rates[i].rate);
1611 if (cur_val < best_val) {
1612 best = i;
1613 best_val = cur_val;
1614 }
1615 }
1616 dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n",
1617 sample_rates[best].rate);
1618 clock1 |= (sample_rates[best].sample_rate
1619 << WM8904_SAMPLE_RATE_SHIFT);
1620
1621 /* Enable sloping stopband filter for low sample rates */
1622 if (wm8904->fs <= 24000)
1623 dac_digital1 |= WM8904_DAC_SB_FILT;
1624
1625 /* BCLK_DIV */
1626 best = 0;
1627 best_val = INT_MAX;
1628 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1629 cur_val = ((wm8904->sysclk_rate * 10) / bclk_divs[i].div)
1630 - wm8904->bclk;
1631 if (cur_val < 0) /* Table is sorted */
1632 break;
1633 if (cur_val < best_val) {
1634 best = i;
1635 best_val = cur_val;
1636 }
1637 }
1638 wm8904->bclk = (wm8904->sysclk_rate * 10) / bclk_divs[best].div;
1639 dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n",
1640 bclk_divs[best].div, wm8904->bclk);
1641 aif2 |= bclk_divs[best].bclk_div;
1642
1643 /* LRCLK is a simple fraction of BCLK */
1644 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8904->bclk / wm8904->fs);
1645 aif3 |= wm8904->bclk / wm8904->fs;
1646
1647 /* Apply the settings */
1648 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1,
1649 WM8904_DAC_SB_FILT, dac_digital1);
1650 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1651 WM8904_AIF_WL_MASK, aif1);
1652 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_2,
1653 WM8904_BCLK_DIV_MASK, aif2);
1654 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1655 WM8904_LRCLK_RATE_MASK, aif3);
1656 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_1,
1657 WM8904_SAMPLE_RATE_MASK |
1658 WM8904_CLK_SYS_RATE_MASK, clock1);
1659
1660 /* Update filters for the new settings */
1661 wm8904_set_retune_mobile(codec);
1662 wm8904_set_deemph(codec);
1663
1664 return 0;
1665}
1666
1667
1668static int wm8904_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1669 unsigned int freq, int dir)
1670{
1671 struct snd_soc_codec *codec = dai->codec;
1672 struct wm8904_priv *priv = codec->private_data;
1673
1674 switch (clk_id) {
1675 case WM8904_CLK_MCLK:
1676 priv->sysclk_src = clk_id;
1677 priv->mclk_rate = freq;
1678 break;
1679
1680 case WM8904_CLK_FLL:
1681 priv->sysclk_src = clk_id;
1682 break;
1683
1684 default:
1685 return -EINVAL;
1686 }
1687
1688 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
1689
1690 wm8904_configure_clocking(codec);
1691
1692 return 0;
1693}
1694
1695static int wm8904_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1696{
1697 struct snd_soc_codec *codec = dai->codec;
1698 unsigned int aif1 = 0;
1699 unsigned int aif3 = 0;
1700
1701 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1702 case SND_SOC_DAIFMT_CBS_CFS:
1703 break;
1704 case SND_SOC_DAIFMT_CBS_CFM:
1705 aif3 |= WM8904_LRCLK_DIR;
1706 break;
1707 case SND_SOC_DAIFMT_CBM_CFS:
1708 aif1 |= WM8904_BCLK_DIR;
1709 break;
1710 case SND_SOC_DAIFMT_CBM_CFM:
1711 aif1 |= WM8904_BCLK_DIR;
1712 aif3 |= WM8904_LRCLK_DIR;
1713 break;
1714 default:
1715 return -EINVAL;
1716 }
1717
1718 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1719 case SND_SOC_DAIFMT_DSP_B:
1720 aif1 |= WM8904_AIF_LRCLK_INV;
1721 case SND_SOC_DAIFMT_DSP_A:
1722 aif1 |= 0x3;
1723 break;
1724 case SND_SOC_DAIFMT_I2S:
1725 aif1 |= 0x2;
1726 break;
1727 case SND_SOC_DAIFMT_RIGHT_J:
1728 break;
1729 case SND_SOC_DAIFMT_LEFT_J:
1730 aif1 |= 0x1;
1731 break;
1732 default:
1733 return -EINVAL;
1734 }
1735
1736 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1737 case SND_SOC_DAIFMT_DSP_A:
1738 case SND_SOC_DAIFMT_DSP_B:
1739 /* frame inversion not valid for DSP modes */
1740 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1741 case SND_SOC_DAIFMT_NB_NF:
1742 break;
1743 case SND_SOC_DAIFMT_IB_NF:
1744 aif1 |= WM8904_AIF_BCLK_INV;
1745 break;
1746 default:
1747 return -EINVAL;
1748 }
1749 break;
1750
1751 case SND_SOC_DAIFMT_I2S:
1752 case SND_SOC_DAIFMT_RIGHT_J:
1753 case SND_SOC_DAIFMT_LEFT_J:
1754 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1755 case SND_SOC_DAIFMT_NB_NF:
1756 break;
1757 case SND_SOC_DAIFMT_IB_IF:
1758 aif1 |= WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV;
1759 break;
1760 case SND_SOC_DAIFMT_IB_NF:
1761 aif1 |= WM8904_AIF_BCLK_INV;
1762 break;
1763 case SND_SOC_DAIFMT_NB_IF:
1764 aif1 |= WM8904_AIF_LRCLK_INV;
1765 break;
1766 default:
1767 return -EINVAL;
1768 }
1769 break;
1770 default:
1771 return -EINVAL;
1772 }
1773
1774 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1775 WM8904_AIF_BCLK_INV | WM8904_AIF_LRCLK_INV |
1776 WM8904_AIF_FMT_MASK | WM8904_BCLK_DIR, aif1);
1777 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_3,
1778 WM8904_LRCLK_DIR, aif3);
1779
1780 return 0;
1781}
1782
1783
1784static int wm8904_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
1785 unsigned int rx_mask, int slots, int slot_width)
1786{
1787 struct snd_soc_codec *codec = dai->codec;
1788 struct wm8904_priv *wm8904 = codec->private_data;
1789 int aif1 = 0;
1790
1791 /* Don't need to validate anything if we're turning off TDM */
1792 if (slots == 0)
1793 goto out;
1794
1795 /* Note that we allow configurations we can't handle ourselves -
1796 * for example, we can generate clocks for slots 2 and up even if
1797 * we can't use those slots ourselves.
1798 */
1799 aif1 |= WM8904_AIFADC_TDM | WM8904_AIFDAC_TDM;
1800
1801 switch (rx_mask) {
1802 case 3:
1803 break;
1804 case 0xc:
1805 aif1 |= WM8904_AIFADC_TDM_CHAN;
1806 break;
1807 default:
1808 return -EINVAL;
1809 }
1810
1811
1812 switch (tx_mask) {
1813 case 3:
1814 break;
1815 case 0xc:
1816 aif1 |= WM8904_AIFDAC_TDM_CHAN;
1817 break;
1818 default:
1819 return -EINVAL;
1820 }
1821
1822out:
1823 wm8904->tdm_width = slot_width;
1824 wm8904->tdm_slots = slots / 2;
1825
1826 snd_soc_update_bits(codec, WM8904_AUDIO_INTERFACE_1,
1827 WM8904_AIFADC_TDM | WM8904_AIFADC_TDM_CHAN |
1828 WM8904_AIFDAC_TDM | WM8904_AIFDAC_TDM_CHAN, aif1);
1829
1830 return 0;
1831}
1832
1833struct _fll_div {
1834 u16 fll_fratio;
1835 u16 fll_outdiv;
1836 u16 fll_clk_ref_div;
1837 u16 n;
1838 u16 k;
1839};
1840
1841/* The size in bits of the FLL divide multiplied by 10
1842 * to allow rounding later */
1843#define FIXED_FLL_SIZE ((1 << 16) * 10)
1844
1845static struct {
1846 unsigned int min;
1847 unsigned int max;
1848 u16 fll_fratio;
1849 int ratio;
1850} fll_fratios[] = {
1851 { 0, 64000, 4, 16 },
1852 { 64000, 128000, 3, 8 },
1853 { 128000, 256000, 2, 4 },
1854 { 256000, 1000000, 1, 2 },
1855 { 1000000, 13500000, 0, 1 },
1856};
1857
1858static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
1859 unsigned int Fout)
1860{
1861 u64 Kpart;
1862 unsigned int K, Ndiv, Nmod, target;
1863 unsigned int div;
1864 int i;
1865
1866 /* Fref must be <=13.5MHz */
1867 div = 1;
1868 fll_div->fll_clk_ref_div = 0;
1869 while ((Fref / div) > 13500000) {
1870 div *= 2;
1871 fll_div->fll_clk_ref_div++;
1872
1873 if (div > 8) {
1874 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",
1875 Fref);
1876 return -EINVAL;
1877 }
1878 }
1879
1880 pr_debug("Fref=%u Fout=%u\n", Fref, Fout);
1881
1882 /* Apply the division for our remaining calculations */
1883 Fref /= div;
1884
1885 /* Fvco should be 90-100MHz; don't check the upper bound */
1886 div = 4;
1887 while (Fout * div < 90000000) {
1888 div++;
1889 if (div > 64) {
1890 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",
1891 Fout);
1892 return -EINVAL;
1893 }
1894 }
1895 target = Fout * div;
1896 fll_div->fll_outdiv = div - 1;
1897
1898 pr_debug("Fvco=%dHz\n", target);
1899
1900 /* Find an appropraite FLL_FRATIO and factor it out of the target */
1901 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
1902 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
1903 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
1904 target /= fll_fratios[i].ratio;
1905 break;
1906 }
1907 }
1908 if (i == ARRAY_SIZE(fll_fratios)) {
1909 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);
1910 return -EINVAL;
1911 }
1912
1913 /* Now, calculate N.K */
1914 Ndiv = target / Fref;
1915
1916 fll_div->n = Ndiv;
1917 Nmod = target % Fref;
1918 pr_debug("Nmod=%d\n", Nmod);
1919
1920 /* Calculate fractional part - scale up so we can round. */
1921 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1922
1923 do_div(Kpart, Fref);
1924
1925 K = Kpart & 0xFFFFFFFF;
1926
1927 if ((K % 10) >= 5)
1928 K += 5;
1929
1930 /* Move down to proper range now rounding is done */
1931 fll_div->k = K / 10;
1932
1933 pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n",
1934 fll_div->n, fll_div->k,
1935 fll_div->fll_fratio, fll_div->fll_outdiv,
1936 fll_div->fll_clk_ref_div);
1937
1938 return 0;
1939}
1940
1941static int wm8904_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
1942 unsigned int Fref, unsigned int Fout)
1943{
1944 struct snd_soc_codec *codec = dai->codec;
1945 struct wm8904_priv *wm8904 = codec->private_data;
1946 struct _fll_div fll_div;
1947 int ret, val;
1948 int clock2, fll1;
1949
1950 /* Any change? */
1951 if (source == wm8904->fll_src && Fref == wm8904->fll_fref &&
1952 Fout == wm8904->fll_fout)
1953 return 0;
1954
1955 clock2 = snd_soc_read(codec, WM8904_CLOCK_RATES_2);
1956
1957 if (Fout == 0) {
1958 dev_dbg(codec->dev, "FLL disabled\n");
1959
1960 wm8904->fll_fref = 0;
1961 wm8904->fll_fout = 0;
1962
1963 /* Gate SYSCLK to avoid glitches */
1964 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
1965 WM8904_CLK_SYS_ENA, 0);
1966
1967 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
1968 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
1969
1970 goto out;
1971 }
1972
1973 /* Validate the FLL ID */
1974 switch (source) {
1975 case WM8904_FLL_MCLK:
1976 case WM8904_FLL_LRCLK:
1977 case WM8904_FLL_BCLK:
1978 ret = fll_factors(&fll_div, Fref, Fout);
1979 if (ret != 0)
1980 return ret;
1981 break;
1982
1983 case WM8904_FLL_FREE_RUNNING:
1984 dev_dbg(codec->dev, "Using free running FLL\n");
1985 /* Force 12MHz and output/4 for now */
1986 Fout = 12000000;
1987 Fref = 12000000;
1988
1989 memset(&fll_div, 0, sizeof(fll_div));
1990 fll_div.fll_outdiv = 3;
1991 break;
1992
1993 default:
1994 dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id);
1995 return -EINVAL;
1996 }
1997
1998 /* Save current state then disable the FLL and SYSCLK to avoid
1999 * misclocking */
2000 fll1 = snd_soc_read(codec, WM8904_FLL_CONTROL_1);
2001 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2002 WM8904_CLK_SYS_ENA, 0);
2003 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2004 WM8904_FLL_OSC_ENA | WM8904_FLL_ENA, 0);
2005
2006 /* Unlock forced oscilator control to switch it on/off */
2007 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2008 WM8904_USER_KEY, WM8904_USER_KEY);
2009
2010 if (fll_id == WM8904_FLL_FREE_RUNNING) {
2011 val = WM8904_FLL_FRC_NCO;
2012 } else {
2013 val = 0;
2014 }
2015
2016 snd_soc_update_bits(codec, WM8904_FLL_NCO_TEST_1, WM8904_FLL_FRC_NCO,
2017 val);
2018 snd_soc_update_bits(codec, WM8904_CONTROL_INTERFACE_TEST_1,
2019 WM8904_USER_KEY, 0);
2020
2021 switch (fll_id) {
2022 case WM8904_FLL_MCLK:
2023 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2024 WM8904_FLL_CLK_REF_SRC_MASK, 0);
2025 break;
2026
2027 case WM8904_FLL_LRCLK:
2028 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2029 WM8904_FLL_CLK_REF_SRC_MASK, 1);
2030 break;
2031
2032 case WM8904_FLL_BCLK:
2033 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2034 WM8904_FLL_CLK_REF_SRC_MASK, 2);
2035 break;
2036 }
2037
2038 if (fll_div.k)
2039 val = WM8904_FLL_FRACN_ENA;
2040 else
2041 val = 0;
2042 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2043 WM8904_FLL_FRACN_ENA, val);
2044
2045 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_2,
2046 WM8904_FLL_OUTDIV_MASK | WM8904_FLL_FRATIO_MASK,
2047 (fll_div.fll_outdiv << WM8904_FLL_OUTDIV_SHIFT) |
2048 (fll_div.fll_fratio << WM8904_FLL_FRATIO_SHIFT));
2049
2050 snd_soc_write(codec, WM8904_FLL_CONTROL_3, fll_div.k);
2051
2052 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_4, WM8904_FLL_N_MASK,
2053 fll_div.n << WM8904_FLL_N_SHIFT);
2054
2055 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_5,
2056 WM8904_FLL_CLK_REF_DIV_MASK,
2057 fll_div.fll_clk_ref_div
2058 << WM8904_FLL_CLK_REF_DIV_SHIFT);
2059
2060 dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);
2061
2062 wm8904->fll_fref = Fref;
2063 wm8904->fll_fout = Fout;
2064 wm8904->fll_src = source;
2065
2066 /* Enable the FLL if it was previously active */
2067 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2068 WM8904_FLL_OSC_ENA, fll1);
2069 snd_soc_update_bits(codec, WM8904_FLL_CONTROL_1,
2070 WM8904_FLL_ENA, fll1);
2071
2072out:
2073 /* Reenable SYSCLK if it was previously active */
2074 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_2,
2075 WM8904_CLK_SYS_ENA, clock2);
2076
2077 return 0;
2078}
2079
2080static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
2081{
2082 struct snd_soc_codec *codec = codec_dai->codec;
2083 int val;
2084
2085 if (mute)
2086 val = WM8904_DAC_MUTE;
2087 else
2088 val = 0;
2089
2090 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_1, WM8904_DAC_MUTE, val);
2091
2092 return 0;
2093}
2094
2095static void wm8904_sync_cache(struct snd_soc_codec *codec)
2096{
2097 struct wm8904_priv *wm8904 = codec->private_data;
2098 int i;
2099
2100 if (!codec->cache_sync)
2101 return;
2102
2103 codec->cache_only = 0;
2104
2105 /* Sync back cached values if they're different from the
2106 * hardware default.
2107 */
2108 for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
2109 if (!wm8904_access[i].writable)
2110 continue;
2111
2112 if (wm8904->reg_cache[i] == wm8904_reg[i])
2113 continue;
2114
2115 snd_soc_write(codec, i, wm8904->reg_cache[i]);
2116 }
2117
2118 codec->cache_sync = 0;
2119}
2120
2121static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2122 enum snd_soc_bias_level level)
2123{
2124 struct wm8904_priv *wm8904 = codec->private_data;
2125 int ret;
2126
2127 switch (level) {
2128 case SND_SOC_BIAS_ON:
2129 break;
2130
2131 case SND_SOC_BIAS_PREPARE:
2132 /* VMID resistance 2*50k */
2133 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2134 WM8904_VMID_RES_MASK,
2135 0x1 << WM8904_VMID_RES_SHIFT);
2136
2137 /* Normal bias current */
2138 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2139 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT);
2140 break;
2141
2142 case SND_SOC_BIAS_STANDBY:
2143 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2144 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2145 wm8904->supplies);
2146 if (ret != 0) {
2147 dev_err(codec->dev,
2148 "Failed to enable supplies: %d\n",
2149 ret);
2150 return ret;
2151 }
2152
2153 wm8904_sync_cache(codec);
2154
2155 /* Enable bias */
2156 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2157 WM8904_BIAS_ENA, WM8904_BIAS_ENA);
2158
2159 /* Enable VMID, VMID buffering, 2*5k resistance */
2160 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2161 WM8904_VMID_ENA |
2162 WM8904_VMID_RES_MASK,
2163 WM8904_VMID_ENA |
2164 0x3 << WM8904_VMID_RES_SHIFT);
2165
2166 /* Let VMID ramp */
2167 msleep(1);
2168 }
2169
2170 /* Maintain VMID with 2*250k */
2171 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2172 WM8904_VMID_RES_MASK,
2173 0x2 << WM8904_VMID_RES_SHIFT);
2174
2175 /* Bias current *0.5 */
2176 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2177 WM8904_ISEL_MASK, 0);
2178 break;
2179
2180 case SND_SOC_BIAS_OFF:
2181 /* Turn off VMID */
2182 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0,
2183 WM8904_VMID_RES_MASK | WM8904_VMID_ENA, 0);
2184
2185 /* Stop bias generation */
2186 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2187 WM8904_BIAS_ENA, 0);
2188
2189#ifdef CONFIG_REGULATOR
2190 /* Post 2.6.34 we will be able to get a callback when
2191 * the regulators are disabled which we can use but
2192 * for now just assume that the power will be cut if
2193 * the regulator API is in use.
2194 */
2195 codec->cache_sync = 1;
2196#endif
2197
2198 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies),
2199 wm8904->supplies);
2200 break;
2201 }
2202 codec->bias_level = level;
2203 return 0;
2204}
2205
2206#define WM8904_RATES SNDRV_PCM_RATE_8000_96000
2207
2208#define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
2209 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
2210
2211static struct snd_soc_dai_ops wm8904_dai_ops = {
2212 .set_sysclk = wm8904_set_sysclk,
2213 .set_fmt = wm8904_set_fmt,
2214 .set_tdm_slot = wm8904_set_tdm_slot,
2215 .set_pll = wm8904_set_fll,
2216 .hw_params = wm8904_hw_params,
2217 .digital_mute = wm8904_digital_mute,
2218};
2219
2220struct snd_soc_dai wm8904_dai = {
2221 .name = "WM8904",
2222 .playback = {
2223 .stream_name = "Playback",
2224 .channels_min = 2,
2225 .channels_max = 2,
2226 .rates = WM8904_RATES,
2227 .formats = WM8904_FORMATS,
2228 },
2229 .capture = {
2230 .stream_name = "Capture",
2231 .channels_min = 2,
2232 .channels_max = 2,
2233 .rates = WM8904_RATES,
2234 .formats = WM8904_FORMATS,
2235 },
2236 .ops = &wm8904_dai_ops,
2237 .symmetric_rates = 1,
2238};
2239EXPORT_SYMBOL_GPL(wm8904_dai);
2240
2241#ifdef CONFIG_PM
2242static int wm8904_suspend(struct platform_device *pdev, pm_message_t state)
2243{
2244 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2245 struct snd_soc_codec *codec = socdev->card->codec;
2246
2247 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2248
2249 return 0;
2250}
2251
2252static int wm8904_resume(struct platform_device *pdev)
2253{
2254 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2255 struct snd_soc_codec *codec = socdev->card->codec;
2256
2257 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2258
2259 return 0;
2260}
2261#else
2262#define wm8904_suspend NULL
2263#define wm8904_resume NULL
2264#endif
2265
2266static void wm8904_handle_retune_mobile_pdata(struct wm8904_priv *wm8904)
2267{
2268 struct snd_soc_codec *codec = &wm8904->codec;
2269 struct wm8904_pdata *pdata = wm8904->pdata;
2270 struct snd_kcontrol_new control =
2271 SOC_ENUM_EXT("EQ Mode",
2272 wm8904->retune_mobile_enum,
2273 wm8904_get_retune_mobile_enum,
2274 wm8904_put_retune_mobile_enum);
2275 int ret, i, j;
2276 const char **t;
2277
2278 /* We need an array of texts for the enum API but the number
2279 * of texts is likely to be less than the number of
2280 * configurations due to the sample rate dependency of the
2281 * configurations. */
2282 wm8904->num_retune_mobile_texts = 0;
2283 wm8904->retune_mobile_texts = NULL;
2284 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
2285 for (j = 0; j < wm8904->num_retune_mobile_texts; j++) {
2286 if (strcmp(pdata->retune_mobile_cfgs[i].name,
2287 wm8904->retune_mobile_texts[j]) == 0)
2288 break;
2289 }
2290
2291 if (j != wm8904->num_retune_mobile_texts)
2292 continue;
2293
2294 /* Expand the array... */
2295 t = krealloc(wm8904->retune_mobile_texts,
2296 sizeof(char *) *
2297 (wm8904->num_retune_mobile_texts + 1),
2298 GFP_KERNEL);
2299 if (t == NULL)
2300 continue;
2301
2302 /* ...store the new entry... */
2303 t[wm8904->num_retune_mobile_texts] =
2304 pdata->retune_mobile_cfgs[i].name;
2305
2306 /* ...and remember the new version. */
2307 wm8904->num_retune_mobile_texts++;
2308 wm8904->retune_mobile_texts = t;
2309 }
2310
2311 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
2312 wm8904->num_retune_mobile_texts);
2313
2314 wm8904->retune_mobile_enum.max = wm8904->num_retune_mobile_texts;
2315 wm8904->retune_mobile_enum.texts = wm8904->retune_mobile_texts;
2316
2317 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2318 if (ret != 0)
2319 dev_err(wm8904->codec.dev,
2320 "Failed to add ReTune Mobile control: %d\n", ret);
2321}
2322
2323static void wm8904_handle_pdata(struct wm8904_priv *wm8904)
2324{
2325 struct snd_soc_codec *codec = &wm8904->codec;
2326 struct wm8904_pdata *pdata = wm8904->pdata;
2327 int ret, i;
2328
2329 if (!pdata) {
2330 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2331 ARRAY_SIZE(wm8904_eq_controls));
2332 return;
2333 }
2334
2335 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
2336
2337 if (pdata->num_drc_cfgs) {
2338 struct snd_kcontrol_new control =
2339 SOC_ENUM_EXT("DRC Mode", wm8904->drc_enum,
2340 wm8904_get_drc_enum, wm8904_put_drc_enum);
2341
2342 /* We need an array of texts for the enum API */
2343 wm8904->drc_texts = kmalloc(sizeof(char *)
2344 * pdata->num_drc_cfgs, GFP_KERNEL);
2345 if (!wm8904->drc_texts) {
2346 dev_err(wm8904->codec.dev,
2347 "Failed to allocate %d DRC config texts\n",
2348 pdata->num_drc_cfgs);
2349 return;
2350 }
2351
2352 for (i = 0; i < pdata->num_drc_cfgs; i++)
2353 wm8904->drc_texts[i] = pdata->drc_cfgs[i].name;
2354
2355 wm8904->drc_enum.max = pdata->num_drc_cfgs;
2356 wm8904->drc_enum.texts = wm8904->drc_texts;
2357
2358 ret = snd_soc_add_controls(&wm8904->codec, &control, 1);
2359 if (ret != 0)
2360 dev_err(wm8904->codec.dev,
2361 "Failed to add DRC mode control: %d\n", ret);
2362
2363 wm8904_set_drc(codec);
2364 }
2365
2366 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
2367 pdata->num_retune_mobile_cfgs);
2368
2369 if (pdata->num_retune_mobile_cfgs)
2370 wm8904_handle_retune_mobile_pdata(wm8904);
2371 else
2372 snd_soc_add_controls(&wm8904->codec, wm8904_eq_controls,
2373 ARRAY_SIZE(wm8904_eq_controls));
2374}
2375
2376static int wm8904_probe(struct platform_device *pdev)
2377{
2378 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2379 struct snd_soc_codec *codec;
2380 int ret = 0;
2381
2382 if (wm8904_codec == NULL) {
2383 dev_err(&pdev->dev, "Codec device not registered\n");
2384 return -ENODEV;
2385 }
2386
2387 socdev->card->codec = wm8904_codec;
2388 codec = wm8904_codec;
2389
2390 /* register pcms */
2391 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2392 if (ret < 0) {
2393 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
2394 goto pcm_err;
2395 }
2396
2397 wm8904_handle_pdata(codec->private_data);
2398
2399 wm8904_add_widgets(codec);
2400
2401 return ret;
2402
2403pcm_err:
2404 return ret;
2405}
2406
2407static int wm8904_remove(struct platform_device *pdev)
2408{
2409 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2410
2411 snd_soc_free_pcms(socdev);
2412 snd_soc_dapm_free(socdev);
2413
2414 return 0;
2415}
2416
2417struct snd_soc_codec_device soc_codec_dev_wm8904 = {
2418 .probe = wm8904_probe,
2419 .remove = wm8904_remove,
2420 .suspend = wm8904_suspend,
2421 .resume = wm8904_resume,
2422};
2423EXPORT_SYMBOL_GPL(soc_codec_dev_wm8904);
2424
2425static int wm8904_register(struct wm8904_priv *wm8904,
2426 enum snd_soc_control_type control)
2427{
2428 int ret;
2429 struct snd_soc_codec *codec = &wm8904->codec;
2430 int i;
2431
2432 if (wm8904_codec) {
2433 dev_err(codec->dev, "Another WM8904 is registered\n");
2434 return -EINVAL;
2435 }
2436
2437 mutex_init(&codec->mutex);
2438 INIT_LIST_HEAD(&codec->dapm_widgets);
2439 INIT_LIST_HEAD(&codec->dapm_paths);
2440
2441 codec->private_data = wm8904;
2442 codec->name = "WM8904";
2443 codec->owner = THIS_MODULE;
2444 codec->bias_level = SND_SOC_BIAS_OFF;
2445 codec->set_bias_level = wm8904_set_bias_level;
2446 codec->dai = &wm8904_dai;
2447 codec->num_dai = 1;
2448 codec->reg_cache_size = WM8904_MAX_REGISTER;
2449 codec->reg_cache = &wm8904->reg_cache;
2450 codec->volatile_register = wm8904_volatile_register;
2451 codec->cache_sync = 1;
2452 codec->idle_bias_off = 1;
2453
2454 switch (wm8904->devtype) {
2455 case WM8904:
2456 break;
2457 case WM8912:
2458 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture));
2459 break;
2460 default:
2461 dev_err(codec->dev, "Unknown device type %d\n",
2462 wm8904->devtype);
2463 return -EINVAL;
2464 }
2465
2466 memcpy(codec->reg_cache, wm8904_reg, sizeof(wm8904_reg));
2467
2468 ret = snd_soc_codec_set_cache_io(codec, 8, 16, control);
2469 if (ret != 0) {
2470 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
2471 goto err;
2472 }
2473
2474 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2475 wm8904->supplies[i].supply = wm8904_supply_names[i];
2476
2477 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2478 wm8904->supplies);
2479 if (ret != 0) {
2480 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2481 goto err;
2482 }
2483
2484 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2485 wm8904->supplies);
2486 if (ret != 0) {
2487 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2488 goto err_get;
2489 }
2490
2491 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2492 if (ret < 0) {
2493 dev_err(codec->dev, "Failed to read ID register\n");
2494 goto err_enable;
2495 }
2496 if (ret != wm8904_reg[WM8904_SW_RESET_AND_ID]) {
2497 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2498 ret = -EINVAL;
2499 goto err_enable;
2500 }
2501
2502 ret = snd_soc_read(codec, WM8904_REVISION);
2503 if (ret < 0) {
2504 dev_err(codec->dev, "Failed to read device revision: %d\n",
2505 ret);
2506 goto err_enable;
2507 }
2508 dev_info(codec->dev, "revision %c\n", ret + 'A');
2509
2510 ret = wm8904_reset(codec);
2511 if (ret < 0) {
2512 dev_err(codec->dev, "Failed to issue reset\n");
2513 goto err_enable;
2514 }
2515
2516 wm8904_dai.dev = codec->dev;
2517
2518 /* Change some default settings - latch VU and enable ZC */
2519 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
2520 wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
2521 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
2522 wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
2523 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
2524 WM8904_HPOUTLZC;
2525 wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
2526 WM8904_HPOUTRZC;
2527 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
2528 WM8904_LINEOUTLZC;
2529 wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
2530 WM8904_LINEOUTRZC;
2531 wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
2532
2533 /* Set Class W by default - this will be managed by the Class
2534 * G widget at runtime where bypass paths are available.
2535 */
2536 wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
2537
2538 /* Use normal bias source */
2539 wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
2540
2541 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2542
2543 /* Bias level configuration will have done an extra enable */
2544 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2545
2546 wm8904_codec = codec;
2547
2548 ret = snd_soc_register_codec(codec);
2549 if (ret != 0) {
2550 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2551 return ret;
2552 }
2553
2554 ret = snd_soc_register_dai(&wm8904_dai);
2555 if (ret != 0) {
2556 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
2557 snd_soc_unregister_codec(codec);
2558 return ret;
2559 }
2560
2561 return 0;
2562
2563err_enable:
2564 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2565err_get:
2566 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2567err:
2568 kfree(wm8904);
2569 return ret;
2570}
2571
2572static void wm8904_unregister(struct wm8904_priv *wm8904)
2573{
2574 wm8904_set_bias_level(&wm8904->codec, SND_SOC_BIAS_OFF);
2575 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2576 snd_soc_unregister_dai(&wm8904_dai);
2577 snd_soc_unregister_codec(&wm8904->codec);
2578 kfree(wm8904);
2579 wm8904_codec = NULL;
2580}
2581
2582#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2583static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2584 const struct i2c_device_id *id)
2585{
2586 struct wm8904_priv *wm8904;
2587 struct snd_soc_codec *codec;
2588
2589 wm8904 = kzalloc(sizeof(struct wm8904_priv), GFP_KERNEL);
2590 if (wm8904 == NULL)
2591 return -ENOMEM;
2592
2593 codec = &wm8904->codec;
2594 codec->hw_write = (hw_write_t)i2c_master_send;
2595
2596 wm8904->devtype = id->driver_data;
2597
2598 i2c_set_clientdata(i2c, wm8904);
2599 codec->control_data = i2c;
2600 wm8904->pdata = i2c->dev.platform_data;
2601
2602 codec->dev = &i2c->dev;
2603
2604 return wm8904_register(wm8904, SND_SOC_I2C);
2605}
2606
2607static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2608{
2609 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2610 wm8904_unregister(wm8904);
2611 return 0;
2612}
2613
2614static const struct i2c_device_id wm8904_i2c_id[] = {
2615 { "wm8904", WM8904 },
2616 { "wm8912", WM8912 },
2617 { }
2618};
2619MODULE_DEVICE_TABLE(i2c, wm8904_i2c_id);
2620
2621static struct i2c_driver wm8904_i2c_driver = {
2622 .driver = {
2623 .name = "WM8904",
2624 .owner = THIS_MODULE,
2625 },
2626 .probe = wm8904_i2c_probe,
2627 .remove = __devexit_p(wm8904_i2c_remove),
2628 .id_table = wm8904_i2c_id,
2629};
2630#endif
2631
2632static int __init wm8904_modinit(void)
2633{
2634 int ret;
2635#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2636 ret = i2c_add_driver(&wm8904_i2c_driver);
2637 if (ret != 0) {
2638 printk(KERN_ERR "Failed to register WM8904 I2C driver: %d\n",
2639 ret);
2640 }
2641#endif
2642 return 0;
2643}
2644module_init(wm8904_modinit);
2645
2646static void __exit wm8904_exit(void)
2647{
2648#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
2649 i2c_del_driver(&wm8904_i2c_driver);
2650#endif
2651}
2652module_exit(wm8904_exit);
2653
2654MODULE_DESCRIPTION("ASoC WM8904 driver");
2655MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
2656MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8904.h b/sound/soc/codecs/wm8904.h
new file mode 100644
index 000000000000..b68886df34e4
--- /dev/null
+++ b/sound/soc/codecs/wm8904.h
@@ -0,0 +1,1681 @@
1/*
2 * wm8904.h -- WM8904 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 _WM8904_H
14#define _WM8904_H
15
16#define WM8904_CLK_MCLK 1
17#define WM8904_CLK_FLL 2
18
19#define WM8904_FLL_MCLK 1
20#define WM8904_FLL_BCLK 2
21#define WM8904_FLL_LRCLK 3
22#define WM8904_FLL_FREE_RUNNING 4
23
24extern struct snd_soc_dai wm8904_dai;
25extern struct snd_soc_codec_device soc_codec_dev_wm8904;
26
27/*
28 * Register values.
29 */
30#define WM8904_SW_RESET_AND_ID 0x00
31#define WM8904_REVISION 0x01
32#define WM8904_BIAS_CONTROL_0 0x04
33#define WM8904_VMID_CONTROL_0 0x05
34#define WM8904_MIC_BIAS_CONTROL_0 0x06
35#define WM8904_MIC_BIAS_CONTROL_1 0x07
36#define WM8904_ANALOGUE_DAC_0 0x08
37#define WM8904_MIC_FILTER_CONTROL 0x09
38#define WM8904_ANALOGUE_ADC_0 0x0A
39#define WM8904_POWER_MANAGEMENT_0 0x0C
40#define WM8904_POWER_MANAGEMENT_2 0x0E
41#define WM8904_POWER_MANAGEMENT_3 0x0F
42#define WM8904_POWER_MANAGEMENT_6 0x12
43#define WM8904_CLOCK_RATES_0 0x14
44#define WM8904_CLOCK_RATES_1 0x15
45#define WM8904_CLOCK_RATES_2 0x16
46#define WM8904_AUDIO_INTERFACE_0 0x18
47#define WM8904_AUDIO_INTERFACE_1 0x19
48#define WM8904_AUDIO_INTERFACE_2 0x1A
49#define WM8904_AUDIO_INTERFACE_3 0x1B
50#define WM8904_DAC_DIGITAL_VOLUME_LEFT 0x1E
51#define WM8904_DAC_DIGITAL_VOLUME_RIGHT 0x1F
52#define WM8904_DAC_DIGITAL_0 0x20
53#define WM8904_DAC_DIGITAL_1 0x21
54#define WM8904_ADC_DIGITAL_VOLUME_LEFT 0x24
55#define WM8904_ADC_DIGITAL_VOLUME_RIGHT 0x25
56#define WM8904_ADC_DIGITAL_0 0x26
57#define WM8904_DIGITAL_MICROPHONE_0 0x27
58#define WM8904_DRC_0 0x28
59#define WM8904_DRC_1 0x29
60#define WM8904_DRC_2 0x2A
61#define WM8904_DRC_3 0x2B
62#define WM8904_ANALOGUE_LEFT_INPUT_0 0x2C
63#define WM8904_ANALOGUE_RIGHT_INPUT_0 0x2D
64#define WM8904_ANALOGUE_LEFT_INPUT_1 0x2E
65#define WM8904_ANALOGUE_RIGHT_INPUT_1 0x2F
66#define WM8904_ANALOGUE_OUT1_LEFT 0x39
67#define WM8904_ANALOGUE_OUT1_RIGHT 0x3A
68#define WM8904_ANALOGUE_OUT2_LEFT 0x3B
69#define WM8904_ANALOGUE_OUT2_RIGHT 0x3C
70#define WM8904_ANALOGUE_OUT12_ZC 0x3D
71#define WM8904_DC_SERVO_0 0x43
72#define WM8904_DC_SERVO_1 0x44
73#define WM8904_DC_SERVO_2 0x45
74#define WM8904_DC_SERVO_4 0x47
75#define WM8904_DC_SERVO_5 0x48
76#define WM8904_DC_SERVO_6 0x49
77#define WM8904_DC_SERVO_7 0x4A
78#define WM8904_DC_SERVO_8 0x4B
79#define WM8904_DC_SERVO_9 0x4C
80#define WM8904_DC_SERVO_READBACK_0 0x4D
81#define WM8904_ANALOGUE_HP_0 0x5A
82#define WM8904_ANALOGUE_LINEOUT_0 0x5E
83#define WM8904_CHARGE_PUMP_0 0x62
84#define WM8904_CLASS_W_0 0x68
85#define WM8904_WRITE_SEQUENCER_0 0x6C
86#define WM8904_WRITE_SEQUENCER_1 0x6D
87#define WM8904_WRITE_SEQUENCER_2 0x6E
88#define WM8904_WRITE_SEQUENCER_3 0x6F
89#define WM8904_WRITE_SEQUENCER_4 0x70
90#define WM8904_FLL_CONTROL_1 0x74
91#define WM8904_FLL_CONTROL_2 0x75
92#define WM8904_FLL_CONTROL_3 0x76
93#define WM8904_FLL_CONTROL_4 0x77
94#define WM8904_FLL_CONTROL_5 0x78
95#define WM8904_GPIO_CONTROL_1 0x79
96#define WM8904_GPIO_CONTROL_2 0x7A
97#define WM8904_GPIO_CONTROL_3 0x7B
98#define WM8904_GPIO_CONTROL_4 0x7C
99#define WM8904_DIGITAL_PULLS 0x7E
100#define WM8904_INTERRUPT_STATUS 0x7F
101#define WM8904_INTERRUPT_STATUS_MASK 0x80
102#define WM8904_INTERRUPT_POLARITY 0x81
103#define WM8904_INTERRUPT_DEBOUNCE 0x82
104#define WM8904_EQ1 0x86
105#define WM8904_EQ2 0x87
106#define WM8904_EQ3 0x88
107#define WM8904_EQ4 0x89
108#define WM8904_EQ5 0x8A
109#define WM8904_EQ6 0x8B
110#define WM8904_EQ7 0x8C
111#define WM8904_EQ8 0x8D
112#define WM8904_EQ9 0x8E
113#define WM8904_EQ10 0x8F
114#define WM8904_EQ11 0x90
115#define WM8904_EQ12 0x91
116#define WM8904_EQ13 0x92
117#define WM8904_EQ14 0x93
118#define WM8904_EQ15 0x94
119#define WM8904_EQ16 0x95
120#define WM8904_EQ17 0x96
121#define WM8904_EQ18 0x97
122#define WM8904_EQ19 0x98
123#define WM8904_EQ20 0x99
124#define WM8904_EQ21 0x9A
125#define WM8904_EQ22 0x9B
126#define WM8904_EQ23 0x9C
127#define WM8904_EQ24 0x9D
128#define WM8904_CONTROL_INTERFACE_TEST_1 0xA1
129#define WM8904_ANALOGUE_OUTPUT_BIAS_0 0xCC
130#define WM8904_FLL_NCO_TEST_0 0xF7
131#define WM8904_FLL_NCO_TEST_1 0xF8
132
133#define WM8904_REGISTER_COUNT 101
134#define WM8904_MAX_REGISTER 0xF8
135
136/*
137 * Field Definitions.
138 */
139
140/*
141 * R0 (0x00) - SW Reset and ID
142 */
143#define WM8904_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */
144#define WM8904_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */
145#define WM8904_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */
146
147/*
148 * R1 (0x01) - Revision
149 */
150#define WM8904_REVISION_MASK 0x000F /* REVISION - [3:0] */
151#define WM8904_REVISION_SHIFT 0 /* REVISION - [3:0] */
152#define WM8904_REVISION_WIDTH 16 /* REVISION - [3:0] */
153
154/*
155 * R4 (0x04) - Bias Control 0
156 */
157#define WM8904_POBCTRL 0x0010 /* POBCTRL */
158#define WM8904_POBCTRL_MASK 0x0010 /* POBCTRL */
159#define WM8904_POBCTRL_SHIFT 4 /* POBCTRL */
160#define WM8904_POBCTRL_WIDTH 1 /* POBCTRL */
161#define WM8904_ISEL_MASK 0x000C /* ISEL - [3:2] */
162#define WM8904_ISEL_SHIFT 2 /* ISEL - [3:2] */
163#define WM8904_ISEL_WIDTH 2 /* ISEL - [3:2] */
164#define WM8904_STARTUP_BIAS_ENA 0x0002 /* STARTUP_BIAS_ENA */
165#define WM8904_STARTUP_BIAS_ENA_MASK 0x0002 /* STARTUP_BIAS_ENA */
166#define WM8904_STARTUP_BIAS_ENA_SHIFT 1 /* STARTUP_BIAS_ENA */
167#define WM8904_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */
168#define WM8904_BIAS_ENA 0x0001 /* BIAS_ENA */
169#define WM8904_BIAS_ENA_MASK 0x0001 /* BIAS_ENA */
170#define WM8904_BIAS_ENA_SHIFT 0 /* BIAS_ENA */
171#define WM8904_BIAS_ENA_WIDTH 1 /* BIAS_ENA */
172
173/*
174 * R5 (0x05) - VMID Control 0
175 */
176#define WM8904_VMID_BUF_ENA 0x0040 /* VMID_BUF_ENA */
177#define WM8904_VMID_BUF_ENA_MASK 0x0040 /* VMID_BUF_ENA */
178#define WM8904_VMID_BUF_ENA_SHIFT 6 /* VMID_BUF_ENA */
179#define WM8904_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */
180#define WM8904_VMID_RES_MASK 0x0006 /* VMID_RES - [2:1] */
181#define WM8904_VMID_RES_SHIFT 1 /* VMID_RES - [2:1] */
182#define WM8904_VMID_RES_WIDTH 2 /* VMID_RES - [2:1] */
183#define WM8904_VMID_ENA 0x0001 /* VMID_ENA */
184#define WM8904_VMID_ENA_MASK 0x0001 /* VMID_ENA */
185#define WM8904_VMID_ENA_SHIFT 0 /* VMID_ENA */
186#define WM8904_VMID_ENA_WIDTH 1 /* VMID_ENA */
187
188/*
189 * R6 (0x06) - Mic Bias Control 0
190 */
191#define WM8904_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
192#define WM8904_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
193#define WM8904_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
194#define WM8904_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
195#define WM8904_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
196#define WM8904_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
197#define WM8904_MICDET_ENA 0x0002 /* MICDET_ENA */
198#define WM8904_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
199#define WM8904_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
200#define WM8904_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
201#define WM8904_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
202#define WM8904_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
203#define WM8904_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
204#define WM8904_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */
205
206/*
207 * R7 (0x07) - Mic Bias Control 1
208 */
209#define WM8904_MIC_DET_FILTER_ENA 0x8000 /* MIC_DET_FILTER_ENA */
210#define WM8904_MIC_DET_FILTER_ENA_MASK 0x8000 /* MIC_DET_FILTER_ENA */
211#define WM8904_MIC_DET_FILTER_ENA_SHIFT 15 /* MIC_DET_FILTER_ENA */
212#define WM8904_MIC_DET_FILTER_ENA_WIDTH 1 /* MIC_DET_FILTER_ENA */
213#define WM8904_MIC_SHORT_FILTER_ENA 0x4000 /* MIC_SHORT_FILTER_ENA */
214#define WM8904_MIC_SHORT_FILTER_ENA_MASK 0x4000 /* MIC_SHORT_FILTER_ENA */
215#define WM8904_MIC_SHORT_FILTER_ENA_SHIFT 14 /* MIC_SHORT_FILTER_ENA */
216#define WM8904_MIC_SHORT_FILTER_ENA_WIDTH 1 /* MIC_SHORT_FILTER_ENA */
217#define WM8904_MICBIAS_SEL_MASK 0x0007 /* MICBIAS_SEL - [2:0] */
218#define WM8904_MICBIAS_SEL_SHIFT 0 /* MICBIAS_SEL - [2:0] */
219#define WM8904_MICBIAS_SEL_WIDTH 3 /* MICBIAS_SEL - [2:0] */
220
221/*
222 * R8 (0x08) - Analogue DAC 0
223 */
224#define WM8904_DAC_BIAS_SEL_MASK 0x0018 /* DAC_BIAS_SEL - [4:3] */
225#define WM8904_DAC_BIAS_SEL_SHIFT 3 /* DAC_BIAS_SEL - [4:3] */
226#define WM8904_DAC_BIAS_SEL_WIDTH 2 /* DAC_BIAS_SEL - [4:3] */
227#define WM8904_DAC_VMID_BIAS_SEL_MASK 0x0006 /* DAC_VMID_BIAS_SEL - [2:1] */
228#define WM8904_DAC_VMID_BIAS_SEL_SHIFT 1 /* DAC_VMID_BIAS_SEL - [2:1] */
229#define WM8904_DAC_VMID_BIAS_SEL_WIDTH 2 /* DAC_VMID_BIAS_SEL - [2:1] */
230
231/*
232 * R9 (0x09) - mic Filter Control
233 */
234#define WM8904_MIC_DET_SET_THRESHOLD_MASK 0xF000 /* MIC_DET_SET_THRESHOLD - [15:12] */
235#define WM8904_MIC_DET_SET_THRESHOLD_SHIFT 12 /* MIC_DET_SET_THRESHOLD - [15:12] */
236#define WM8904_MIC_DET_SET_THRESHOLD_WIDTH 4 /* MIC_DET_SET_THRESHOLD - [15:12] */
237#define WM8904_MIC_DET_RESET_THRESHOLD_MASK 0x0F00 /* MIC_DET_RESET_THRESHOLD - [11:8] */
238#define WM8904_MIC_DET_RESET_THRESHOLD_SHIFT 8 /* MIC_DET_RESET_THRESHOLD - [11:8] */
239#define WM8904_MIC_DET_RESET_THRESHOLD_WIDTH 4 /* MIC_DET_RESET_THRESHOLD - [11:8] */
240#define WM8904_MIC_SHORT_SET_THRESHOLD_MASK 0x00F0 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
241#define WM8904_MIC_SHORT_SET_THRESHOLD_SHIFT 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
242#define WM8904_MIC_SHORT_SET_THRESHOLD_WIDTH 4 /* MIC_SHORT_SET_THRESHOLD - [7:4] */
243#define WM8904_MIC_SHORT_RESET_THRESHOLD_MASK 0x000F /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
244#define WM8904_MIC_SHORT_RESET_THRESHOLD_SHIFT 0 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
245#define WM8904_MIC_SHORT_RESET_THRESHOLD_WIDTH 4 /* MIC_SHORT_RESET_THRESHOLD - [3:0] */
246
247/*
248 * R10 (0x0A) - Analogue ADC 0
249 */
250#define WM8904_ADC_OSR128 0x0001 /* ADC_OSR128 */
251#define WM8904_ADC_OSR128_MASK 0x0001 /* ADC_OSR128 */
252#define WM8904_ADC_OSR128_SHIFT 0 /* ADC_OSR128 */
253#define WM8904_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
254
255/*
256 * R12 (0x0C) - Power Management 0
257 */
258#define WM8904_INL_ENA 0x0002 /* INL_ENA */
259#define WM8904_INL_ENA_MASK 0x0002 /* INL_ENA */
260#define WM8904_INL_ENA_SHIFT 1 /* INL_ENA */
261#define WM8904_INL_ENA_WIDTH 1 /* INL_ENA */
262#define WM8904_INR_ENA 0x0001 /* INR_ENA */
263#define WM8904_INR_ENA_MASK 0x0001 /* INR_ENA */
264#define WM8904_INR_ENA_SHIFT 0 /* INR_ENA */
265#define WM8904_INR_ENA_WIDTH 1 /* INR_ENA */
266
267/*
268 * R14 (0x0E) - Power Management 2
269 */
270#define WM8904_HPL_PGA_ENA 0x0002 /* HPL_PGA_ENA */
271#define WM8904_HPL_PGA_ENA_MASK 0x0002 /* HPL_PGA_ENA */
272#define WM8904_HPL_PGA_ENA_SHIFT 1 /* HPL_PGA_ENA */
273#define WM8904_HPL_PGA_ENA_WIDTH 1 /* HPL_PGA_ENA */
274#define WM8904_HPR_PGA_ENA 0x0001 /* HPR_PGA_ENA */
275#define WM8904_HPR_PGA_ENA_MASK 0x0001 /* HPR_PGA_ENA */
276#define WM8904_HPR_PGA_ENA_SHIFT 0 /* HPR_PGA_ENA */
277#define WM8904_HPR_PGA_ENA_WIDTH 1 /* HPR_PGA_ENA */
278
279/*
280 * R15 (0x0F) - Power Management 3
281 */
282#define WM8904_LINEOUTL_PGA_ENA 0x0002 /* LINEOUTL_PGA_ENA */
283#define WM8904_LINEOUTL_PGA_ENA_MASK 0x0002 /* LINEOUTL_PGA_ENA */
284#define WM8904_LINEOUTL_PGA_ENA_SHIFT 1 /* LINEOUTL_PGA_ENA */
285#define WM8904_LINEOUTL_PGA_ENA_WIDTH 1 /* LINEOUTL_PGA_ENA */
286#define WM8904_LINEOUTR_PGA_ENA 0x0001 /* LINEOUTR_PGA_ENA */
287#define WM8904_LINEOUTR_PGA_ENA_MASK 0x0001 /* LINEOUTR_PGA_ENA */
288#define WM8904_LINEOUTR_PGA_ENA_SHIFT 0 /* LINEOUTR_PGA_ENA */
289#define WM8904_LINEOUTR_PGA_ENA_WIDTH 1 /* LINEOUTR_PGA_ENA */
290
291/*
292 * R18 (0x12) - Power Management 6
293 */
294#define WM8904_DACL_ENA 0x0008 /* DACL_ENA */
295#define WM8904_DACL_ENA_MASK 0x0008 /* DACL_ENA */
296#define WM8904_DACL_ENA_SHIFT 3 /* DACL_ENA */
297#define WM8904_DACL_ENA_WIDTH 1 /* DACL_ENA */
298#define WM8904_DACR_ENA 0x0004 /* DACR_ENA */
299#define WM8904_DACR_ENA_MASK 0x0004 /* DACR_ENA */
300#define WM8904_DACR_ENA_SHIFT 2 /* DACR_ENA */
301#define WM8904_DACR_ENA_WIDTH 1 /* DACR_ENA */
302#define WM8904_ADCL_ENA 0x0002 /* ADCL_ENA */
303#define WM8904_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
304#define WM8904_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
305#define WM8904_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
306#define WM8904_ADCR_ENA 0x0001 /* ADCR_ENA */
307#define WM8904_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
308#define WM8904_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
309#define WM8904_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
310
311/*
312 * R20 (0x14) - Clock Rates 0
313 */
314#define WM8904_TOCLK_RATE_DIV16 0x4000 /* TOCLK_RATE_DIV16 */
315#define WM8904_TOCLK_RATE_DIV16_MASK 0x4000 /* TOCLK_RATE_DIV16 */
316#define WM8904_TOCLK_RATE_DIV16_SHIFT 14 /* TOCLK_RATE_DIV16 */
317#define WM8904_TOCLK_RATE_DIV16_WIDTH 1 /* TOCLK_RATE_DIV16 */
318#define WM8904_TOCLK_RATE_X4 0x2000 /* TOCLK_RATE_X4 */
319#define WM8904_TOCLK_RATE_X4_MASK 0x2000 /* TOCLK_RATE_X4 */
320#define WM8904_TOCLK_RATE_X4_SHIFT 13 /* TOCLK_RATE_X4 */
321#define WM8904_TOCLK_RATE_X4_WIDTH 1 /* TOCLK_RATE_X4 */
322#define WM8904_SR_MODE 0x1000 /* SR_MODE */
323#define WM8904_SR_MODE_MASK 0x1000 /* SR_MODE */
324#define WM8904_SR_MODE_SHIFT 12 /* SR_MODE */
325#define WM8904_SR_MODE_WIDTH 1 /* SR_MODE */
326#define WM8904_MCLK_DIV 0x0001 /* MCLK_DIV */
327#define WM8904_MCLK_DIV_MASK 0x0001 /* MCLK_DIV */
328#define WM8904_MCLK_DIV_SHIFT 0 /* MCLK_DIV */
329#define WM8904_MCLK_DIV_WIDTH 1 /* MCLK_DIV */
330
331/*
332 * R21 (0x15) - Clock Rates 1
333 */
334#define WM8904_CLK_SYS_RATE_MASK 0x3C00 /* CLK_SYS_RATE - [13:10] */
335#define WM8904_CLK_SYS_RATE_SHIFT 10 /* CLK_SYS_RATE - [13:10] */
336#define WM8904_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [13:10] */
337#define WM8904_SAMPLE_RATE_MASK 0x0007 /* SAMPLE_RATE - [2:0] */
338#define WM8904_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [2:0] */
339#define WM8904_SAMPLE_RATE_WIDTH 3 /* SAMPLE_RATE - [2:0] */
340
341/*
342 * R22 (0x16) - Clock Rates 2
343 */
344#define WM8904_MCLK_INV 0x8000 /* MCLK_INV */
345#define WM8904_MCLK_INV_MASK 0x8000 /* MCLK_INV */
346#define WM8904_MCLK_INV_SHIFT 15 /* MCLK_INV */
347#define WM8904_MCLK_INV_WIDTH 1 /* MCLK_INV */
348#define WM8904_SYSCLK_SRC 0x4000 /* SYSCLK_SRC */
349#define WM8904_SYSCLK_SRC_MASK 0x4000 /* SYSCLK_SRC */
350#define WM8904_SYSCLK_SRC_SHIFT 14 /* SYSCLK_SRC */
351#define WM8904_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
352#define WM8904_TOCLK_RATE 0x1000 /* TOCLK_RATE */
353#define WM8904_TOCLK_RATE_MASK 0x1000 /* TOCLK_RATE */
354#define WM8904_TOCLK_RATE_SHIFT 12 /* TOCLK_RATE */
355#define WM8904_TOCLK_RATE_WIDTH 1 /* TOCLK_RATE */
356#define WM8904_OPCLK_ENA 0x0008 /* OPCLK_ENA */
357#define WM8904_OPCLK_ENA_MASK 0x0008 /* OPCLK_ENA */
358#define WM8904_OPCLK_ENA_SHIFT 3 /* OPCLK_ENA */
359#define WM8904_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
360#define WM8904_CLK_SYS_ENA 0x0004 /* CLK_SYS_ENA */
361#define WM8904_CLK_SYS_ENA_MASK 0x0004 /* CLK_SYS_ENA */
362#define WM8904_CLK_SYS_ENA_SHIFT 2 /* CLK_SYS_ENA */
363#define WM8904_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */
364#define WM8904_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */
365#define WM8904_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */
366#define WM8904_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */
367#define WM8904_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */
368#define WM8904_TOCLK_ENA 0x0001 /* TOCLK_ENA */
369#define WM8904_TOCLK_ENA_MASK 0x0001 /* TOCLK_ENA */
370#define WM8904_TOCLK_ENA_SHIFT 0 /* TOCLK_ENA */
371#define WM8904_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
372
373/*
374 * R24 (0x18) - Audio Interface 0
375 */
376#define WM8904_DACL_DATINV 0x1000 /* DACL_DATINV */
377#define WM8904_DACL_DATINV_MASK 0x1000 /* DACL_DATINV */
378#define WM8904_DACL_DATINV_SHIFT 12 /* DACL_DATINV */
379#define WM8904_DACL_DATINV_WIDTH 1 /* DACL_DATINV */
380#define WM8904_DACR_DATINV 0x0800 /* DACR_DATINV */
381#define WM8904_DACR_DATINV_MASK 0x0800 /* DACR_DATINV */
382#define WM8904_DACR_DATINV_SHIFT 11 /* DACR_DATINV */
383#define WM8904_DACR_DATINV_WIDTH 1 /* DACR_DATINV */
384#define WM8904_DAC_BOOST_MASK 0x0600 /* DAC_BOOST - [10:9] */
385#define WM8904_DAC_BOOST_SHIFT 9 /* DAC_BOOST - [10:9] */
386#define WM8904_DAC_BOOST_WIDTH 2 /* DAC_BOOST - [10:9] */
387#define WM8904_LOOPBACK 0x0100 /* LOOPBACK */
388#define WM8904_LOOPBACK_MASK 0x0100 /* LOOPBACK */
389#define WM8904_LOOPBACK_SHIFT 8 /* LOOPBACK */
390#define WM8904_LOOPBACK_WIDTH 1 /* LOOPBACK */
391#define WM8904_AIFADCL_SRC 0x0080 /* AIFADCL_SRC */
392#define WM8904_AIFADCL_SRC_MASK 0x0080 /* AIFADCL_SRC */
393#define WM8904_AIFADCL_SRC_SHIFT 7 /* AIFADCL_SRC */
394#define WM8904_AIFADCL_SRC_WIDTH 1 /* AIFADCL_SRC */
395#define WM8904_AIFADCR_SRC 0x0040 /* AIFADCR_SRC */
396#define WM8904_AIFADCR_SRC_MASK 0x0040 /* AIFADCR_SRC */
397#define WM8904_AIFADCR_SRC_SHIFT 6 /* AIFADCR_SRC */
398#define WM8904_AIFADCR_SRC_WIDTH 1 /* AIFADCR_SRC */
399#define WM8904_AIFDACL_SRC 0x0020 /* AIFDACL_SRC */
400#define WM8904_AIFDACL_SRC_MASK 0x0020 /* AIFDACL_SRC */
401#define WM8904_AIFDACL_SRC_SHIFT 5 /* AIFDACL_SRC */
402#define WM8904_AIFDACL_SRC_WIDTH 1 /* AIFDACL_SRC */
403#define WM8904_AIFDACR_SRC 0x0010 /* AIFDACR_SRC */
404#define WM8904_AIFDACR_SRC_MASK 0x0010 /* AIFDACR_SRC */
405#define WM8904_AIFDACR_SRC_SHIFT 4 /* AIFDACR_SRC */
406#define WM8904_AIFDACR_SRC_WIDTH 1 /* AIFDACR_SRC */
407#define WM8904_ADC_COMP 0x0008 /* ADC_COMP */
408#define WM8904_ADC_COMP_MASK 0x0008 /* ADC_COMP */
409#define WM8904_ADC_COMP_SHIFT 3 /* ADC_COMP */
410#define WM8904_ADC_COMP_WIDTH 1 /* ADC_COMP */
411#define WM8904_ADC_COMPMODE 0x0004 /* ADC_COMPMODE */
412#define WM8904_ADC_COMPMODE_MASK 0x0004 /* ADC_COMPMODE */
413#define WM8904_ADC_COMPMODE_SHIFT 2 /* ADC_COMPMODE */
414#define WM8904_ADC_COMPMODE_WIDTH 1 /* ADC_COMPMODE */
415#define WM8904_DAC_COMP 0x0002 /* DAC_COMP */
416#define WM8904_DAC_COMP_MASK 0x0002 /* DAC_COMP */
417#define WM8904_DAC_COMP_SHIFT 1 /* DAC_COMP */
418#define WM8904_DAC_COMP_WIDTH 1 /* DAC_COMP */
419#define WM8904_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */
420#define WM8904_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */
421#define WM8904_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */
422#define WM8904_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */
423
424/*
425 * R25 (0x19) - Audio Interface 1
426 */
427#define WM8904_AIFDAC_TDM 0x2000 /* AIFDAC_TDM */
428#define WM8904_AIFDAC_TDM_MASK 0x2000 /* AIFDAC_TDM */
429#define WM8904_AIFDAC_TDM_SHIFT 13 /* AIFDAC_TDM */
430#define WM8904_AIFDAC_TDM_WIDTH 1 /* AIFDAC_TDM */
431#define WM8904_AIFDAC_TDM_CHAN 0x1000 /* AIFDAC_TDM_CHAN */
432#define WM8904_AIFDAC_TDM_CHAN_MASK 0x1000 /* AIFDAC_TDM_CHAN */
433#define WM8904_AIFDAC_TDM_CHAN_SHIFT 12 /* AIFDAC_TDM_CHAN */
434#define WM8904_AIFDAC_TDM_CHAN_WIDTH 1 /* AIFDAC_TDM_CHAN */
435#define WM8904_AIFADC_TDM 0x0800 /* AIFADC_TDM */
436#define WM8904_AIFADC_TDM_MASK 0x0800 /* AIFADC_TDM */
437#define WM8904_AIFADC_TDM_SHIFT 11 /* AIFADC_TDM */
438#define WM8904_AIFADC_TDM_WIDTH 1 /* AIFADC_TDM */
439#define WM8904_AIFADC_TDM_CHAN 0x0400 /* AIFADC_TDM_CHAN */
440#define WM8904_AIFADC_TDM_CHAN_MASK 0x0400 /* AIFADC_TDM_CHAN */
441#define WM8904_AIFADC_TDM_CHAN_SHIFT 10 /* AIFADC_TDM_CHAN */
442#define WM8904_AIFADC_TDM_CHAN_WIDTH 1 /* AIFADC_TDM_CHAN */
443#define WM8904_AIF_TRIS 0x0100 /* AIF_TRIS */
444#define WM8904_AIF_TRIS_MASK 0x0100 /* AIF_TRIS */
445#define WM8904_AIF_TRIS_SHIFT 8 /* AIF_TRIS */
446#define WM8904_AIF_TRIS_WIDTH 1 /* AIF_TRIS */
447#define WM8904_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */
448#define WM8904_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */
449#define WM8904_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */
450#define WM8904_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */
451#define WM8904_BCLK_DIR 0x0040 /* BCLK_DIR */
452#define WM8904_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */
453#define WM8904_BCLK_DIR_SHIFT 6 /* BCLK_DIR */
454#define WM8904_BCLK_DIR_WIDTH 1 /* BCLK_DIR */
455#define WM8904_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */
456#define WM8904_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */
457#define WM8904_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */
458#define WM8904_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */
459#define WM8904_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */
460#define WM8904_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */
461#define WM8904_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */
462#define WM8904_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */
463#define WM8904_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */
464#define WM8904_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */
465
466/*
467 * R26 (0x1A) - Audio Interface 2
468 */
469#define WM8904_OPCLK_DIV_MASK 0x0F00 /* OPCLK_DIV - [11:8] */
470#define WM8904_OPCLK_DIV_SHIFT 8 /* OPCLK_DIV - [11:8] */
471#define WM8904_OPCLK_DIV_WIDTH 4 /* OPCLK_DIV - [11:8] */
472#define WM8904_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */
473#define WM8904_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */
474#define WM8904_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */
475
476/*
477 * R27 (0x1B) - Audio Interface 3
478 */
479#define WM8904_LRCLK_DIR 0x0800 /* LRCLK_DIR */
480#define WM8904_LRCLK_DIR_MASK 0x0800 /* LRCLK_DIR */
481#define WM8904_LRCLK_DIR_SHIFT 11 /* LRCLK_DIR */
482#define WM8904_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */
483#define WM8904_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */
484#define WM8904_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */
485#define WM8904_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */
486
487/*
488 * R30 (0x1E) - DAC Digital Volume Left
489 */
490#define WM8904_DAC_VU 0x0100 /* DAC_VU */
491#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
492#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
493#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
494#define WM8904_DACL_VOL_MASK 0x00FF /* DACL_VOL - [7:0] */
495#define WM8904_DACL_VOL_SHIFT 0 /* DACL_VOL - [7:0] */
496#define WM8904_DACL_VOL_WIDTH 8 /* DACL_VOL - [7:0] */
497
498/*
499 * R31 (0x1F) - DAC Digital Volume Right
500 */
501#define WM8904_DAC_VU 0x0100 /* DAC_VU */
502#define WM8904_DAC_VU_MASK 0x0100 /* DAC_VU */
503#define WM8904_DAC_VU_SHIFT 8 /* DAC_VU */
504#define WM8904_DAC_VU_WIDTH 1 /* DAC_VU */
505#define WM8904_DACR_VOL_MASK 0x00FF /* DACR_VOL - [7:0] */
506#define WM8904_DACR_VOL_SHIFT 0 /* DACR_VOL - [7:0] */
507#define WM8904_DACR_VOL_WIDTH 8 /* DACR_VOL - [7:0] */
508
509/*
510 * R32 (0x20) - DAC Digital 0
511 */
512#define WM8904_ADCL_DAC_SVOL_MASK 0x0F00 /* ADCL_DAC_SVOL - [11:8] */
513#define WM8904_ADCL_DAC_SVOL_SHIFT 8 /* ADCL_DAC_SVOL - [11:8] */
514#define WM8904_ADCL_DAC_SVOL_WIDTH 4 /* ADCL_DAC_SVOL - [11:8] */
515#define WM8904_ADCR_DAC_SVOL_MASK 0x00F0 /* ADCR_DAC_SVOL - [7:4] */
516#define WM8904_ADCR_DAC_SVOL_SHIFT 4 /* ADCR_DAC_SVOL - [7:4] */
517#define WM8904_ADCR_DAC_SVOL_WIDTH 4 /* ADCR_DAC_SVOL - [7:4] */
518#define WM8904_ADC_TO_DACL_MASK 0x000C /* ADC_TO_DACL - [3:2] */
519#define WM8904_ADC_TO_DACL_SHIFT 2 /* ADC_TO_DACL - [3:2] */
520#define WM8904_ADC_TO_DACL_WIDTH 2 /* ADC_TO_DACL - [3:2] */
521#define WM8904_ADC_TO_DACR_MASK 0x0003 /* ADC_TO_DACR - [1:0] */
522#define WM8904_ADC_TO_DACR_SHIFT 0 /* ADC_TO_DACR - [1:0] */
523#define WM8904_ADC_TO_DACR_WIDTH 2 /* ADC_TO_DACR - [1:0] */
524
525/*
526 * R33 (0x21) - DAC Digital 1
527 */
528#define WM8904_DAC_MONO 0x1000 /* DAC_MONO */
529#define WM8904_DAC_MONO_MASK 0x1000 /* DAC_MONO */
530#define WM8904_DAC_MONO_SHIFT 12 /* DAC_MONO */
531#define WM8904_DAC_MONO_WIDTH 1 /* DAC_MONO */
532#define WM8904_DAC_SB_FILT 0x0800 /* DAC_SB_FILT */
533#define WM8904_DAC_SB_FILT_MASK 0x0800 /* DAC_SB_FILT */
534#define WM8904_DAC_SB_FILT_SHIFT 11 /* DAC_SB_FILT */
535#define WM8904_DAC_SB_FILT_WIDTH 1 /* DAC_SB_FILT */
536#define WM8904_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */
537#define WM8904_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */
538#define WM8904_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */
539#define WM8904_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
540#define WM8904_DAC_UNMUTE_RAMP 0x0200 /* DAC_UNMUTE_RAMP */
541#define WM8904_DAC_UNMUTE_RAMP_MASK 0x0200 /* DAC_UNMUTE_RAMP */
542#define WM8904_DAC_UNMUTE_RAMP_SHIFT 9 /* DAC_UNMUTE_RAMP */
543#define WM8904_DAC_UNMUTE_RAMP_WIDTH 1 /* DAC_UNMUTE_RAMP */
544#define WM8904_DAC_OSR128 0x0040 /* DAC_OSR128 */
545#define WM8904_DAC_OSR128_MASK 0x0040 /* DAC_OSR128 */
546#define WM8904_DAC_OSR128_SHIFT 6 /* DAC_OSR128 */
547#define WM8904_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
548#define WM8904_DAC_MUTE 0x0008 /* DAC_MUTE */
549#define WM8904_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */
550#define WM8904_DAC_MUTE_SHIFT 3 /* DAC_MUTE */
551#define WM8904_DAC_MUTE_WIDTH 1 /* DAC_MUTE */
552#define WM8904_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
553#define WM8904_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
554#define WM8904_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
555
556/*
557 * R36 (0x24) - ADC Digital Volume Left
558 */
559#define WM8904_ADC_VU 0x0100 /* ADC_VU */
560#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
561#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
562#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
563#define WM8904_ADCL_VOL_MASK 0x00FF /* ADCL_VOL - [7:0] */
564#define WM8904_ADCL_VOL_SHIFT 0 /* ADCL_VOL - [7:0] */
565#define WM8904_ADCL_VOL_WIDTH 8 /* ADCL_VOL - [7:0] */
566
567/*
568 * R37 (0x25) - ADC Digital Volume Right
569 */
570#define WM8904_ADC_VU 0x0100 /* ADC_VU */
571#define WM8904_ADC_VU_MASK 0x0100 /* ADC_VU */
572#define WM8904_ADC_VU_SHIFT 8 /* ADC_VU */
573#define WM8904_ADC_VU_WIDTH 1 /* ADC_VU */
574#define WM8904_ADCR_VOL_MASK 0x00FF /* ADCR_VOL - [7:0] */
575#define WM8904_ADCR_VOL_SHIFT 0 /* ADCR_VOL - [7:0] */
576#define WM8904_ADCR_VOL_WIDTH 8 /* ADCR_VOL - [7:0] */
577
578/*
579 * R38 (0x26) - ADC Digital 0
580 */
581#define WM8904_ADC_HPF_CUT_MASK 0x0060 /* ADC_HPF_CUT - [6:5] */
582#define WM8904_ADC_HPF_CUT_SHIFT 5 /* ADC_HPF_CUT - [6:5] */
583#define WM8904_ADC_HPF_CUT_WIDTH 2 /* ADC_HPF_CUT - [6:5] */
584#define WM8904_ADC_HPF 0x0010 /* ADC_HPF */
585#define WM8904_ADC_HPF_MASK 0x0010 /* ADC_HPF */
586#define WM8904_ADC_HPF_SHIFT 4 /* ADC_HPF */
587#define WM8904_ADC_HPF_WIDTH 1 /* ADC_HPF */
588#define WM8904_ADCL_DATINV 0x0002 /* ADCL_DATINV */
589#define WM8904_ADCL_DATINV_MASK 0x0002 /* ADCL_DATINV */
590#define WM8904_ADCL_DATINV_SHIFT 1 /* ADCL_DATINV */
591#define WM8904_ADCL_DATINV_WIDTH 1 /* ADCL_DATINV */
592#define WM8904_ADCR_DATINV 0x0001 /* ADCR_DATINV */
593#define WM8904_ADCR_DATINV_MASK 0x0001 /* ADCR_DATINV */
594#define WM8904_ADCR_DATINV_SHIFT 0 /* ADCR_DATINV */
595#define WM8904_ADCR_DATINV_WIDTH 1 /* ADCR_DATINV */
596
597/*
598 * R39 (0x27) - Digital Microphone 0
599 */
600#define WM8904_DMIC_ENA 0x1000 /* DMIC_ENA */
601#define WM8904_DMIC_ENA_MASK 0x1000 /* DMIC_ENA */
602#define WM8904_DMIC_ENA_SHIFT 12 /* DMIC_ENA */
603#define WM8904_DMIC_ENA_WIDTH 1 /* DMIC_ENA */
604#define WM8904_DMIC_SRC 0x0800 /* DMIC_SRC */
605#define WM8904_DMIC_SRC_MASK 0x0800 /* DMIC_SRC */
606#define WM8904_DMIC_SRC_SHIFT 11 /* DMIC_SRC */
607#define WM8904_DMIC_SRC_WIDTH 1 /* DMIC_SRC */
608
609/*
610 * R40 (0x28) - DRC 0
611 */
612#define WM8904_DRC_ENA 0x8000 /* DRC_ENA */
613#define WM8904_DRC_ENA_MASK 0x8000 /* DRC_ENA */
614#define WM8904_DRC_ENA_SHIFT 15 /* DRC_ENA */
615#define WM8904_DRC_ENA_WIDTH 1 /* DRC_ENA */
616#define WM8904_DRC_DAC_PATH 0x4000 /* DRC_DAC_PATH */
617#define WM8904_DRC_DAC_PATH_MASK 0x4000 /* DRC_DAC_PATH */
618#define WM8904_DRC_DAC_PATH_SHIFT 14 /* DRC_DAC_PATH */
619#define WM8904_DRC_DAC_PATH_WIDTH 1 /* DRC_DAC_PATH */
620#define WM8904_DRC_GS_HYST_LVL_MASK 0x1800 /* DRC_GS_HYST_LVL - [12:11] */
621#define WM8904_DRC_GS_HYST_LVL_SHIFT 11 /* DRC_GS_HYST_LVL - [12:11] */
622#define WM8904_DRC_GS_HYST_LVL_WIDTH 2 /* DRC_GS_HYST_LVL - [12:11] */
623#define WM8904_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */
624#define WM8904_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */
625#define WM8904_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */
626#define WM8904_DRC_FF_DELAY 0x0020 /* DRC_FF_DELAY */
627#define WM8904_DRC_FF_DELAY_MASK 0x0020 /* DRC_FF_DELAY */
628#define WM8904_DRC_FF_DELAY_SHIFT 5 /* DRC_FF_DELAY */
629#define WM8904_DRC_FF_DELAY_WIDTH 1 /* DRC_FF_DELAY */
630#define WM8904_DRC_GS_ENA 0x0008 /* DRC_GS_ENA */
631#define WM8904_DRC_GS_ENA_MASK 0x0008 /* DRC_GS_ENA */
632#define WM8904_DRC_GS_ENA_SHIFT 3 /* DRC_GS_ENA */
633#define WM8904_DRC_GS_ENA_WIDTH 1 /* DRC_GS_ENA */
634#define WM8904_DRC_QR 0x0004 /* DRC_QR */
635#define WM8904_DRC_QR_MASK 0x0004 /* DRC_QR */
636#define WM8904_DRC_QR_SHIFT 2 /* DRC_QR */
637#define WM8904_DRC_QR_WIDTH 1 /* DRC_QR */
638#define WM8904_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */
639#define WM8904_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */
640#define WM8904_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */
641#define WM8904_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */
642#define WM8904_DRC_GS_HYST 0x0001 /* DRC_GS_HYST */
643#define WM8904_DRC_GS_HYST_MASK 0x0001 /* DRC_GS_HYST */
644#define WM8904_DRC_GS_HYST_SHIFT 0 /* DRC_GS_HYST */
645#define WM8904_DRC_GS_HYST_WIDTH 1 /* DRC_GS_HYST */
646
647/*
648 * R41 (0x29) - DRC 1
649 */
650#define WM8904_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */
651#define WM8904_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */
652#define WM8904_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */
653#define WM8904_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */
654#define WM8904_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */
655#define WM8904_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */
656#define WM8904_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */
657#define WM8904_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */
658#define WM8904_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */
659#define WM8904_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */
660#define WM8904_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */
661#define WM8904_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */
662#define WM8904_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */
663#define WM8904_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */
664#define WM8904_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */
665#define WM8904_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */
666#define WM8904_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */
667#define WM8904_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */
668
669/*
670 * R42 (0x2A) - DRC 2
671 */
672#define WM8904_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */
673#define WM8904_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */
674#define WM8904_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */
675#define WM8904_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */
676#define WM8904_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */
677#define WM8904_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */
678
679/*
680 * R43 (0x2B) - DRC 3
681 */
682#define WM8904_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */
683#define WM8904_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */
684#define WM8904_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */
685#define WM8904_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */
686#define WM8904_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */
687#define WM8904_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */
688
689/*
690 * R44 (0x2C) - Analogue Left Input 0
691 */
692#define WM8904_LINMUTE 0x0080 /* LINMUTE */
693#define WM8904_LINMUTE_MASK 0x0080 /* LINMUTE */
694#define WM8904_LINMUTE_SHIFT 7 /* LINMUTE */
695#define WM8904_LINMUTE_WIDTH 1 /* LINMUTE */
696#define WM8904_LIN_VOL_MASK 0x001F /* LIN_VOL - [4:0] */
697#define WM8904_LIN_VOL_SHIFT 0 /* LIN_VOL - [4:0] */
698#define WM8904_LIN_VOL_WIDTH 5 /* LIN_VOL - [4:0] */
699
700/*
701 * R45 (0x2D) - Analogue Right Input 0
702 */
703#define WM8904_RINMUTE 0x0080 /* RINMUTE */
704#define WM8904_RINMUTE_MASK 0x0080 /* RINMUTE */
705#define WM8904_RINMUTE_SHIFT 7 /* RINMUTE */
706#define WM8904_RINMUTE_WIDTH 1 /* RINMUTE */
707#define WM8904_RIN_VOL_MASK 0x001F /* RIN_VOL - [4:0] */
708#define WM8904_RIN_VOL_SHIFT 0 /* RIN_VOL - [4:0] */
709#define WM8904_RIN_VOL_WIDTH 5 /* RIN_VOL - [4:0] */
710
711/*
712 * R46 (0x2E) - Analogue Left Input 1
713 */
714#define WM8904_INL_CM_ENA 0x0040 /* INL_CM_ENA */
715#define WM8904_INL_CM_ENA_MASK 0x0040 /* INL_CM_ENA */
716#define WM8904_INL_CM_ENA_SHIFT 6 /* INL_CM_ENA */
717#define WM8904_INL_CM_ENA_WIDTH 1 /* INL_CM_ENA */
718#define WM8904_L_IP_SEL_N_MASK 0x0030 /* L_IP_SEL_N - [5:4] */
719#define WM8904_L_IP_SEL_N_SHIFT 4 /* L_IP_SEL_N - [5:4] */
720#define WM8904_L_IP_SEL_N_WIDTH 2 /* L_IP_SEL_N - [5:4] */
721#define WM8904_L_IP_SEL_P_MASK 0x000C /* L_IP_SEL_P - [3:2] */
722#define WM8904_L_IP_SEL_P_SHIFT 2 /* L_IP_SEL_P - [3:2] */
723#define WM8904_L_IP_SEL_P_WIDTH 2 /* L_IP_SEL_P - [3:2] */
724#define WM8904_L_MODE_MASK 0x0003 /* L_MODE - [1:0] */
725#define WM8904_L_MODE_SHIFT 0 /* L_MODE - [1:0] */
726#define WM8904_L_MODE_WIDTH 2 /* L_MODE - [1:0] */
727
728/*
729 * R47 (0x2F) - Analogue Right Input 1
730 */
731#define WM8904_INR_CM_ENA 0x0040 /* INR_CM_ENA */
732#define WM8904_INR_CM_ENA_MASK 0x0040 /* INR_CM_ENA */
733#define WM8904_INR_CM_ENA_SHIFT 6 /* INR_CM_ENA */
734#define WM8904_INR_CM_ENA_WIDTH 1 /* INR_CM_ENA */
735#define WM8904_R_IP_SEL_N_MASK 0x0030 /* R_IP_SEL_N - [5:4] */
736#define WM8904_R_IP_SEL_N_SHIFT 4 /* R_IP_SEL_N - [5:4] */
737#define WM8904_R_IP_SEL_N_WIDTH 2 /* R_IP_SEL_N - [5:4] */
738#define WM8904_R_IP_SEL_P_MASK 0x000C /* R_IP_SEL_P - [3:2] */
739#define WM8904_R_IP_SEL_P_SHIFT 2 /* R_IP_SEL_P - [3:2] */
740#define WM8904_R_IP_SEL_P_WIDTH 2 /* R_IP_SEL_P - [3:2] */
741#define WM8904_R_MODE_MASK 0x0003 /* R_MODE - [1:0] */
742#define WM8904_R_MODE_SHIFT 0 /* R_MODE - [1:0] */
743#define WM8904_R_MODE_WIDTH 2 /* R_MODE - [1:0] */
744
745/*
746 * R57 (0x39) - Analogue OUT1 Left
747 */
748#define WM8904_HPOUTL_MUTE 0x0100 /* HPOUTL_MUTE */
749#define WM8904_HPOUTL_MUTE_MASK 0x0100 /* HPOUTL_MUTE */
750#define WM8904_HPOUTL_MUTE_SHIFT 8 /* HPOUTL_MUTE */
751#define WM8904_HPOUTL_MUTE_WIDTH 1 /* HPOUTL_MUTE */
752#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
753#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
754#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
755#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
756#define WM8904_HPOUTLZC 0x0040 /* HPOUTLZC */
757#define WM8904_HPOUTLZC_MASK 0x0040 /* HPOUTLZC */
758#define WM8904_HPOUTLZC_SHIFT 6 /* HPOUTLZC */
759#define WM8904_HPOUTLZC_WIDTH 1 /* HPOUTLZC */
760#define WM8904_HPOUTL_VOL_MASK 0x003F /* HPOUTL_VOL - [5:0] */
761#define WM8904_HPOUTL_VOL_SHIFT 0 /* HPOUTL_VOL - [5:0] */
762#define WM8904_HPOUTL_VOL_WIDTH 6 /* HPOUTL_VOL - [5:0] */
763
764/*
765 * R58 (0x3A) - Analogue OUT1 Right
766 */
767#define WM8904_HPOUTR_MUTE 0x0100 /* HPOUTR_MUTE */
768#define WM8904_HPOUTR_MUTE_MASK 0x0100 /* HPOUTR_MUTE */
769#define WM8904_HPOUTR_MUTE_SHIFT 8 /* HPOUTR_MUTE */
770#define WM8904_HPOUTR_MUTE_WIDTH 1 /* HPOUTR_MUTE */
771#define WM8904_HPOUT_VU 0x0080 /* HPOUT_VU */
772#define WM8904_HPOUT_VU_MASK 0x0080 /* HPOUT_VU */
773#define WM8904_HPOUT_VU_SHIFT 7 /* HPOUT_VU */
774#define WM8904_HPOUT_VU_WIDTH 1 /* HPOUT_VU */
775#define WM8904_HPOUTRZC 0x0040 /* HPOUTRZC */
776#define WM8904_HPOUTRZC_MASK 0x0040 /* HPOUTRZC */
777#define WM8904_HPOUTRZC_SHIFT 6 /* HPOUTRZC */
778#define WM8904_HPOUTRZC_WIDTH 1 /* HPOUTRZC */
779#define WM8904_HPOUTR_VOL_MASK 0x003F /* HPOUTR_VOL - [5:0] */
780#define WM8904_HPOUTR_VOL_SHIFT 0 /* HPOUTR_VOL - [5:0] */
781#define WM8904_HPOUTR_VOL_WIDTH 6 /* HPOUTR_VOL - [5:0] */
782
783/*
784 * R59 (0x3B) - Analogue OUT2 Left
785 */
786#define WM8904_LINEOUTL_MUTE 0x0100 /* LINEOUTL_MUTE */
787#define WM8904_LINEOUTL_MUTE_MASK 0x0100 /* LINEOUTL_MUTE */
788#define WM8904_LINEOUTL_MUTE_SHIFT 8 /* LINEOUTL_MUTE */
789#define WM8904_LINEOUTL_MUTE_WIDTH 1 /* LINEOUTL_MUTE */
790#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
791#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
792#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
793#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
794#define WM8904_LINEOUTLZC 0x0040 /* LINEOUTLZC */
795#define WM8904_LINEOUTLZC_MASK 0x0040 /* LINEOUTLZC */
796#define WM8904_LINEOUTLZC_SHIFT 6 /* LINEOUTLZC */
797#define WM8904_LINEOUTLZC_WIDTH 1 /* LINEOUTLZC */
798#define WM8904_LINEOUTL_VOL_MASK 0x003F /* LINEOUTL_VOL - [5:0] */
799#define WM8904_LINEOUTL_VOL_SHIFT 0 /* LINEOUTL_VOL - [5:0] */
800#define WM8904_LINEOUTL_VOL_WIDTH 6 /* LINEOUTL_VOL - [5:0] */
801
802/*
803 * R60 (0x3C) - Analogue OUT2 Right
804 */
805#define WM8904_LINEOUTR_MUTE 0x0100 /* LINEOUTR_MUTE */
806#define WM8904_LINEOUTR_MUTE_MASK 0x0100 /* LINEOUTR_MUTE */
807#define WM8904_LINEOUTR_MUTE_SHIFT 8 /* LINEOUTR_MUTE */
808#define WM8904_LINEOUTR_MUTE_WIDTH 1 /* LINEOUTR_MUTE */
809#define WM8904_LINEOUT_VU 0x0080 /* LINEOUT_VU */
810#define WM8904_LINEOUT_VU_MASK 0x0080 /* LINEOUT_VU */
811#define WM8904_LINEOUT_VU_SHIFT 7 /* LINEOUT_VU */
812#define WM8904_LINEOUT_VU_WIDTH 1 /* LINEOUT_VU */
813#define WM8904_LINEOUTRZC 0x0040 /* LINEOUTRZC */
814#define WM8904_LINEOUTRZC_MASK 0x0040 /* LINEOUTRZC */
815#define WM8904_LINEOUTRZC_SHIFT 6 /* LINEOUTRZC */
816#define WM8904_LINEOUTRZC_WIDTH 1 /* LINEOUTRZC */
817#define WM8904_LINEOUTR_VOL_MASK 0x003F /* LINEOUTR_VOL - [5:0] */
818#define WM8904_LINEOUTR_VOL_SHIFT 0 /* LINEOUTR_VOL - [5:0] */
819#define WM8904_LINEOUTR_VOL_WIDTH 6 /* LINEOUTR_VOL - [5:0] */
820
821/*
822 * R61 (0x3D) - Analogue OUT12 ZC
823 */
824#define WM8904_HPL_BYP_ENA 0x0008 /* HPL_BYP_ENA */
825#define WM8904_HPL_BYP_ENA_MASK 0x0008 /* HPL_BYP_ENA */
826#define WM8904_HPL_BYP_ENA_SHIFT 3 /* HPL_BYP_ENA */
827#define WM8904_HPL_BYP_ENA_WIDTH 1 /* HPL_BYP_ENA */
828#define WM8904_HPR_BYP_ENA 0x0004 /* HPR_BYP_ENA */
829#define WM8904_HPR_BYP_ENA_MASK 0x0004 /* HPR_BYP_ENA */
830#define WM8904_HPR_BYP_ENA_SHIFT 2 /* HPR_BYP_ENA */
831#define WM8904_HPR_BYP_ENA_WIDTH 1 /* HPR_BYP_ENA */
832#define WM8904_LINEOUTL_BYP_ENA 0x0002 /* LINEOUTL_BYP_ENA */
833#define WM8904_LINEOUTL_BYP_ENA_MASK 0x0002 /* LINEOUTL_BYP_ENA */
834#define WM8904_LINEOUTL_BYP_ENA_SHIFT 1 /* LINEOUTL_BYP_ENA */
835#define WM8904_LINEOUTL_BYP_ENA_WIDTH 1 /* LINEOUTL_BYP_ENA */
836#define WM8904_LINEOUTR_BYP_ENA 0x0001 /* LINEOUTR_BYP_ENA */
837#define WM8904_LINEOUTR_BYP_ENA_MASK 0x0001 /* LINEOUTR_BYP_ENA */
838#define WM8904_LINEOUTR_BYP_ENA_SHIFT 0 /* LINEOUTR_BYP_ENA */
839#define WM8904_LINEOUTR_BYP_ENA_WIDTH 1 /* LINEOUTR_BYP_ENA */
840
841/*
842 * R67 (0x43) - DC Servo 0
843 */
844#define WM8904_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
845#define WM8904_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
846#define WM8904_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
847#define WM8904_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
848#define WM8904_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
849#define WM8904_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
850#define WM8904_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
851#define WM8904_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
852#define WM8904_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
853#define WM8904_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
854#define WM8904_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
855#define WM8904_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
856#define WM8904_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
857#define WM8904_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
858#define WM8904_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
859#define WM8904_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
860
861/*
862 * R68 (0x44) - DC Servo 1
863 */
864#define WM8904_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
865#define WM8904_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
866#define WM8904_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
867#define WM8904_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
868#define WM8904_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
869#define WM8904_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
870#define WM8904_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
871#define WM8904_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
872#define WM8904_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
873#define WM8904_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
874#define WM8904_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
875#define WM8904_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
876#define WM8904_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
877#define WM8904_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
878#define WM8904_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
879#define WM8904_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
880#define WM8904_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
881#define WM8904_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
882#define WM8904_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
883#define WM8904_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
884#define WM8904_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
885#define WM8904_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
886#define WM8904_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
887#define WM8904_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
888#define WM8904_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
889#define WM8904_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
890#define WM8904_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
891#define WM8904_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
892#define WM8904_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
893#define WM8904_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
894#define WM8904_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
895#define WM8904_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
896#define WM8904_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
897#define WM8904_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
898#define WM8904_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
899#define WM8904_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
900#define WM8904_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
901#define WM8904_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
902#define WM8904_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
903#define WM8904_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
904#define WM8904_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
905#define WM8904_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
906#define WM8904_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
907#define WM8904_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
908#define WM8904_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
909#define WM8904_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
910#define WM8904_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
911#define WM8904_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
912#define WM8904_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
913#define WM8904_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
914#define WM8904_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
915#define WM8904_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
916#define WM8904_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
917#define WM8904_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
918#define WM8904_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
919#define WM8904_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
920#define WM8904_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
921#define WM8904_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
922#define WM8904_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
923#define WM8904_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
924#define WM8904_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
925#define WM8904_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
926#define WM8904_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
927#define WM8904_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
928
929/*
930 * R69 (0x45) - DC Servo 2
931 */
932#define WM8904_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
933#define WM8904_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
934#define WM8904_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
935#define WM8904_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
936#define WM8904_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
937#define WM8904_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
938
939/*
940 * R71 (0x47) - DC Servo 4
941 */
942#define WM8904_DCS_SERIES_NO_23_MASK 0x007F /* DCS_SERIES_NO_23 - [6:0] */
943#define WM8904_DCS_SERIES_NO_23_SHIFT 0 /* DCS_SERIES_NO_23 - [6:0] */
944#define WM8904_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [6:0] */
945
946/*
947 * R72 (0x48) - DC Servo 5
948 */
949#define WM8904_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
950#define WM8904_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
951#define WM8904_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
952
953/*
954 * R73 (0x49) - DC Servo 6
955 */
956#define WM8904_DCS_DAC_WR_VAL_3_MASK 0x00FF /* DCS_DAC_WR_VAL_3 - [7:0] */
957#define WM8904_DCS_DAC_WR_VAL_3_SHIFT 0 /* DCS_DAC_WR_VAL_3 - [7:0] */
958#define WM8904_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [7:0] */
959
960/*
961 * R74 (0x4A) - DC Servo 7
962 */
963#define WM8904_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
964#define WM8904_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
965#define WM8904_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
966
967/*
968 * R75 (0x4B) - DC Servo 8
969 */
970#define WM8904_DCS_DAC_WR_VAL_1_MASK 0x00FF /* DCS_DAC_WR_VAL_1 - [7:0] */
971#define WM8904_DCS_DAC_WR_VAL_1_SHIFT 0 /* DCS_DAC_WR_VAL_1 - [7:0] */
972#define WM8904_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [7:0] */
973
974/*
975 * R76 (0x4C) - DC Servo 9
976 */
977#define WM8904_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
978#define WM8904_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
979#define WM8904_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
980
981/*
982 * R77 (0x4D) - DC Servo Readback 0
983 */
984#define WM8904_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
985#define WM8904_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
986#define WM8904_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
987#define WM8904_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
988#define WM8904_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
989#define WM8904_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
990#define WM8904_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
991#define WM8904_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
992#define WM8904_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
993
994/*
995 * R90 (0x5A) - Analogue HP 0
996 */
997#define WM8904_HPL_RMV_SHORT 0x0080 /* HPL_RMV_SHORT */
998#define WM8904_HPL_RMV_SHORT_MASK 0x0080 /* HPL_RMV_SHORT */
999#define WM8904_HPL_RMV_SHORT_SHIFT 7 /* HPL_RMV_SHORT */
1000#define WM8904_HPL_RMV_SHORT_WIDTH 1 /* HPL_RMV_SHORT */
1001#define WM8904_HPL_ENA_OUTP 0x0040 /* HPL_ENA_OUTP */
1002#define WM8904_HPL_ENA_OUTP_MASK 0x0040 /* HPL_ENA_OUTP */
1003#define WM8904_HPL_ENA_OUTP_SHIFT 6 /* HPL_ENA_OUTP */
1004#define WM8904_HPL_ENA_OUTP_WIDTH 1 /* HPL_ENA_OUTP */
1005#define WM8904_HPL_ENA_DLY 0x0020 /* HPL_ENA_DLY */
1006#define WM8904_HPL_ENA_DLY_MASK 0x0020 /* HPL_ENA_DLY */
1007#define WM8904_HPL_ENA_DLY_SHIFT 5 /* HPL_ENA_DLY */
1008#define WM8904_HPL_ENA_DLY_WIDTH 1 /* HPL_ENA_DLY */
1009#define WM8904_HPL_ENA 0x0010 /* HPL_ENA */
1010#define WM8904_HPL_ENA_MASK 0x0010 /* HPL_ENA */
1011#define WM8904_HPL_ENA_SHIFT 4 /* HPL_ENA */
1012#define WM8904_HPL_ENA_WIDTH 1 /* HPL_ENA */
1013#define WM8904_HPR_RMV_SHORT 0x0008 /* HPR_RMV_SHORT */
1014#define WM8904_HPR_RMV_SHORT_MASK 0x0008 /* HPR_RMV_SHORT */
1015#define WM8904_HPR_RMV_SHORT_SHIFT 3 /* HPR_RMV_SHORT */
1016#define WM8904_HPR_RMV_SHORT_WIDTH 1 /* HPR_RMV_SHORT */
1017#define WM8904_HPR_ENA_OUTP 0x0004 /* HPR_ENA_OUTP */
1018#define WM8904_HPR_ENA_OUTP_MASK 0x0004 /* HPR_ENA_OUTP */
1019#define WM8904_HPR_ENA_OUTP_SHIFT 2 /* HPR_ENA_OUTP */
1020#define WM8904_HPR_ENA_OUTP_WIDTH 1 /* HPR_ENA_OUTP */
1021#define WM8904_HPR_ENA_DLY 0x0002 /* HPR_ENA_DLY */
1022#define WM8904_HPR_ENA_DLY_MASK 0x0002 /* HPR_ENA_DLY */
1023#define WM8904_HPR_ENA_DLY_SHIFT 1 /* HPR_ENA_DLY */
1024#define WM8904_HPR_ENA_DLY_WIDTH 1 /* HPR_ENA_DLY */
1025#define WM8904_HPR_ENA 0x0001 /* HPR_ENA */
1026#define WM8904_HPR_ENA_MASK 0x0001 /* HPR_ENA */
1027#define WM8904_HPR_ENA_SHIFT 0 /* HPR_ENA */
1028#define WM8904_HPR_ENA_WIDTH 1 /* HPR_ENA */
1029
1030/*
1031 * R94 (0x5E) - Analogue Lineout 0
1032 */
1033#define WM8904_LINEOUTL_RMV_SHORT 0x0080 /* LINEOUTL_RMV_SHORT */
1034#define WM8904_LINEOUTL_RMV_SHORT_MASK 0x0080 /* LINEOUTL_RMV_SHORT */
1035#define WM8904_LINEOUTL_RMV_SHORT_SHIFT 7 /* LINEOUTL_RMV_SHORT */
1036#define WM8904_LINEOUTL_RMV_SHORT_WIDTH 1 /* LINEOUTL_RMV_SHORT */
1037#define WM8904_LINEOUTL_ENA_OUTP 0x0040 /* LINEOUTL_ENA_OUTP */
1038#define WM8904_LINEOUTL_ENA_OUTP_MASK 0x0040 /* LINEOUTL_ENA_OUTP */
1039#define WM8904_LINEOUTL_ENA_OUTP_SHIFT 6 /* LINEOUTL_ENA_OUTP */
1040#define WM8904_LINEOUTL_ENA_OUTP_WIDTH 1 /* LINEOUTL_ENA_OUTP */
1041#define WM8904_LINEOUTL_ENA_DLY 0x0020 /* LINEOUTL_ENA_DLY */
1042#define WM8904_LINEOUTL_ENA_DLY_MASK 0x0020 /* LINEOUTL_ENA_DLY */
1043#define WM8904_LINEOUTL_ENA_DLY_SHIFT 5 /* LINEOUTL_ENA_DLY */
1044#define WM8904_LINEOUTL_ENA_DLY_WIDTH 1 /* LINEOUTL_ENA_DLY */
1045#define WM8904_LINEOUTL_ENA 0x0010 /* LINEOUTL_ENA */
1046#define WM8904_LINEOUTL_ENA_MASK 0x0010 /* LINEOUTL_ENA */
1047#define WM8904_LINEOUTL_ENA_SHIFT 4 /* LINEOUTL_ENA */
1048#define WM8904_LINEOUTL_ENA_WIDTH 1 /* LINEOUTL_ENA */
1049#define WM8904_LINEOUTR_RMV_SHORT 0x0008 /* LINEOUTR_RMV_SHORT */
1050#define WM8904_LINEOUTR_RMV_SHORT_MASK 0x0008 /* LINEOUTR_RMV_SHORT */
1051#define WM8904_LINEOUTR_RMV_SHORT_SHIFT 3 /* LINEOUTR_RMV_SHORT */
1052#define WM8904_LINEOUTR_RMV_SHORT_WIDTH 1 /* LINEOUTR_RMV_SHORT */
1053#define WM8904_LINEOUTR_ENA_OUTP 0x0004 /* LINEOUTR_ENA_OUTP */
1054#define WM8904_LINEOUTR_ENA_OUTP_MASK 0x0004 /* LINEOUTR_ENA_OUTP */
1055#define WM8904_LINEOUTR_ENA_OUTP_SHIFT 2 /* LINEOUTR_ENA_OUTP */
1056#define WM8904_LINEOUTR_ENA_OUTP_WIDTH 1 /* LINEOUTR_ENA_OUTP */
1057#define WM8904_LINEOUTR_ENA_DLY 0x0002 /* LINEOUTR_ENA_DLY */
1058#define WM8904_LINEOUTR_ENA_DLY_MASK 0x0002 /* LINEOUTR_ENA_DLY */
1059#define WM8904_LINEOUTR_ENA_DLY_SHIFT 1 /* LINEOUTR_ENA_DLY */
1060#define WM8904_LINEOUTR_ENA_DLY_WIDTH 1 /* LINEOUTR_ENA_DLY */
1061#define WM8904_LINEOUTR_ENA 0x0001 /* LINEOUTR_ENA */
1062#define WM8904_LINEOUTR_ENA_MASK 0x0001 /* LINEOUTR_ENA */
1063#define WM8904_LINEOUTR_ENA_SHIFT 0 /* LINEOUTR_ENA */
1064#define WM8904_LINEOUTR_ENA_WIDTH 1 /* LINEOUTR_ENA */
1065
1066/*
1067 * R98 (0x62) - Charge Pump 0
1068 */
1069#define WM8904_CP_ENA 0x0001 /* CP_ENA */
1070#define WM8904_CP_ENA_MASK 0x0001 /* CP_ENA */
1071#define WM8904_CP_ENA_SHIFT 0 /* CP_ENA */
1072#define WM8904_CP_ENA_WIDTH 1 /* CP_ENA */
1073
1074/*
1075 * R104 (0x68) - Class W 0
1076 */
1077#define WM8904_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1078#define WM8904_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1079#define WM8904_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1080#define WM8904_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1081
1082/*
1083 * R108 (0x6C) - Write Sequencer 0
1084 */
1085#define WM8904_WSEQ_ENA 0x0100 /* WSEQ_ENA */
1086#define WM8904_WSEQ_ENA_MASK 0x0100 /* WSEQ_ENA */
1087#define WM8904_WSEQ_ENA_SHIFT 8 /* WSEQ_ENA */
1088#define WM8904_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1089#define WM8904_WSEQ_WRITE_INDEX_MASK 0x001F /* WSEQ_WRITE_INDEX - [4:0] */
1090#define WM8904_WSEQ_WRITE_INDEX_SHIFT 0 /* WSEQ_WRITE_INDEX - [4:0] */
1091#define WM8904_WSEQ_WRITE_INDEX_WIDTH 5 /* WSEQ_WRITE_INDEX - [4:0] */
1092
1093/*
1094 * R109 (0x6D) - Write Sequencer 1
1095 */
1096#define WM8904_WSEQ_DATA_WIDTH_MASK 0x7000 /* WSEQ_DATA_WIDTH - [14:12] */
1097#define WM8904_WSEQ_DATA_WIDTH_SHIFT 12 /* WSEQ_DATA_WIDTH - [14:12] */
1098#define WM8904_WSEQ_DATA_WIDTH_WIDTH 3 /* WSEQ_DATA_WIDTH - [14:12] */
1099#define WM8904_WSEQ_DATA_START_MASK 0x0F00 /* WSEQ_DATA_START - [11:8] */
1100#define WM8904_WSEQ_DATA_START_SHIFT 8 /* WSEQ_DATA_START - [11:8] */
1101#define WM8904_WSEQ_DATA_START_WIDTH 4 /* WSEQ_DATA_START - [11:8] */
1102#define WM8904_WSEQ_ADDR_MASK 0x00FF /* WSEQ_ADDR - [7:0] */
1103#define WM8904_WSEQ_ADDR_SHIFT 0 /* WSEQ_ADDR - [7:0] */
1104#define WM8904_WSEQ_ADDR_WIDTH 8 /* WSEQ_ADDR - [7:0] */
1105
1106/*
1107 * R110 (0x6E) - Write Sequencer 2
1108 */
1109#define WM8904_WSEQ_EOS 0x4000 /* WSEQ_EOS */
1110#define WM8904_WSEQ_EOS_MASK 0x4000 /* WSEQ_EOS */
1111#define WM8904_WSEQ_EOS_SHIFT 14 /* WSEQ_EOS */
1112#define WM8904_WSEQ_EOS_WIDTH 1 /* WSEQ_EOS */
1113#define WM8904_WSEQ_DELAY_MASK 0x0F00 /* WSEQ_DELAY - [11:8] */
1114#define WM8904_WSEQ_DELAY_SHIFT 8 /* WSEQ_DELAY - [11:8] */
1115#define WM8904_WSEQ_DELAY_WIDTH 4 /* WSEQ_DELAY - [11:8] */
1116#define WM8904_WSEQ_DATA_MASK 0x00FF /* WSEQ_DATA - [7:0] */
1117#define WM8904_WSEQ_DATA_SHIFT 0 /* WSEQ_DATA - [7:0] */
1118#define WM8904_WSEQ_DATA_WIDTH 8 /* WSEQ_DATA - [7:0] */
1119
1120/*
1121 * R111 (0x6F) - Write Sequencer 3
1122 */
1123#define WM8904_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1124#define WM8904_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1125#define WM8904_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1126#define WM8904_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1127#define WM8904_WSEQ_START 0x0100 /* WSEQ_START */
1128#define WM8904_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1129#define WM8904_WSEQ_START_SHIFT 8 /* WSEQ_START */
1130#define WM8904_WSEQ_START_WIDTH 1 /* WSEQ_START */
1131#define WM8904_WSEQ_START_INDEX_MASK 0x003F /* WSEQ_START_INDEX - [5:0] */
1132#define WM8904_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [5:0] */
1133#define WM8904_WSEQ_START_INDEX_WIDTH 6 /* WSEQ_START_INDEX - [5:0] */
1134
1135/*
1136 * R112 (0x70) - Write Sequencer 4
1137 */
1138#define WM8904_WSEQ_CURRENT_INDEX_MASK 0x03F0 /* WSEQ_CURRENT_INDEX - [9:4] */
1139#define WM8904_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [9:4] */
1140#define WM8904_WSEQ_CURRENT_INDEX_WIDTH 6 /* WSEQ_CURRENT_INDEX - [9:4] */
1141#define WM8904_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */
1142#define WM8904_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */
1143#define WM8904_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */
1144#define WM8904_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1145
1146/*
1147 * R116 (0x74) - FLL Control 1
1148 */
1149#define WM8904_FLL_FRACN_ENA 0x0004 /* FLL_FRACN_ENA */
1150#define WM8904_FLL_FRACN_ENA_MASK 0x0004 /* FLL_FRACN_ENA */
1151#define WM8904_FLL_FRACN_ENA_SHIFT 2 /* FLL_FRACN_ENA */
1152#define WM8904_FLL_FRACN_ENA_WIDTH 1 /* FLL_FRACN_ENA */
1153#define WM8904_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */
1154#define WM8904_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */
1155#define WM8904_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */
1156#define WM8904_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */
1157#define WM8904_FLL_ENA 0x0001 /* FLL_ENA */
1158#define WM8904_FLL_ENA_MASK 0x0001 /* FLL_ENA */
1159#define WM8904_FLL_ENA_SHIFT 0 /* FLL_ENA */
1160#define WM8904_FLL_ENA_WIDTH 1 /* FLL_ENA */
1161
1162/*
1163 * R117 (0x75) - FLL Control 2
1164 */
1165#define WM8904_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */
1166#define WM8904_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */
1167#define WM8904_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */
1168#define WM8904_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */
1169#define WM8904_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */
1170#define WM8904_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */
1171#define WM8904_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */
1172#define WM8904_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */
1173#define WM8904_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */
1174
1175/*
1176 * R118 (0x76) - FLL Control 3
1177 */
1178#define WM8904_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */
1179#define WM8904_FLL_K_SHIFT 0 /* FLL_K - [15:0] */
1180#define WM8904_FLL_K_WIDTH 16 /* FLL_K - [15:0] */
1181
1182/*
1183 * R119 (0x77) - FLL Control 4
1184 */
1185#define WM8904_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */
1186#define WM8904_FLL_N_SHIFT 5 /* FLL_N - [14:5] */
1187#define WM8904_FLL_N_WIDTH 10 /* FLL_N - [14:5] */
1188#define WM8904_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */
1189#define WM8904_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */
1190#define WM8904_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */
1191
1192/*
1193 * R120 (0x78) - FLL Control 5
1194 */
1195#define WM8904_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */
1196#define WM8904_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */
1197#define WM8904_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */
1198#define WM8904_FLL_CLK_REF_SRC_MASK 0x0003 /* FLL_CLK_REF_SRC - [1:0] */
1199#define WM8904_FLL_CLK_REF_SRC_SHIFT 0 /* FLL_CLK_REF_SRC - [1:0] */
1200#define WM8904_FLL_CLK_REF_SRC_WIDTH 2 /* FLL_CLK_REF_SRC - [1:0] */
1201
1202/*
1203 * R121 (0x79) - GPIO Control 1
1204 */
1205#define WM8904_GPIO1_PU 0x0020 /* GPIO1_PU */
1206#define WM8904_GPIO1_PU_MASK 0x0020 /* GPIO1_PU */
1207#define WM8904_GPIO1_PU_SHIFT 5 /* GPIO1_PU */
1208#define WM8904_GPIO1_PU_WIDTH 1 /* GPIO1_PU */
1209#define WM8904_GPIO1_PD 0x0010 /* GPIO1_PD */
1210#define WM8904_GPIO1_PD_MASK 0x0010 /* GPIO1_PD */
1211#define WM8904_GPIO1_PD_SHIFT 4 /* GPIO1_PD */
1212#define WM8904_GPIO1_PD_WIDTH 1 /* GPIO1_PD */
1213#define WM8904_GPIO1_SEL_MASK 0x000F /* GPIO1_SEL - [3:0] */
1214#define WM8904_GPIO1_SEL_SHIFT 0 /* GPIO1_SEL - [3:0] */
1215#define WM8904_GPIO1_SEL_WIDTH 4 /* GPIO1_SEL - [3:0] */
1216
1217/*
1218 * R122 (0x7A) - GPIO Control 2
1219 */
1220#define WM8904_GPIO2_PU 0x0020 /* GPIO2_PU */
1221#define WM8904_GPIO2_PU_MASK 0x0020 /* GPIO2_PU */
1222#define WM8904_GPIO2_PU_SHIFT 5 /* GPIO2_PU */
1223#define WM8904_GPIO2_PU_WIDTH 1 /* GPIO2_PU */
1224#define WM8904_GPIO2_PD 0x0010 /* GPIO2_PD */
1225#define WM8904_GPIO2_PD_MASK 0x0010 /* GPIO2_PD */
1226#define WM8904_GPIO2_PD_SHIFT 4 /* GPIO2_PD */
1227#define WM8904_GPIO2_PD_WIDTH 1 /* GPIO2_PD */
1228#define WM8904_GPIO2_SEL_MASK 0x000F /* GPIO2_SEL - [3:0] */
1229#define WM8904_GPIO2_SEL_SHIFT 0 /* GPIO2_SEL - [3:0] */
1230#define WM8904_GPIO2_SEL_WIDTH 4 /* GPIO2_SEL - [3:0] */
1231
1232/*
1233 * R123 (0x7B) - GPIO Control 3
1234 */
1235#define WM8904_GPIO3_PU 0x0020 /* GPIO3_PU */
1236#define WM8904_GPIO3_PU_MASK 0x0020 /* GPIO3_PU */
1237#define WM8904_GPIO3_PU_SHIFT 5 /* GPIO3_PU */
1238#define WM8904_GPIO3_PU_WIDTH 1 /* GPIO3_PU */
1239#define WM8904_GPIO3_PD 0x0010 /* GPIO3_PD */
1240#define WM8904_GPIO3_PD_MASK 0x0010 /* GPIO3_PD */
1241#define WM8904_GPIO3_PD_SHIFT 4 /* GPIO3_PD */
1242#define WM8904_GPIO3_PD_WIDTH 1 /* GPIO3_PD */
1243#define WM8904_GPIO3_SEL_MASK 0x000F /* GPIO3_SEL - [3:0] */
1244#define WM8904_GPIO3_SEL_SHIFT 0 /* GPIO3_SEL - [3:0] */
1245#define WM8904_GPIO3_SEL_WIDTH 4 /* GPIO3_SEL - [3:0] */
1246
1247/*
1248 * R124 (0x7C) - GPIO Control 4
1249 */
1250#define WM8904_GPI7_ENA 0x0200 /* GPI7_ENA */
1251#define WM8904_GPI7_ENA_MASK 0x0200 /* GPI7_ENA */
1252#define WM8904_GPI7_ENA_SHIFT 9 /* GPI7_ENA */
1253#define WM8904_GPI7_ENA_WIDTH 1 /* GPI7_ENA */
1254#define WM8904_GPI8_ENA 0x0100 /* GPI8_ENA */
1255#define WM8904_GPI8_ENA_MASK 0x0100 /* GPI8_ENA */
1256#define WM8904_GPI8_ENA_SHIFT 8 /* GPI8_ENA */
1257#define WM8904_GPI8_ENA_WIDTH 1 /* GPI8_ENA */
1258#define WM8904_GPIO_BCLK_MODE_ENA 0x0080 /* GPIO_BCLK_MODE_ENA */
1259#define WM8904_GPIO_BCLK_MODE_ENA_MASK 0x0080 /* GPIO_BCLK_MODE_ENA */
1260#define WM8904_GPIO_BCLK_MODE_ENA_SHIFT 7 /* GPIO_BCLK_MODE_ENA */
1261#define WM8904_GPIO_BCLK_MODE_ENA_WIDTH 1 /* GPIO_BCLK_MODE_ENA */
1262#define WM8904_GPIO_BCLK_SEL_MASK 0x000F /* GPIO_BCLK_SEL - [3:0] */
1263#define WM8904_GPIO_BCLK_SEL_SHIFT 0 /* GPIO_BCLK_SEL - [3:0] */
1264#define WM8904_GPIO_BCLK_SEL_WIDTH 4 /* GPIO_BCLK_SEL - [3:0] */
1265
1266/*
1267 * R126 (0x7E) - Digital Pulls
1268 */
1269#define WM8904_MCLK_PU 0x0080 /* MCLK_PU */
1270#define WM8904_MCLK_PU_MASK 0x0080 /* MCLK_PU */
1271#define WM8904_MCLK_PU_SHIFT 7 /* MCLK_PU */
1272#define WM8904_MCLK_PU_WIDTH 1 /* MCLK_PU */
1273#define WM8904_MCLK_PD 0x0040 /* MCLK_PD */
1274#define WM8904_MCLK_PD_MASK 0x0040 /* MCLK_PD */
1275#define WM8904_MCLK_PD_SHIFT 6 /* MCLK_PD */
1276#define WM8904_MCLK_PD_WIDTH 1 /* MCLK_PD */
1277#define WM8904_DACDAT_PU 0x0020 /* DACDAT_PU */
1278#define WM8904_DACDAT_PU_MASK 0x0020 /* DACDAT_PU */
1279#define WM8904_DACDAT_PU_SHIFT 5 /* DACDAT_PU */
1280#define WM8904_DACDAT_PU_WIDTH 1 /* DACDAT_PU */
1281#define WM8904_DACDAT_PD 0x0010 /* DACDAT_PD */
1282#define WM8904_DACDAT_PD_MASK 0x0010 /* DACDAT_PD */
1283#define WM8904_DACDAT_PD_SHIFT 4 /* DACDAT_PD */
1284#define WM8904_DACDAT_PD_WIDTH 1 /* DACDAT_PD */
1285#define WM8904_LRCLK_PU 0x0008 /* LRCLK_PU */
1286#define WM8904_LRCLK_PU_MASK 0x0008 /* LRCLK_PU */
1287#define WM8904_LRCLK_PU_SHIFT 3 /* LRCLK_PU */
1288#define WM8904_LRCLK_PU_WIDTH 1 /* LRCLK_PU */
1289#define WM8904_LRCLK_PD 0x0004 /* LRCLK_PD */
1290#define WM8904_LRCLK_PD_MASK 0x0004 /* LRCLK_PD */
1291#define WM8904_LRCLK_PD_SHIFT 2 /* LRCLK_PD */
1292#define WM8904_LRCLK_PD_WIDTH 1 /* LRCLK_PD */
1293#define WM8904_BCLK_PU 0x0002 /* BCLK_PU */
1294#define WM8904_BCLK_PU_MASK 0x0002 /* BCLK_PU */
1295#define WM8904_BCLK_PU_SHIFT 1 /* BCLK_PU */
1296#define WM8904_BCLK_PU_WIDTH 1 /* BCLK_PU */
1297#define WM8904_BCLK_PD 0x0001 /* BCLK_PD */
1298#define WM8904_BCLK_PD_MASK 0x0001 /* BCLK_PD */
1299#define WM8904_BCLK_PD_SHIFT 0 /* BCLK_PD */
1300#define WM8904_BCLK_PD_WIDTH 1 /* BCLK_PD */
1301
1302/*
1303 * R127 (0x7F) - Interrupt Status
1304 */
1305#define WM8904_IRQ 0x0400 /* IRQ */
1306#define WM8904_IRQ_MASK 0x0400 /* IRQ */
1307#define WM8904_IRQ_SHIFT 10 /* IRQ */
1308#define WM8904_IRQ_WIDTH 1 /* IRQ */
1309#define WM8904_GPIO_BCLK_EINT 0x0200 /* GPIO_BCLK_EINT */
1310#define WM8904_GPIO_BCLK_EINT_MASK 0x0200 /* GPIO_BCLK_EINT */
1311#define WM8904_GPIO_BCLK_EINT_SHIFT 9 /* GPIO_BCLK_EINT */
1312#define WM8904_GPIO_BCLK_EINT_WIDTH 1 /* GPIO_BCLK_EINT */
1313#define WM8904_WSEQ_EINT 0x0100 /* WSEQ_EINT */
1314#define WM8904_WSEQ_EINT_MASK 0x0100 /* WSEQ_EINT */
1315#define WM8904_WSEQ_EINT_SHIFT 8 /* WSEQ_EINT */
1316#define WM8904_WSEQ_EINT_WIDTH 1 /* WSEQ_EINT */
1317#define WM8904_GPIO3_EINT 0x0080 /* GPIO3_EINT */
1318#define WM8904_GPIO3_EINT_MASK 0x0080 /* GPIO3_EINT */
1319#define WM8904_GPIO3_EINT_SHIFT 7 /* GPIO3_EINT */
1320#define WM8904_GPIO3_EINT_WIDTH 1 /* GPIO3_EINT */
1321#define WM8904_GPIO2_EINT 0x0040 /* GPIO2_EINT */
1322#define WM8904_GPIO2_EINT_MASK 0x0040 /* GPIO2_EINT */
1323#define WM8904_GPIO2_EINT_SHIFT 6 /* GPIO2_EINT */
1324#define WM8904_GPIO2_EINT_WIDTH 1 /* GPIO2_EINT */
1325#define WM8904_GPIO1_EINT 0x0020 /* GPIO1_EINT */
1326#define WM8904_GPIO1_EINT_MASK 0x0020 /* GPIO1_EINT */
1327#define WM8904_GPIO1_EINT_SHIFT 5 /* GPIO1_EINT */
1328#define WM8904_GPIO1_EINT_WIDTH 1 /* GPIO1_EINT */
1329#define WM8904_GPI8_EINT 0x0010 /* GPI8_EINT */
1330#define WM8904_GPI8_EINT_MASK 0x0010 /* GPI8_EINT */
1331#define WM8904_GPI8_EINT_SHIFT 4 /* GPI8_EINT */
1332#define WM8904_GPI8_EINT_WIDTH 1 /* GPI8_EINT */
1333#define WM8904_GPI7_EINT 0x0008 /* GPI7_EINT */
1334#define WM8904_GPI7_EINT_MASK 0x0008 /* GPI7_EINT */
1335#define WM8904_GPI7_EINT_SHIFT 3 /* GPI7_EINT */
1336#define WM8904_GPI7_EINT_WIDTH 1 /* GPI7_EINT */
1337#define WM8904_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */
1338#define WM8904_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */
1339#define WM8904_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */
1340#define WM8904_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */
1341#define WM8904_MIC_SHRT_EINT 0x0002 /* MIC_SHRT_EINT */
1342#define WM8904_MIC_SHRT_EINT_MASK 0x0002 /* MIC_SHRT_EINT */
1343#define WM8904_MIC_SHRT_EINT_SHIFT 1 /* MIC_SHRT_EINT */
1344#define WM8904_MIC_SHRT_EINT_WIDTH 1 /* MIC_SHRT_EINT */
1345#define WM8904_MIC_DET_EINT 0x0001 /* MIC_DET_EINT */
1346#define WM8904_MIC_DET_EINT_MASK 0x0001 /* MIC_DET_EINT */
1347#define WM8904_MIC_DET_EINT_SHIFT 0 /* MIC_DET_EINT */
1348#define WM8904_MIC_DET_EINT_WIDTH 1 /* MIC_DET_EINT */
1349
1350/*
1351 * R128 (0x80) - Interrupt Status Mask
1352 */
1353#define WM8904_IM_GPIO_BCLK_EINT 0x0200 /* IM_GPIO_BCLK_EINT */
1354#define WM8904_IM_GPIO_BCLK_EINT_MASK 0x0200 /* IM_GPIO_BCLK_EINT */
1355#define WM8904_IM_GPIO_BCLK_EINT_SHIFT 9 /* IM_GPIO_BCLK_EINT */
1356#define WM8904_IM_GPIO_BCLK_EINT_WIDTH 1 /* IM_GPIO_BCLK_EINT */
1357#define WM8904_IM_WSEQ_EINT 0x0100 /* IM_WSEQ_EINT */
1358#define WM8904_IM_WSEQ_EINT_MASK 0x0100 /* IM_WSEQ_EINT */
1359#define WM8904_IM_WSEQ_EINT_SHIFT 8 /* IM_WSEQ_EINT */
1360#define WM8904_IM_WSEQ_EINT_WIDTH 1 /* IM_WSEQ_EINT */
1361#define WM8904_IM_GPIO3_EINT 0x0080 /* IM_GPIO3_EINT */
1362#define WM8904_IM_GPIO3_EINT_MASK 0x0080 /* IM_GPIO3_EINT */
1363#define WM8904_IM_GPIO3_EINT_SHIFT 7 /* IM_GPIO3_EINT */
1364#define WM8904_IM_GPIO3_EINT_WIDTH 1 /* IM_GPIO3_EINT */
1365#define WM8904_IM_GPIO2_EINT 0x0040 /* IM_GPIO2_EINT */
1366#define WM8904_IM_GPIO2_EINT_MASK 0x0040 /* IM_GPIO2_EINT */
1367#define WM8904_IM_GPIO2_EINT_SHIFT 6 /* IM_GPIO2_EINT */
1368#define WM8904_IM_GPIO2_EINT_WIDTH 1 /* IM_GPIO2_EINT */
1369#define WM8904_IM_GPIO1_EINT 0x0020 /* IM_GPIO1_EINT */
1370#define WM8904_IM_GPIO1_EINT_MASK 0x0020 /* IM_GPIO1_EINT */
1371#define WM8904_IM_GPIO1_EINT_SHIFT 5 /* IM_GPIO1_EINT */
1372#define WM8904_IM_GPIO1_EINT_WIDTH 1 /* IM_GPIO1_EINT */
1373#define WM8904_IM_GPI8_EINT 0x0010 /* IM_GPI8_EINT */
1374#define WM8904_IM_GPI8_EINT_MASK 0x0010 /* IM_GPI8_EINT */
1375#define WM8904_IM_GPI8_EINT_SHIFT 4 /* IM_GPI8_EINT */
1376#define WM8904_IM_GPI8_EINT_WIDTH 1 /* IM_GPI8_EINT */
1377#define WM8904_IM_GPI7_EINT 0x0008 /* IM_GPI7_EINT */
1378#define WM8904_IM_GPI7_EINT_MASK 0x0008 /* IM_GPI7_EINT */
1379#define WM8904_IM_GPI7_EINT_SHIFT 3 /* IM_GPI7_EINT */
1380#define WM8904_IM_GPI7_EINT_WIDTH 1 /* IM_GPI7_EINT */
1381#define WM8904_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */
1382#define WM8904_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */
1383#define WM8904_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */
1384#define WM8904_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */
1385#define WM8904_IM_MIC_SHRT_EINT 0x0002 /* IM_MIC_SHRT_EINT */
1386#define WM8904_IM_MIC_SHRT_EINT_MASK 0x0002 /* IM_MIC_SHRT_EINT */
1387#define WM8904_IM_MIC_SHRT_EINT_SHIFT 1 /* IM_MIC_SHRT_EINT */
1388#define WM8904_IM_MIC_SHRT_EINT_WIDTH 1 /* IM_MIC_SHRT_EINT */
1389#define WM8904_IM_MIC_DET_EINT 0x0001 /* IM_MIC_DET_EINT */
1390#define WM8904_IM_MIC_DET_EINT_MASK 0x0001 /* IM_MIC_DET_EINT */
1391#define WM8904_IM_MIC_DET_EINT_SHIFT 0 /* IM_MIC_DET_EINT */
1392#define WM8904_IM_MIC_DET_EINT_WIDTH 1 /* IM_MIC_DET_EINT */
1393
1394/*
1395 * R129 (0x81) - Interrupt Polarity
1396 */
1397#define WM8904_GPIO_BCLK_EINT_POL 0x0200 /* GPIO_BCLK_EINT_POL */
1398#define WM8904_GPIO_BCLK_EINT_POL_MASK 0x0200 /* GPIO_BCLK_EINT_POL */
1399#define WM8904_GPIO_BCLK_EINT_POL_SHIFT 9 /* GPIO_BCLK_EINT_POL */
1400#define WM8904_GPIO_BCLK_EINT_POL_WIDTH 1 /* GPIO_BCLK_EINT_POL */
1401#define WM8904_WSEQ_EINT_POL 0x0100 /* WSEQ_EINT_POL */
1402#define WM8904_WSEQ_EINT_POL_MASK 0x0100 /* WSEQ_EINT_POL */
1403#define WM8904_WSEQ_EINT_POL_SHIFT 8 /* WSEQ_EINT_POL */
1404#define WM8904_WSEQ_EINT_POL_WIDTH 1 /* WSEQ_EINT_POL */
1405#define WM8904_GPIO3_EINT_POL 0x0080 /* GPIO3_EINT_POL */
1406#define WM8904_GPIO3_EINT_POL_MASK 0x0080 /* GPIO3_EINT_POL */
1407#define WM8904_GPIO3_EINT_POL_SHIFT 7 /* GPIO3_EINT_POL */
1408#define WM8904_GPIO3_EINT_POL_WIDTH 1 /* GPIO3_EINT_POL */
1409#define WM8904_GPIO2_EINT_POL 0x0040 /* GPIO2_EINT_POL */
1410#define WM8904_GPIO2_EINT_POL_MASK 0x0040 /* GPIO2_EINT_POL */
1411#define WM8904_GPIO2_EINT_POL_SHIFT 6 /* GPIO2_EINT_POL */
1412#define WM8904_GPIO2_EINT_POL_WIDTH 1 /* GPIO2_EINT_POL */
1413#define WM8904_GPIO1_EINT_POL 0x0020 /* GPIO1_EINT_POL */
1414#define WM8904_GPIO1_EINT_POL_MASK 0x0020 /* GPIO1_EINT_POL */
1415#define WM8904_GPIO1_EINT_POL_SHIFT 5 /* GPIO1_EINT_POL */
1416#define WM8904_GPIO1_EINT_POL_WIDTH 1 /* GPIO1_EINT_POL */
1417#define WM8904_GPI8_EINT_POL 0x0010 /* GPI8_EINT_POL */
1418#define WM8904_GPI8_EINT_POL_MASK 0x0010 /* GPI8_EINT_POL */
1419#define WM8904_GPI8_EINT_POL_SHIFT 4 /* GPI8_EINT_POL */
1420#define WM8904_GPI8_EINT_POL_WIDTH 1 /* GPI8_EINT_POL */
1421#define WM8904_GPI7_EINT_POL 0x0008 /* GPI7_EINT_POL */
1422#define WM8904_GPI7_EINT_POL_MASK 0x0008 /* GPI7_EINT_POL */
1423#define WM8904_GPI7_EINT_POL_SHIFT 3 /* GPI7_EINT_POL */
1424#define WM8904_GPI7_EINT_POL_WIDTH 1 /* GPI7_EINT_POL */
1425#define WM8904_FLL_LOCK_EINT_POL 0x0004 /* FLL_LOCK_EINT_POL */
1426#define WM8904_FLL_LOCK_EINT_POL_MASK 0x0004 /* FLL_LOCK_EINT_POL */
1427#define WM8904_FLL_LOCK_EINT_POL_SHIFT 2 /* FLL_LOCK_EINT_POL */
1428#define WM8904_FLL_LOCK_EINT_POL_WIDTH 1 /* FLL_LOCK_EINT_POL */
1429#define WM8904_MIC_SHRT_EINT_POL 0x0002 /* MIC_SHRT_EINT_POL */
1430#define WM8904_MIC_SHRT_EINT_POL_MASK 0x0002 /* MIC_SHRT_EINT_POL */
1431#define WM8904_MIC_SHRT_EINT_POL_SHIFT 1 /* MIC_SHRT_EINT_POL */
1432#define WM8904_MIC_SHRT_EINT_POL_WIDTH 1 /* MIC_SHRT_EINT_POL */
1433#define WM8904_MIC_DET_EINT_POL 0x0001 /* MIC_DET_EINT_POL */
1434#define WM8904_MIC_DET_EINT_POL_MASK 0x0001 /* MIC_DET_EINT_POL */
1435#define WM8904_MIC_DET_EINT_POL_SHIFT 0 /* MIC_DET_EINT_POL */
1436#define WM8904_MIC_DET_EINT_POL_WIDTH 1 /* MIC_DET_EINT_POL */
1437
1438/*
1439 * R130 (0x82) - Interrupt Debounce
1440 */
1441#define WM8904_GPIO_BCLK_EINT_DB 0x0200 /* GPIO_BCLK_EINT_DB */
1442#define WM8904_GPIO_BCLK_EINT_DB_MASK 0x0200 /* GPIO_BCLK_EINT_DB */
1443#define WM8904_GPIO_BCLK_EINT_DB_SHIFT 9 /* GPIO_BCLK_EINT_DB */
1444#define WM8904_GPIO_BCLK_EINT_DB_WIDTH 1 /* GPIO_BCLK_EINT_DB */
1445#define WM8904_WSEQ_EINT_DB 0x0100 /* WSEQ_EINT_DB */
1446#define WM8904_WSEQ_EINT_DB_MASK 0x0100 /* WSEQ_EINT_DB */
1447#define WM8904_WSEQ_EINT_DB_SHIFT 8 /* WSEQ_EINT_DB */
1448#define WM8904_WSEQ_EINT_DB_WIDTH 1 /* WSEQ_EINT_DB */
1449#define WM8904_GPIO3_EINT_DB 0x0080 /* GPIO3_EINT_DB */
1450#define WM8904_GPIO3_EINT_DB_MASK 0x0080 /* GPIO3_EINT_DB */
1451#define WM8904_GPIO3_EINT_DB_SHIFT 7 /* GPIO3_EINT_DB */
1452#define WM8904_GPIO3_EINT_DB_WIDTH 1 /* GPIO3_EINT_DB */
1453#define WM8904_GPIO2_EINT_DB 0x0040 /* GPIO2_EINT_DB */
1454#define WM8904_GPIO2_EINT_DB_MASK 0x0040 /* GPIO2_EINT_DB */
1455#define WM8904_GPIO2_EINT_DB_SHIFT 6 /* GPIO2_EINT_DB */
1456#define WM8904_GPIO2_EINT_DB_WIDTH 1 /* GPIO2_EINT_DB */
1457#define WM8904_GPIO1_EINT_DB 0x0020 /* GPIO1_EINT_DB */
1458#define WM8904_GPIO1_EINT_DB_MASK 0x0020 /* GPIO1_EINT_DB */
1459#define WM8904_GPIO1_EINT_DB_SHIFT 5 /* GPIO1_EINT_DB */
1460#define WM8904_GPIO1_EINT_DB_WIDTH 1 /* GPIO1_EINT_DB */
1461#define WM8904_GPI8_EINT_DB 0x0010 /* GPI8_EINT_DB */
1462#define WM8904_GPI8_EINT_DB_MASK 0x0010 /* GPI8_EINT_DB */
1463#define WM8904_GPI8_EINT_DB_SHIFT 4 /* GPI8_EINT_DB */
1464#define WM8904_GPI8_EINT_DB_WIDTH 1 /* GPI8_EINT_DB */
1465#define WM8904_GPI7_EINT_DB 0x0008 /* GPI7_EINT_DB */
1466#define WM8904_GPI7_EINT_DB_MASK 0x0008 /* GPI7_EINT_DB */
1467#define WM8904_GPI7_EINT_DB_SHIFT 3 /* GPI7_EINT_DB */
1468#define WM8904_GPI7_EINT_DB_WIDTH 1 /* GPI7_EINT_DB */
1469#define WM8904_FLL_LOCK_EINT_DB 0x0004 /* FLL_LOCK_EINT_DB */
1470#define WM8904_FLL_LOCK_EINT_DB_MASK 0x0004 /* FLL_LOCK_EINT_DB */
1471#define WM8904_FLL_LOCK_EINT_DB_SHIFT 2 /* FLL_LOCK_EINT_DB */
1472#define WM8904_FLL_LOCK_EINT_DB_WIDTH 1 /* FLL_LOCK_EINT_DB */
1473#define WM8904_MIC_SHRT_EINT_DB 0x0002 /* MIC_SHRT_EINT_DB */
1474#define WM8904_MIC_SHRT_EINT_DB_MASK 0x0002 /* MIC_SHRT_EINT_DB */
1475#define WM8904_MIC_SHRT_EINT_DB_SHIFT 1 /* MIC_SHRT_EINT_DB */
1476#define WM8904_MIC_SHRT_EINT_DB_WIDTH 1 /* MIC_SHRT_EINT_DB */
1477#define WM8904_MIC_DET_EINT_DB 0x0001 /* MIC_DET_EINT_DB */
1478#define WM8904_MIC_DET_EINT_DB_MASK 0x0001 /* MIC_DET_EINT_DB */
1479#define WM8904_MIC_DET_EINT_DB_SHIFT 0 /* MIC_DET_EINT_DB */
1480#define WM8904_MIC_DET_EINT_DB_WIDTH 1 /* MIC_DET_EINT_DB */
1481
1482/*
1483 * R134 (0x86) - EQ1
1484 */
1485#define WM8904_EQ_ENA 0x0001 /* EQ_ENA */
1486#define WM8904_EQ_ENA_MASK 0x0001 /* EQ_ENA */
1487#define WM8904_EQ_ENA_SHIFT 0 /* EQ_ENA */
1488#define WM8904_EQ_ENA_WIDTH 1 /* EQ_ENA */
1489
1490/*
1491 * R135 (0x87) - EQ2
1492 */
1493#define WM8904_EQ_B1_GAIN_MASK 0x001F /* EQ_B1_GAIN - [4:0] */
1494#define WM8904_EQ_B1_GAIN_SHIFT 0 /* EQ_B1_GAIN - [4:0] */
1495#define WM8904_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [4:0] */
1496
1497/*
1498 * R136 (0x88) - EQ3
1499 */
1500#define WM8904_EQ_B2_GAIN_MASK 0x001F /* EQ_B2_GAIN - [4:0] */
1501#define WM8904_EQ_B2_GAIN_SHIFT 0 /* EQ_B2_GAIN - [4:0] */
1502#define WM8904_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [4:0] */
1503
1504/*
1505 * R137 (0x89) - EQ4
1506 */
1507#define WM8904_EQ_B3_GAIN_MASK 0x001F /* EQ_B3_GAIN - [4:0] */
1508#define WM8904_EQ_B3_GAIN_SHIFT 0 /* EQ_B3_GAIN - [4:0] */
1509#define WM8904_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [4:0] */
1510
1511/*
1512 * R138 (0x8A) - EQ5
1513 */
1514#define WM8904_EQ_B4_GAIN_MASK 0x001F /* EQ_B4_GAIN - [4:0] */
1515#define WM8904_EQ_B4_GAIN_SHIFT 0 /* EQ_B4_GAIN - [4:0] */
1516#define WM8904_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [4:0] */
1517
1518/*
1519 * R139 (0x8B) - EQ6
1520 */
1521#define WM8904_EQ_B5_GAIN_MASK 0x001F /* EQ_B5_GAIN - [4:0] */
1522#define WM8904_EQ_B5_GAIN_SHIFT 0 /* EQ_B5_GAIN - [4:0] */
1523#define WM8904_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [4:0] */
1524
1525/*
1526 * R140 (0x8C) - EQ7
1527 */
1528#define WM8904_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */
1529#define WM8904_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */
1530#define WM8904_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */
1531
1532/*
1533 * R141 (0x8D) - EQ8
1534 */
1535#define WM8904_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */
1536#define WM8904_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */
1537#define WM8904_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */
1538
1539/*
1540 * R142 (0x8E) - EQ9
1541 */
1542#define WM8904_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */
1543#define WM8904_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */
1544#define WM8904_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */
1545
1546/*
1547 * R143 (0x8F) - EQ10
1548 */
1549#define WM8904_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */
1550#define WM8904_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */
1551#define WM8904_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */
1552
1553/*
1554 * R144 (0x90) - EQ11
1555 */
1556#define WM8904_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */
1557#define WM8904_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */
1558#define WM8904_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */
1559
1560/*
1561 * R145 (0x91) - EQ12
1562 */
1563#define WM8904_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */
1564#define WM8904_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */
1565#define WM8904_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */
1566
1567/*
1568 * R146 (0x92) - EQ13
1569 */
1570#define WM8904_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */
1571#define WM8904_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */
1572#define WM8904_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */
1573
1574/*
1575 * R147 (0x93) - EQ14
1576 */
1577#define WM8904_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */
1578#define WM8904_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */
1579#define WM8904_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */
1580
1581/*
1582 * R148 (0x94) - EQ15
1583 */
1584#define WM8904_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */
1585#define WM8904_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */
1586#define WM8904_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */
1587
1588/*
1589 * R149 (0x95) - EQ16
1590 */
1591#define WM8904_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */
1592#define WM8904_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */
1593#define WM8904_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */
1594
1595/*
1596 * R150 (0x96) - EQ17
1597 */
1598#define WM8904_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */
1599#define WM8904_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */
1600#define WM8904_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */
1601
1602/*
1603 * R151 (0x97) - EQ18
1604 */
1605#define WM8904_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */
1606#define WM8904_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */
1607#define WM8904_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */
1608
1609/*
1610 * R152 (0x98) - EQ19
1611 */
1612#define WM8904_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */
1613#define WM8904_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */
1614#define WM8904_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */
1615
1616/*
1617 * R153 (0x99) - EQ20
1618 */
1619#define WM8904_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */
1620#define WM8904_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */
1621#define WM8904_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */
1622
1623/*
1624 * R154 (0x9A) - EQ21
1625 */
1626#define WM8904_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */
1627#define WM8904_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */
1628#define WM8904_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */
1629
1630/*
1631 * R155 (0x9B) - EQ22
1632 */
1633#define WM8904_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */
1634#define WM8904_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */
1635#define WM8904_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */
1636
1637/*
1638 * R156 (0x9C) - EQ23
1639 */
1640#define WM8904_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */
1641#define WM8904_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */
1642#define WM8904_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */
1643
1644/*
1645 * R157 (0x9D) - EQ24
1646 */
1647#define WM8904_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */
1648#define WM8904_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */
1649#define WM8904_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */
1650
1651/*
1652 * R161 (0xA1) - Control Interface Test 1
1653 */
1654#define WM8904_USER_KEY 0x0002 /* USER_KEY */
1655#define WM8904_USER_KEY_MASK 0x0002 /* USER_KEY */
1656#define WM8904_USER_KEY_SHIFT 1 /* USER_KEY */
1657#define WM8904_USER_KEY_WIDTH 1 /* USER_KEY */
1658
1659/*
1660 * R204 (0xCC) - Analogue Output Bias 0
1661 */
1662#define WM8904_PGA_BIAS_MASK 0x0070 /* PGA_BIAS - [6:4] */
1663#define WM8904_PGA_BIAS_SHIFT 4 /* PGA_BIAS - [6:4] */
1664#define WM8904_PGA_BIAS_WIDTH 3 /* PGA_BIAS - [6:4] */
1665
1666/*
1667 * R247 (0xF7) - FLL NCO Test 0
1668 */
1669#define WM8904_FLL_FRC_NCO 0x0001 /* FLL_FRC_NCO */
1670#define WM8904_FLL_FRC_NCO_MASK 0x0001 /* FLL_FRC_NCO */
1671#define WM8904_FLL_FRC_NCO_SHIFT 0 /* FLL_FRC_NCO */
1672#define WM8904_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */
1673
1674/*
1675 * R248 (0xF8) - FLL NCO Test 1
1676 */
1677#define WM8904_FLL_FRC_NCO_VAL_MASK 0x003F /* FLL_FRC_NCO_VAL - [5:0] */
1678#define WM8904_FLL_FRC_NCO_VAL_SHIFT 0 /* FLL_FRC_NCO_VAL - [5:0] */
1679#define WM8904_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [5:0] */
1680
1681#endif
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
new file mode 100644
index 000000000000..615dab2b62ef
--- /dev/null
+++ b/sound/soc/codecs/wm8955.c
@@ -0,0 +1,1151 @@
1/*
2 * wm8955.c -- WM8955 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/platform_device.h>
20#include <linux/regulator/consumer.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#include <sound/wm8955.h>
29
30#include "wm8955.h"
31
32static struct snd_soc_codec *wm8955_codec;
33struct snd_soc_codec_device soc_codec_dev_wm8955;
34
35#define WM8955_NUM_SUPPLIES 4
36static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = {
37 "DCVDD",
38 "DBVDD",
39 "HPVDD",
40 "AVDD",
41};
42
43/* codec private data */
44struct wm8955_priv {
45 struct snd_soc_codec codec;
46 u16 reg_cache[WM8955_MAX_REGISTER + 1];
47
48 unsigned int mclk_rate;
49
50 int deemph;
51 int fs;
52
53 struct regulator_bulk_data supplies[WM8955_NUM_SUPPLIES];
54
55 struct wm8955_pdata *pdata;
56};
57
58static const u16 wm8955_reg[WM8955_MAX_REGISTER + 1] = {
59 0x0000, /* R0 */
60 0x0000, /* R1 */
61 0x0079, /* R2 - LOUT1 volume */
62 0x0079, /* R3 - ROUT1 volume */
63 0x0000, /* R4 */
64 0x0008, /* R5 - DAC Control */
65 0x0000, /* R6 */
66 0x000A, /* R7 - Audio Interface */
67 0x0000, /* R8 - Sample Rate */
68 0x0000, /* R9 */
69 0x00FF, /* R10 - Left DAC volume */
70 0x00FF, /* R11 - Right DAC volume */
71 0x000F, /* R12 - Bass control */
72 0x000F, /* R13 - Treble control */
73 0x0000, /* R14 */
74 0x0000, /* R15 - Reset */
75 0x0000, /* R16 */
76 0x0000, /* R17 */
77 0x0000, /* R18 */
78 0x0000, /* R19 */
79 0x0000, /* R20 */
80 0x0000, /* R21 */
81 0x0000, /* R22 */
82 0x00C1, /* R23 - Additional control (1) */
83 0x0000, /* R24 - Additional control (2) */
84 0x0000, /* R25 - Power Management (1) */
85 0x0000, /* R26 - Power Management (2) */
86 0x0000, /* R27 - Additional Control (3) */
87 0x0000, /* R28 */
88 0x0000, /* R29 */
89 0x0000, /* R30 */
90 0x0000, /* R31 */
91 0x0000, /* R32 */
92 0x0000, /* R33 */
93 0x0050, /* R34 - Left out Mix (1) */
94 0x0050, /* R35 - Left out Mix (2) */
95 0x0050, /* R36 - Right out Mix (1) */
96 0x0050, /* R37 - Right Out Mix (2) */
97 0x0050, /* R38 - Mono out Mix (1) */
98 0x0050, /* R39 - Mono out Mix (2) */
99 0x0079, /* R40 - LOUT2 volume */
100 0x0079, /* R41 - ROUT2 volume */
101 0x0079, /* R42 - MONOOUT volume */
102 0x0000, /* R43 - Clocking / PLL */
103 0x0103, /* R44 - PLL Control 1 */
104 0x0024, /* R45 - PLL Control 2 */
105 0x01BA, /* R46 - PLL Control 3 */
106 0x0000, /* R47 */
107 0x0000, /* R48 */
108 0x0000, /* R49 */
109 0x0000, /* R50 */
110 0x0000, /* R51 */
111 0x0000, /* R52 */
112 0x0000, /* R53 */
113 0x0000, /* R54 */
114 0x0000, /* R55 */
115 0x0000, /* R56 */
116 0x0000, /* R57 */
117 0x0000, /* R58 */
118 0x0000, /* R59 - PLL Control 4 */
119};
120
121static int wm8955_reset(struct snd_soc_codec *codec)
122{
123 return snd_soc_write(codec, WM8955_RESET, 0);
124}
125
126struct pll_factors {
127 int n;
128 int k;
129 int outdiv;
130};
131
132/* The size in bits of the FLL divide multiplied by 10
133 * to allow rounding later */
134#define FIXED_FLL_SIZE ((1 << 22) * 10)
135
136static int wm8995_pll_factors(struct device *dev,
137 int Fref, int Fout, struct pll_factors *pll)
138{
139 u64 Kpart;
140 unsigned int K, Ndiv, Nmod, target;
141
142 dev_dbg(dev, "Fref=%u Fout=%u\n", Fref, Fout);
143
144 /* The oscilator should run at should be 90-100MHz, and
145 * there's a divide by 4 plus an optional divide by 2 in the
146 * output path to generate the system clock. The clock table
147 * is sortd so we should always generate a suitable target. */
148 target = Fout * 4;
149 if (target < 90000000) {
150 pll->outdiv = 1;
151 target *= 2;
152 } else {
153 pll->outdiv = 0;
154 }
155
156 WARN_ON(target < 90000000 || target > 100000000);
157
158 dev_dbg(dev, "Fvco=%dHz\n", target);
159
160 /* Now, calculate N.K */
161 Ndiv = target / Fref;
162
163 pll->n = Ndiv;
164 Nmod = target % Fref;
165 dev_dbg(dev, "Nmod=%d\n", Nmod);
166
167 /* Calculate fractional part - scale up so we can round. */
168 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
169
170 do_div(Kpart, Fref);
171
172 K = Kpart & 0xFFFFFFFF;
173
174 if ((K % 10) >= 5)
175 K += 5;
176
177 /* Move down to proper range now rounding is done */
178 pll->k = K / 10;
179
180 dev_dbg(dev, "N=%x K=%x OUTDIV=%x\n", pll->n, pll->k, pll->outdiv);
181
182 return 0;
183}
184
185/* Lookup table specifiying SRATE (table 25 in datasheet); some of the
186 * output frequencies have been rounded to the standard frequencies
187 * they are intended to match where the error is slight. */
188static struct {
189 int mclk;
190 int fs;
191 int usb;
192 int sr;
193} clock_cfgs[] = {
194 { 18432000, 8000, 0, 3, },
195 { 18432000, 12000, 0, 9, },
196 { 18432000, 16000, 0, 11, },
197 { 18432000, 24000, 0, 29, },
198 { 18432000, 32000, 0, 13, },
199 { 18432000, 48000, 0, 1, },
200 { 18432000, 96000, 0, 15, },
201
202 { 16934400, 8018, 0, 19, },
203 { 16934400, 11025, 0, 25, },
204 { 16934400, 22050, 0, 27, },
205 { 16934400, 44100, 0, 17, },
206 { 16934400, 88200, 0, 31, },
207
208 { 12000000, 8000, 1, 2, },
209 { 12000000, 11025, 1, 25, },
210 { 12000000, 12000, 1, 8, },
211 { 12000000, 16000, 1, 10, },
212 { 12000000, 22050, 1, 27, },
213 { 12000000, 24000, 1, 28, },
214 { 12000000, 32000, 1, 12, },
215 { 12000000, 44100, 1, 17, },
216 { 12000000, 48000, 1, 0, },
217 { 12000000, 88200, 1, 31, },
218 { 12000000, 96000, 1, 14, },
219
220 { 12288000, 8000, 0, 2, },
221 { 12288000, 12000, 0, 8, },
222 { 12288000, 16000, 0, 10, },
223 { 12288000, 24000, 0, 28, },
224 { 12288000, 32000, 0, 12, },
225 { 12288000, 48000, 0, 0, },
226 { 12288000, 96000, 0, 14, },
227
228 { 12289600, 8018, 0, 18, },
229 { 12289600, 11025, 0, 24, },
230 { 12289600, 22050, 0, 26, },
231 { 11289600, 44100, 0, 16, },
232 { 11289600, 88200, 0, 31, },
233};
234
235static int wm8955_configure_clocking(struct snd_soc_codec *codec)
236{
237 struct wm8955_priv *wm8955 = codec->private_data;
238 int i, ret, val;
239 int clocking = 0;
240 int srate = 0;
241 int sr = -1;
242 struct pll_factors pll;
243
244 /* If we're not running a sample rate currently just pick one */
245 if (wm8955->fs == 0)
246 wm8955->fs = 8000;
247
248 /* Can we generate an exact output? */
249 for (i = 0; i < ARRAY_SIZE(clock_cfgs); i++) {
250 if (wm8955->fs != clock_cfgs[i].fs)
251 continue;
252 sr = i;
253
254 if (wm8955->mclk_rate == clock_cfgs[i].mclk)
255 break;
256 }
257
258 /* We should never get here with an unsupported sample rate */
259 if (sr == -1) {
260 dev_err(codec->dev, "Sample rate %dHz unsupported\n",
261 wm8955->fs);
262 WARN_ON(sr == -1);
263 return -EINVAL;
264 }
265
266 if (i == ARRAY_SIZE(clock_cfgs)) {
267 /* If we can't generate the right clock from MCLK then
268 * we should configure the PLL to supply us with an
269 * appropriate clock.
270 */
271 clocking |= WM8955_MCLKSEL;
272
273 /* Use the last divider configuration we saw for the
274 * sample rate. */
275 ret = wm8995_pll_factors(codec->dev, wm8955->mclk_rate,
276 clock_cfgs[sr].mclk, &pll);
277 if (ret != 0) {
278 dev_err(codec->dev,
279 "Unable to generate %dHz from %dHz MCLK\n",
280 wm8955->fs, wm8955->mclk_rate);
281 return -EINVAL;
282 }
283
284 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_1,
285 WM8955_N_MASK | WM8955_K_21_18_MASK,
286 (pll.n << WM8955_N_SHIFT) |
287 pll.k >> 18);
288 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
289 WM8955_K_17_9_MASK,
290 (pll.k >> 9) & WM8955_K_17_9_MASK);
291 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_2,
292 WM8955_K_8_0_MASK,
293 pll.k & WM8955_K_8_0_MASK);
294 if (pll.k)
295 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
296 WM8955_KEN, WM8955_KEN);
297 else
298 snd_soc_update_bits(codec, WM8955_PLL_CONTROL_4,
299 WM8955_KEN, 0);
300
301 if (pll.outdiv)
302 val = WM8955_PLL_RB | WM8955_PLLOUTDIV2;
303 else
304 val = WM8955_PLL_RB;
305
306 /* Now start the PLL running */
307 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
308 WM8955_PLL_RB | WM8955_PLLOUTDIV2, val);
309 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
310 WM8955_PLLEN, WM8955_PLLEN);
311 }
312
313 srate = clock_cfgs[sr].usb | (clock_cfgs[sr].sr << WM8955_SR_SHIFT);
314
315 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
316 WM8955_USB | WM8955_SR_MASK, srate);
317 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
318 WM8955_MCLKSEL, clocking);
319
320 return 0;
321}
322
323static int wm8955_sysclk(struct snd_soc_dapm_widget *w,
324 struct snd_kcontrol *kcontrol, int event)
325{
326 struct snd_soc_codec *codec = w->codec;
327 int ret = 0;
328
329 /* Always disable the clocks - if we're doing reconfiguration this
330 * avoids misclocking.
331 */
332 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
333 WM8955_DIGENB, 0);
334 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
335 WM8955_PLL_RB | WM8955_PLLEN, 0);
336
337 switch (event) {
338 case SND_SOC_DAPM_POST_PMD:
339 break;
340 case SND_SOC_DAPM_PRE_PMU:
341 ret = wm8955_configure_clocking(codec);
342 break;
343 default:
344 ret = -EINVAL;
345 break;
346 }
347
348 return ret;
349}
350
351static int deemph_settings[] = { 0, 32000, 44100, 48000 };
352
353static int wm8955_set_deemph(struct snd_soc_codec *codec)
354{
355 struct wm8955_priv *wm8955 = codec->private_data;
356 int val, i, best;
357
358 /* If we're using deemphasis select the nearest available sample
359 * rate.
360 */
361 if (wm8955->deemph) {
362 best = 1;
363 for (i = 2; i < ARRAY_SIZE(deemph_settings); i++) {
364 if (abs(deemph_settings[i] - wm8955->fs) <
365 abs(deemph_settings[best] - wm8955->fs))
366 best = i;
367 }
368
369 val = best << WM8955_DEEMPH_SHIFT;
370 } else {
371 val = 0;
372 }
373
374 dev_dbg(codec->dev, "Set deemphasis %d\n", val);
375
376 return snd_soc_update_bits(codec, WM8955_DAC_CONTROL,
377 WM8955_DEEMPH_MASK, val);
378}
379
380static int wm8955_get_deemph(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
384 struct wm8955_priv *wm8955 = codec->private_data;
385
386 return wm8955->deemph;
387}
388
389static int wm8955_put_deemph(struct snd_kcontrol *kcontrol,
390 struct snd_ctl_elem_value *ucontrol)
391{
392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
393 struct wm8955_priv *wm8955 = codec->private_data;
394 int deemph = ucontrol->value.enumerated.item[0];
395
396 if (deemph > 1)
397 return -EINVAL;
398
399 wm8955->deemph = deemph;
400
401 return wm8955_set_deemph(codec);
402}
403
404static const char *bass_mode_text[] = {
405 "Linear", "Adaptive",
406};
407
408static const struct soc_enum bass_mode =
409 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 7, 2, bass_mode_text);
410
411static const char *bass_cutoff_text[] = {
412 "Low", "High"
413};
414
415static const struct soc_enum bass_cutoff =
416 SOC_ENUM_SINGLE(WM8955_BASS_CONTROL, 6, 2, bass_cutoff_text);
417
418static const char *treble_cutoff_text[] = {
419 "High", "Low"
420};
421
422static const struct soc_enum treble_cutoff =
423 SOC_ENUM_SINGLE(WM8955_TREBLE_CONTROL, 6, 2, treble_cutoff_text);
424
425static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
426static const DECLARE_TLV_DB_SCALE(atten_tlv, -600, 600, 0);
427static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);
428static const DECLARE_TLV_DB_SCALE(mono_tlv, -2100, 300, 0);
429static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
430static const DECLARE_TLV_DB_SCALE(treble_tlv, -1200, 150, 1);
431
432static const struct snd_kcontrol_new wm8955_snd_controls[] = {
433SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8955_LEFT_DAC_VOLUME,
434 WM8955_RIGHT_DAC_VOLUME, 0, 255, 0, digital_tlv),
435SOC_SINGLE_TLV("Playback Attenuation Volume", WM8955_DAC_CONTROL, 7, 1, 1,
436 atten_tlv),
437SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,
438 wm8955_get_deemph, wm8955_put_deemph),
439
440SOC_ENUM("Bass Mode", bass_mode),
441SOC_ENUM("Bass Cutoff", bass_cutoff),
442SOC_SINGLE("Bass Volume", WM8955_BASS_CONTROL, 0, 15, 1),
443
444SOC_ENUM("Treble Cutoff", treble_cutoff),
445SOC_SINGLE_TLV("Treble Volume", WM8955_TREBLE_CONTROL, 0, 14, 1, treble_tlv),
446
447SOC_SINGLE_TLV("Left Bypass Volume", WM8955_LEFT_OUT_MIX_1, 4, 7, 1,
448 bypass_tlv),
449SOC_SINGLE_TLV("Left Mono Volume", WM8955_LEFT_OUT_MIX_2, 4, 7, 1,
450 bypass_tlv),
451
452SOC_SINGLE_TLV("Right Mono Volume", WM8955_RIGHT_OUT_MIX_1, 4, 7, 1,
453 bypass_tlv),
454SOC_SINGLE_TLV("Right Bypass Volume", WM8955_RIGHT_OUT_MIX_2, 4, 7, 1,
455 bypass_tlv),
456
457/* Not a stereo pair so they line up with the DAPM switches */
458SOC_SINGLE_TLV("Mono Left Bypass Volume", WM8955_MONO_OUT_MIX_1, 4, 7, 1,
459 mono_tlv),
460SOC_SINGLE_TLV("Mono Right Bypass Volume", WM8955_MONO_OUT_MIX_2, 4, 7, 1,
461 mono_tlv),
462
463SOC_DOUBLE_R_TLV("Headphone Volume", WM8955_LOUT1_VOLUME,
464 WM8955_ROUT1_VOLUME, 0, 127, 0, out_tlv),
465SOC_DOUBLE_R("Headphone ZC Switch", WM8955_LOUT1_VOLUME,
466 WM8955_ROUT1_VOLUME, 7, 1, 0),
467
468SOC_DOUBLE_R_TLV("Speaker Volume", WM8955_LOUT2_VOLUME,
469 WM8955_ROUT2_VOLUME, 0, 127, 0, out_tlv),
470SOC_DOUBLE_R("Speaker ZC Switch", WM8955_LOUT2_VOLUME,
471 WM8955_ROUT2_VOLUME, 7, 1, 0),
472
473SOC_SINGLE_TLV("Mono Volume", WM8955_MONOOUT_VOLUME, 0, 127, 0, out_tlv),
474SOC_SINGLE("Mono ZC Switch", WM8955_MONOOUT_VOLUME, 7, 1, 0),
475};
476
477static const struct snd_kcontrol_new lmixer[] = {
478SOC_DAPM_SINGLE("Playback Switch", WM8955_LEFT_OUT_MIX_1, 8, 1, 0),
479SOC_DAPM_SINGLE("Bypass Switch", WM8955_LEFT_OUT_MIX_1, 7, 1, 0),
480SOC_DAPM_SINGLE("Right Playback Switch", WM8955_LEFT_OUT_MIX_2, 8, 1, 0),
481SOC_DAPM_SINGLE("Mono Switch", WM8955_LEFT_OUT_MIX_2, 7, 1, 0),
482};
483
484static const struct snd_kcontrol_new rmixer[] = {
485SOC_DAPM_SINGLE("Left Playback Switch", WM8955_RIGHT_OUT_MIX_1, 8, 1, 0),
486SOC_DAPM_SINGLE("Mono Switch", WM8955_RIGHT_OUT_MIX_1, 7, 1, 0),
487SOC_DAPM_SINGLE("Playback Switch", WM8955_RIGHT_OUT_MIX_2, 8, 1, 0),
488SOC_DAPM_SINGLE("Bypass Switch", WM8955_RIGHT_OUT_MIX_2, 7, 1, 0),
489};
490
491static const struct snd_kcontrol_new mmixer[] = {
492SOC_DAPM_SINGLE("Left Playback Switch", WM8955_MONO_OUT_MIX_1, 8, 1, 0),
493SOC_DAPM_SINGLE("Left Bypass Switch", WM8955_MONO_OUT_MIX_1, 7, 1, 0),
494SOC_DAPM_SINGLE("Right Playback Switch", WM8955_MONO_OUT_MIX_2, 8, 1, 0),
495SOC_DAPM_SINGLE("Right Bypass Switch", WM8955_MONO_OUT_MIX_2, 7, 1, 0),
496};
497
498static const struct snd_soc_dapm_widget wm8955_dapm_widgets[] = {
499SND_SOC_DAPM_INPUT("MONOIN-"),
500SND_SOC_DAPM_INPUT("MONOIN+"),
501SND_SOC_DAPM_INPUT("LINEINR"),
502SND_SOC_DAPM_INPUT("LINEINL"),
503
504SND_SOC_DAPM_PGA("Mono Input", SND_SOC_NOPM, 0, 0, NULL, 0),
505
506SND_SOC_DAPM_SUPPLY("SYSCLK", WM8955_POWER_MANAGEMENT_1, 0, 1, wm8955_sysclk,
507 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
508SND_SOC_DAPM_SUPPLY("TSDEN", WM8955_ADDITIONAL_CONTROL_1, 8, 0, NULL, 0),
509
510SND_SOC_DAPM_DAC("DACL", "Playback", WM8955_POWER_MANAGEMENT_2, 8, 0),
511SND_SOC_DAPM_DAC("DACR", "Playback", WM8955_POWER_MANAGEMENT_2, 7, 0),
512
513SND_SOC_DAPM_PGA("LOUT1 PGA", WM8955_POWER_MANAGEMENT_2, 6, 0, NULL, 0),
514SND_SOC_DAPM_PGA("ROUT1 PGA", WM8955_POWER_MANAGEMENT_2, 5, 0, NULL, 0),
515SND_SOC_DAPM_PGA("LOUT2 PGA", WM8955_POWER_MANAGEMENT_2, 4, 0, NULL, 0),
516SND_SOC_DAPM_PGA("ROUT2 PGA", WM8955_POWER_MANAGEMENT_2, 3, 0, NULL, 0),
517SND_SOC_DAPM_PGA("MOUT PGA", WM8955_POWER_MANAGEMENT_2, 2, 0, NULL, 0),
518SND_SOC_DAPM_PGA("OUT3 PGA", WM8955_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
519
520/* The names are chosen to make the control names nice */
521SND_SOC_DAPM_MIXER("Left", SND_SOC_NOPM, 0, 0,
522 lmixer, ARRAY_SIZE(lmixer)),
523SND_SOC_DAPM_MIXER("Right", SND_SOC_NOPM, 0, 0,
524 rmixer, ARRAY_SIZE(rmixer)),
525SND_SOC_DAPM_MIXER("Mono", SND_SOC_NOPM, 0, 0,
526 mmixer, ARRAY_SIZE(mmixer)),
527
528SND_SOC_DAPM_OUTPUT("LOUT1"),
529SND_SOC_DAPM_OUTPUT("ROUT1"),
530SND_SOC_DAPM_OUTPUT("LOUT2"),
531SND_SOC_DAPM_OUTPUT("ROUT2"),
532SND_SOC_DAPM_OUTPUT("MONOOUT"),
533SND_SOC_DAPM_OUTPUT("OUT3"),
534};
535
536static const struct snd_soc_dapm_route wm8955_intercon[] = {
537 { "DACL", NULL, "SYSCLK" },
538 { "DACR", NULL, "SYSCLK" },
539
540 { "Mono Input", NULL, "MONOIN-" },
541 { "Mono Input", NULL, "MONOIN+" },
542
543 { "Left", "Playback Switch", "DACL" },
544 { "Left", "Right Playback Switch", "DACR" },
545 { "Left", "Bypass Switch", "LINEINL" },
546 { "Left", "Mono Switch", "Mono Input" },
547
548 { "Right", "Playback Switch", "DACR" },
549 { "Right", "Left Playback Switch", "DACL" },
550 { "Right", "Bypass Switch", "LINEINR" },
551 { "Right", "Mono Switch", "Mono Input" },
552
553 { "Mono", "Left Playback Switch", "DACL" },
554 { "Mono", "Right Playback Switch", "DACR" },
555 { "Mono", "Left Bypass Switch", "LINEINL" },
556 { "Mono", "Right Bypass Switch", "LINEINR" },
557
558 { "LOUT1 PGA", NULL, "Left" },
559 { "LOUT1", NULL, "TSDEN" },
560 { "LOUT1", NULL, "LOUT1 PGA" },
561
562 { "ROUT1 PGA", NULL, "Right" },
563 { "ROUT1", NULL, "TSDEN" },
564 { "ROUT1", NULL, "ROUT1 PGA" },
565
566 { "LOUT2 PGA", NULL, "Left" },
567 { "LOUT2", NULL, "TSDEN" },
568 { "LOUT2", NULL, "LOUT2 PGA" },
569
570 { "ROUT2 PGA", NULL, "Right" },
571 { "ROUT2", NULL, "TSDEN" },
572 { "ROUT2", NULL, "ROUT2 PGA" },
573
574 { "MOUT PGA", NULL, "Mono" },
575 { "MONOOUT", NULL, "MOUT PGA" },
576
577 /* OUT3 not currently implemented */
578 { "OUT3", NULL, "OUT3 PGA" },
579};
580
581static int wm8955_add_widgets(struct snd_soc_codec *codec)
582{
583 snd_soc_add_controls(codec, wm8955_snd_controls,
584 ARRAY_SIZE(wm8955_snd_controls));
585
586 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets,
587 ARRAY_SIZE(wm8955_dapm_widgets));
588
589 snd_soc_dapm_add_routes(codec, wm8955_intercon,
590 ARRAY_SIZE(wm8955_intercon));
591
592 return 0;
593}
594
595static int wm8955_hw_params(struct snd_pcm_substream *substream,
596 struct snd_pcm_hw_params *params,
597 struct snd_soc_dai *dai)
598{
599 struct snd_soc_codec *codec = dai->codec;
600 struct wm8955_priv *wm8955 = codec->private_data;
601 int ret;
602 int wl;
603
604 switch (params_format(params)) {
605 case SNDRV_PCM_FORMAT_S16_LE:
606 wl = 0;
607 break;
608 case SNDRV_PCM_FORMAT_S20_3LE:
609 wl = 0x4;
610 break;
611 case SNDRV_PCM_FORMAT_S24_LE:
612 wl = 0x8;
613 break;
614 case SNDRV_PCM_FORMAT_S32_LE:
615 wl = 0xc;
616 break;
617 default:
618 return -EINVAL;
619 }
620 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
621 WM8955_WL_MASK, wl);
622
623 wm8955->fs = params_rate(params);
624 wm8955_set_deemph(codec);
625
626 /* If the chip is clocked then disable the clocks and force a
627 * reconfiguration, otherwise DAPM will power up the
628 * clocks for us later. */
629 ret = snd_soc_read(codec, WM8955_POWER_MANAGEMENT_1);
630 if (ret < 0)
631 return ret;
632 if (ret & WM8955_DIGENB) {
633 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
634 WM8955_DIGENB, 0);
635 snd_soc_update_bits(codec, WM8955_CLOCKING_PLL,
636 WM8955_PLL_RB | WM8955_PLLEN, 0);
637
638 wm8955_configure_clocking(codec);
639 }
640
641 return 0;
642}
643
644
645static int wm8955_set_sysclk(struct snd_soc_dai *dai, int clk_id,
646 unsigned int freq, int dir)
647{
648 struct snd_soc_codec *codec = dai->codec;
649 struct wm8955_priv *priv = codec->private_data;
650 int div;
651
652 switch (clk_id) {
653 case WM8955_CLK_MCLK:
654 if (freq > 15000000) {
655 priv->mclk_rate = freq /= 2;
656 div = WM8955_MCLKDIV2;
657 } else {
658 priv->mclk_rate = freq;
659 div = 0;
660 }
661
662 snd_soc_update_bits(codec, WM8955_SAMPLE_RATE,
663 WM8955_MCLKDIV2, div);
664 break;
665
666 default:
667 return -EINVAL;
668 }
669
670 dev_dbg(dai->dev, "Clock source is %d at %uHz\n", clk_id, freq);
671
672 return 0;
673}
674
675static int wm8955_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
676{
677 struct snd_soc_codec *codec = dai->codec;
678 u16 aif = 0;
679
680 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
681 case SND_SOC_DAIFMT_CBS_CFS:
682 break;
683 case SND_SOC_DAIFMT_CBM_CFM:
684 aif |= WM8955_MS;
685 break;
686 default:
687 return -EINVAL;
688 }
689
690 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
691 case SND_SOC_DAIFMT_DSP_B:
692 aif |= WM8955_LRP;
693 case SND_SOC_DAIFMT_DSP_A:
694 aif |= 0x3;
695 break;
696 case SND_SOC_DAIFMT_I2S:
697 aif |= 0x2;
698 break;
699 case SND_SOC_DAIFMT_RIGHT_J:
700 break;
701 case SND_SOC_DAIFMT_LEFT_J:
702 aif |= 0x1;
703 break;
704 default:
705 return -EINVAL;
706 }
707
708 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
709 case SND_SOC_DAIFMT_DSP_A:
710 case SND_SOC_DAIFMT_DSP_B:
711 /* frame inversion not valid for DSP modes */
712 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
713 case SND_SOC_DAIFMT_NB_NF:
714 break;
715 case SND_SOC_DAIFMT_IB_NF:
716 aif |= WM8955_BCLKINV;
717 break;
718 default:
719 return -EINVAL;
720 }
721 break;
722
723 case SND_SOC_DAIFMT_I2S:
724 case SND_SOC_DAIFMT_RIGHT_J:
725 case SND_SOC_DAIFMT_LEFT_J:
726 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
727 case SND_SOC_DAIFMT_NB_NF:
728 break;
729 case SND_SOC_DAIFMT_IB_IF:
730 aif |= WM8955_BCLKINV | WM8955_LRP;
731 break;
732 case SND_SOC_DAIFMT_IB_NF:
733 aif |= WM8955_BCLKINV;
734 break;
735 case SND_SOC_DAIFMT_NB_IF:
736 aif |= WM8955_LRP;
737 break;
738 default:
739 return -EINVAL;
740 }
741 break;
742 default:
743 return -EINVAL;
744 }
745
746 snd_soc_update_bits(codec, WM8955_AUDIO_INTERFACE,
747 WM8955_MS | WM8955_FORMAT_MASK | WM8955_BCLKINV |
748 WM8955_LRP, aif);
749
750 return 0;
751}
752
753
754static int wm8955_digital_mute(struct snd_soc_dai *codec_dai, int mute)
755{
756 struct snd_soc_codec *codec = codec_dai->codec;
757 int val;
758
759 if (mute)
760 val = WM8955_DACMU;
761 else
762 val = 0;
763
764 snd_soc_update_bits(codec, WM8955_DAC_CONTROL, WM8955_DACMU, val);
765
766 return 0;
767}
768
769static int wm8955_set_bias_level(struct snd_soc_codec *codec,
770 enum snd_soc_bias_level level)
771{
772 struct wm8955_priv *wm8955 = codec->private_data;
773 int ret, i;
774
775 switch (level) {
776 case SND_SOC_BIAS_ON:
777 break;
778
779 case SND_SOC_BIAS_PREPARE:
780 /* VMID resistance 2*50k */
781 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
782 WM8955_VMIDSEL_MASK,
783 0x1 << WM8955_VMIDSEL_SHIFT);
784
785 /* Default bias current */
786 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
787 WM8955_VSEL_MASK,
788 0x2 << WM8955_VSEL_SHIFT);
789 break;
790
791 case SND_SOC_BIAS_STANDBY:
792 if (codec->bias_level == SND_SOC_BIAS_OFF) {
793 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
794 wm8955->supplies);
795 if (ret != 0) {
796 dev_err(codec->dev,
797 "Failed to enable supplies: %d\n",
798 ret);
799 return ret;
800 }
801
802 /* Sync back cached values if they're
803 * different from the hardware default.
804 */
805 for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) {
806 if (i == WM8955_RESET)
807 continue;
808
809 if (wm8955->reg_cache[i] == wm8955_reg[i])
810 continue;
811
812 snd_soc_write(codec, i, wm8955->reg_cache[i]);
813 }
814
815 /* Enable VREF and VMID */
816 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
817 WM8955_VREF |
818 WM8955_VMIDSEL_MASK,
819 WM8955_VREF |
820 0x3 << WM8955_VREF_SHIFT);
821
822 /* Let VMID ramp */
823 msleep(500);
824
825 /* High resistance VROI to maintain outputs */
826 snd_soc_update_bits(codec,
827 WM8955_ADDITIONAL_CONTROL_3,
828 WM8955_VROI, WM8955_VROI);
829 }
830
831 /* Maintain VMID with 2*250k */
832 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
833 WM8955_VMIDSEL_MASK,
834 0x2 << WM8955_VMIDSEL_SHIFT);
835
836 /* Minimum bias current */
837 snd_soc_update_bits(codec, WM8955_ADDITIONAL_CONTROL_1,
838 WM8955_VSEL_MASK, 0);
839 break;
840
841 case SND_SOC_BIAS_OFF:
842 /* Low resistance VROI to help discharge */
843 snd_soc_update_bits(codec,
844 WM8955_ADDITIONAL_CONTROL_3,
845 WM8955_VROI, 0);
846
847 /* Turn off VMID and VREF */
848 snd_soc_update_bits(codec, WM8955_POWER_MANAGEMENT_1,
849 WM8955_VREF |
850 WM8955_VMIDSEL_MASK, 0);
851
852 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies),
853 wm8955->supplies);
854 break;
855 }
856 codec->bias_level = level;
857 return 0;
858}
859
860#define WM8955_RATES SNDRV_PCM_RATE_8000_96000
861
862#define WM8955_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
863 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
864
865static struct snd_soc_dai_ops wm8955_dai_ops = {
866 .set_sysclk = wm8955_set_sysclk,
867 .set_fmt = wm8955_set_fmt,
868 .hw_params = wm8955_hw_params,
869 .digital_mute = wm8955_digital_mute,
870};
871
872struct snd_soc_dai wm8955_dai = {
873 .name = "WM8955",
874 .playback = {
875 .stream_name = "Playback",
876 .channels_min = 2,
877 .channels_max = 2,
878 .rates = WM8955_RATES,
879 .formats = WM8955_FORMATS,
880 },
881 .ops = &wm8955_dai_ops,
882};
883EXPORT_SYMBOL_GPL(wm8955_dai);
884
885#ifdef CONFIG_PM
886static int wm8955_suspend(struct platform_device *pdev, pm_message_t state)
887{
888 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
889 struct snd_soc_codec *codec = socdev->card->codec;
890
891 wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF);
892
893 return 0;
894}
895
896static int wm8955_resume(struct platform_device *pdev)
897{
898 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
899 struct snd_soc_codec *codec = socdev->card->codec;
900
901 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
902
903 return 0;
904}
905#else
906#define wm8955_suspend NULL
907#define wm8955_resume NULL
908#endif
909
910static int wm8955_probe(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec;
914 int ret = 0;
915
916 if (wm8955_codec == NULL) {
917 dev_err(&pdev->dev, "Codec device not registered\n");
918 return -ENODEV;
919 }
920
921 socdev->card->codec = wm8955_codec;
922 codec = wm8955_codec;
923
924 /* register pcms */
925 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
926 if (ret < 0) {
927 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
928 goto pcm_err;
929 }
930
931 wm8955_add_widgets(codec);
932
933 return ret;
934
935pcm_err:
936 return ret;
937}
938
939static int wm8955_remove(struct platform_device *pdev)
940{
941 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
942
943 snd_soc_free_pcms(socdev);
944 snd_soc_dapm_free(socdev);
945
946 return 0;
947}
948
949struct snd_soc_codec_device soc_codec_dev_wm8955 = {
950 .probe = wm8955_probe,
951 .remove = wm8955_remove,
952 .suspend = wm8955_suspend,
953 .resume = wm8955_resume,
954};
955EXPORT_SYMBOL_GPL(soc_codec_dev_wm8955);
956
957static int wm8955_register(struct wm8955_priv *wm8955,
958 enum snd_soc_control_type control)
959{
960 int ret;
961 struct snd_soc_codec *codec = &wm8955->codec;
962 int i;
963
964 if (wm8955_codec) {
965 dev_err(codec->dev, "Another WM8955 is registered\n");
966 return -EINVAL;
967 }
968
969 mutex_init(&codec->mutex);
970 INIT_LIST_HEAD(&codec->dapm_widgets);
971 INIT_LIST_HEAD(&codec->dapm_paths);
972
973 codec->private_data = wm8955;
974 codec->name = "WM8955";
975 codec->owner = THIS_MODULE;
976 codec->bias_level = SND_SOC_BIAS_OFF;
977 codec->set_bias_level = wm8955_set_bias_level;
978 codec->dai = &wm8955_dai;
979 codec->num_dai = 1;
980 codec->reg_cache_size = WM8955_MAX_REGISTER;
981 codec->reg_cache = &wm8955->reg_cache;
982
983 memcpy(codec->reg_cache, wm8955_reg, sizeof(wm8955_reg));
984
985 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
986 if (ret != 0) {
987 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
988 goto err;
989 }
990
991 for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++)
992 wm8955->supplies[i].supply = wm8955_supply_names[i];
993
994 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies),
995 wm8955->supplies);
996 if (ret != 0) {
997 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
998 goto err;
999 }
1000
1001 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
1002 wm8955->supplies);
1003 if (ret != 0) {
1004 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1005 goto err_get;
1006 }
1007
1008 ret = wm8955_reset(codec);
1009 if (ret < 0) {
1010 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1011 goto err_enable;
1012 }
1013
1014 wm8955_dai.dev = codec->dev;
1015
1016 /* Change some default settings - latch VU and enable ZC */
1017 wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU;
1018 wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU;
1019 wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC;
1020 wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC;
1021 wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC;
1022 wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC;
1023 wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC;
1024
1025 /* Also enable adaptive bass boost by default */
1026 wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB;
1027
1028 /* Set platform data values */
1029 if (wm8955->pdata) {
1030 if (wm8955->pdata->out2_speaker)
1031 wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2]
1032 |= WM8955_ROUT2INV;
1033
1034 if (wm8955->pdata->monoin_diff)
1035 wm8955->reg_cache[WM8955_MONO_OUT_MIX_1]
1036 |= WM8955_DMEN;
1037 }
1038
1039 wm8955_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1040
1041 /* Bias level configuration will have done an extra enable */
1042 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1043
1044 wm8955_codec = codec;
1045
1046 ret = snd_soc_register_codec(codec);
1047 if (ret != 0) {
1048 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1049 return ret;
1050 }
1051
1052 ret = snd_soc_register_dai(&wm8955_dai);
1053 if (ret != 0) {
1054 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1055 snd_soc_unregister_codec(codec);
1056 return ret;
1057 }
1058
1059 return 0;
1060
1061err_enable:
1062 regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1063err_get:
1064 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1065err:
1066 kfree(wm8955);
1067 return ret;
1068}
1069
1070static void wm8955_unregister(struct wm8955_priv *wm8955)
1071{
1072 wm8955_set_bias_level(&wm8955->codec, SND_SOC_BIAS_OFF);
1073 regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies);
1074 snd_soc_unregister_dai(&wm8955_dai);
1075 snd_soc_unregister_codec(&wm8955->codec);
1076 kfree(wm8955);
1077 wm8955_codec = NULL;
1078}
1079
1080#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1081static __devinit int wm8955_i2c_probe(struct i2c_client *i2c,
1082 const struct i2c_device_id *id)
1083{
1084 struct wm8955_priv *wm8955;
1085 struct snd_soc_codec *codec;
1086
1087 wm8955 = kzalloc(sizeof(struct wm8955_priv), GFP_KERNEL);
1088 if (wm8955 == NULL)
1089 return -ENOMEM;
1090
1091 codec = &wm8955->codec;
1092 codec->hw_write = (hw_write_t)i2c_master_send;
1093
1094 i2c_set_clientdata(i2c, wm8955);
1095 codec->control_data = i2c;
1096 wm8955->pdata = i2c->dev.platform_data;
1097
1098 codec->dev = &i2c->dev;
1099
1100 return wm8955_register(wm8955, SND_SOC_I2C);
1101}
1102
1103static __devexit int wm8955_i2c_remove(struct i2c_client *client)
1104{
1105 struct wm8955_priv *wm8955 = i2c_get_clientdata(client);
1106 wm8955_unregister(wm8955);
1107 return 0;
1108}
1109
1110static const struct i2c_device_id wm8955_i2c_id[] = {
1111 { "wm8955", 0 },
1112 { }
1113};
1114MODULE_DEVICE_TABLE(i2c, wm8955_i2c_id);
1115
1116static struct i2c_driver wm8955_i2c_driver = {
1117 .driver = {
1118 .name = "wm8955",
1119 .owner = THIS_MODULE,
1120 },
1121 .probe = wm8955_i2c_probe,
1122 .remove = __devexit_p(wm8955_i2c_remove),
1123 .id_table = wm8955_i2c_id,
1124};
1125#endif
1126
1127static int __init wm8955_modinit(void)
1128{
1129 int ret;
1130#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1131 ret = i2c_add_driver(&wm8955_i2c_driver);
1132 if (ret != 0) {
1133 printk(KERN_ERR "Failed to register WM8955 I2C driver: %d\n",
1134 ret);
1135 }
1136#endif
1137 return 0;
1138}
1139module_init(wm8955_modinit);
1140
1141static void __exit wm8955_exit(void)
1142{
1143#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1144 i2c_del_driver(&wm8955_i2c_driver);
1145#endif
1146}
1147module_exit(wm8955_exit);
1148
1149MODULE_DESCRIPTION("ASoC WM8955 driver");
1150MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1151MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8955.h b/sound/soc/codecs/wm8955.h
new file mode 100644
index 000000000000..ae349c8531f6
--- /dev/null
+++ b/sound/soc/codecs/wm8955.h
@@ -0,0 +1,489 @@
1/*
2 * wm8955.h -- WM8904 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 _WM8955_H
14#define _WM8955_H
15
16#define WM8955_CLK_MCLK 1
17
18extern struct snd_soc_dai wm8955_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8955;
20
21/*
22 * Register values.
23 */
24#define WM8955_LOUT1_VOLUME 0x02
25#define WM8955_ROUT1_VOLUME 0x03
26#define WM8955_DAC_CONTROL 0x05
27#define WM8955_AUDIO_INTERFACE 0x07
28#define WM8955_SAMPLE_RATE 0x08
29#define WM8955_LEFT_DAC_VOLUME 0x0A
30#define WM8955_RIGHT_DAC_VOLUME 0x0B
31#define WM8955_BASS_CONTROL 0x0C
32#define WM8955_TREBLE_CONTROL 0x0D
33#define WM8955_RESET 0x0F
34#define WM8955_ADDITIONAL_CONTROL_1 0x17
35#define WM8955_ADDITIONAL_CONTROL_2 0x18
36#define WM8955_POWER_MANAGEMENT_1 0x19
37#define WM8955_POWER_MANAGEMENT_2 0x1A
38#define WM8955_ADDITIONAL_CONTROL_3 0x1B
39#define WM8955_LEFT_OUT_MIX_1 0x22
40#define WM8955_LEFT_OUT_MIX_2 0x23
41#define WM8955_RIGHT_OUT_MIX_1 0x24
42#define WM8955_RIGHT_OUT_MIX_2 0x25
43#define WM8955_MONO_OUT_MIX_1 0x26
44#define WM8955_MONO_OUT_MIX_2 0x27
45#define WM8955_LOUT2_VOLUME 0x28
46#define WM8955_ROUT2_VOLUME 0x29
47#define WM8955_MONOOUT_VOLUME 0x2A
48#define WM8955_CLOCKING_PLL 0x2B
49#define WM8955_PLL_CONTROL_1 0x2C
50#define WM8955_PLL_CONTROL_2 0x2D
51#define WM8955_PLL_CONTROL_3 0x2E
52#define WM8955_PLL_CONTROL_4 0x3B
53
54#define WM8955_REGISTER_COUNT 29
55#define WM8955_MAX_REGISTER 0x3B
56
57/*
58 * Field Definitions.
59 */
60
61/*
62 * R2 (0x02) - LOUT1 volume
63 */
64#define WM8955_LO1VU 0x0100 /* LO1VU */
65#define WM8955_LO1VU_MASK 0x0100 /* LO1VU */
66#define WM8955_LO1VU_SHIFT 8 /* LO1VU */
67#define WM8955_LO1VU_WIDTH 1 /* LO1VU */
68#define WM8955_LO1ZC 0x0080 /* LO1ZC */
69#define WM8955_LO1ZC_MASK 0x0080 /* LO1ZC */
70#define WM8955_LO1ZC_SHIFT 7 /* LO1ZC */
71#define WM8955_LO1ZC_WIDTH 1 /* LO1ZC */
72#define WM8955_LOUTVOL_MASK 0x007F /* LOUTVOL - [6:0] */
73#define WM8955_LOUTVOL_SHIFT 0 /* LOUTVOL - [6:0] */
74#define WM8955_LOUTVOL_WIDTH 7 /* LOUTVOL - [6:0] */
75
76/*
77 * R3 (0x03) - ROUT1 volume
78 */
79#define WM8955_RO1VU 0x0100 /* RO1VU */
80#define WM8955_RO1VU_MASK 0x0100 /* RO1VU */
81#define WM8955_RO1VU_SHIFT 8 /* RO1VU */
82#define WM8955_RO1VU_WIDTH 1 /* RO1VU */
83#define WM8955_RO1ZC 0x0080 /* RO1ZC */
84#define WM8955_RO1ZC_MASK 0x0080 /* RO1ZC */
85#define WM8955_RO1ZC_SHIFT 7 /* RO1ZC */
86#define WM8955_RO1ZC_WIDTH 1 /* RO1ZC */
87#define WM8955_ROUTVOL_MASK 0x007F /* ROUTVOL - [6:0] */
88#define WM8955_ROUTVOL_SHIFT 0 /* ROUTVOL - [6:0] */
89#define WM8955_ROUTVOL_WIDTH 7 /* ROUTVOL - [6:0] */
90
91/*
92 * R5 (0x05) - DAC Control
93 */
94#define WM8955_DAT 0x0080 /* DAT */
95#define WM8955_DAT_MASK 0x0080 /* DAT */
96#define WM8955_DAT_SHIFT 7 /* DAT */
97#define WM8955_DAT_WIDTH 1 /* DAT */
98#define WM8955_DACMU 0x0008 /* DACMU */
99#define WM8955_DACMU_MASK 0x0008 /* DACMU */
100#define WM8955_DACMU_SHIFT 3 /* DACMU */
101#define WM8955_DACMU_WIDTH 1 /* DACMU */
102#define WM8955_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */
103#define WM8955_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */
104#define WM8955_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */
105
106/*
107 * R7 (0x07) - Audio Interface
108 */
109#define WM8955_BCLKINV 0x0080 /* BCLKINV */
110#define WM8955_BCLKINV_MASK 0x0080 /* BCLKINV */
111#define WM8955_BCLKINV_SHIFT 7 /* BCLKINV */
112#define WM8955_BCLKINV_WIDTH 1 /* BCLKINV */
113#define WM8955_MS 0x0040 /* MS */
114#define WM8955_MS_MASK 0x0040 /* MS */
115#define WM8955_MS_SHIFT 6 /* MS */
116#define WM8955_MS_WIDTH 1 /* MS */
117#define WM8955_LRSWAP 0x0020 /* LRSWAP */
118#define WM8955_LRSWAP_MASK 0x0020 /* LRSWAP */
119#define WM8955_LRSWAP_SHIFT 5 /* LRSWAP */
120#define WM8955_LRSWAP_WIDTH 1 /* LRSWAP */
121#define WM8955_LRP 0x0010 /* LRP */
122#define WM8955_LRP_MASK 0x0010 /* LRP */
123#define WM8955_LRP_SHIFT 4 /* LRP */
124#define WM8955_LRP_WIDTH 1 /* LRP */
125#define WM8955_WL_MASK 0x000C /* WL - [3:2] */
126#define WM8955_WL_SHIFT 2 /* WL - [3:2] */
127#define WM8955_WL_WIDTH 2 /* WL - [3:2] */
128#define WM8955_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
129#define WM8955_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
130#define WM8955_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
131
132/*
133 * R8 (0x08) - Sample Rate
134 */
135#define WM8955_BCLKDIV2 0x0080 /* BCLKDIV2 */
136#define WM8955_BCLKDIV2_MASK 0x0080 /* BCLKDIV2 */
137#define WM8955_BCLKDIV2_SHIFT 7 /* BCLKDIV2 */
138#define WM8955_BCLKDIV2_WIDTH 1 /* BCLKDIV2 */
139#define WM8955_MCLKDIV2 0x0040 /* MCLKDIV2 */
140#define WM8955_MCLKDIV2_MASK 0x0040 /* MCLKDIV2 */
141#define WM8955_MCLKDIV2_SHIFT 6 /* MCLKDIV2 */
142#define WM8955_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */
143#define WM8955_SR_MASK 0x003E /* SR - [5:1] */
144#define WM8955_SR_SHIFT 1 /* SR - [5:1] */
145#define WM8955_SR_WIDTH 5 /* SR - [5:1] */
146#define WM8955_USB 0x0001 /* USB */
147#define WM8955_USB_MASK 0x0001 /* USB */
148#define WM8955_USB_SHIFT 0 /* USB */
149#define WM8955_USB_WIDTH 1 /* USB */
150
151/*
152 * R10 (0x0A) - Left DAC volume
153 */
154#define WM8955_LDVU 0x0100 /* LDVU */
155#define WM8955_LDVU_MASK 0x0100 /* LDVU */
156#define WM8955_LDVU_SHIFT 8 /* LDVU */
157#define WM8955_LDVU_WIDTH 1 /* LDVU */
158#define WM8955_LDACVOL_MASK 0x00FF /* LDACVOL - [7:0] */
159#define WM8955_LDACVOL_SHIFT 0 /* LDACVOL - [7:0] */
160#define WM8955_LDACVOL_WIDTH 8 /* LDACVOL - [7:0] */
161
162/*
163 * R11 (0x0B) - Right DAC volume
164 */
165#define WM8955_RDVU 0x0100 /* RDVU */
166#define WM8955_RDVU_MASK 0x0100 /* RDVU */
167#define WM8955_RDVU_SHIFT 8 /* RDVU */
168#define WM8955_RDVU_WIDTH 1 /* RDVU */
169#define WM8955_RDACVOL_MASK 0x00FF /* RDACVOL - [7:0] */
170#define WM8955_RDACVOL_SHIFT 0 /* RDACVOL - [7:0] */
171#define WM8955_RDACVOL_WIDTH 8 /* RDACVOL - [7:0] */
172
173/*
174 * R12 (0x0C) - Bass control
175 */
176#define WM8955_BB 0x0080 /* BB */
177#define WM8955_BB_MASK 0x0080 /* BB */
178#define WM8955_BB_SHIFT 7 /* BB */
179#define WM8955_BB_WIDTH 1 /* BB */
180#define WM8955_BC 0x0040 /* BC */
181#define WM8955_BC_MASK 0x0040 /* BC */
182#define WM8955_BC_SHIFT 6 /* BC */
183#define WM8955_BC_WIDTH 1 /* BC */
184#define WM8955_BASS_MASK 0x000F /* BASS - [3:0] */
185#define WM8955_BASS_SHIFT 0 /* BASS - [3:0] */
186#define WM8955_BASS_WIDTH 4 /* BASS - [3:0] */
187
188/*
189 * R13 (0x0D) - Treble control
190 */
191#define WM8955_TC 0x0040 /* TC */
192#define WM8955_TC_MASK 0x0040 /* TC */
193#define WM8955_TC_SHIFT 6 /* TC */
194#define WM8955_TC_WIDTH 1 /* TC */
195#define WM8955_TRBL_MASK 0x000F /* TRBL - [3:0] */
196#define WM8955_TRBL_SHIFT 0 /* TRBL - [3:0] */
197#define WM8955_TRBL_WIDTH 4 /* TRBL - [3:0] */
198
199/*
200 * R15 (0x0F) - Reset
201 */
202#define WM8955_RESET_MASK 0x01FF /* RESET - [8:0] */
203#define WM8955_RESET_SHIFT 0 /* RESET - [8:0] */
204#define WM8955_RESET_WIDTH 9 /* RESET - [8:0] */
205
206/*
207 * R23 (0x17) - Additional control (1)
208 */
209#define WM8955_TSDEN 0x0100 /* TSDEN */
210#define WM8955_TSDEN_MASK 0x0100 /* TSDEN */
211#define WM8955_TSDEN_SHIFT 8 /* TSDEN */
212#define WM8955_TSDEN_WIDTH 1 /* TSDEN */
213#define WM8955_VSEL_MASK 0x00C0 /* VSEL - [7:6] */
214#define WM8955_VSEL_SHIFT 6 /* VSEL - [7:6] */
215#define WM8955_VSEL_WIDTH 2 /* VSEL - [7:6] */
216#define WM8955_DMONOMIX_MASK 0x0030 /* DMONOMIX - [5:4] */
217#define WM8955_DMONOMIX_SHIFT 4 /* DMONOMIX - [5:4] */
218#define WM8955_DMONOMIX_WIDTH 2 /* DMONOMIX - [5:4] */
219#define WM8955_DACINV 0x0002 /* DACINV */
220#define WM8955_DACINV_MASK 0x0002 /* DACINV */
221#define WM8955_DACINV_SHIFT 1 /* DACINV */
222#define WM8955_DACINV_WIDTH 1 /* DACINV */
223#define WM8955_TOEN 0x0001 /* TOEN */
224#define WM8955_TOEN_MASK 0x0001 /* TOEN */
225#define WM8955_TOEN_SHIFT 0 /* TOEN */
226#define WM8955_TOEN_WIDTH 1 /* TOEN */
227
228/*
229 * R24 (0x18) - Additional control (2)
230 */
231#define WM8955_OUT3SW_MASK 0x0180 /* OUT3SW - [8:7] */
232#define WM8955_OUT3SW_SHIFT 7 /* OUT3SW - [8:7] */
233#define WM8955_OUT3SW_WIDTH 2 /* OUT3SW - [8:7] */
234#define WM8955_ROUT2INV 0x0010 /* ROUT2INV */
235#define WM8955_ROUT2INV_MASK 0x0010 /* ROUT2INV */
236#define WM8955_ROUT2INV_SHIFT 4 /* ROUT2INV */
237#define WM8955_ROUT2INV_WIDTH 1 /* ROUT2INV */
238#define WM8955_DACOSR 0x0001 /* DACOSR */
239#define WM8955_DACOSR_MASK 0x0001 /* DACOSR */
240#define WM8955_DACOSR_SHIFT 0 /* DACOSR */
241#define WM8955_DACOSR_WIDTH 1 /* DACOSR */
242
243/*
244 * R25 (0x19) - Power Management (1)
245 */
246#define WM8955_VMIDSEL_MASK 0x0180 /* VMIDSEL - [8:7] */
247#define WM8955_VMIDSEL_SHIFT 7 /* VMIDSEL - [8:7] */
248#define WM8955_VMIDSEL_WIDTH 2 /* VMIDSEL - [8:7] */
249#define WM8955_VREF 0x0040 /* VREF */
250#define WM8955_VREF_MASK 0x0040 /* VREF */
251#define WM8955_VREF_SHIFT 6 /* VREF */
252#define WM8955_VREF_WIDTH 1 /* VREF */
253#define WM8955_DIGENB 0x0001 /* DIGENB */
254#define WM8955_DIGENB_MASK 0x0001 /* DIGENB */
255#define WM8955_DIGENB_SHIFT 0 /* DIGENB */
256#define WM8955_DIGENB_WIDTH 1 /* DIGENB */
257
258/*
259 * R26 (0x1A) - Power Management (2)
260 */
261#define WM8955_DACL 0x0100 /* DACL */
262#define WM8955_DACL_MASK 0x0100 /* DACL */
263#define WM8955_DACL_SHIFT 8 /* DACL */
264#define WM8955_DACL_WIDTH 1 /* DACL */
265#define WM8955_DACR 0x0080 /* DACR */
266#define WM8955_DACR_MASK 0x0080 /* DACR */
267#define WM8955_DACR_SHIFT 7 /* DACR */
268#define WM8955_DACR_WIDTH 1 /* DACR */
269#define WM8955_LOUT1 0x0040 /* LOUT1 */
270#define WM8955_LOUT1_MASK 0x0040 /* LOUT1 */
271#define WM8955_LOUT1_SHIFT 6 /* LOUT1 */
272#define WM8955_LOUT1_WIDTH 1 /* LOUT1 */
273#define WM8955_ROUT1 0x0020 /* ROUT1 */
274#define WM8955_ROUT1_MASK 0x0020 /* ROUT1 */
275#define WM8955_ROUT1_SHIFT 5 /* ROUT1 */
276#define WM8955_ROUT1_WIDTH 1 /* ROUT1 */
277#define WM8955_LOUT2 0x0010 /* LOUT2 */
278#define WM8955_LOUT2_MASK 0x0010 /* LOUT2 */
279#define WM8955_LOUT2_SHIFT 4 /* LOUT2 */
280#define WM8955_LOUT2_WIDTH 1 /* LOUT2 */
281#define WM8955_ROUT2 0x0008 /* ROUT2 */
282#define WM8955_ROUT2_MASK 0x0008 /* ROUT2 */
283#define WM8955_ROUT2_SHIFT 3 /* ROUT2 */
284#define WM8955_ROUT2_WIDTH 1 /* ROUT2 */
285#define WM8955_MONO 0x0004 /* MONO */
286#define WM8955_MONO_MASK 0x0004 /* MONO */
287#define WM8955_MONO_SHIFT 2 /* MONO */
288#define WM8955_MONO_WIDTH 1 /* MONO */
289#define WM8955_OUT3 0x0002 /* OUT3 */
290#define WM8955_OUT3_MASK 0x0002 /* OUT3 */
291#define WM8955_OUT3_SHIFT 1 /* OUT3 */
292#define WM8955_OUT3_WIDTH 1 /* OUT3 */
293
294/*
295 * R27 (0x1B) - Additional Control (3)
296 */
297#define WM8955_VROI 0x0040 /* VROI */
298#define WM8955_VROI_MASK 0x0040 /* VROI */
299#define WM8955_VROI_SHIFT 6 /* VROI */
300#define WM8955_VROI_WIDTH 1 /* VROI */
301
302/*
303 * R34 (0x22) - Left out Mix (1)
304 */
305#define WM8955_LD2LO 0x0100 /* LD2LO */
306#define WM8955_LD2LO_MASK 0x0100 /* LD2LO */
307#define WM8955_LD2LO_SHIFT 8 /* LD2LO */
308#define WM8955_LD2LO_WIDTH 1 /* LD2LO */
309#define WM8955_LI2LO 0x0080 /* LI2LO */
310#define WM8955_LI2LO_MASK 0x0080 /* LI2LO */
311#define WM8955_LI2LO_SHIFT 7 /* LI2LO */
312#define WM8955_LI2LO_WIDTH 1 /* LI2LO */
313#define WM8955_LI2LOVOL_MASK 0x0070 /* LI2LOVOL - [6:4] */
314#define WM8955_LI2LOVOL_SHIFT 4 /* LI2LOVOL - [6:4] */
315#define WM8955_LI2LOVOL_WIDTH 3 /* LI2LOVOL - [6:4] */
316
317/*
318 * R35 (0x23) - Left out Mix (2)
319 */
320#define WM8955_RD2LO 0x0100 /* RD2LO */
321#define WM8955_RD2LO_MASK 0x0100 /* RD2LO */
322#define WM8955_RD2LO_SHIFT 8 /* RD2LO */
323#define WM8955_RD2LO_WIDTH 1 /* RD2LO */
324#define WM8955_RI2LO 0x0080 /* RI2LO */
325#define WM8955_RI2LO_MASK 0x0080 /* RI2LO */
326#define WM8955_RI2LO_SHIFT 7 /* RI2LO */
327#define WM8955_RI2LO_WIDTH 1 /* RI2LO */
328#define WM8955_RI2LOVOL_MASK 0x0070 /* RI2LOVOL - [6:4] */
329#define WM8955_RI2LOVOL_SHIFT 4 /* RI2LOVOL - [6:4] */
330#define WM8955_RI2LOVOL_WIDTH 3 /* RI2LOVOL - [6:4] */
331
332/*
333 * R36 (0x24) - Right out Mix (1)
334 */
335#define WM8955_LD2RO 0x0100 /* LD2RO */
336#define WM8955_LD2RO_MASK 0x0100 /* LD2RO */
337#define WM8955_LD2RO_SHIFT 8 /* LD2RO */
338#define WM8955_LD2RO_WIDTH 1 /* LD2RO */
339#define WM8955_LI2RO 0x0080 /* LI2RO */
340#define WM8955_LI2RO_MASK 0x0080 /* LI2RO */
341#define WM8955_LI2RO_SHIFT 7 /* LI2RO */
342#define WM8955_LI2RO_WIDTH 1 /* LI2RO */
343#define WM8955_LI2ROVOL_MASK 0x0070 /* LI2ROVOL - [6:4] */
344#define WM8955_LI2ROVOL_SHIFT 4 /* LI2ROVOL - [6:4] */
345#define WM8955_LI2ROVOL_WIDTH 3 /* LI2ROVOL - [6:4] */
346
347/*
348 * R37 (0x25) - Right Out Mix (2)
349 */
350#define WM8955_RD2RO 0x0100 /* RD2RO */
351#define WM8955_RD2RO_MASK 0x0100 /* RD2RO */
352#define WM8955_RD2RO_SHIFT 8 /* RD2RO */
353#define WM8955_RD2RO_WIDTH 1 /* RD2RO */
354#define WM8955_RI2RO 0x0080 /* RI2RO */
355#define WM8955_RI2RO_MASK 0x0080 /* RI2RO */
356#define WM8955_RI2RO_SHIFT 7 /* RI2RO */
357#define WM8955_RI2RO_WIDTH 1 /* RI2RO */
358#define WM8955_RI2ROVOL_MASK 0x0070 /* RI2ROVOL - [6:4] */
359#define WM8955_RI2ROVOL_SHIFT 4 /* RI2ROVOL - [6:4] */
360#define WM8955_RI2ROVOL_WIDTH 3 /* RI2ROVOL - [6:4] */
361
362/*
363 * R38 (0x26) - Mono out Mix (1)
364 */
365#define WM8955_LD2MO 0x0100 /* LD2MO */
366#define WM8955_LD2MO_MASK 0x0100 /* LD2MO */
367#define WM8955_LD2MO_SHIFT 8 /* LD2MO */
368#define WM8955_LD2MO_WIDTH 1 /* LD2MO */
369#define WM8955_LI2MO 0x0080 /* LI2MO */
370#define WM8955_LI2MO_MASK 0x0080 /* LI2MO */
371#define WM8955_LI2MO_SHIFT 7 /* LI2MO */
372#define WM8955_LI2MO_WIDTH 1 /* LI2MO */
373#define WM8955_LI2MOVOL_MASK 0x0070 /* LI2MOVOL - [6:4] */
374#define WM8955_LI2MOVOL_SHIFT 4 /* LI2MOVOL - [6:4] */
375#define WM8955_LI2MOVOL_WIDTH 3 /* LI2MOVOL - [6:4] */
376#define WM8955_DMEN 0x0001 /* DMEN */
377#define WM8955_DMEN_MASK 0x0001 /* DMEN */
378#define WM8955_DMEN_SHIFT 0 /* DMEN */
379#define WM8955_DMEN_WIDTH 1 /* DMEN */
380
381/*
382 * R39 (0x27) - Mono out Mix (2)
383 */
384#define WM8955_RD2MO 0x0100 /* RD2MO */
385#define WM8955_RD2MO_MASK 0x0100 /* RD2MO */
386#define WM8955_RD2MO_SHIFT 8 /* RD2MO */
387#define WM8955_RD2MO_WIDTH 1 /* RD2MO */
388#define WM8955_RI2MO 0x0080 /* RI2MO */
389#define WM8955_RI2MO_MASK 0x0080 /* RI2MO */
390#define WM8955_RI2MO_SHIFT 7 /* RI2MO */
391#define WM8955_RI2MO_WIDTH 1 /* RI2MO */
392#define WM8955_RI2MOVOL_MASK 0x0070 /* RI2MOVOL - [6:4] */
393#define WM8955_RI2MOVOL_SHIFT 4 /* RI2MOVOL - [6:4] */
394#define WM8955_RI2MOVOL_WIDTH 3 /* RI2MOVOL - [6:4] */
395
396/*
397 * R40 (0x28) - LOUT2 volume
398 */
399#define WM8955_LO2VU 0x0100 /* LO2VU */
400#define WM8955_LO2VU_MASK 0x0100 /* LO2VU */
401#define WM8955_LO2VU_SHIFT 8 /* LO2VU */
402#define WM8955_LO2VU_WIDTH 1 /* LO2VU */
403#define WM8955_LO2ZC 0x0080 /* LO2ZC */
404#define WM8955_LO2ZC_MASK 0x0080 /* LO2ZC */
405#define WM8955_LO2ZC_SHIFT 7 /* LO2ZC */
406#define WM8955_LO2ZC_WIDTH 1 /* LO2ZC */
407#define WM8955_LOUT2VOL_MASK 0x007F /* LOUT2VOL - [6:0] */
408#define WM8955_LOUT2VOL_SHIFT 0 /* LOUT2VOL - [6:0] */
409#define WM8955_LOUT2VOL_WIDTH 7 /* LOUT2VOL - [6:0] */
410
411/*
412 * R41 (0x29) - ROUT2 volume
413 */
414#define WM8955_RO2VU 0x0100 /* RO2VU */
415#define WM8955_RO2VU_MASK 0x0100 /* RO2VU */
416#define WM8955_RO2VU_SHIFT 8 /* RO2VU */
417#define WM8955_RO2VU_WIDTH 1 /* RO2VU */
418#define WM8955_RO2ZC 0x0080 /* RO2ZC */
419#define WM8955_RO2ZC_MASK 0x0080 /* RO2ZC */
420#define WM8955_RO2ZC_SHIFT 7 /* RO2ZC */
421#define WM8955_RO2ZC_WIDTH 1 /* RO2ZC */
422#define WM8955_ROUT2VOL_MASK 0x007F /* ROUT2VOL - [6:0] */
423#define WM8955_ROUT2VOL_SHIFT 0 /* ROUT2VOL - [6:0] */
424#define WM8955_ROUT2VOL_WIDTH 7 /* ROUT2VOL - [6:0] */
425
426/*
427 * R42 (0x2A) - MONOOUT volume
428 */
429#define WM8955_MOZC 0x0080 /* MOZC */
430#define WM8955_MOZC_MASK 0x0080 /* MOZC */
431#define WM8955_MOZC_SHIFT 7 /* MOZC */
432#define WM8955_MOZC_WIDTH 1 /* MOZC */
433#define WM8955_MOUTVOL_MASK 0x007F /* MOUTVOL - [6:0] */
434#define WM8955_MOUTVOL_SHIFT 0 /* MOUTVOL - [6:0] */
435#define WM8955_MOUTVOL_WIDTH 7 /* MOUTVOL - [6:0] */
436
437/*
438 * R43 (0x2B) - Clocking / PLL
439 */
440#define WM8955_MCLKSEL 0x0100 /* MCLKSEL */
441#define WM8955_MCLKSEL_MASK 0x0100 /* MCLKSEL */
442#define WM8955_MCLKSEL_SHIFT 8 /* MCLKSEL */
443#define WM8955_MCLKSEL_WIDTH 1 /* MCLKSEL */
444#define WM8955_PLLOUTDIV2 0x0020 /* PLLOUTDIV2 */
445#define WM8955_PLLOUTDIV2_MASK 0x0020 /* PLLOUTDIV2 */
446#define WM8955_PLLOUTDIV2_SHIFT 5 /* PLLOUTDIV2 */
447#define WM8955_PLLOUTDIV2_WIDTH 1 /* PLLOUTDIV2 */
448#define WM8955_PLL_RB 0x0010 /* PLL_RB */
449#define WM8955_PLL_RB_MASK 0x0010 /* PLL_RB */
450#define WM8955_PLL_RB_SHIFT 4 /* PLL_RB */
451#define WM8955_PLL_RB_WIDTH 1 /* PLL_RB */
452#define WM8955_PLLEN 0x0008 /* PLLEN */
453#define WM8955_PLLEN_MASK 0x0008 /* PLLEN */
454#define WM8955_PLLEN_SHIFT 3 /* PLLEN */
455#define WM8955_PLLEN_WIDTH 1 /* PLLEN */
456
457/*
458 * R44 (0x2C) - PLL Control 1
459 */
460#define WM8955_N_MASK 0x01E0 /* N - [8:5] */
461#define WM8955_N_SHIFT 5 /* N - [8:5] */
462#define WM8955_N_WIDTH 4 /* N - [8:5] */
463#define WM8955_K_21_18_MASK 0x000F /* K(21:18) - [3:0] */
464#define WM8955_K_21_18_SHIFT 0 /* K(21:18) - [3:0] */
465#define WM8955_K_21_18_WIDTH 4 /* K(21:18) - [3:0] */
466
467/*
468 * R45 (0x2D) - PLL Control 2
469 */
470#define WM8955_K_17_9_MASK 0x01FF /* K(17:9) - [8:0] */
471#define WM8955_K_17_9_SHIFT 0 /* K(17:9) - [8:0] */
472#define WM8955_K_17_9_WIDTH 9 /* K(17:9) - [8:0] */
473
474/*
475 * R46 (0x2E) - PLL Control 3
476 */
477#define WM8955_K_8_0_MASK 0x01FF /* K(8:0) - [8:0] */
478#define WM8955_K_8_0_SHIFT 0 /* K(8:0) - [8:0] */
479#define WM8955_K_8_0_WIDTH 9 /* K(8:0) - [8:0] */
480
481/*
482 * R59 (0x3B) - PLL Control 4
483 */
484#define WM8955_KEN 0x0080 /* KEN */
485#define WM8955_KEN_MASK 0x0080 /* KEN */
486#define WM8955_KEN_SHIFT 7 /* KEN */
487#define WM8955_KEN_WIDTH 1 /* KEN */
488
489#endif
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index a8007d58813f..d2342c5e0425 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1022,6 +1022,9 @@ static int wm8961_resume(struct platform_device *pdev)
1022 int i; 1022 int i;
1023 1023
1024 for (i = 0; i < codec->reg_cache_size; i++) { 1024 for (i = 0; i < codec->reg_cache_size; i++) {
1025 if (reg_cache[i] == wm8961_reg_defaults[i])
1026 continue;
1027
1025 if (i == WM8961_SOFTWARE_RESET) 1028 if (i == WM8961_SOFTWARE_RESET)
1026 continue; 1029 continue;
1027 1030
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 8812751da8c9..ee637af4737a 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -170,6 +170,10 @@ SOC_ENUM("Aux Mode", wm8974_auxmode),
170 170
171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0), 171SOC_SINGLE("Capture Boost(+20dB)", WM8974_ADCBOOST, 8, 1, 0),
172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1), 172SOC_SINGLE("Mono Playback Switch", WM8974_MONOMIX, 6, 1, 1),
173
174/* DAC / ADC oversampling */
175SOC_SINGLE("DAC 128x Oversampling Switch", WM8974_DAC, 8, 1, 0),
176SOC_SINGLE("ADC 128x Oversampling Switch", WM8974_ADC, 8, 1, 0),
173}; 177};
174 178
175/* Speaker Output Mixer */ 179/* Speaker Output Mixer */
@@ -381,14 +385,6 @@ static int wm8974_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
381 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f; 385 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x11f;
382 snd_soc_write(codec, WM8974_CLOCK, reg | div); 386 snd_soc_write(codec, WM8974_CLOCK, reg | div);
383 break; 387 break;
384 case WM8974_ADCCLK:
385 reg = snd_soc_read(codec, WM8974_ADC) & 0x1f7;
386 snd_soc_write(codec, WM8974_ADC, reg | div);
387 break;
388 case WM8974_DACCLK:
389 reg = snd_soc_read(codec, WM8974_DAC) & 0x1f7;
390 snd_soc_write(codec, WM8974_DAC, reg | div);
391 break;
392 case WM8974_BCLKDIV: 388 case WM8974_BCLKDIV:
393 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3; 389 reg = snd_soc_read(codec, WM8974_CLOCK) & 0x1e3;
394 snd_soc_write(codec, WM8974_CLOCK, reg | div); 390 snd_soc_write(codec, WM8974_CLOCK, reg | div);
diff --git a/sound/soc/codecs/wm8974.h b/sound/soc/codecs/wm8974.h
index 98de9562d4d2..896a7f0f3fc4 100644
--- a/sound/soc/codecs/wm8974.h
+++ b/sound/soc/codecs/wm8974.h
@@ -57,17 +57,7 @@
57/* Clock divider Id's */ 57/* Clock divider Id's */
58#define WM8974_OPCLKDIV 0 58#define WM8974_OPCLKDIV 0
59#define WM8974_MCLKDIV 1 59#define WM8974_MCLKDIV 1
60#define WM8974_ADCCLK 2 60#define WM8974_BCLKDIV 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 61
72/* PLL Out dividers */ 62/* PLL Out dividers */
73#define WM8974_OPCLKDIV_1 (0 << 4) 63#define WM8974_OPCLKDIV_1 (0 << 4)
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
new file mode 100644
index 000000000000..28bb59ea6ea1
--- /dev/null
+++ b/sound/soc/codecs/wm8978.c
@@ -0,0 +1,1149 @@
1/*
2 * wm8978.c -- WM8978 ALSA SoC Audio Codec driver
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2007 Carlos Munoz <carlos@kenati.com>
6 * Copyright 2006-2009 Wolfson Microelectronics PLC.
7 * Based on wm8974 and wm8990 by Liam Girdwood <lrg@slimlogic.co.uk>
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/kernel.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29#include <asm/div64.h>
30
31#include "wm8978.h"
32
33static struct snd_soc_codec *wm8978_codec;
34
35/* wm8978 register cache. Note that register 0 is not included in the cache. */
36static const u16 wm8978_reg[WM8978_CACHEREGNUM] = {
37 0x0000, 0x0000, 0x0000, 0x0000, /* 0x00...0x03 */
38 0x0050, 0x0000, 0x0140, 0x0000, /* 0x04...0x07 */
39 0x0000, 0x0000, 0x0000, 0x00ff, /* 0x08...0x0b */
40 0x00ff, 0x0000, 0x0100, 0x00ff, /* 0x0c...0x0f */
41 0x00ff, 0x0000, 0x012c, 0x002c, /* 0x10...0x13 */
42 0x002c, 0x002c, 0x002c, 0x0000, /* 0x14...0x17 */
43 0x0032, 0x0000, 0x0000, 0x0000, /* 0x18...0x1b */
44 0x0000, 0x0000, 0x0000, 0x0000, /* 0x1c...0x1f */
45 0x0038, 0x000b, 0x0032, 0x0000, /* 0x20...0x23 */
46 0x0008, 0x000c, 0x0093, 0x00e9, /* 0x24...0x27 */
47 0x0000, 0x0000, 0x0000, 0x0000, /* 0x28...0x2b */
48 0x0033, 0x0010, 0x0010, 0x0100, /* 0x2c...0x2f */
49 0x0100, 0x0002, 0x0001, 0x0001, /* 0x30...0x33 */
50 0x0039, 0x0039, 0x0039, 0x0039, /* 0x34...0x37 */
51 0x0001, 0x0001, /* 0x38...0x3b */
52};
53
54/* codec private data */
55struct wm8978_priv {
56 struct snd_soc_codec codec;
57 unsigned int f_pllout;
58 unsigned int f_mclk;
59 unsigned int f_256fs;
60 unsigned int f_opclk;
61 int mclk_idx;
62 enum wm8978_sysclk_src sysclk;
63 u16 reg_cache[WM8978_CACHEREGNUM];
64};
65
66static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
67static const char *wm8978_eqmode[] = {"Capture", "Playback"};
68static const char *wm8978_bw[] = {"Narrow", "Wide"};
69static const char *wm8978_eq1[] = {"80Hz", "105Hz", "135Hz", "175Hz"};
70static const char *wm8978_eq2[] = {"230Hz", "300Hz", "385Hz", "500Hz"};
71static const char *wm8978_eq3[] = {"650Hz", "850Hz", "1.1kHz", "1.4kHz"};
72static const char *wm8978_eq4[] = {"1.8kHz", "2.4kHz", "3.2kHz", "4.1kHz"};
73static const char *wm8978_eq5[] = {"5.3kHz", "6.9kHz", "9kHz", "11.7kHz"};
74static const char *wm8978_alc3[] = {"ALC", "Limiter"};
75static const char *wm8978_alc1[] = {"Off", "Right", "Left", "Both"};
76
77static const SOC_ENUM_SINGLE_DECL(adc_compand, WM8978_COMPANDING_CONTROL, 1,
78 wm8978_companding);
79static const SOC_ENUM_SINGLE_DECL(dac_compand, WM8978_COMPANDING_CONTROL, 3,
80 wm8978_companding);
81static const SOC_ENUM_SINGLE_DECL(eqmode, WM8978_EQ1, 8, wm8978_eqmode);
82static const SOC_ENUM_SINGLE_DECL(eq1, WM8978_EQ1, 5, wm8978_eq1);
83static const SOC_ENUM_SINGLE_DECL(eq2bw, WM8978_EQ2, 8, wm8978_bw);
84static const SOC_ENUM_SINGLE_DECL(eq2, WM8978_EQ2, 5, wm8978_eq2);
85static const SOC_ENUM_SINGLE_DECL(eq3bw, WM8978_EQ3, 8, wm8978_bw);
86static const SOC_ENUM_SINGLE_DECL(eq3, WM8978_EQ3, 5, wm8978_eq3);
87static const SOC_ENUM_SINGLE_DECL(eq4bw, WM8978_EQ4, 8, wm8978_bw);
88static const SOC_ENUM_SINGLE_DECL(eq4, WM8978_EQ4, 5, wm8978_eq4);
89static const SOC_ENUM_SINGLE_DECL(eq5, WM8978_EQ5, 5, wm8978_eq5);
90static const SOC_ENUM_SINGLE_DECL(alc3, WM8978_ALC_CONTROL_3, 8, wm8978_alc3);
91static const SOC_ENUM_SINGLE_DECL(alc1, WM8978_ALC_CONTROL_1, 7, wm8978_alc1);
92
93static const DECLARE_TLV_DB_SCALE(digital_tlv, -12750, 50, 1);
94static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
95static const DECLARE_TLV_DB_SCALE(inpga_tlv, -1200, 75, 0);
96static const DECLARE_TLV_DB_SCALE(spk_tlv, -5700, 100, 0);
97static const DECLARE_TLV_DB_SCALE(boost_tlv, -1500, 300, 1);
98
99static const struct snd_kcontrol_new wm8978_snd_controls[] = {
100
101 SOC_SINGLE("Digital Loopback Switch",
102 WM8978_COMPANDING_CONTROL, 0, 1, 0),
103
104 SOC_ENUM("ADC Companding", adc_compand),
105 SOC_ENUM("DAC Companding", dac_compand),
106
107 SOC_DOUBLE("DAC Inversion Switch", WM8978_DAC_CONTROL, 0, 1, 1, 0),
108
109 SOC_DOUBLE_R_TLV("PCM Volume",
110 WM8978_LEFT_DAC_DIGITAL_VOLUME, WM8978_RIGHT_DAC_DIGITAL_VOLUME,
111 0, 255, 0, digital_tlv),
112
113 SOC_SINGLE("High Pass Filter Switch", WM8978_ADC_CONTROL, 8, 1, 0),
114 SOC_SINGLE("High Pass Cut Off", WM8978_ADC_CONTROL, 4, 7, 0),
115 SOC_DOUBLE("ADC Inversion Switch", WM8978_ADC_CONTROL, 0, 1, 1, 0),
116
117 SOC_DOUBLE_R_TLV("ADC Volume",
118 WM8978_LEFT_ADC_DIGITAL_VOLUME, WM8978_RIGHT_ADC_DIGITAL_VOLUME,
119 0, 255, 0, digital_tlv),
120
121 SOC_ENUM("Equaliser Function", eqmode),
122 SOC_ENUM("EQ1 Cut Off", eq1),
123 SOC_SINGLE_TLV("EQ1 Volume", WM8978_EQ1, 0, 24, 1, eq_tlv),
124
125 SOC_ENUM("Equaliser EQ2 Bandwith", eq2bw),
126 SOC_ENUM("EQ2 Cut Off", eq2),
127 SOC_SINGLE_TLV("EQ2 Volume", WM8978_EQ2, 0, 24, 1, eq_tlv),
128
129 SOC_ENUM("Equaliser EQ3 Bandwith", eq3bw),
130 SOC_ENUM("EQ3 Cut Off", eq3),
131 SOC_SINGLE_TLV("EQ3 Volume", WM8978_EQ3, 0, 24, 1, eq_tlv),
132
133 SOC_ENUM("Equaliser EQ4 Bandwith", eq4bw),
134 SOC_ENUM("EQ4 Cut Off", eq4),
135 SOC_SINGLE_TLV("EQ4 Volume", WM8978_EQ4, 0, 24, 1, eq_tlv),
136
137 SOC_ENUM("EQ5 Cut Off", eq5),
138 SOC_SINGLE_TLV("EQ5 Volume", WM8978_EQ5, 0, 24, 1, eq_tlv),
139
140 SOC_SINGLE("DAC Playback Limiter Switch",
141 WM8978_DAC_LIMITER_1, 8, 1, 0),
142 SOC_SINGLE("DAC Playback Limiter Decay",
143 WM8978_DAC_LIMITER_1, 4, 15, 0),
144 SOC_SINGLE("DAC Playback Limiter Attack",
145 WM8978_DAC_LIMITER_1, 0, 15, 0),
146
147 SOC_SINGLE("DAC Playback Limiter Threshold",
148 WM8978_DAC_LIMITER_2, 4, 7, 0),
149 SOC_SINGLE("DAC Playback Limiter Boost",
150 WM8978_DAC_LIMITER_2, 0, 15, 0),
151
152 SOC_ENUM("ALC Enable Switch", alc1),
153 SOC_SINGLE("ALC Capture Min Gain", WM8978_ALC_CONTROL_1, 0, 7, 0),
154 SOC_SINGLE("ALC Capture Max Gain", WM8978_ALC_CONTROL_1, 3, 7, 0),
155
156 SOC_SINGLE("ALC Capture Hold", WM8978_ALC_CONTROL_2, 4, 7, 0),
157 SOC_SINGLE("ALC Capture Target", WM8978_ALC_CONTROL_2, 0, 15, 0),
158
159 SOC_ENUM("ALC Capture Mode", alc3),
160 SOC_SINGLE("ALC Capture Decay", WM8978_ALC_CONTROL_3, 4, 15, 0),
161 SOC_SINGLE("ALC Capture Attack", WM8978_ALC_CONTROL_3, 0, 15, 0),
162
163 SOC_SINGLE("ALC Capture Noise Gate Switch", WM8978_NOISE_GATE, 3, 1, 0),
164 SOC_SINGLE("ALC Capture Noise Gate Threshold",
165 WM8978_NOISE_GATE, 0, 7, 0),
166
167 SOC_DOUBLE_R("Capture PGA ZC Switch",
168 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
169 7, 1, 0),
170
171 /* OUT1 - Headphones */
172 SOC_DOUBLE_R("Headphone Playback ZC Switch",
173 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 7, 1, 0),
174
175 SOC_DOUBLE_R_TLV("Headphone Playback Volume",
176 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL,
177 0, 63, 0, spk_tlv),
178
179 /* OUT2 - Speakers */
180 SOC_DOUBLE_R("Speaker Playback ZC Switch",
181 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 7, 1, 0),
182
183 SOC_DOUBLE_R_TLV("Speaker Playback Volume",
184 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL,
185 0, 63, 0, spk_tlv),
186
187 /* OUT3/4 - Line Output */
188 SOC_DOUBLE_R("Line Playback Switch",
189 WM8978_OUT3_MIXER_CONTROL, WM8978_OUT4_MIXER_CONTROL, 6, 1, 1),
190
191 /* Mixer #3: Boost (Input) mixer */
192 SOC_DOUBLE_R("PGA Boost (+20dB)",
193 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
194 8, 1, 0),
195 SOC_DOUBLE_R_TLV("L2/R2 Boost Volume",
196 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
197 4, 7, 0, boost_tlv),
198 SOC_DOUBLE_R_TLV("Aux Boost Volume",
199 WM8978_LEFT_ADC_BOOST_CONTROL, WM8978_RIGHT_ADC_BOOST_CONTROL,
200 0, 7, 0, boost_tlv),
201
202 /* Input PGA volume */
203 SOC_DOUBLE_R_TLV("Input PGA Volume",
204 WM8978_LEFT_INP_PGA_CONTROL, WM8978_RIGHT_INP_PGA_CONTROL,
205 0, 63, 0, inpga_tlv),
206
207 /* Headphone */
208 SOC_DOUBLE_R("Headphone Switch",
209 WM8978_LOUT1_HP_CONTROL, WM8978_ROUT1_HP_CONTROL, 6, 1, 1),
210
211 /* Speaker */
212 SOC_DOUBLE_R("Speaker Switch",
213 WM8978_LOUT2_SPK_CONTROL, WM8978_ROUT2_SPK_CONTROL, 6, 1, 1),
214
215 /* DAC / ADC oversampling */
216 SOC_SINGLE("DAC 128x Oversampling Switch", WM8978_DAC_CONTROL, 8, 1, 0),
217 SOC_SINGLE("ADC 128x Oversampling Switch", WM8978_ADC_CONTROL, 8, 1, 0),
218};
219
220/* Mixer #1: Output (OUT1, OUT2) Mixer: mix AUX, Input mixer output and DAC */
221static const struct snd_kcontrol_new wm8978_left_out_mixer[] = {
222 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_LEFT_MIXER_CONTROL, 1, 1, 0),
223 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_LEFT_MIXER_CONTROL, 5, 1, 0),
224 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_LEFT_MIXER_CONTROL, 0, 1, 0),
225};
226
227static const struct snd_kcontrol_new wm8978_right_out_mixer[] = {
228 SOC_DAPM_SINGLE("Line Bypass Switch", WM8978_RIGHT_MIXER_CONTROL, 1, 1, 0),
229 SOC_DAPM_SINGLE("Aux Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 5, 1, 0),
230 SOC_DAPM_SINGLE("PCM Playback Switch", WM8978_RIGHT_MIXER_CONTROL, 0, 1, 0),
231};
232
233/* OUT3/OUT4 Mixer not implemented */
234
235/* Mixer #2: Input PGA Mute */
236static const struct snd_kcontrol_new wm8978_left_input_mixer[] = {
237 SOC_DAPM_SINGLE("L2 Switch", WM8978_INPUT_CONTROL, 2, 1, 0),
238 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 1, 1, 0),
239 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 0, 1, 0),
240};
241static const struct snd_kcontrol_new wm8978_right_input_mixer[] = {
242 SOC_DAPM_SINGLE("R2 Switch", WM8978_INPUT_CONTROL, 6, 1, 0),
243 SOC_DAPM_SINGLE("MicN Switch", WM8978_INPUT_CONTROL, 5, 1, 0),
244 SOC_DAPM_SINGLE("MicP Switch", WM8978_INPUT_CONTROL, 4, 1, 0),
245};
246
247static const struct snd_soc_dapm_widget wm8978_dapm_widgets[] = {
248 SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
249 WM8978_POWER_MANAGEMENT_3, 0, 0),
250 SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
251 WM8978_POWER_MANAGEMENT_3, 1, 0),
252 SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
253 WM8978_POWER_MANAGEMENT_2, 0, 0),
254 SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
255 WM8978_POWER_MANAGEMENT_2, 1, 0),
256
257 /* Mixer #1: OUT1,2 */
258 SOC_MIXER_ARRAY("Left Output Mixer", WM8978_POWER_MANAGEMENT_3,
259 2, 0, wm8978_left_out_mixer),
260 SOC_MIXER_ARRAY("Right Output Mixer", WM8978_POWER_MANAGEMENT_3,
261 3, 0, wm8978_right_out_mixer),
262
263 SOC_MIXER_ARRAY("Left Input Mixer", WM8978_POWER_MANAGEMENT_2,
264 2, 0, wm8978_left_input_mixer),
265 SOC_MIXER_ARRAY("Right Input Mixer", WM8978_POWER_MANAGEMENT_2,
266 3, 0, wm8978_right_input_mixer),
267
268 SND_SOC_DAPM_PGA("Left Boost Mixer", WM8978_POWER_MANAGEMENT_2,
269 4, 0, NULL, 0),
270 SND_SOC_DAPM_PGA("Right Boost Mixer", WM8978_POWER_MANAGEMENT_2,
271 5, 0, NULL, 0),
272
273 SND_SOC_DAPM_PGA("Left Capture PGA", WM8978_LEFT_INP_PGA_CONTROL,
274 6, 1, NULL, 0),
275 SND_SOC_DAPM_PGA("Right Capture PGA", WM8978_RIGHT_INP_PGA_CONTROL,
276 6, 1, NULL, 0),
277
278 SND_SOC_DAPM_PGA("Left Headphone Out", WM8978_POWER_MANAGEMENT_2,
279 7, 0, NULL, 0),
280 SND_SOC_DAPM_PGA("Right Headphone Out", WM8978_POWER_MANAGEMENT_2,
281 8, 0, NULL, 0),
282
283 SND_SOC_DAPM_PGA("Left Speaker Out", WM8978_POWER_MANAGEMENT_3,
284 6, 0, NULL, 0),
285 SND_SOC_DAPM_PGA("Right Speaker Out", WM8978_POWER_MANAGEMENT_3,
286 5, 0, NULL, 0),
287
288 SND_SOC_DAPM_MIXER("OUT4 VMID", WM8978_POWER_MANAGEMENT_3,
289 8, 0, NULL, 0),
290
291 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8978_POWER_MANAGEMENT_1, 4, 0),
292
293 SND_SOC_DAPM_INPUT("LMICN"),
294 SND_SOC_DAPM_INPUT("LMICP"),
295 SND_SOC_DAPM_INPUT("RMICN"),
296 SND_SOC_DAPM_INPUT("RMICP"),
297 SND_SOC_DAPM_INPUT("LAUX"),
298 SND_SOC_DAPM_INPUT("RAUX"),
299 SND_SOC_DAPM_INPUT("L2"),
300 SND_SOC_DAPM_INPUT("R2"),
301 SND_SOC_DAPM_OUTPUT("LHP"),
302 SND_SOC_DAPM_OUTPUT("RHP"),
303 SND_SOC_DAPM_OUTPUT("LSPK"),
304 SND_SOC_DAPM_OUTPUT("RSPK"),
305};
306
307static const struct snd_soc_dapm_route audio_map[] = {
308 /* Output mixer */
309 {"Right Output Mixer", "PCM Playback Switch", "Right DAC"},
310 {"Right Output Mixer", "Aux Playback Switch", "RAUX"},
311 {"Right Output Mixer", "Line Bypass Switch", "Right Boost Mixer"},
312
313 {"Left Output Mixer", "PCM Playback Switch", "Left DAC"},
314 {"Left Output Mixer", "Aux Playback Switch", "LAUX"},
315 {"Left Output Mixer", "Line Bypass Switch", "Left Boost Mixer"},
316
317 /* Outputs */
318 {"Right Headphone Out", NULL, "Right Output Mixer"},
319 {"RHP", NULL, "Right Headphone Out"},
320
321 {"Left Headphone Out", NULL, "Left Output Mixer"},
322 {"LHP", NULL, "Left Headphone Out"},
323
324 {"Right Speaker Out", NULL, "Right Output Mixer"},
325 {"RSPK", NULL, "Right Speaker Out"},
326
327 {"Left Speaker Out", NULL, "Left Output Mixer"},
328 {"LSPK", NULL, "Left Speaker Out"},
329
330 /* Boost Mixer */
331 {"Right ADC", NULL, "Right Boost Mixer"},
332
333 {"Right Boost Mixer", NULL, "RAUX"},
334 {"Right Boost Mixer", NULL, "Right Capture PGA"},
335 {"Right Boost Mixer", NULL, "R2"},
336
337 {"Left ADC", NULL, "Left Boost Mixer"},
338
339 {"Left Boost Mixer", NULL, "LAUX"},
340 {"Left Boost Mixer", NULL, "Left Capture PGA"},
341 {"Left Boost Mixer", NULL, "L2"},
342
343 /* Input PGA */
344 {"Right Capture PGA", NULL, "Right Input Mixer"},
345 {"Left Capture PGA", NULL, "Left Input Mixer"},
346
347 {"Right Input Mixer", "R2 Switch", "R2"},
348 {"Right Input Mixer", "MicN Switch", "RMICN"},
349 {"Right Input Mixer", "MicP Switch", "RMICP"},
350
351 {"Left Input Mixer", "L2 Switch", "L2"},
352 {"Left Input Mixer", "MicN Switch", "LMICN"},
353 {"Left Input Mixer", "MicP Switch", "LMICP"},
354};
355
356static int wm8978_add_widgets(struct snd_soc_codec *codec)
357{
358 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets,
359 ARRAY_SIZE(wm8978_dapm_widgets));
360
361 /* set up the WM8978 audio map */
362 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
363
364 return 0;
365}
366
367/* PLL divisors */
368struct wm8978_pll_div {
369 u32 k;
370 u8 n;
371 u8 div2;
372};
373
374#define FIXED_PLL_SIZE (1 << 24)
375
376static void pll_factors(struct wm8978_pll_div *pll_div, unsigned int target,
377 unsigned int source)
378{
379 u64 k_part;
380 unsigned int k, n_div, n_mod;
381
382 n_div = target / source;
383 if (n_div < 6) {
384 source >>= 1;
385 pll_div->div2 = 1;
386 n_div = target / source;
387 } else {
388 pll_div->div2 = 0;
389 }
390
391 if (n_div < 6 || n_div > 12)
392 dev_warn(wm8978_codec->dev,
393 "WM8978 N value exceeds recommended range! N = %u\n",
394 n_div);
395
396 pll_div->n = n_div;
397 n_mod = target - source * n_div;
398 k_part = FIXED_PLL_SIZE * (long long)n_mod + source / 2;
399
400 do_div(k_part, source);
401
402 k = k_part & 0xFFFFFFFF;
403
404 pll_div->k = k;
405}
406
407/* MCLK dividers */
408static const int mclk_numerator[] = {1, 3, 2, 3, 4, 6, 8, 12};
409static const int mclk_denominator[] = {1, 2, 1, 1, 1, 1, 1, 1};
410
411/*
412 * find index >= idx, such that, for a given f_out,
413 * 3 * f_mclk / 4 <= f_PLLOUT < 13 * f_mclk / 4
414 * f_out can be f_256fs or f_opclk, currently only used for f_256fs. Can be
415 * generalised for f_opclk with suitable coefficient arrays, but currently
416 * the OPCLK divisor is calculated directly, not iteratively.
417 */
418static int wm8978_enum_mclk(unsigned int f_out, unsigned int f_mclk,
419 unsigned int *f_pllout)
420{
421 int i;
422
423 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
424 unsigned int f_pllout_x4 = 4 * f_out * mclk_numerator[i] /
425 mclk_denominator[i];
426 if (3 * f_mclk <= f_pllout_x4 && f_pllout_x4 < 13 * f_mclk) {
427 *f_pllout = f_pllout_x4 / 4;
428 return i;
429 }
430 }
431
432 return -EINVAL;
433}
434
435/*
436 * Calculate internal frequencies and dividers, according to Figure 40
437 * "PLL and Clock Select Circuit" in WM8978 datasheet Rev. 2.6
438 */
439static int wm8978_configure_pll(struct snd_soc_codec *codec)
440{
441 struct wm8978_priv *wm8978 = codec->private_data;
442 struct wm8978_pll_div pll_div;
443 unsigned int f_opclk = wm8978->f_opclk, f_mclk = wm8978->f_mclk,
444 f_256fs = wm8978->f_256fs;
445 unsigned int f2;
446
447 if (!f_mclk)
448 return -EINVAL;
449
450 if (f_opclk) {
451 unsigned int opclk_div;
452 /* Cannot set up MCLK divider now, do later */
453 wm8978->mclk_idx = -1;
454
455 /*
456 * The user needs OPCLK. Choose OPCLKDIV to put
457 * 6 <= R = f2 / f1 < 13, 1 <= OPCLKDIV <= 4.
458 * f_opclk = f_mclk * prescale * R / 4 / OPCLKDIV, where
459 * prescale = 1, or prescale = 2. Prescale is calculated inside
460 * pll_factors(). We have to select f_PLLOUT, such that
461 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
462 * f_mclk * 3 / 16 <= f_opclk < f_mclk * 13 / 4.
463 */
464 if (16 * f_opclk < 3 * f_mclk || 4 * f_opclk >= 13 * f_mclk)
465 return -EINVAL;
466
467 if (4 * f_opclk < 3 * f_mclk)
468 /* Have to use OPCLKDIV */
469 opclk_div = (3 * f_mclk / 4 + f_opclk - 1) / f_opclk;
470 else
471 opclk_div = 1;
472
473 dev_dbg(codec->dev, "%s: OPCLKDIV=%d\n", __func__, opclk_div);
474
475 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 0x30,
476 (opclk_div - 1) << 4);
477
478 wm8978->f_pllout = f_opclk * opclk_div;
479 } else if (f_256fs) {
480 /*
481 * Not using OPCLK, but PLL is used for the codec, choose R:
482 * 6 <= R = f2 / f1 < 13, to put 1 <= MCLKDIV <= 12.
483 * f_256fs = f_mclk * prescale * R / 4 / MCLKDIV, where
484 * prescale = 1, or prescale = 2. Prescale is calculated inside
485 * pll_factors(). We have to select f_PLLOUT, such that
486 * f_mclk * 3 / 4 <= f_PLLOUT < f_mclk * 13 / 4. Must be
487 * f_mclk * 3 / 48 <= f_256fs < f_mclk * 13 / 4. This means MCLK
488 * must be 3.781MHz <= f_MCLK <= 32.768MHz
489 */
490 int idx = wm8978_enum_mclk(f_256fs, f_mclk, &wm8978->f_pllout);
491 if (idx < 0)
492 return idx;
493
494 wm8978->mclk_idx = idx;
495
496 /* GPIO1 into default mode as input - before configuring PLL */
497 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
498 } else {
499 return -EINVAL;
500 }
501
502 f2 = wm8978->f_pllout * 4;
503
504 dev_dbg(codec->dev, "%s: f_MCLK=%uHz, f_PLLOUT=%uHz\n", __func__,
505 wm8978->f_mclk, wm8978->f_pllout);
506
507 pll_factors(&pll_div, f2, wm8978->f_mclk);
508
509 dev_dbg(codec->dev, "%s: calculated PLL N=0x%x, K=0x%x, div2=%d\n",
510 __func__, pll_div.n, pll_div.k, pll_div.div2);
511
512 /* Turn PLL off for configuration... */
513 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
514
515 snd_soc_write(codec, WM8978_PLL_N, (pll_div.div2 << 4) | pll_div.n);
516 snd_soc_write(codec, WM8978_PLL_K1, pll_div.k >> 18);
517 snd_soc_write(codec, WM8978_PLL_K2, (pll_div.k >> 9) & 0x1ff);
518 snd_soc_write(codec, WM8978_PLL_K3, pll_div.k & 0x1ff);
519
520 /* ...and on again */
521 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
522
523 if (f_opclk)
524 /* Output PLL (OPCLK) to GPIO1 */
525 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 4);
526
527 return 0;
528}
529
530/*
531 * Configure WM8978 clock dividers.
532 */
533static int wm8978_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
534 int div_id, int div)
535{
536 struct snd_soc_codec *codec = codec_dai->codec;
537 struct wm8978_priv *wm8978 = codec->private_data;
538 int ret = 0;
539
540 switch (div_id) {
541 case WM8978_OPCLKRATE:
542 wm8978->f_opclk = div;
543
544 if (wm8978->f_mclk)
545 /*
546 * We know the MCLK frequency, the user has requested
547 * OPCLK, configure the PLL based on that and start it
548 * and OPCLK immediately. We will configure PLL to match
549 * user-requested OPCLK frquency as good as possible.
550 * In fact, it is likely, that matching the sampling
551 * rate, when it becomes known, is more important, and
552 * we will not be reconfiguring PLL then, because we
553 * must not interrupt OPCLK. But it should be fine,
554 * because typically the user will request OPCLK to run
555 * at 256fs or 512fs, and for these cases we will also
556 * find an exact MCLK divider configuration - it will
557 * be equal to or double the OPCLK divisor.
558 */
559 ret = wm8978_configure_pll(codec);
560 break;
561 case WM8978_BCLKDIV:
562 if (div & ~0x1c)
563 return -EINVAL;
564 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x1c, div);
565 break;
566 default:
567 return -EINVAL;
568 }
569
570 dev_dbg(codec->dev, "%s: ID %d, value %u\n", __func__, div_id, div);
571
572 return ret;
573}
574
575/*
576 * @freq: when .set_pll() us not used, freq is codec MCLK input frequency
577 */
578static int wm8978_set_dai_sysclk(struct snd_soc_dai *codec_dai, int clk_id,
579 unsigned int freq, int dir)
580{
581 struct snd_soc_codec *codec = codec_dai->codec;
582 struct wm8978_priv *wm8978 = codec->private_data;
583 int ret = 0;
584
585 dev_dbg(codec->dev, "%s: ID %d, freq %u\n", __func__, clk_id, freq);
586
587 if (freq) {
588 wm8978->f_mclk = freq;
589
590 /* Even if MCLK is used for system clock, might have to drive OPCLK */
591 if (wm8978->f_opclk)
592 ret = wm8978_configure_pll(codec);
593
594 /* Our sysclk is fixed to 256 * fs, will configure in .hw_params() */
595
596 if (!ret)
597 wm8978->sysclk = clk_id;
598 }
599
600 if (wm8978->sysclk == WM8978_PLL && (!freq || clk_id == WM8978_MCLK)) {
601 /* Clock CODEC directly from MCLK */
602 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
603
604 /* GPIO1 into default mode as input - before configuring PLL */
605 snd_soc_update_bits(codec, WM8978_GPIO_CONTROL, 7, 0);
606
607 /* Turn off PLL */
608 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0);
609 wm8978->sysclk = WM8978_MCLK;
610 wm8978->f_pllout = 0;
611 wm8978->f_opclk = 0;
612 }
613
614 return ret;
615}
616
617/*
618 * Set ADC and Voice DAC format.
619 */
620static int wm8978_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
621{
622 struct snd_soc_codec *codec = codec_dai->codec;
623 /*
624 * BCLK polarity mask = 0x100, LRC clock polarity mask = 0x80,
625 * Data Format mask = 0x18: all will be calculated anew
626 */
627 u16 iface = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x198;
628 u16 clk = snd_soc_read(codec, WM8978_CLOCKING);
629
630 dev_dbg(codec->dev, "%s\n", __func__);
631
632 /* set master/slave audio interface */
633 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
634 case SND_SOC_DAIFMT_CBM_CFM:
635 clk |= 1;
636 break;
637 case SND_SOC_DAIFMT_CBS_CFS:
638 clk &= ~1;
639 break;
640 default:
641 return -EINVAL;
642 }
643
644 /* interface format */
645 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
646 case SND_SOC_DAIFMT_I2S:
647 iface |= 0x10;
648 break;
649 case SND_SOC_DAIFMT_RIGHT_J:
650 break;
651 case SND_SOC_DAIFMT_LEFT_J:
652 iface |= 0x8;
653 break;
654 case SND_SOC_DAIFMT_DSP_A:
655 iface |= 0x18;
656 break;
657 default:
658 return -EINVAL;
659 }
660
661 /* clock inversion */
662 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
663 case SND_SOC_DAIFMT_NB_NF:
664 break;
665 case SND_SOC_DAIFMT_IB_IF:
666 iface |= 0x180;
667 break;
668 case SND_SOC_DAIFMT_IB_NF:
669 iface |= 0x100;
670 break;
671 case SND_SOC_DAIFMT_NB_IF:
672 iface |= 0x80;
673 break;
674 default:
675 return -EINVAL;
676 }
677
678 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface);
679 snd_soc_write(codec, WM8978_CLOCKING, clk);
680
681 return 0;
682}
683
684/*
685 * Set PCM DAI bit size and sample rate.
686 */
687static int wm8978_hw_params(struct snd_pcm_substream *substream,
688 struct snd_pcm_hw_params *params,
689 struct snd_soc_dai *dai)
690{
691 struct snd_soc_pcm_runtime *rtd = substream->private_data;
692 struct snd_soc_device *socdev = rtd->socdev;
693 struct snd_soc_codec *codec = socdev->card->codec;
694 struct wm8978_priv *wm8978 = codec->private_data;
695 /* Word length mask = 0x60 */
696 u16 iface_ctl = snd_soc_read(codec, WM8978_AUDIO_INTERFACE) & ~0x60;
697 /* Sampling rate mask = 0xe (for filters) */
698 u16 add_ctl = snd_soc_read(codec, WM8978_ADDITIONAL_CONTROL) & ~0xe;
699 u16 clking = snd_soc_read(codec, WM8978_CLOCKING);
700 enum wm8978_sysclk_src current_clk_id = clking & 0x100 ?
701 WM8978_PLL : WM8978_MCLK;
702 unsigned int f_sel, diff, diff_best = INT_MAX;
703 int i, best = 0;
704
705 if (!wm8978->f_mclk)
706 return -EINVAL;
707
708 /* bit size */
709 switch (params_format(params)) {
710 case SNDRV_PCM_FORMAT_S16_LE:
711 break;
712 case SNDRV_PCM_FORMAT_S20_3LE:
713 iface_ctl |= 0x20;
714 break;
715 case SNDRV_PCM_FORMAT_S24_LE:
716 iface_ctl |= 0x40;
717 break;
718 case SNDRV_PCM_FORMAT_S32_LE:
719 iface_ctl |= 0x60;
720 break;
721 }
722
723 /* filter coefficient */
724 switch (params_rate(params)) {
725 case 8000:
726 add_ctl |= 0x5 << 1;
727 break;
728 case 11025:
729 add_ctl |= 0x4 << 1;
730 break;
731 case 16000:
732 add_ctl |= 0x3 << 1;
733 break;
734 case 22050:
735 add_ctl |= 0x2 << 1;
736 break;
737 case 32000:
738 add_ctl |= 0x1 << 1;
739 break;
740 case 44100:
741 case 48000:
742 break;
743 }
744
745 /* Sampling rate is known now, can configure the MCLK divider */
746 wm8978->f_256fs = params_rate(params) * 256;
747
748 if (wm8978->sysclk == WM8978_MCLK) {
749 wm8978->mclk_idx = -1;
750 f_sel = wm8978->f_mclk;
751 } else {
752 if (!wm8978->f_pllout) {
753 /* We only enter here, if OPCLK is not used */
754 int ret = wm8978_configure_pll(codec);
755 if (ret < 0)
756 return ret;
757 }
758 f_sel = wm8978->f_pllout;
759 }
760
761 if (wm8978->mclk_idx < 0) {
762 /* Either MCLK is used directly, or OPCLK is used */
763 if (f_sel < wm8978->f_256fs || f_sel > 12 * wm8978->f_256fs)
764 return -EINVAL;
765
766 for (i = 0; i < ARRAY_SIZE(mclk_numerator); i++) {
767 diff = abs(wm8978->f_256fs * 3 -
768 f_sel * 3 * mclk_denominator[i] / mclk_numerator[i]);
769
770 if (diff < diff_best) {
771 diff_best = diff;
772 best = i;
773 }
774
775 if (!diff)
776 break;
777 }
778 } else {
779 /* OPCLK not used, codec driven by PLL */
780 best = wm8978->mclk_idx;
781 diff = 0;
782 }
783
784 if (diff)
785 dev_warn(codec->dev, "Imprecise sampling rate: %uHz%s\n",
786 f_sel * mclk_denominator[best] / mclk_numerator[best] / 256,
787 wm8978->sysclk == WM8978_MCLK ?
788 ", consider using PLL" : "");
789
790 dev_dbg(codec->dev, "%s: fmt %d, rate %u, MCLK divisor #%d\n", __func__,
791 params_format(params), params_rate(params), best);
792
793 /* MCLK divisor mask = 0xe0 */
794 snd_soc_update_bits(codec, WM8978_CLOCKING, 0xe0, best << 5);
795
796 snd_soc_write(codec, WM8978_AUDIO_INTERFACE, iface_ctl);
797 snd_soc_write(codec, WM8978_ADDITIONAL_CONTROL, add_ctl);
798
799 if (wm8978->sysclk != current_clk_id) {
800 if (wm8978->sysclk == WM8978_PLL)
801 /* Run CODEC from PLL instead of MCLK */
802 snd_soc_update_bits(codec, WM8978_CLOCKING,
803 0x100, 0x100);
804 else
805 /* Clock CODEC directly from MCLK */
806 snd_soc_update_bits(codec, WM8978_CLOCKING, 0x100, 0);
807 }
808
809 return 0;
810}
811
812static int wm8978_mute(struct snd_soc_dai *dai, int mute)
813{
814 struct snd_soc_codec *codec = dai->codec;
815
816 dev_dbg(codec->dev, "%s: %d\n", __func__, mute);
817
818 if (mute)
819 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0x40);
820 else
821 snd_soc_update_bits(codec, WM8978_DAC_CONTROL, 0x40, 0);
822
823 return 0;
824}
825
826static int wm8978_set_bias_level(struct snd_soc_codec *codec,
827 enum snd_soc_bias_level level)
828{
829 u16 power1 = snd_soc_read(codec, WM8978_POWER_MANAGEMENT_1) & ~3;
830
831 switch (level) {
832 case SND_SOC_BIAS_ON:
833 case SND_SOC_BIAS_PREPARE:
834 power1 |= 1; /* VMID 75k */
835 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
836 break;
837 case SND_SOC_BIAS_STANDBY:
838 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
839 power1 |= 0xc;
840
841 if (codec->bias_level == SND_SOC_BIAS_OFF) {
842 /* Initial cap charge at VMID 5k */
843 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
844 power1 | 0x3);
845 mdelay(100);
846 }
847
848 power1 |= 0x2; /* VMID 500k */
849 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1);
850 break;
851 case SND_SOC_BIAS_OFF:
852 /* Preserve PLL - OPCLK may be used by someone */
853 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, ~0x20, 0);
854 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_2, 0);
855 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_3, 0);
856 break;
857 }
858
859 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
860
861 codec->bias_level = level;
862 return 0;
863}
864
865#define WM8978_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
866 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
867
868static struct snd_soc_dai_ops wm8978_dai_ops = {
869 .hw_params = wm8978_hw_params,
870 .digital_mute = wm8978_mute,
871 .set_fmt = wm8978_set_dai_fmt,
872 .set_clkdiv = wm8978_set_dai_clkdiv,
873 .set_sysclk = wm8978_set_dai_sysclk,
874};
875
876/* Also supports 12kHz */
877struct snd_soc_dai wm8978_dai = {
878 .name = "WM8978 HiFi",
879 .id = 1,
880 .playback = {
881 .stream_name = "Playback",
882 .channels_min = 1,
883 .channels_max = 2,
884 .rates = SNDRV_PCM_RATE_8000_48000,
885 .formats = WM8978_FORMATS,
886 },
887 .capture = {
888 .stream_name = "Capture",
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = SNDRV_PCM_RATE_8000_48000,
892 .formats = WM8978_FORMATS,
893 },
894 .ops = &wm8978_dai_ops,
895};
896EXPORT_SYMBOL_GPL(wm8978_dai);
897
898static int wm8978_suspend(struct platform_device *pdev, pm_message_t state)
899{
900 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
901 struct snd_soc_codec *codec = socdev->card->codec;
902
903 wm8978_set_bias_level(codec, SND_SOC_BIAS_OFF);
904 /* Also switch PLL off */
905 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 0);
906
907 return 0;
908}
909
910static int wm8978_resume(struct platform_device *pdev)
911{
912 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
913 struct snd_soc_codec *codec = socdev->card->codec;
914 struct wm8978_priv *wm8978 = codec->private_data;
915 int i;
916 u16 *cache = codec->reg_cache;
917
918 /* Sync reg_cache with the hardware */
919 for (i = 0; i < ARRAY_SIZE(wm8978_reg); i++) {
920 if (i == WM8978_RESET)
921 continue;
922 if (cache[i] != wm8978_reg[i])
923 snd_soc_write(codec, i, cache[i]);
924 }
925
926 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
927
928 if (wm8978->f_pllout)
929 /* Switch PLL on */
930 snd_soc_update_bits(codec, WM8978_POWER_MANAGEMENT_1, 0x20, 0x20);
931
932 return 0;
933}
934
935static int wm8978_probe(struct platform_device *pdev)
936{
937 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
938 struct snd_soc_codec *codec;
939 int ret = 0;
940
941 if (wm8978_codec == NULL) {
942 dev_err(&pdev->dev, "Codec device not registered\n");
943 return -ENODEV;
944 }
945
946 socdev->card->codec = wm8978_codec;
947 codec = wm8978_codec;
948
949 /* register pcms */
950 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
951 if (ret < 0) {
952 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
953 goto pcm_err;
954 }
955
956 snd_soc_add_controls(codec, wm8978_snd_controls,
957 ARRAY_SIZE(wm8978_snd_controls));
958 wm8978_add_widgets(codec);
959
960pcm_err:
961 return ret;
962}
963
964/* power down chip */
965static int wm8978_remove(struct platform_device *pdev)
966{
967 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
968
969 snd_soc_free_pcms(socdev);
970 snd_soc_dapm_free(socdev);
971
972 return 0;
973}
974
975struct snd_soc_codec_device soc_codec_dev_wm8978 = {
976 .probe = wm8978_probe,
977 .remove = wm8978_remove,
978 .suspend = wm8978_suspend,
979 .resume = wm8978_resume,
980};
981EXPORT_SYMBOL_GPL(soc_codec_dev_wm8978);
982
983/*
984 * These registers contain an "update" bit - bit 8. This means, for example,
985 * that one can write new DAC digital volume for both channels, but only when
986 * the update bit is set, will also the volume be updated - simultaneously for
987 * both channels.
988 */
989static const int update_reg[] = {
990 WM8978_LEFT_DAC_DIGITAL_VOLUME,
991 WM8978_RIGHT_DAC_DIGITAL_VOLUME,
992 WM8978_LEFT_ADC_DIGITAL_VOLUME,
993 WM8978_RIGHT_ADC_DIGITAL_VOLUME,
994 WM8978_LEFT_INP_PGA_CONTROL,
995 WM8978_RIGHT_INP_PGA_CONTROL,
996 WM8978_LOUT1_HP_CONTROL,
997 WM8978_ROUT1_HP_CONTROL,
998 WM8978_LOUT2_SPK_CONTROL,
999 WM8978_ROUT2_SPK_CONTROL,
1000};
1001
1002static __devinit int wm8978_register(struct wm8978_priv *wm8978)
1003{
1004 int ret, i;
1005 struct snd_soc_codec *codec = &wm8978->codec;
1006
1007 if (wm8978_codec) {
1008 dev_err(codec->dev, "Another WM8978 is registered\n");
1009 return -EINVAL;
1010 }
1011
1012 /*
1013 * Set default system clock to PLL, it is more precise, this is also the
1014 * default hardware setting
1015 */
1016 wm8978->sysclk = WM8978_PLL;
1017
1018 mutex_init(&codec->mutex);
1019 INIT_LIST_HEAD(&codec->dapm_widgets);
1020 INIT_LIST_HEAD(&codec->dapm_paths);
1021
1022 codec->private_data = wm8978;
1023 codec->name = "WM8978";
1024 codec->owner = THIS_MODULE;
1025 codec->bias_level = SND_SOC_BIAS_OFF;
1026 codec->set_bias_level = wm8978_set_bias_level;
1027 codec->dai = &wm8978_dai;
1028 codec->num_dai = 1;
1029 codec->reg_cache_size = WM8978_CACHEREGNUM;
1030 codec->reg_cache = &wm8978->reg_cache;
1031
1032 ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C);
1033 if (ret < 0) {
1034 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1035 goto err;
1036 }
1037
1038 memcpy(codec->reg_cache, wm8978_reg, sizeof(wm8978_reg));
1039
1040 /*
1041 * Set the update bit in all registers, that have one. This way all
1042 * writes to those registers will also cause the update bit to be
1043 * written.
1044 */
1045 for (i = 0; i < ARRAY_SIZE(update_reg); i++)
1046 ((u16 *)codec->reg_cache)[update_reg[i]] |= 0x100;
1047
1048 /* Reset the codec */
1049 ret = snd_soc_write(codec, WM8978_RESET, 0);
1050 if (ret < 0) {
1051 dev_err(codec->dev, "Failed to issue reset\n");
1052 goto err;
1053 }
1054
1055 wm8978_dai.dev = codec->dev;
1056
1057 wm8978_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1058
1059 wm8978_codec = codec;
1060
1061 ret = snd_soc_register_codec(codec);
1062 if (ret != 0) {
1063 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1064 goto err;
1065 }
1066
1067 ret = snd_soc_register_dai(&wm8978_dai);
1068 if (ret != 0) {
1069 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1070 goto err_codec;
1071 }
1072
1073 return 0;
1074
1075err_codec:
1076 snd_soc_unregister_codec(codec);
1077err:
1078 kfree(wm8978);
1079 return ret;
1080}
1081
1082static __devexit void wm8978_unregister(struct wm8978_priv *wm8978)
1083{
1084 wm8978_set_bias_level(&wm8978->codec, SND_SOC_BIAS_OFF);
1085 snd_soc_unregister_dai(&wm8978_dai);
1086 snd_soc_unregister_codec(&wm8978->codec);
1087 kfree(wm8978);
1088 wm8978_codec = NULL;
1089}
1090
1091static __devinit int wm8978_i2c_probe(struct i2c_client *i2c,
1092 const struct i2c_device_id *id)
1093{
1094 struct wm8978_priv *wm8978;
1095 struct snd_soc_codec *codec;
1096
1097 wm8978 = kzalloc(sizeof(struct wm8978_priv), GFP_KERNEL);
1098 if (wm8978 == NULL)
1099 return -ENOMEM;
1100
1101 codec = &wm8978->codec;
1102 codec->hw_write = (hw_write_t)i2c_master_send;
1103
1104 i2c_set_clientdata(i2c, wm8978);
1105 codec->control_data = i2c;
1106
1107 codec->dev = &i2c->dev;
1108
1109 return wm8978_register(wm8978);
1110}
1111
1112static __devexit int wm8978_i2c_remove(struct i2c_client *client)
1113{
1114 struct wm8978_priv *wm8978 = i2c_get_clientdata(client);
1115 wm8978_unregister(wm8978);
1116 return 0;
1117}
1118
1119static const struct i2c_device_id wm8978_i2c_id[] = {
1120 { "wm8978", 0 },
1121 { }
1122};
1123MODULE_DEVICE_TABLE(i2c, wm8978_i2c_id);
1124
1125static struct i2c_driver wm8978_i2c_driver = {
1126 .driver = {
1127 .name = "WM8978",
1128 .owner = THIS_MODULE,
1129 },
1130 .probe = wm8978_i2c_probe,
1131 .remove = __devexit_p(wm8978_i2c_remove),
1132 .id_table = wm8978_i2c_id,
1133};
1134
1135static int __init wm8978_modinit(void)
1136{
1137 return i2c_add_driver(&wm8978_i2c_driver);
1138}
1139module_init(wm8978_modinit);
1140
1141static void __exit wm8978_exit(void)
1142{
1143 i2c_del_driver(&wm8978_i2c_driver);
1144}
1145module_exit(wm8978_exit);
1146
1147MODULE_DESCRIPTION("ASoC WM8978 codec driver");
1148MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
1149MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8978.h b/sound/soc/codecs/wm8978.h
new file mode 100644
index 000000000000..56ec83270917
--- /dev/null
+++ b/sound/soc/codecs/wm8978.h
@@ -0,0 +1,86 @@
1/*
2 * wm8978.h -- codec driver for WM8978
3 *
4 * Copyright 2009 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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 __WM8978_H__
12#define __WM8978_H__
13
14/*
15 * Register values.
16 */
17#define WM8978_RESET 0x00
18#define WM8978_POWER_MANAGEMENT_1 0x01
19#define WM8978_POWER_MANAGEMENT_2 0x02
20#define WM8978_POWER_MANAGEMENT_3 0x03
21#define WM8978_AUDIO_INTERFACE 0x04
22#define WM8978_COMPANDING_CONTROL 0x05
23#define WM8978_CLOCKING 0x06
24#define WM8978_ADDITIONAL_CONTROL 0x07
25#define WM8978_GPIO_CONTROL 0x08
26#define WM8978_JACK_DETECT_CONTROL_1 0x09
27#define WM8978_DAC_CONTROL 0x0A
28#define WM8978_LEFT_DAC_DIGITAL_VOLUME 0x0B
29#define WM8978_RIGHT_DAC_DIGITAL_VOLUME 0x0C
30#define WM8978_JACK_DETECT_CONTROL_2 0x0D
31#define WM8978_ADC_CONTROL 0x0E
32#define WM8978_LEFT_ADC_DIGITAL_VOLUME 0x0F
33#define WM8978_RIGHT_ADC_DIGITAL_VOLUME 0x10
34#define WM8978_EQ1 0x12
35#define WM8978_EQ2 0x13
36#define WM8978_EQ3 0x14
37#define WM8978_EQ4 0x15
38#define WM8978_EQ5 0x16
39#define WM8978_DAC_LIMITER_1 0x18
40#define WM8978_DAC_LIMITER_2 0x19
41#define WM8978_NOTCH_FILTER_1 0x1b
42#define WM8978_NOTCH_FILTER_2 0x1c
43#define WM8978_NOTCH_FILTER_3 0x1d
44#define WM8978_NOTCH_FILTER_4 0x1e
45#define WM8978_ALC_CONTROL_1 0x20
46#define WM8978_ALC_CONTROL_2 0x21
47#define WM8978_ALC_CONTROL_3 0x22
48#define WM8978_NOISE_GATE 0x23
49#define WM8978_PLL_N 0x24
50#define WM8978_PLL_K1 0x25
51#define WM8978_PLL_K2 0x26
52#define WM8978_PLL_K3 0x27
53#define WM8978_3D_CONTROL 0x29
54#define WM8978_BEEP_CONTROL 0x2b
55#define WM8978_INPUT_CONTROL 0x2c
56#define WM8978_LEFT_INP_PGA_CONTROL 0x2d
57#define WM8978_RIGHT_INP_PGA_CONTROL 0x2e
58#define WM8978_LEFT_ADC_BOOST_CONTROL 0x2f
59#define WM8978_RIGHT_ADC_BOOST_CONTROL 0x30
60#define WM8978_OUTPUT_CONTROL 0x31
61#define WM8978_LEFT_MIXER_CONTROL 0x32
62#define WM8978_RIGHT_MIXER_CONTROL 0x33
63#define WM8978_LOUT1_HP_CONTROL 0x34
64#define WM8978_ROUT1_HP_CONTROL 0x35
65#define WM8978_LOUT2_SPK_CONTROL 0x36
66#define WM8978_ROUT2_SPK_CONTROL 0x37
67#define WM8978_OUT3_MIXER_CONTROL 0x38
68#define WM8978_OUT4_MIXER_CONTROL 0x39
69
70#define WM8978_CACHEREGNUM 58
71
72/* Clock divider Id's */
73enum wm8978_clk_id {
74 WM8978_OPCLKRATE,
75 WM8978_BCLKDIV,
76};
77
78enum wm8978_sysclk_src {
79 WM8978_PLL,
80 WM8978_MCLK
81};
82
83extern struct snd_soc_dai wm8978_dai;
84extern struct snd_soc_codec_device soc_codec_dev_wm8978;
85
86#endif /* __WM8978_H__ */
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 341481e0e830..a54dc77b7f34 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -1319,10 +1319,6 @@ static int wm8990_suspend(struct platform_device *pdev, pm_message_t state)
1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1319 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1320 struct snd_soc_codec *codec = socdev->card->codec; 1320 struct snd_soc_codec *codec = socdev->card->codec;
1321 1321
1322 /* we only need to suspend if we are a valid card */
1323 if (!codec->card)
1324 return 0;
1325
1326 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF); 1322 wm8990_set_bias_level(codec, SND_SOC_BIAS_OFF);
1327 return 0; 1323 return 0;
1328} 1324}
@@ -1335,10 +1331,6 @@ static int wm8990_resume(struct platform_device *pdev)
1335 u8 data[2]; 1331 u8 data[2];
1336 u16 *cache = codec->reg_cache; 1332 u16 *cache = codec->reg_cache;
1337 1333
1338 /* we only need to resume if we are a valid card */
1339 if (!codec->card)
1340 return 0;
1341
1342 /* Sync reg_cache with the hardware */ 1334 /* Sync reg_cache with the hardware */
1343 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { 1335 for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) {
1344 if (i + 1 == WM8990_RESET) 1336 if (i + 1 == WM8990_RESET)
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 2981afae842c..bf022f68b84f 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009, 2010 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -16,6 +16,7 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/regulator/consumer.h>
19#include <linux/spi/spi.h> 20#include <linux/spi/spi.h>
20#include <sound/core.h> 21#include <sound/core.h>
21#include <sound/pcm.h> 22#include <sound/pcm.h>
@@ -29,6 +30,16 @@
29#include "wm8993.h" 30#include "wm8993.h"
30#include "wm_hubs.h" 31#include "wm_hubs.h"
31 32
33#define WM8993_NUM_SUPPLIES 6
34static const char *wm8993_supply_names[WM8993_NUM_SUPPLIES] = {
35 "DCVDD",
36 "DBVDD",
37 "AVDD1",
38 "AVDD2",
39 "CPVDD",
40 "SPKVDD",
41};
42
32static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = { 43static u16 wm8993_reg_defaults[WM8993_REGISTER_COUNT] = {
33 0x8993, /* R0 - Software Reset */ 44 0x8993, /* R0 - Software Reset */
34 0x0000, /* R1 - Power Management (1) */ 45 0x0000, /* R1 - Power Management (1) */
@@ -213,7 +224,9 @@ static struct {
213}; 224};
214 225
215struct wm8993_priv { 226struct wm8993_priv {
227 struct wm_hubs_data hubs_data;
216 u16 reg_cache[WM8993_REGISTER_COUNT]; 228 u16 reg_cache[WM8993_REGISTER_COUNT];
229 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
217 struct wm8993_platform_data pdata; 230 struct wm8993_platform_data pdata;
218 struct snd_soc_codec codec; 231 struct snd_soc_codec codec;
219 int master; 232 int master;
@@ -227,36 +240,9 @@ struct wm8993_priv {
227 int class_w_users; 240 int class_w_users;
228 unsigned int fll_fref; 241 unsigned int fll_fref;
229 unsigned int fll_fout; 242 unsigned int fll_fout;
243 int fll_src;
230}; 244};
231 245
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) 246static int wm8993_volatile(unsigned int reg)
261{ 247{
262 switch (reg) { 248 switch (reg) {
@@ -271,48 +257,6 @@ static int wm8993_volatile(unsigned int reg)
271 } 257 }
272} 258}
273 259
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 { 260struct _fll_div {
317 u16 fll_fratio; 261 u16 fll_fratio;
318 u16 fll_outdiv; 262 u16 fll_outdiv;
@@ -441,9 +385,9 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
441 wm8993->fll_fref = 0; 385 wm8993->fll_fref = 0;
442 wm8993->fll_fout = 0; 386 wm8993->fll_fout = 0;
443 387
444 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 388 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
445 reg1 &= ~WM8993_FLL_ENA; 389 reg1 &= ~WM8993_FLL_ENA;
446 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 390 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
447 391
448 return 0; 392 return 0;
449 } 393 }
@@ -452,7 +396,7 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
452 if (ret != 0) 396 if (ret != 0)
453 return ret; 397 return ret;
454 398
455 reg5 = wm8993_read(codec, WM8993_FLL_CONTROL_5); 399 reg5 = snd_soc_read(codec, WM8993_FLL_CONTROL_5);
456 reg5 &= ~WM8993_FLL_CLK_SRC_MASK; 400 reg5 &= ~WM8993_FLL_CLK_SRC_MASK;
457 401
458 switch (fll_id) { 402 switch (fll_id) {
@@ -474,38 +418,39 @@ static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
474 418
475 /* Any FLL configuration change requires that the FLL be 419 /* Any FLL configuration change requires that the FLL be
476 * disabled first. */ 420 * disabled first. */
477 reg1 = wm8993_read(codec, WM8993_FLL_CONTROL_1); 421 reg1 = snd_soc_read(codec, WM8993_FLL_CONTROL_1);
478 reg1 &= ~WM8993_FLL_ENA; 422 reg1 &= ~WM8993_FLL_ENA;
479 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 423 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
480 424
481 /* Apply the configuration */ 425 /* Apply the configuration */
482 if (fll_div.k) 426 if (fll_div.k)
483 reg1 |= WM8993_FLL_FRAC_MASK; 427 reg1 |= WM8993_FLL_FRAC_MASK;
484 else 428 else
485 reg1 &= ~WM8993_FLL_FRAC_MASK; 429 reg1 &= ~WM8993_FLL_FRAC_MASK;
486 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1); 430 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1);
487 431
488 wm8993_write(codec, WM8993_FLL_CONTROL_2, 432 snd_soc_write(codec, WM8993_FLL_CONTROL_2,
489 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) | 433 (fll_div.fll_outdiv << WM8993_FLL_OUTDIV_SHIFT) |
490 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT)); 434 (fll_div.fll_fratio << WM8993_FLL_FRATIO_SHIFT));
491 wm8993_write(codec, WM8993_FLL_CONTROL_3, fll_div.k); 435 snd_soc_write(codec, WM8993_FLL_CONTROL_3, fll_div.k);
492 436
493 reg4 = wm8993_read(codec, WM8993_FLL_CONTROL_4); 437 reg4 = snd_soc_read(codec, WM8993_FLL_CONTROL_4);
494 reg4 &= ~WM8993_FLL_N_MASK; 438 reg4 &= ~WM8993_FLL_N_MASK;
495 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT; 439 reg4 |= fll_div.n << WM8993_FLL_N_SHIFT;
496 wm8993_write(codec, WM8993_FLL_CONTROL_4, reg4); 440 snd_soc_write(codec, WM8993_FLL_CONTROL_4, reg4);
497 441
498 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK; 442 reg5 &= ~WM8993_FLL_CLK_REF_DIV_MASK;
499 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT; 443 reg5 |= fll_div.fll_clk_ref_div << WM8993_FLL_CLK_REF_DIV_SHIFT;
500 wm8993_write(codec, WM8993_FLL_CONTROL_5, reg5); 444 snd_soc_write(codec, WM8993_FLL_CONTROL_5, reg5);
501 445
502 /* Enable the FLL */ 446 /* Enable the FLL */
503 wm8993_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA); 447 snd_soc_write(codec, WM8993_FLL_CONTROL_1, reg1 | WM8993_FLL_ENA);
504 448
505 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); 449 dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout);
506 450
507 wm8993->fll_fref = Fref; 451 wm8993->fll_fref = Fref;
508 wm8993->fll_fout = Fout; 452 wm8993->fll_fout = Fout;
453 wm8993->fll_src = source;
509 454
510 return 0; 455 return 0;
511} 456}
@@ -520,7 +465,7 @@ static int configure_clock(struct snd_soc_codec *codec)
520 case WM8993_SYSCLK_MCLK: 465 case WM8993_SYSCLK_MCLK:
521 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 466 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate);
522 467
523 reg = wm8993_read(codec, WM8993_CLOCKING_2); 468 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
524 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC); 469 reg &= ~(WM8993_MCLK_DIV | WM8993_SYSCLK_SRC);
525 if (wm8993->mclk_rate > 13500000) { 470 if (wm8993->mclk_rate > 13500000) {
526 reg |= WM8993_MCLK_DIV; 471 reg |= WM8993_MCLK_DIV;
@@ -529,14 +474,14 @@ static int configure_clock(struct snd_soc_codec *codec)
529 reg &= ~WM8993_MCLK_DIV; 474 reg &= ~WM8993_MCLK_DIV;
530 wm8993->sysclk_rate = wm8993->mclk_rate; 475 wm8993->sysclk_rate = wm8993->mclk_rate;
531 } 476 }
532 wm8993_write(codec, WM8993_CLOCKING_2, reg); 477 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
533 break; 478 break;
534 479
535 case WM8993_SYSCLK_FLL: 480 case WM8993_SYSCLK_FLL:
536 dev_dbg(codec->dev, "Using %dHz FLL clock\n", 481 dev_dbg(codec->dev, "Using %dHz FLL clock\n",
537 wm8993->fll_fout); 482 wm8993->fll_fout);
538 483
539 reg = wm8993_read(codec, WM8993_CLOCKING_2); 484 reg = snd_soc_read(codec, WM8993_CLOCKING_2);
540 reg |= WM8993_SYSCLK_SRC; 485 reg |= WM8993_SYSCLK_SRC;
541 if (wm8993->fll_fout > 13500000) { 486 if (wm8993->fll_fout > 13500000) {
542 reg |= WM8993_MCLK_DIV; 487 reg |= WM8993_MCLK_DIV;
@@ -545,7 +490,7 @@ static int configure_clock(struct snd_soc_codec *codec)
545 reg &= ~WM8993_MCLK_DIV; 490 reg &= ~WM8993_MCLK_DIV;
546 wm8993->sysclk_rate = wm8993->fll_fout; 491 wm8993->sysclk_rate = wm8993->fll_fout;
547 } 492 }
548 wm8993_write(codec, WM8993_CLOCKING_2, reg); 493 snd_soc_write(codec, WM8993_CLOCKING_2, reg);
549 break; 494 break;
550 495
551 default: 496 default:
@@ -978,10 +923,33 @@ static const struct snd_soc_dapm_route routes[] = {
978 { "Right Headphone Mux", "DAC", "DACR" }, 923 { "Right Headphone Mux", "DAC", "DACR" },
979}; 924};
980 925
926static void wm8993_cache_restore(struct snd_soc_codec *codec)
927{
928 u16 *cache = codec->reg_cache;
929 int i;
930
931 if (!codec->cache_sync)
932 return;
933
934 /* Reenable hardware writes */
935 codec->cache_only = 0;
936
937 /* Restore the register settings */
938 for (i = 1; i < WM8993_MAX_REGISTER; i++) {
939 if (cache[i] == wm8993_reg_defaults[i])
940 continue;
941 snd_soc_write(codec, i, cache[i]);
942 }
943
944 /* We're in sync again */
945 codec->cache_sync = 0;
946}
947
981static int wm8993_set_bias_level(struct snd_soc_codec *codec, 948static int wm8993_set_bias_level(struct snd_soc_codec *codec,
982 enum snd_soc_bias_level level) 949 enum snd_soc_bias_level level)
983{ 950{
984 struct wm8993_priv *wm8993 = codec->private_data; 951 struct wm8993_priv *wm8993 = codec->private_data;
952 int ret;
985 953
986 switch (level) { 954 switch (level) {
987 case SND_SOC_BIAS_ON: 955 case SND_SOC_BIAS_ON:
@@ -995,6 +963,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
995 963
996 case SND_SOC_BIAS_STANDBY: 964 case SND_SOC_BIAS_STANDBY:
997 if (codec->bias_level == SND_SOC_BIAS_OFF) { 965 if (codec->bias_level == SND_SOC_BIAS_OFF) {
966 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
967 wm8993->supplies);
968 if (ret != 0)
969 return ret;
970
971 wm8993_cache_restore(codec);
972
973 /* Tune DC servo configuration */
974 snd_soc_write(codec, 0x44, 3);
975 snd_soc_write(codec, 0x56, 3);
976 snd_soc_write(codec, 0x44, 0);
977
998 /* Bring up VMID with fast soft start */ 978 /* Bring up VMID with fast soft start */
999 snd_soc_update_bits(codec, WM8993_ANTIPOP2, 979 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1000 WM8993_STARTUP_BIAS_ENA | 980 WM8993_STARTUP_BIAS_ENA |
@@ -1042,6 +1022,18 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1042 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 1022 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
1043 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1023 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1044 0); 1024 0);
1025
1026#ifdef CONFIG_REGULATOR
1027 /* Post 2.6.34 we will be able to get a callback when
1028 * the regulators are disabled which we can use but
1029 * for now just assume that the power will be cut if
1030 * the regulator API is in use.
1031 */
1032 codec->cache_sync = 1;
1033#endif
1034
1035 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies),
1036 wm8993->supplies);
1045 break; 1037 break;
1046 } 1038 }
1047 1039
@@ -1075,8 +1067,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1075{ 1067{
1076 struct snd_soc_codec *codec = dai->codec; 1068 struct snd_soc_codec *codec = dai->codec;
1077 struct wm8993_priv *wm8993 = codec->private_data; 1069 struct wm8993_priv *wm8993 = codec->private_data;
1078 unsigned int aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1070 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1079 unsigned int aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1071 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1080 1072
1081 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1073 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV |
1082 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1074 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK);
@@ -1159,8 +1151,8 @@ static int wm8993_set_dai_fmt(struct snd_soc_dai *dai,
1159 return -EINVAL; 1151 return -EINVAL;
1160 } 1152 }
1161 1153
1162 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1154 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1163 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1155 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1164 1156
1165 return 0; 1157 return 0;
1166} 1158}
@@ -1174,16 +1166,16 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1174 int ret, i, best, best_val, cur_val; 1166 int ret, i, best, best_val, cur_val;
1175 unsigned int clocking1, clocking3, aif1, aif4; 1167 unsigned int clocking1, clocking3, aif1, aif4;
1176 1168
1177 clocking1 = wm8993_read(codec, WM8993_CLOCKING_1); 1169 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1);
1178 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1170 clocking1 &= ~WM8993_BCLK_DIV_MASK;
1179 1171
1180 clocking3 = wm8993_read(codec, WM8993_CLOCKING_3); 1172 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3);
1181 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); 1173 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK);
1182 1174
1183 aif1 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_1); 1175 aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1);
1184 aif1 &= ~WM8993_AIF_WL_MASK; 1176 aif1 &= ~WM8993_AIF_WL_MASK;
1185 1177
1186 aif4 = wm8993_read(codec, WM8993_AUDIO_INTERFACE_4); 1178 aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4);
1187 aif4 &= ~WM8993_LRCLK_RATE_MASK; 1179 aif4 &= ~WM8993_LRCLK_RATE_MASK;
1188 1180
1189 /* What BCLK do we need? */ 1181 /* What BCLK do we need? */
@@ -1276,14 +1268,14 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1276 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs); 1268 dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm8993->bclk / wm8993->fs);
1277 aif4 |= wm8993->bclk / wm8993->fs; 1269 aif4 |= wm8993->bclk / wm8993->fs;
1278 1270
1279 wm8993_write(codec, WM8993_CLOCKING_1, clocking1); 1271 snd_soc_write(codec, WM8993_CLOCKING_1, clocking1);
1280 wm8993_write(codec, WM8993_CLOCKING_3, clocking3); 1272 snd_soc_write(codec, WM8993_CLOCKING_3, clocking3);
1281 wm8993_write(codec, WM8993_AUDIO_INTERFACE_1, aif1); 1273 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_1, aif1);
1282 wm8993_write(codec, WM8993_AUDIO_INTERFACE_4, aif4); 1274 snd_soc_write(codec, WM8993_AUDIO_INTERFACE_4, aif4);
1283 1275
1284 /* ReTune Mobile? */ 1276 /* ReTune Mobile? */
1285 if (wm8993->pdata.num_retune_configs) { 1277 if (wm8993->pdata.num_retune_configs) {
1286 u16 eq1 = wm8993_read(codec, WM8993_EQ1); 1278 u16 eq1 = snd_soc_read(codec, WM8993_EQ1);
1287 struct wm8993_retune_mobile_setting *s; 1279 struct wm8993_retune_mobile_setting *s;
1288 1280
1289 best = 0; 1281 best = 0;
@@ -1306,7 +1298,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1306 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0); 1298 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, 0);
1307 1299
1308 for (i = 1; i < ARRAY_SIZE(s->config); i++) 1300 for (i = 1; i < ARRAY_SIZE(s->config); i++)
1309 wm8993_write(codec, WM8993_EQ1 + i, s->config[i]); 1301 snd_soc_write(codec, WM8993_EQ1 + i, s->config[i]);
1310 1302
1311 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1); 1303 snd_soc_update_bits(codec, WM8993_EQ1, WM8993_EQ_ENA, eq1);
1312 } 1304 }
@@ -1319,14 +1311,14 @@ static int wm8993_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1319 struct snd_soc_codec *codec = codec_dai->codec; 1311 struct snd_soc_codec *codec = codec_dai->codec;
1320 unsigned int reg; 1312 unsigned int reg;
1321 1313
1322 reg = wm8993_read(codec, WM8993_DAC_CTRL); 1314 reg = snd_soc_read(codec, WM8993_DAC_CTRL);
1323 1315
1324 if (mute) 1316 if (mute)
1325 reg |= WM8993_DAC_MUTE; 1317 reg |= WM8993_DAC_MUTE;
1326 else 1318 else
1327 reg &= ~WM8993_DAC_MUTE; 1319 reg &= ~WM8993_DAC_MUTE;
1328 1320
1329 wm8993_write(codec, WM8993_DAC_CTRL, reg); 1321 snd_soc_write(codec, WM8993_DAC_CTRL, reg);
1330 1322
1331 return 0; 1323 return 0;
1332} 1324}
@@ -1480,9 +1472,66 @@ static int wm8993_remove(struct platform_device *pdev)
1480 return 0; 1472 return 0;
1481} 1473}
1482 1474
1475#ifdef CONFIG_PM
1476static int wm8993_suspend(struct platform_device *pdev, pm_message_t state)
1477{
1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1479 struct snd_soc_codec *codec = socdev->card->codec;
1480 struct wm8993_priv *wm8993 = codec->private_data;
1481 int fll_fout = wm8993->fll_fout;
1482 int fll_fref = wm8993->fll_fref;
1483 int ret;
1484
1485 /* Stop the FLL in an orderly fashion */
1486 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0);
1487 if (ret != 0) {
1488 dev_err(&pdev->dev, "Failed to stop FLL\n");
1489 return ret;
1490 }
1491
1492 wm8993->fll_fout = fll_fout;
1493 wm8993->fll_fref = fll_fref;
1494
1495 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1496
1497 return 0;
1498}
1499
1500static int wm8993_resume(struct platform_device *pdev)
1501{
1502 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1503 struct snd_soc_codec *codec = socdev->card->codec;
1504 struct wm8993_priv *wm8993 = codec->private_data;
1505 int ret;
1506
1507 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1508
1509 /* Restart the FLL? */
1510 if (wm8993->fll_fout) {
1511 int fll_fout = wm8993->fll_fout;
1512 int fll_fref = wm8993->fll_fref;
1513
1514 wm8993->fll_fref = 0;
1515 wm8993->fll_fout = 0;
1516
1517 ret = wm8993_set_fll(codec->dai, 0, wm8993->fll_src,
1518 fll_fref, fll_fout);
1519 if (ret != 0)
1520 dev_err(codec->dev, "Failed to restart FLL\n");
1521 }
1522
1523 return 0;
1524}
1525#else
1526#define wm8993_suspend NULL
1527#define wm8993_resume NULL
1528#endif
1529
1483struct snd_soc_codec_device soc_codec_dev_wm8993 = { 1530struct snd_soc_codec_device soc_codec_dev_wm8993 = {
1484 .probe = wm8993_probe, 1531 .probe = wm8993_probe,
1485 .remove = wm8993_remove, 1532 .remove = wm8993_remove,
1533 .suspend = wm8993_suspend,
1534 .resume = wm8993_resume,
1486}; 1535};
1487EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993); 1536EXPORT_SYMBOL_GPL(soc_codec_dev_wm8993);
1488 1537
@@ -1493,6 +1542,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1493 struct snd_soc_codec *codec; 1542 struct snd_soc_codec *codec;
1494 unsigned int val; 1543 unsigned int val;
1495 int ret; 1544 int ret;
1545 int i;
1496 1546
1497 if (wm8993_codec) { 1547 if (wm8993_codec) {
1498 dev_err(&i2c->dev, "A WM8993 is already registered\n"); 1548 dev_err(&i2c->dev, "A WM8993 is already registered\n");
@@ -1513,9 +1563,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1513 INIT_LIST_HEAD(&codec->dapm_paths); 1563 INIT_LIST_HEAD(&codec->dapm_paths);
1514 1564
1515 codec->name = "WM8993"; 1565 codec->name = "WM8993";
1516 codec->read = wm8993_read; 1566 codec->volatile_register = wm8993_volatile;
1517 codec->write = wm8993_write;
1518 codec->hw_write = (hw_write_t)i2c_master_send;
1519 codec->reg_cache = wm8993->reg_cache; 1567 codec->reg_cache = wm8993->reg_cache;
1520 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1568 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache);
1521 codec->bias_level = SND_SOC_BIAS_OFF; 1569 codec->bias_level = SND_SOC_BIAS_OFF;
@@ -1524,25 +1572,53 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1524 codec->num_dai = 1; 1572 codec->num_dai = 1;
1525 codec->private_data = wm8993; 1573 codec->private_data = wm8993;
1526 1574
1575 wm8993->hubs_data.hp_startup_mode = 1;
1576 wm8993->hubs_data.dcs_codes = -2;
1577
1527 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1578 memcpy(wm8993->reg_cache, wm8993_reg_defaults,
1528 sizeof(wm8993->reg_cache)); 1579 sizeof(wm8993->reg_cache));
1529 1580
1581 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
1582 if (ret != 0) {
1583 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1584 goto err;
1585 }
1586
1530 i2c_set_clientdata(i2c, wm8993); 1587 i2c_set_clientdata(i2c, wm8993);
1531 codec->control_data = i2c; 1588 codec->control_data = i2c;
1532 wm8993_codec = codec; 1589 wm8993_codec = codec;
1533 1590
1534 codec->dev = &i2c->dev; 1591 codec->dev = &i2c->dev;
1535 1592
1536 val = wm8993_read_hw(codec, WM8993_SOFTWARE_RESET); 1593 for (i = 0; i < ARRAY_SIZE(wm8993->supplies); i++)
1594 wm8993->supplies[i].supply = wm8993_supply_names[i];
1595
1596 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8993->supplies),
1597 wm8993->supplies);
1598 if (ret != 0) {
1599 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
1600 goto err;
1601 }
1602
1603 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
1604 wm8993->supplies);
1605 if (ret != 0) {
1606 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
1607 goto err_get;
1608 }
1609
1610 val = snd_soc_read(codec, WM8993_SOFTWARE_RESET);
1537 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) { 1611 if (val != wm8993_reg_defaults[WM8993_SOFTWARE_RESET]) {
1538 dev_err(codec->dev, "Invalid ID register value %x\n", val); 1612 dev_err(codec->dev, "Invalid ID register value %x\n", val);
1539 ret = -EINVAL; 1613 ret = -EINVAL;
1540 goto err; 1614 goto err_enable;
1541 } 1615 }
1542 1616
1543 ret = wm8993_write(codec, WM8993_SOFTWARE_RESET, 0xffff); 1617 ret = snd_soc_write(codec, WM8993_SOFTWARE_RESET, 0xffff);
1544 if (ret != 0) 1618 if (ret != 0)
1545 goto err; 1619 goto err_enable;
1620
1621 codec->cache_only = 1;
1546 1622
1547 /* By default we're using the output mixers */ 1623 /* By default we're using the output mixers */
1548 wm8993->class_w_users = 2; 1624 wm8993->class_w_users = 2;
@@ -1572,7 +1648,7 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 1648
1573 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1649 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1574 if (ret != 0) 1650 if (ret != 0)
1575 goto err; 1651 goto err_enable;
1576 1652
1577 wm8993_dai.dev = codec->dev; 1653 wm8993_dai.dev = codec->dev;
1578 1654
@@ -1586,6 +1662,10 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1586 1662
1587err_bias: 1663err_bias:
1588 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF); 1664 wm8993_set_bias_level(codec, SND_SOC_BIAS_OFF);
1665err_enable:
1666 regulator_bulk_disable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1667err_get:
1668 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1589err: 1669err:
1590 wm8993_codec = NULL; 1670 wm8993_codec = NULL;
1591 kfree(wm8993); 1671 kfree(wm8993);
@@ -1600,6 +1680,7 @@ static int wm8993_i2c_remove(struct i2c_client *client)
1600 snd_soc_unregister_dai(&wm8993_dai); 1680 snd_soc_unregister_dai(&wm8993_dai);
1601 1681
1602 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF); 1682 wm8993_set_bias_level(&wm8993->codec, SND_SOC_BIAS_OFF);
1683 regulator_bulk_free(ARRAY_SIZE(wm8993->supplies), wm8993->supplies);
1603 kfree(wm8993); 1684 kfree(wm8993);
1604 1685
1605 return 0; 1686 return 0;
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
new file mode 100644
index 000000000000..29f3771c33a4
--- /dev/null
+++ b/sound/soc/codecs/wm8994.c
@@ -0,0 +1,3867 @@
1/*
2 * wm8994.c -- WM8994 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 <linux/mfd/wm8994/core.h>
31#include <linux/mfd/wm8994/registers.h>
32#include <linux/mfd/wm8994/pdata.h>
33#include <linux/mfd/wm8994/gpio.h>
34
35#include "wm8994.h"
36#include "wm_hubs.h"
37
38static struct snd_soc_codec *wm8994_codec;
39struct snd_soc_codec_device soc_codec_dev_wm8994;
40
41struct fll_config {
42 int src;
43 int in;
44 int out;
45};
46
47#define WM8994_NUM_DRC 3
48#define WM8994_NUM_EQ 3
49
50static int wm8994_drc_base[] = {
51 WM8994_AIF1_DRC1_1,
52 WM8994_AIF1_DRC2_1,
53 WM8994_AIF2_DRC_1,
54};
55
56static int wm8994_retune_mobile_base[] = {
57 WM8994_AIF1_DAC1_EQ_GAINS_1,
58 WM8994_AIF1_DAC2_EQ_GAINS_1,
59 WM8994_AIF2_EQ_GAINS_1,
60};
61
62#define WM8994_REG_CACHE_SIZE 0x621
63
64/* codec private data */
65struct wm8994_priv {
66 struct wm_hubs_data hubs;
67 struct snd_soc_codec codec;
68 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
69 int sysclk[2];
70 int sysclk_rate[2];
71 int mclk[2];
72 int aifclk[2];
73 struct fll_config fll[2], fll_suspend[2];
74
75 int dac_rates[2];
76 int lrclk_shared[2];
77
78 /* Platform dependant DRC configuration */
79 const char **drc_texts;
80 int drc_cfg[WM8994_NUM_DRC];
81 struct soc_enum drc_enum;
82
83 /* Platform dependant ReTune mobile configuration */
84 int num_retune_mobile_texts;
85 const char **retune_mobile_texts;
86 int retune_mobile_cfg[WM8994_NUM_EQ];
87 struct soc_enum retune_mobile_enum;
88
89 struct wm8994_pdata *pdata;
90};
91
92static struct {
93 unsigned short readable; /* Mask of readable bits */
94 unsigned short writable; /* Mask of writable bits */
95 unsigned short vol; /* Mask of volatile bits */
96} access_masks[] = {
97 { 0xFFFF, 0xFFFF, 0x0000 }, /* R0 - Software Reset */
98 { 0x3B37, 0x3B37, 0x0000 }, /* R1 - Power Management (1) */
99 { 0x6BF0, 0x6BF0, 0x0000 }, /* R2 - Power Management (2) */
100 { 0x3FF0, 0x3FF0, 0x0000 }, /* R3 - Power Management (3) */
101 { 0x3F3F, 0x3F3F, 0x0000 }, /* R4 - Power Management (4) */
102 { 0x3F0F, 0x3F0F, 0x0000 }, /* R5 - Power Management (5) */
103 { 0x003F, 0x003F, 0x0000 }, /* R6 - Power Management (6) */
104 { 0x0000, 0x0000, 0x0000 }, /* R7 */
105 { 0x0000, 0x0000, 0x0000 }, /* R8 */
106 { 0x0000, 0x0000, 0x0000 }, /* R9 */
107 { 0x0000, 0x0000, 0x0000 }, /* R10 */
108 { 0x0000, 0x0000, 0x0000 }, /* R11 */
109 { 0x0000, 0x0000, 0x0000 }, /* R12 */
110 { 0x0000, 0x0000, 0x0000 }, /* R13 */
111 { 0x0000, 0x0000, 0x0000 }, /* R14 */
112 { 0x0000, 0x0000, 0x0000 }, /* R15 */
113 { 0x0000, 0x0000, 0x0000 }, /* R16 */
114 { 0x0000, 0x0000, 0x0000 }, /* R17 */
115 { 0x0000, 0x0000, 0x0000 }, /* R18 */
116 { 0x0000, 0x0000, 0x0000 }, /* R19 */
117 { 0x0000, 0x0000, 0x0000 }, /* R20 */
118 { 0x01C0, 0x01C0, 0x0000 }, /* R21 - Input Mixer (1) */
119 { 0x0000, 0x0000, 0x0000 }, /* R22 */
120 { 0x0000, 0x0000, 0x0000 }, /* R23 */
121 { 0x00DF, 0x01DF, 0x0000 }, /* R24 - Left Line Input 1&2 Volume */
122 { 0x00DF, 0x01DF, 0x0000 }, /* R25 - Left Line Input 3&4 Volume */
123 { 0x00DF, 0x01DF, 0x0000 }, /* R26 - Right Line Input 1&2 Volume */
124 { 0x00DF, 0x01DF, 0x0000 }, /* R27 - Right Line Input 3&4 Volume */
125 { 0x00FF, 0x01FF, 0x0000 }, /* R28 - Left Output Volume */
126 { 0x00FF, 0x01FF, 0x0000 }, /* R29 - Right Output Volume */
127 { 0x0077, 0x0077, 0x0000 }, /* R30 - Line Outputs Volume */
128 { 0x0030, 0x0030, 0x0000 }, /* R31 - HPOUT2 Volume */
129 { 0x00FF, 0x01FF, 0x0000 }, /* R32 - Left OPGA Volume */
130 { 0x00FF, 0x01FF, 0x0000 }, /* R33 - Right OPGA Volume */
131 { 0x007F, 0x007F, 0x0000 }, /* R34 - SPKMIXL Attenuation */
132 { 0x017F, 0x017F, 0x0000 }, /* R35 - SPKMIXR Attenuation */
133 { 0x003F, 0x003F, 0x0000 }, /* R36 - SPKOUT Mixers */
134 { 0x003F, 0x003F, 0x0000 }, /* R37 - ClassD */
135 { 0x00FF, 0x01FF, 0x0000 }, /* R38 - Speaker Volume Left */
136 { 0x00FF, 0x01FF, 0x0000 }, /* R39 - Speaker Volume Right */
137 { 0x00FF, 0x00FF, 0x0000 }, /* R40 - Input Mixer (2) */
138 { 0x01B7, 0x01B7, 0x0000 }, /* R41 - Input Mixer (3) */
139 { 0x01B7, 0x01B7, 0x0000 }, /* R42 - Input Mixer (4) */
140 { 0x01C7, 0x01C7, 0x0000 }, /* R43 - Input Mixer (5) */
141 { 0x01C7, 0x01C7, 0x0000 }, /* R44 - Input Mixer (6) */
142 { 0x01FF, 0x01FF, 0x0000 }, /* R45 - Output Mixer (1) */
143 { 0x01FF, 0x01FF, 0x0000 }, /* R46 - Output Mixer (2) */
144 { 0x0FFF, 0x0FFF, 0x0000 }, /* R47 - Output Mixer (3) */
145 { 0x0FFF, 0x0FFF, 0x0000 }, /* R48 - Output Mixer (4) */
146 { 0x0FFF, 0x0FFF, 0x0000 }, /* R49 - Output Mixer (5) */
147 { 0x0FFF, 0x0FFF, 0x0000 }, /* R50 - Output Mixer (6) */
148 { 0x0038, 0x0038, 0x0000 }, /* R51 - HPOUT2 Mixer */
149 { 0x0077, 0x0077, 0x0000 }, /* R52 - Line Mixer (1) */
150 { 0x0077, 0x0077, 0x0000 }, /* R53 - Line Mixer (2) */
151 { 0x03FF, 0x03FF, 0x0000 }, /* R54 - Speaker Mixer */
152 { 0x00C1, 0x00C1, 0x0000 }, /* R55 - Additional Control */
153 { 0x00F0, 0x00F0, 0x0000 }, /* R56 - AntiPOP (1) */
154 { 0x01EF, 0x01EF, 0x0000 }, /* R57 - AntiPOP (2) */
155 { 0x00FF, 0x00FF, 0x0000 }, /* R58 - MICBIAS */
156 { 0x000F, 0x000F, 0x0000 }, /* R59 - LDO 1 */
157 { 0x0007, 0x0007, 0x0000 }, /* R60 - LDO 2 */
158 { 0x0000, 0x0000, 0x0000 }, /* R61 */
159 { 0x0000, 0x0000, 0x0000 }, /* R62 */
160 { 0x0000, 0x0000, 0x0000 }, /* R63 */
161 { 0x0000, 0x0000, 0x0000 }, /* R64 */
162 { 0x0000, 0x0000, 0x0000 }, /* R65 */
163 { 0x0000, 0x0000, 0x0000 }, /* R66 */
164 { 0x0000, 0x0000, 0x0000 }, /* R67 */
165 { 0x0000, 0x0000, 0x0000 }, /* R68 */
166 { 0x0000, 0x0000, 0x0000 }, /* R69 */
167 { 0x0000, 0x0000, 0x0000 }, /* R70 */
168 { 0x0000, 0x0000, 0x0000 }, /* R71 */
169 { 0x0000, 0x0000, 0x0000 }, /* R72 */
170 { 0x0000, 0x0000, 0x0000 }, /* R73 */
171 { 0x0000, 0x0000, 0x0000 }, /* R74 */
172 { 0x0000, 0x0000, 0x0000 }, /* R75 */
173 { 0x8000, 0x8000, 0x0000 }, /* R76 - Charge Pump (1) */
174 { 0x0000, 0x0000, 0x0000 }, /* R77 */
175 { 0x0000, 0x0000, 0x0000 }, /* R78 */
176 { 0x0000, 0x0000, 0x0000 }, /* R79 */
177 { 0x0000, 0x0000, 0x0000 }, /* R80 */
178 { 0x0301, 0x0301, 0x0000 }, /* R81 - Class W (1) */
179 { 0x0000, 0x0000, 0x0000 }, /* R82 */
180 { 0x0000, 0x0000, 0x0000 }, /* R83 */
181 { 0x333F, 0x333F, 0x0000 }, /* R84 - DC Servo (1) */
182 { 0x0FEF, 0x0FEF, 0x0000 }, /* R85 - DC Servo (2) */
183 { 0x0000, 0x0000, 0x0000 }, /* R86 */
184 { 0xFFFF, 0xFFFF, 0x0000 }, /* R87 - DC Servo (4) */
185 { 0x0333, 0x0000, 0x0000 }, /* R88 - DC Servo Readback */
186 { 0x0000, 0x0000, 0x0000 }, /* R89 */
187 { 0x0000, 0x0000, 0x0000 }, /* R90 */
188 { 0x0000, 0x0000, 0x0000 }, /* R91 */
189 { 0x0000, 0x0000, 0x0000 }, /* R92 */
190 { 0x0000, 0x0000, 0x0000 }, /* R93 */
191 { 0x0000, 0x0000, 0x0000 }, /* R94 */
192 { 0x0000, 0x0000, 0x0000 }, /* R95 */
193 { 0x00EE, 0x00EE, 0x0000 }, /* R96 - Analogue HP (1) */
194 { 0x0000, 0x0000, 0x0000 }, /* R97 */
195 { 0x0000, 0x0000, 0x0000 }, /* R98 */
196 { 0x0000, 0x0000, 0x0000 }, /* R99 */
197 { 0x0000, 0x0000, 0x0000 }, /* R100 */
198 { 0x0000, 0x0000, 0x0000 }, /* R101 */
199 { 0x0000, 0x0000, 0x0000 }, /* R102 */
200 { 0x0000, 0x0000, 0x0000 }, /* R103 */
201 { 0x0000, 0x0000, 0x0000 }, /* R104 */
202 { 0x0000, 0x0000, 0x0000 }, /* R105 */
203 { 0x0000, 0x0000, 0x0000 }, /* R106 */
204 { 0x0000, 0x0000, 0x0000 }, /* R107 */
205 { 0x0000, 0x0000, 0x0000 }, /* R108 */
206 { 0x0000, 0x0000, 0x0000 }, /* R109 */
207 { 0x0000, 0x0000, 0x0000 }, /* R110 */
208 { 0x0000, 0x0000, 0x0000 }, /* R111 */
209 { 0x0000, 0x0000, 0x0000 }, /* R112 */
210 { 0x0000, 0x0000, 0x0000 }, /* R113 */
211 { 0x0000, 0x0000, 0x0000 }, /* R114 */
212 { 0x0000, 0x0000, 0x0000 }, /* R115 */
213 { 0x0000, 0x0000, 0x0000 }, /* R116 */
214 { 0x0000, 0x0000, 0x0000 }, /* R117 */
215 { 0x0000, 0x0000, 0x0000 }, /* R118 */
216 { 0x0000, 0x0000, 0x0000 }, /* R119 */
217 { 0x0000, 0x0000, 0x0000 }, /* R120 */
218 { 0x0000, 0x0000, 0x0000 }, /* R121 */
219 { 0x0000, 0x0000, 0x0000 }, /* R122 */
220 { 0x0000, 0x0000, 0x0000 }, /* R123 */
221 { 0x0000, 0x0000, 0x0000 }, /* R124 */
222 { 0x0000, 0x0000, 0x0000 }, /* R125 */
223 { 0x0000, 0x0000, 0x0000 }, /* R126 */
224 { 0x0000, 0x0000, 0x0000 }, /* R127 */
225 { 0x0000, 0x0000, 0x0000 }, /* R128 */
226 { 0x0000, 0x0000, 0x0000 }, /* R129 */
227 { 0x0000, 0x0000, 0x0000 }, /* R130 */
228 { 0x0000, 0x0000, 0x0000 }, /* R131 */
229 { 0x0000, 0x0000, 0x0000 }, /* R132 */
230 { 0x0000, 0x0000, 0x0000 }, /* R133 */
231 { 0x0000, 0x0000, 0x0000 }, /* R134 */
232 { 0x0000, 0x0000, 0x0000 }, /* R135 */
233 { 0x0000, 0x0000, 0x0000 }, /* R136 */
234 { 0x0000, 0x0000, 0x0000 }, /* R137 */
235 { 0x0000, 0x0000, 0x0000 }, /* R138 */
236 { 0x0000, 0x0000, 0x0000 }, /* R139 */
237 { 0x0000, 0x0000, 0x0000 }, /* R140 */
238 { 0x0000, 0x0000, 0x0000 }, /* R141 */
239 { 0x0000, 0x0000, 0x0000 }, /* R142 */
240 { 0x0000, 0x0000, 0x0000 }, /* R143 */
241 { 0x0000, 0x0000, 0x0000 }, /* R144 */
242 { 0x0000, 0x0000, 0x0000 }, /* R145 */
243 { 0x0000, 0x0000, 0x0000 }, /* R146 */
244 { 0x0000, 0x0000, 0x0000 }, /* R147 */
245 { 0x0000, 0x0000, 0x0000 }, /* R148 */
246 { 0x0000, 0x0000, 0x0000 }, /* R149 */
247 { 0x0000, 0x0000, 0x0000 }, /* R150 */
248 { 0x0000, 0x0000, 0x0000 }, /* R151 */
249 { 0x0000, 0x0000, 0x0000 }, /* R152 */
250 { 0x0000, 0x0000, 0x0000 }, /* R153 */
251 { 0x0000, 0x0000, 0x0000 }, /* R154 */
252 { 0x0000, 0x0000, 0x0000 }, /* R155 */
253 { 0x0000, 0x0000, 0x0000 }, /* R156 */
254 { 0x0000, 0x0000, 0x0000 }, /* R157 */
255 { 0x0000, 0x0000, 0x0000 }, /* R158 */
256 { 0x0000, 0x0000, 0x0000 }, /* R159 */
257 { 0x0000, 0x0000, 0x0000 }, /* R160 */
258 { 0x0000, 0x0000, 0x0000 }, /* R161 */
259 { 0x0000, 0x0000, 0x0000 }, /* R162 */
260 { 0x0000, 0x0000, 0x0000 }, /* R163 */
261 { 0x0000, 0x0000, 0x0000 }, /* R164 */
262 { 0x0000, 0x0000, 0x0000 }, /* R165 */
263 { 0x0000, 0x0000, 0x0000 }, /* R166 */
264 { 0x0000, 0x0000, 0x0000 }, /* R167 */
265 { 0x0000, 0x0000, 0x0000 }, /* R168 */
266 { 0x0000, 0x0000, 0x0000 }, /* R169 */
267 { 0x0000, 0x0000, 0x0000 }, /* R170 */
268 { 0x0000, 0x0000, 0x0000 }, /* R171 */
269 { 0x0000, 0x0000, 0x0000 }, /* R172 */
270 { 0x0000, 0x0000, 0x0000 }, /* R173 */
271 { 0x0000, 0x0000, 0x0000 }, /* R174 */
272 { 0x0000, 0x0000, 0x0000 }, /* R175 */
273 { 0x0000, 0x0000, 0x0000 }, /* R176 */
274 { 0x0000, 0x0000, 0x0000 }, /* R177 */
275 { 0x0000, 0x0000, 0x0000 }, /* R178 */
276 { 0x0000, 0x0000, 0x0000 }, /* R179 */
277 { 0x0000, 0x0000, 0x0000 }, /* R180 */
278 { 0x0000, 0x0000, 0x0000 }, /* R181 */
279 { 0x0000, 0x0000, 0x0000 }, /* R182 */
280 { 0x0000, 0x0000, 0x0000 }, /* R183 */
281 { 0x0000, 0x0000, 0x0000 }, /* R184 */
282 { 0x0000, 0x0000, 0x0000 }, /* R185 */
283 { 0x0000, 0x0000, 0x0000 }, /* R186 */
284 { 0x0000, 0x0000, 0x0000 }, /* R187 */
285 { 0x0000, 0x0000, 0x0000 }, /* R188 */
286 { 0x0000, 0x0000, 0x0000 }, /* R189 */
287 { 0x0000, 0x0000, 0x0000 }, /* R190 */
288 { 0x0000, 0x0000, 0x0000 }, /* R191 */
289 { 0x0000, 0x0000, 0x0000 }, /* R192 */
290 { 0x0000, 0x0000, 0x0000 }, /* R193 */
291 { 0x0000, 0x0000, 0x0000 }, /* R194 */
292 { 0x0000, 0x0000, 0x0000 }, /* R195 */
293 { 0x0000, 0x0000, 0x0000 }, /* R196 */
294 { 0x0000, 0x0000, 0x0000 }, /* R197 */
295 { 0x0000, 0x0000, 0x0000 }, /* R198 */
296 { 0x0000, 0x0000, 0x0000 }, /* R199 */
297 { 0x0000, 0x0000, 0x0000 }, /* R200 */
298 { 0x0000, 0x0000, 0x0000 }, /* R201 */
299 { 0x0000, 0x0000, 0x0000 }, /* R202 */
300 { 0x0000, 0x0000, 0x0000 }, /* R203 */
301 { 0x0000, 0x0000, 0x0000 }, /* R204 */
302 { 0x0000, 0x0000, 0x0000 }, /* R205 */
303 { 0x0000, 0x0000, 0x0000 }, /* R206 */
304 { 0x0000, 0x0000, 0x0000 }, /* R207 */
305 { 0x0000, 0x0000, 0x0000 }, /* R208 */
306 { 0x0000, 0x0000, 0x0000 }, /* R209 */
307 { 0x0000, 0x0000, 0x0000 }, /* R210 */
308 { 0x0000, 0x0000, 0x0000 }, /* R211 */
309 { 0x0000, 0x0000, 0x0000 }, /* R212 */
310 { 0x0000, 0x0000, 0x0000 }, /* R213 */
311 { 0x0000, 0x0000, 0x0000 }, /* R214 */
312 { 0x0000, 0x0000, 0x0000 }, /* R215 */
313 { 0x0000, 0x0000, 0x0000 }, /* R216 */
314 { 0x0000, 0x0000, 0x0000 }, /* R217 */
315 { 0x0000, 0x0000, 0x0000 }, /* R218 */
316 { 0x0000, 0x0000, 0x0000 }, /* R219 */
317 { 0x0000, 0x0000, 0x0000 }, /* R220 */
318 { 0x0000, 0x0000, 0x0000 }, /* R221 */
319 { 0x0000, 0x0000, 0x0000 }, /* R222 */
320 { 0x0000, 0x0000, 0x0000 }, /* R223 */
321 { 0x0000, 0x0000, 0x0000 }, /* R224 */
322 { 0x0000, 0x0000, 0x0000 }, /* R225 */
323 { 0x0000, 0x0000, 0x0000 }, /* R226 */
324 { 0x0000, 0x0000, 0x0000 }, /* R227 */
325 { 0x0000, 0x0000, 0x0000 }, /* R228 */
326 { 0x0000, 0x0000, 0x0000 }, /* R229 */
327 { 0x0000, 0x0000, 0x0000 }, /* R230 */
328 { 0x0000, 0x0000, 0x0000 }, /* R231 */
329 { 0x0000, 0x0000, 0x0000 }, /* R232 */
330 { 0x0000, 0x0000, 0x0000 }, /* R233 */
331 { 0x0000, 0x0000, 0x0000 }, /* R234 */
332 { 0x0000, 0x0000, 0x0000 }, /* R235 */
333 { 0x0000, 0x0000, 0x0000 }, /* R236 */
334 { 0x0000, 0x0000, 0x0000 }, /* R237 */
335 { 0x0000, 0x0000, 0x0000 }, /* R238 */
336 { 0x0000, 0x0000, 0x0000 }, /* R239 */
337 { 0x0000, 0x0000, 0x0000 }, /* R240 */
338 { 0x0000, 0x0000, 0x0000 }, /* R241 */
339 { 0x0000, 0x0000, 0x0000 }, /* R242 */
340 { 0x0000, 0x0000, 0x0000 }, /* R243 */
341 { 0x0000, 0x0000, 0x0000 }, /* R244 */
342 { 0x0000, 0x0000, 0x0000 }, /* R245 */
343 { 0x0000, 0x0000, 0x0000 }, /* R246 */
344 { 0x0000, 0x0000, 0x0000 }, /* R247 */
345 { 0x0000, 0x0000, 0x0000 }, /* R248 */
346 { 0x0000, 0x0000, 0x0000 }, /* R249 */
347 { 0x0000, 0x0000, 0x0000 }, /* R250 */
348 { 0x0000, 0x0000, 0x0000 }, /* R251 */
349 { 0x0000, 0x0000, 0x0000 }, /* R252 */
350 { 0x0000, 0x0000, 0x0000 }, /* R253 */
351 { 0x0000, 0x0000, 0x0000 }, /* R254 */
352 { 0x0000, 0x0000, 0x0000 }, /* R255 */
353 { 0x000F, 0x0000, 0x0000 }, /* R256 - Chip Revision */
354 { 0x0074, 0x0074, 0x0000 }, /* R257 - Control Interface */
355 { 0x0000, 0x0000, 0x0000 }, /* R258 */
356 { 0x0000, 0x0000, 0x0000 }, /* R259 */
357 { 0x0000, 0x0000, 0x0000 }, /* R260 */
358 { 0x0000, 0x0000, 0x0000 }, /* R261 */
359 { 0x0000, 0x0000, 0x0000 }, /* R262 */
360 { 0x0000, 0x0000, 0x0000 }, /* R263 */
361 { 0x0000, 0x0000, 0x0000 }, /* R264 */
362 { 0x0000, 0x0000, 0x0000 }, /* R265 */
363 { 0x0000, 0x0000, 0x0000 }, /* R266 */
364 { 0x0000, 0x0000, 0x0000 }, /* R267 */
365 { 0x0000, 0x0000, 0x0000 }, /* R268 */
366 { 0x0000, 0x0000, 0x0000 }, /* R269 */
367 { 0x0000, 0x0000, 0x0000 }, /* R270 */
368 { 0x0000, 0x0000, 0x0000 }, /* R271 */
369 { 0x807F, 0x837F, 0x0000 }, /* R272 - Write Sequencer Ctrl (1) */
370 { 0x017F, 0x0000, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
371 { 0x0000, 0x0000, 0x0000 }, /* R274 */
372 { 0x0000, 0x0000, 0x0000 }, /* R275 */
373 { 0x0000, 0x0000, 0x0000 }, /* R276 */
374 { 0x0000, 0x0000, 0x0000 }, /* R277 */
375 { 0x0000, 0x0000, 0x0000 }, /* R278 */
376 { 0x0000, 0x0000, 0x0000 }, /* R279 */
377 { 0x0000, 0x0000, 0x0000 }, /* R280 */
378 { 0x0000, 0x0000, 0x0000 }, /* R281 */
379 { 0x0000, 0x0000, 0x0000 }, /* R282 */
380 { 0x0000, 0x0000, 0x0000 }, /* R283 */
381 { 0x0000, 0x0000, 0x0000 }, /* R284 */
382 { 0x0000, 0x0000, 0x0000 }, /* R285 */
383 { 0x0000, 0x0000, 0x0000 }, /* R286 */
384 { 0x0000, 0x0000, 0x0000 }, /* R287 */
385 { 0x0000, 0x0000, 0x0000 }, /* R288 */
386 { 0x0000, 0x0000, 0x0000 }, /* R289 */
387 { 0x0000, 0x0000, 0x0000 }, /* R290 */
388 { 0x0000, 0x0000, 0x0000 }, /* R291 */
389 { 0x0000, 0x0000, 0x0000 }, /* R292 */
390 { 0x0000, 0x0000, 0x0000 }, /* R293 */
391 { 0x0000, 0x0000, 0x0000 }, /* R294 */
392 { 0x0000, 0x0000, 0x0000 }, /* R295 */
393 { 0x0000, 0x0000, 0x0000 }, /* R296 */
394 { 0x0000, 0x0000, 0x0000 }, /* R297 */
395 { 0x0000, 0x0000, 0x0000 }, /* R298 */
396 { 0x0000, 0x0000, 0x0000 }, /* R299 */
397 { 0x0000, 0x0000, 0x0000 }, /* R300 */
398 { 0x0000, 0x0000, 0x0000 }, /* R301 */
399 { 0x0000, 0x0000, 0x0000 }, /* R302 */
400 { 0x0000, 0x0000, 0x0000 }, /* R303 */
401 { 0x0000, 0x0000, 0x0000 }, /* R304 */
402 { 0x0000, 0x0000, 0x0000 }, /* R305 */
403 { 0x0000, 0x0000, 0x0000 }, /* R306 */
404 { 0x0000, 0x0000, 0x0000 }, /* R307 */
405 { 0x0000, 0x0000, 0x0000 }, /* R308 */
406 { 0x0000, 0x0000, 0x0000 }, /* R309 */
407 { 0x0000, 0x0000, 0x0000 }, /* R310 */
408 { 0x0000, 0x0000, 0x0000 }, /* R311 */
409 { 0x0000, 0x0000, 0x0000 }, /* R312 */
410 { 0x0000, 0x0000, 0x0000 }, /* R313 */
411 { 0x0000, 0x0000, 0x0000 }, /* R314 */
412 { 0x0000, 0x0000, 0x0000 }, /* R315 */
413 { 0x0000, 0x0000, 0x0000 }, /* R316 */
414 { 0x0000, 0x0000, 0x0000 }, /* R317 */
415 { 0x0000, 0x0000, 0x0000 }, /* R318 */
416 { 0x0000, 0x0000, 0x0000 }, /* R319 */
417 { 0x0000, 0x0000, 0x0000 }, /* R320 */
418 { 0x0000, 0x0000, 0x0000 }, /* R321 */
419 { 0x0000, 0x0000, 0x0000 }, /* R322 */
420 { 0x0000, 0x0000, 0x0000 }, /* R323 */
421 { 0x0000, 0x0000, 0x0000 }, /* R324 */
422 { 0x0000, 0x0000, 0x0000 }, /* R325 */
423 { 0x0000, 0x0000, 0x0000 }, /* R326 */
424 { 0x0000, 0x0000, 0x0000 }, /* R327 */
425 { 0x0000, 0x0000, 0x0000 }, /* R328 */
426 { 0x0000, 0x0000, 0x0000 }, /* R329 */
427 { 0x0000, 0x0000, 0x0000 }, /* R330 */
428 { 0x0000, 0x0000, 0x0000 }, /* R331 */
429 { 0x0000, 0x0000, 0x0000 }, /* R332 */
430 { 0x0000, 0x0000, 0x0000 }, /* R333 */
431 { 0x0000, 0x0000, 0x0000 }, /* R334 */
432 { 0x0000, 0x0000, 0x0000 }, /* R335 */
433 { 0x0000, 0x0000, 0x0000 }, /* R336 */
434 { 0x0000, 0x0000, 0x0000 }, /* R337 */
435 { 0x0000, 0x0000, 0x0000 }, /* R338 */
436 { 0x0000, 0x0000, 0x0000 }, /* R339 */
437 { 0x0000, 0x0000, 0x0000 }, /* R340 */
438 { 0x0000, 0x0000, 0x0000 }, /* R341 */
439 { 0x0000, 0x0000, 0x0000 }, /* R342 */
440 { 0x0000, 0x0000, 0x0000 }, /* R343 */
441 { 0x0000, 0x0000, 0x0000 }, /* R344 */
442 { 0x0000, 0x0000, 0x0000 }, /* R345 */
443 { 0x0000, 0x0000, 0x0000 }, /* R346 */
444 { 0x0000, 0x0000, 0x0000 }, /* R347 */
445 { 0x0000, 0x0000, 0x0000 }, /* R348 */
446 { 0x0000, 0x0000, 0x0000 }, /* R349 */
447 { 0x0000, 0x0000, 0x0000 }, /* R350 */
448 { 0x0000, 0x0000, 0x0000 }, /* R351 */
449 { 0x0000, 0x0000, 0x0000 }, /* R352 */
450 { 0x0000, 0x0000, 0x0000 }, /* R353 */
451 { 0x0000, 0x0000, 0x0000 }, /* R354 */
452 { 0x0000, 0x0000, 0x0000 }, /* R355 */
453 { 0x0000, 0x0000, 0x0000 }, /* R356 */
454 { 0x0000, 0x0000, 0x0000 }, /* R357 */
455 { 0x0000, 0x0000, 0x0000 }, /* R358 */
456 { 0x0000, 0x0000, 0x0000 }, /* R359 */
457 { 0x0000, 0x0000, 0x0000 }, /* R360 */
458 { 0x0000, 0x0000, 0x0000 }, /* R361 */
459 { 0x0000, 0x0000, 0x0000 }, /* R362 */
460 { 0x0000, 0x0000, 0x0000 }, /* R363 */
461 { 0x0000, 0x0000, 0x0000 }, /* R364 */
462 { 0x0000, 0x0000, 0x0000 }, /* R365 */
463 { 0x0000, 0x0000, 0x0000 }, /* R366 */
464 { 0x0000, 0x0000, 0x0000 }, /* R367 */
465 { 0x0000, 0x0000, 0x0000 }, /* R368 */
466 { 0x0000, 0x0000, 0x0000 }, /* R369 */
467 { 0x0000, 0x0000, 0x0000 }, /* R370 */
468 { 0x0000, 0x0000, 0x0000 }, /* R371 */
469 { 0x0000, 0x0000, 0x0000 }, /* R372 */
470 { 0x0000, 0x0000, 0x0000 }, /* R373 */
471 { 0x0000, 0x0000, 0x0000 }, /* R374 */
472 { 0x0000, 0x0000, 0x0000 }, /* R375 */
473 { 0x0000, 0x0000, 0x0000 }, /* R376 */
474 { 0x0000, 0x0000, 0x0000 }, /* R377 */
475 { 0x0000, 0x0000, 0x0000 }, /* R378 */
476 { 0x0000, 0x0000, 0x0000 }, /* R379 */
477 { 0x0000, 0x0000, 0x0000 }, /* R380 */
478 { 0x0000, 0x0000, 0x0000 }, /* R381 */
479 { 0x0000, 0x0000, 0x0000 }, /* R382 */
480 { 0x0000, 0x0000, 0x0000 }, /* R383 */
481 { 0x0000, 0x0000, 0x0000 }, /* R384 */
482 { 0x0000, 0x0000, 0x0000 }, /* R385 */
483 { 0x0000, 0x0000, 0x0000 }, /* R386 */
484 { 0x0000, 0x0000, 0x0000 }, /* R387 */
485 { 0x0000, 0x0000, 0x0000 }, /* R388 */
486 { 0x0000, 0x0000, 0x0000 }, /* R389 */
487 { 0x0000, 0x0000, 0x0000 }, /* R390 */
488 { 0x0000, 0x0000, 0x0000 }, /* R391 */
489 { 0x0000, 0x0000, 0x0000 }, /* R392 */
490 { 0x0000, 0x0000, 0x0000 }, /* R393 */
491 { 0x0000, 0x0000, 0x0000 }, /* R394 */
492 { 0x0000, 0x0000, 0x0000 }, /* R395 */
493 { 0x0000, 0x0000, 0x0000 }, /* R396 */
494 { 0x0000, 0x0000, 0x0000 }, /* R397 */
495 { 0x0000, 0x0000, 0x0000 }, /* R398 */
496 { 0x0000, 0x0000, 0x0000 }, /* R399 */
497 { 0x0000, 0x0000, 0x0000 }, /* R400 */
498 { 0x0000, 0x0000, 0x0000 }, /* R401 */
499 { 0x0000, 0x0000, 0x0000 }, /* R402 */
500 { 0x0000, 0x0000, 0x0000 }, /* R403 */
501 { 0x0000, 0x0000, 0x0000 }, /* R404 */
502 { 0x0000, 0x0000, 0x0000 }, /* R405 */
503 { 0x0000, 0x0000, 0x0000 }, /* R406 */
504 { 0x0000, 0x0000, 0x0000 }, /* R407 */
505 { 0x0000, 0x0000, 0x0000 }, /* R408 */
506 { 0x0000, 0x0000, 0x0000 }, /* R409 */
507 { 0x0000, 0x0000, 0x0000 }, /* R410 */
508 { 0x0000, 0x0000, 0x0000 }, /* R411 */
509 { 0x0000, 0x0000, 0x0000 }, /* R412 */
510 { 0x0000, 0x0000, 0x0000 }, /* R413 */
511 { 0x0000, 0x0000, 0x0000 }, /* R414 */
512 { 0x0000, 0x0000, 0x0000 }, /* R415 */
513 { 0x0000, 0x0000, 0x0000 }, /* R416 */
514 { 0x0000, 0x0000, 0x0000 }, /* R417 */
515 { 0x0000, 0x0000, 0x0000 }, /* R418 */
516 { 0x0000, 0x0000, 0x0000 }, /* R419 */
517 { 0x0000, 0x0000, 0x0000 }, /* R420 */
518 { 0x0000, 0x0000, 0x0000 }, /* R421 */
519 { 0x0000, 0x0000, 0x0000 }, /* R422 */
520 { 0x0000, 0x0000, 0x0000 }, /* R423 */
521 { 0x0000, 0x0000, 0x0000 }, /* R424 */
522 { 0x0000, 0x0000, 0x0000 }, /* R425 */
523 { 0x0000, 0x0000, 0x0000 }, /* R426 */
524 { 0x0000, 0x0000, 0x0000 }, /* R427 */
525 { 0x0000, 0x0000, 0x0000 }, /* R428 */
526 { 0x0000, 0x0000, 0x0000 }, /* R429 */
527 { 0x0000, 0x0000, 0x0000 }, /* R430 */
528 { 0x0000, 0x0000, 0x0000 }, /* R431 */
529 { 0x0000, 0x0000, 0x0000 }, /* R432 */
530 { 0x0000, 0x0000, 0x0000 }, /* R433 */
531 { 0x0000, 0x0000, 0x0000 }, /* R434 */
532 { 0x0000, 0x0000, 0x0000 }, /* R435 */
533 { 0x0000, 0x0000, 0x0000 }, /* R436 */
534 { 0x0000, 0x0000, 0x0000 }, /* R437 */
535 { 0x0000, 0x0000, 0x0000 }, /* R438 */
536 { 0x0000, 0x0000, 0x0000 }, /* R439 */
537 { 0x0000, 0x0000, 0x0000 }, /* R440 */
538 { 0x0000, 0x0000, 0x0000 }, /* R441 */
539 { 0x0000, 0x0000, 0x0000 }, /* R442 */
540 { 0x0000, 0x0000, 0x0000 }, /* R443 */
541 { 0x0000, 0x0000, 0x0000 }, /* R444 */
542 { 0x0000, 0x0000, 0x0000 }, /* R445 */
543 { 0x0000, 0x0000, 0x0000 }, /* R446 */
544 { 0x0000, 0x0000, 0x0000 }, /* R447 */
545 { 0x0000, 0x0000, 0x0000 }, /* R448 */
546 { 0x0000, 0x0000, 0x0000 }, /* R449 */
547 { 0x0000, 0x0000, 0x0000 }, /* R450 */
548 { 0x0000, 0x0000, 0x0000 }, /* R451 */
549 { 0x0000, 0x0000, 0x0000 }, /* R452 */
550 { 0x0000, 0x0000, 0x0000 }, /* R453 */
551 { 0x0000, 0x0000, 0x0000 }, /* R454 */
552 { 0x0000, 0x0000, 0x0000 }, /* R455 */
553 { 0x0000, 0x0000, 0x0000 }, /* R456 */
554 { 0x0000, 0x0000, 0x0000 }, /* R457 */
555 { 0x0000, 0x0000, 0x0000 }, /* R458 */
556 { 0x0000, 0x0000, 0x0000 }, /* R459 */
557 { 0x0000, 0x0000, 0x0000 }, /* R460 */
558 { 0x0000, 0x0000, 0x0000 }, /* R461 */
559 { 0x0000, 0x0000, 0x0000 }, /* R462 */
560 { 0x0000, 0x0000, 0x0000 }, /* R463 */
561 { 0x0000, 0x0000, 0x0000 }, /* R464 */
562 { 0x0000, 0x0000, 0x0000 }, /* R465 */
563 { 0x0000, 0x0000, 0x0000 }, /* R466 */
564 { 0x0000, 0x0000, 0x0000 }, /* R467 */
565 { 0x0000, 0x0000, 0x0000 }, /* R468 */
566 { 0x0000, 0x0000, 0x0000 }, /* R469 */
567 { 0x0000, 0x0000, 0x0000 }, /* R470 */
568 { 0x0000, 0x0000, 0x0000 }, /* R471 */
569 { 0x0000, 0x0000, 0x0000 }, /* R472 */
570 { 0x0000, 0x0000, 0x0000 }, /* R473 */
571 { 0x0000, 0x0000, 0x0000 }, /* R474 */
572 { 0x0000, 0x0000, 0x0000 }, /* R475 */
573 { 0x0000, 0x0000, 0x0000 }, /* R476 */
574 { 0x0000, 0x0000, 0x0000 }, /* R477 */
575 { 0x0000, 0x0000, 0x0000 }, /* R478 */
576 { 0x0000, 0x0000, 0x0000 }, /* R479 */
577 { 0x0000, 0x0000, 0x0000 }, /* R480 */
578 { 0x0000, 0x0000, 0x0000 }, /* R481 */
579 { 0x0000, 0x0000, 0x0000 }, /* R482 */
580 { 0x0000, 0x0000, 0x0000 }, /* R483 */
581 { 0x0000, 0x0000, 0x0000 }, /* R484 */
582 { 0x0000, 0x0000, 0x0000 }, /* R485 */
583 { 0x0000, 0x0000, 0x0000 }, /* R486 */
584 { 0x0000, 0x0000, 0x0000 }, /* R487 */
585 { 0x0000, 0x0000, 0x0000 }, /* R488 */
586 { 0x0000, 0x0000, 0x0000 }, /* R489 */
587 { 0x0000, 0x0000, 0x0000 }, /* R490 */
588 { 0x0000, 0x0000, 0x0000 }, /* R491 */
589 { 0x0000, 0x0000, 0x0000 }, /* R492 */
590 { 0x0000, 0x0000, 0x0000 }, /* R493 */
591 { 0x0000, 0x0000, 0x0000 }, /* R494 */
592 { 0x0000, 0x0000, 0x0000 }, /* R495 */
593 { 0x0000, 0x0000, 0x0000 }, /* R496 */
594 { 0x0000, 0x0000, 0x0000 }, /* R497 */
595 { 0x0000, 0x0000, 0x0000 }, /* R498 */
596 { 0x0000, 0x0000, 0x0000 }, /* R499 */
597 { 0x0000, 0x0000, 0x0000 }, /* R500 */
598 { 0x0000, 0x0000, 0x0000 }, /* R501 */
599 { 0x0000, 0x0000, 0x0000 }, /* R502 */
600 { 0x0000, 0x0000, 0x0000 }, /* R503 */
601 { 0x0000, 0x0000, 0x0000 }, /* R504 */
602 { 0x0000, 0x0000, 0x0000 }, /* R505 */
603 { 0x0000, 0x0000, 0x0000 }, /* R506 */
604 { 0x0000, 0x0000, 0x0000 }, /* R507 */
605 { 0x0000, 0x0000, 0x0000 }, /* R508 */
606 { 0x0000, 0x0000, 0x0000 }, /* R509 */
607 { 0x0000, 0x0000, 0x0000 }, /* R510 */
608 { 0x0000, 0x0000, 0x0000 }, /* R511 */
609 { 0x001F, 0x001F, 0x0000 }, /* R512 - AIF1 Clocking (1) */
610 { 0x003F, 0x003F, 0x0000 }, /* R513 - AIF1 Clocking (2) */
611 { 0x0000, 0x0000, 0x0000 }, /* R514 */
612 { 0x0000, 0x0000, 0x0000 }, /* R515 */
613 { 0x001F, 0x001F, 0x0000 }, /* R516 - AIF2 Clocking (1) */
614 { 0x003F, 0x003F, 0x0000 }, /* R517 - AIF2 Clocking (2) */
615 { 0x0000, 0x0000, 0x0000 }, /* R518 */
616 { 0x0000, 0x0000, 0x0000 }, /* R519 */
617 { 0x001F, 0x001F, 0x0000 }, /* R520 - Clocking (1) */
618 { 0x0777, 0x0777, 0x0000 }, /* R521 - Clocking (2) */
619 { 0x0000, 0x0000, 0x0000 }, /* R522 */
620 { 0x0000, 0x0000, 0x0000 }, /* R523 */
621 { 0x0000, 0x0000, 0x0000 }, /* R524 */
622 { 0x0000, 0x0000, 0x0000 }, /* R525 */
623 { 0x0000, 0x0000, 0x0000 }, /* R526 */
624 { 0x0000, 0x0000, 0x0000 }, /* R527 */
625 { 0x00FF, 0x00FF, 0x0000 }, /* R528 - AIF1 Rate */
626 { 0x00FF, 0x00FF, 0x0000 }, /* R529 - AIF2 Rate */
627 { 0x000F, 0x0000, 0x0000 }, /* R530 - Rate Status */
628 { 0x0000, 0x0000, 0x0000 }, /* R531 */
629 { 0x0000, 0x0000, 0x0000 }, /* R532 */
630 { 0x0000, 0x0000, 0x0000 }, /* R533 */
631 { 0x0000, 0x0000, 0x0000 }, /* R534 */
632 { 0x0000, 0x0000, 0x0000 }, /* R535 */
633 { 0x0000, 0x0000, 0x0000 }, /* R536 */
634 { 0x0000, 0x0000, 0x0000 }, /* R537 */
635 { 0x0000, 0x0000, 0x0000 }, /* R538 */
636 { 0x0000, 0x0000, 0x0000 }, /* R539 */
637 { 0x0000, 0x0000, 0x0000 }, /* R540 */
638 { 0x0000, 0x0000, 0x0000 }, /* R541 */
639 { 0x0000, 0x0000, 0x0000 }, /* R542 */
640 { 0x0000, 0x0000, 0x0000 }, /* R543 */
641 { 0x0007, 0x0007, 0x0000 }, /* R544 - FLL1 Control (1) */
642 { 0x3F77, 0x3F77, 0x0000 }, /* R545 - FLL1 Control (2) */
643 { 0xFFFF, 0xFFFF, 0x0000 }, /* R546 - FLL1 Control (3) */
644 { 0x7FEF, 0x7FEF, 0x0000 }, /* R547 - FLL1 Control (4) */
645 { 0x1FDB, 0x1FDB, 0x0000 }, /* R548 - FLL1 Control (5) */
646 { 0x0000, 0x0000, 0x0000 }, /* R549 */
647 { 0x0000, 0x0000, 0x0000 }, /* R550 */
648 { 0x0000, 0x0000, 0x0000 }, /* R551 */
649 { 0x0000, 0x0000, 0x0000 }, /* R552 */
650 { 0x0000, 0x0000, 0x0000 }, /* R553 */
651 { 0x0000, 0x0000, 0x0000 }, /* R554 */
652 { 0x0000, 0x0000, 0x0000 }, /* R555 */
653 { 0x0000, 0x0000, 0x0000 }, /* R556 */
654 { 0x0000, 0x0000, 0x0000 }, /* R557 */
655 { 0x0000, 0x0000, 0x0000 }, /* R558 */
656 { 0x0000, 0x0000, 0x0000 }, /* R559 */
657 { 0x0000, 0x0000, 0x0000 }, /* R560 */
658 { 0x0000, 0x0000, 0x0000 }, /* R561 */
659 { 0x0000, 0x0000, 0x0000 }, /* R562 */
660 { 0x0000, 0x0000, 0x0000 }, /* R563 */
661 { 0x0000, 0x0000, 0x0000 }, /* R564 */
662 { 0x0000, 0x0000, 0x0000 }, /* R565 */
663 { 0x0000, 0x0000, 0x0000 }, /* R566 */
664 { 0x0000, 0x0000, 0x0000 }, /* R567 */
665 { 0x0000, 0x0000, 0x0000 }, /* R568 */
666 { 0x0000, 0x0000, 0x0000 }, /* R569 */
667 { 0x0000, 0x0000, 0x0000 }, /* R570 */
668 { 0x0000, 0x0000, 0x0000 }, /* R571 */
669 { 0x0000, 0x0000, 0x0000 }, /* R572 */
670 { 0x0000, 0x0000, 0x0000 }, /* R573 */
671 { 0x0000, 0x0000, 0x0000 }, /* R574 */
672 { 0x0000, 0x0000, 0x0000 }, /* R575 */
673 { 0x0007, 0x0007, 0x0000 }, /* R576 - FLL2 Control (1) */
674 { 0x3F77, 0x3F77, 0x0000 }, /* R577 - FLL2 Control (2) */
675 { 0xFFFF, 0xFFFF, 0x0000 }, /* R578 - FLL2 Control (3) */
676 { 0x7FEF, 0x7FEF, 0x0000 }, /* R579 - FLL2 Control (4) */
677 { 0x1FDB, 0x1FDB, 0x0000 }, /* R580 - FLL2 Control (5) */
678 { 0x0000, 0x0000, 0x0000 }, /* R581 */
679 { 0x0000, 0x0000, 0x0000 }, /* R582 */
680 { 0x0000, 0x0000, 0x0000 }, /* R583 */
681 { 0x0000, 0x0000, 0x0000 }, /* R584 */
682 { 0x0000, 0x0000, 0x0000 }, /* R585 */
683 { 0x0000, 0x0000, 0x0000 }, /* R586 */
684 { 0x0000, 0x0000, 0x0000 }, /* R587 */
685 { 0x0000, 0x0000, 0x0000 }, /* R588 */
686 { 0x0000, 0x0000, 0x0000 }, /* R589 */
687 { 0x0000, 0x0000, 0x0000 }, /* R590 */
688 { 0x0000, 0x0000, 0x0000 }, /* R591 */
689 { 0x0000, 0x0000, 0x0000 }, /* R592 */
690 { 0x0000, 0x0000, 0x0000 }, /* R593 */
691 { 0x0000, 0x0000, 0x0000 }, /* R594 */
692 { 0x0000, 0x0000, 0x0000 }, /* R595 */
693 { 0x0000, 0x0000, 0x0000 }, /* R596 */
694 { 0x0000, 0x0000, 0x0000 }, /* R597 */
695 { 0x0000, 0x0000, 0x0000 }, /* R598 */
696 { 0x0000, 0x0000, 0x0000 }, /* R599 */
697 { 0x0000, 0x0000, 0x0000 }, /* R600 */
698 { 0x0000, 0x0000, 0x0000 }, /* R601 */
699 { 0x0000, 0x0000, 0x0000 }, /* R602 */
700 { 0x0000, 0x0000, 0x0000 }, /* R603 */
701 { 0x0000, 0x0000, 0x0000 }, /* R604 */
702 { 0x0000, 0x0000, 0x0000 }, /* R605 */
703 { 0x0000, 0x0000, 0x0000 }, /* R606 */
704 { 0x0000, 0x0000, 0x0000 }, /* R607 */
705 { 0x0000, 0x0000, 0x0000 }, /* R608 */
706 { 0x0000, 0x0000, 0x0000 }, /* R609 */
707 { 0x0000, 0x0000, 0x0000 }, /* R610 */
708 { 0x0000, 0x0000, 0x0000 }, /* R611 */
709 { 0x0000, 0x0000, 0x0000 }, /* R612 */
710 { 0x0000, 0x0000, 0x0000 }, /* R613 */
711 { 0x0000, 0x0000, 0x0000 }, /* R614 */
712 { 0x0000, 0x0000, 0x0000 }, /* R615 */
713 { 0x0000, 0x0000, 0x0000 }, /* R616 */
714 { 0x0000, 0x0000, 0x0000 }, /* R617 */
715 { 0x0000, 0x0000, 0x0000 }, /* R618 */
716 { 0x0000, 0x0000, 0x0000 }, /* R619 */
717 { 0x0000, 0x0000, 0x0000 }, /* R620 */
718 { 0x0000, 0x0000, 0x0000 }, /* R621 */
719 { 0x0000, 0x0000, 0x0000 }, /* R622 */
720 { 0x0000, 0x0000, 0x0000 }, /* R623 */
721 { 0x0000, 0x0000, 0x0000 }, /* R624 */
722 { 0x0000, 0x0000, 0x0000 }, /* R625 */
723 { 0x0000, 0x0000, 0x0000 }, /* R626 */
724 { 0x0000, 0x0000, 0x0000 }, /* R627 */
725 { 0x0000, 0x0000, 0x0000 }, /* R628 */
726 { 0x0000, 0x0000, 0x0000 }, /* R629 */
727 { 0x0000, 0x0000, 0x0000 }, /* R630 */
728 { 0x0000, 0x0000, 0x0000 }, /* R631 */
729 { 0x0000, 0x0000, 0x0000 }, /* R632 */
730 { 0x0000, 0x0000, 0x0000 }, /* R633 */
731 { 0x0000, 0x0000, 0x0000 }, /* R634 */
732 { 0x0000, 0x0000, 0x0000 }, /* R635 */
733 { 0x0000, 0x0000, 0x0000 }, /* R636 */
734 { 0x0000, 0x0000, 0x0000 }, /* R637 */
735 { 0x0000, 0x0000, 0x0000 }, /* R638 */
736 { 0x0000, 0x0000, 0x0000 }, /* R639 */
737 { 0x0000, 0x0000, 0x0000 }, /* R640 */
738 { 0x0000, 0x0000, 0x0000 }, /* R641 */
739 { 0x0000, 0x0000, 0x0000 }, /* R642 */
740 { 0x0000, 0x0000, 0x0000 }, /* R643 */
741 { 0x0000, 0x0000, 0x0000 }, /* R644 */
742 { 0x0000, 0x0000, 0x0000 }, /* R645 */
743 { 0x0000, 0x0000, 0x0000 }, /* R646 */
744 { 0x0000, 0x0000, 0x0000 }, /* R647 */
745 { 0x0000, 0x0000, 0x0000 }, /* R648 */
746 { 0x0000, 0x0000, 0x0000 }, /* R649 */
747 { 0x0000, 0x0000, 0x0000 }, /* R650 */
748 { 0x0000, 0x0000, 0x0000 }, /* R651 */
749 { 0x0000, 0x0000, 0x0000 }, /* R652 */
750 { 0x0000, 0x0000, 0x0000 }, /* R653 */
751 { 0x0000, 0x0000, 0x0000 }, /* R654 */
752 { 0x0000, 0x0000, 0x0000 }, /* R655 */
753 { 0x0000, 0x0000, 0x0000 }, /* R656 */
754 { 0x0000, 0x0000, 0x0000 }, /* R657 */
755 { 0x0000, 0x0000, 0x0000 }, /* R658 */
756 { 0x0000, 0x0000, 0x0000 }, /* R659 */
757 { 0x0000, 0x0000, 0x0000 }, /* R660 */
758 { 0x0000, 0x0000, 0x0000 }, /* R661 */
759 { 0x0000, 0x0000, 0x0000 }, /* R662 */
760 { 0x0000, 0x0000, 0x0000 }, /* R663 */
761 { 0x0000, 0x0000, 0x0000 }, /* R664 */
762 { 0x0000, 0x0000, 0x0000 }, /* R665 */
763 { 0x0000, 0x0000, 0x0000 }, /* R666 */
764 { 0x0000, 0x0000, 0x0000 }, /* R667 */
765 { 0x0000, 0x0000, 0x0000 }, /* R668 */
766 { 0x0000, 0x0000, 0x0000 }, /* R669 */
767 { 0x0000, 0x0000, 0x0000 }, /* R670 */
768 { 0x0000, 0x0000, 0x0000 }, /* R671 */
769 { 0x0000, 0x0000, 0x0000 }, /* R672 */
770 { 0x0000, 0x0000, 0x0000 }, /* R673 */
771 { 0x0000, 0x0000, 0x0000 }, /* R674 */
772 { 0x0000, 0x0000, 0x0000 }, /* R675 */
773 { 0x0000, 0x0000, 0x0000 }, /* R676 */
774 { 0x0000, 0x0000, 0x0000 }, /* R677 */
775 { 0x0000, 0x0000, 0x0000 }, /* R678 */
776 { 0x0000, 0x0000, 0x0000 }, /* R679 */
777 { 0x0000, 0x0000, 0x0000 }, /* R680 */
778 { 0x0000, 0x0000, 0x0000 }, /* R681 */
779 { 0x0000, 0x0000, 0x0000 }, /* R682 */
780 { 0x0000, 0x0000, 0x0000 }, /* R683 */
781 { 0x0000, 0x0000, 0x0000 }, /* R684 */
782 { 0x0000, 0x0000, 0x0000 }, /* R685 */
783 { 0x0000, 0x0000, 0x0000 }, /* R686 */
784 { 0x0000, 0x0000, 0x0000 }, /* R687 */
785 { 0x0000, 0x0000, 0x0000 }, /* R688 */
786 { 0x0000, 0x0000, 0x0000 }, /* R689 */
787 { 0x0000, 0x0000, 0x0000 }, /* R690 */
788 { 0x0000, 0x0000, 0x0000 }, /* R691 */
789 { 0x0000, 0x0000, 0x0000 }, /* R692 */
790 { 0x0000, 0x0000, 0x0000 }, /* R693 */
791 { 0x0000, 0x0000, 0x0000 }, /* R694 */
792 { 0x0000, 0x0000, 0x0000 }, /* R695 */
793 { 0x0000, 0x0000, 0x0000 }, /* R696 */
794 { 0x0000, 0x0000, 0x0000 }, /* R697 */
795 { 0x0000, 0x0000, 0x0000 }, /* R698 */
796 { 0x0000, 0x0000, 0x0000 }, /* R699 */
797 { 0x0000, 0x0000, 0x0000 }, /* R700 */
798 { 0x0000, 0x0000, 0x0000 }, /* R701 */
799 { 0x0000, 0x0000, 0x0000 }, /* R702 */
800 { 0x0000, 0x0000, 0x0000 }, /* R703 */
801 { 0x0000, 0x0000, 0x0000 }, /* R704 */
802 { 0x0000, 0x0000, 0x0000 }, /* R705 */
803 { 0x0000, 0x0000, 0x0000 }, /* R706 */
804 { 0x0000, 0x0000, 0x0000 }, /* R707 */
805 { 0x0000, 0x0000, 0x0000 }, /* R708 */
806 { 0x0000, 0x0000, 0x0000 }, /* R709 */
807 { 0x0000, 0x0000, 0x0000 }, /* R710 */
808 { 0x0000, 0x0000, 0x0000 }, /* R711 */
809 { 0x0000, 0x0000, 0x0000 }, /* R712 */
810 { 0x0000, 0x0000, 0x0000 }, /* R713 */
811 { 0x0000, 0x0000, 0x0000 }, /* R714 */
812 { 0x0000, 0x0000, 0x0000 }, /* R715 */
813 { 0x0000, 0x0000, 0x0000 }, /* R716 */
814 { 0x0000, 0x0000, 0x0000 }, /* R717 */
815 { 0x0000, 0x0000, 0x0000 }, /* R718 */
816 { 0x0000, 0x0000, 0x0000 }, /* R719 */
817 { 0x0000, 0x0000, 0x0000 }, /* R720 */
818 { 0x0000, 0x0000, 0x0000 }, /* R721 */
819 { 0x0000, 0x0000, 0x0000 }, /* R722 */
820 { 0x0000, 0x0000, 0x0000 }, /* R723 */
821 { 0x0000, 0x0000, 0x0000 }, /* R724 */
822 { 0x0000, 0x0000, 0x0000 }, /* R725 */
823 { 0x0000, 0x0000, 0x0000 }, /* R726 */
824 { 0x0000, 0x0000, 0x0000 }, /* R727 */
825 { 0x0000, 0x0000, 0x0000 }, /* R728 */
826 { 0x0000, 0x0000, 0x0000 }, /* R729 */
827 { 0x0000, 0x0000, 0x0000 }, /* R730 */
828 { 0x0000, 0x0000, 0x0000 }, /* R731 */
829 { 0x0000, 0x0000, 0x0000 }, /* R732 */
830 { 0x0000, 0x0000, 0x0000 }, /* R733 */
831 { 0x0000, 0x0000, 0x0000 }, /* R734 */
832 { 0x0000, 0x0000, 0x0000 }, /* R735 */
833 { 0x0000, 0x0000, 0x0000 }, /* R736 */
834 { 0x0000, 0x0000, 0x0000 }, /* R737 */
835 { 0x0000, 0x0000, 0x0000 }, /* R738 */
836 { 0x0000, 0x0000, 0x0000 }, /* R739 */
837 { 0x0000, 0x0000, 0x0000 }, /* R740 */
838 { 0x0000, 0x0000, 0x0000 }, /* R741 */
839 { 0x0000, 0x0000, 0x0000 }, /* R742 */
840 { 0x0000, 0x0000, 0x0000 }, /* R743 */
841 { 0x0000, 0x0000, 0x0000 }, /* R744 */
842 { 0x0000, 0x0000, 0x0000 }, /* R745 */
843 { 0x0000, 0x0000, 0x0000 }, /* R746 */
844 { 0x0000, 0x0000, 0x0000 }, /* R747 */
845 { 0x0000, 0x0000, 0x0000 }, /* R748 */
846 { 0x0000, 0x0000, 0x0000 }, /* R749 */
847 { 0x0000, 0x0000, 0x0000 }, /* R750 */
848 { 0x0000, 0x0000, 0x0000 }, /* R751 */
849 { 0x0000, 0x0000, 0x0000 }, /* R752 */
850 { 0x0000, 0x0000, 0x0000 }, /* R753 */
851 { 0x0000, 0x0000, 0x0000 }, /* R754 */
852 { 0x0000, 0x0000, 0x0000 }, /* R755 */
853 { 0x0000, 0x0000, 0x0000 }, /* R756 */
854 { 0x0000, 0x0000, 0x0000 }, /* R757 */
855 { 0x0000, 0x0000, 0x0000 }, /* R758 */
856 { 0x0000, 0x0000, 0x0000 }, /* R759 */
857 { 0x0000, 0x0000, 0x0000 }, /* R760 */
858 { 0x0000, 0x0000, 0x0000 }, /* R761 */
859 { 0x0000, 0x0000, 0x0000 }, /* R762 */
860 { 0x0000, 0x0000, 0x0000 }, /* R763 */
861 { 0x0000, 0x0000, 0x0000 }, /* R764 */
862 { 0x0000, 0x0000, 0x0000 }, /* R765 */
863 { 0x0000, 0x0000, 0x0000 }, /* R766 */
864 { 0x0000, 0x0000, 0x0000 }, /* R767 */
865 { 0xE1F8, 0xE1F8, 0x0000 }, /* R768 - AIF1 Control (1) */
866 { 0xCD1F, 0xCD1F, 0x0000 }, /* R769 - AIF1 Control (2) */
867 { 0xF000, 0xF000, 0x0000 }, /* R770 - AIF1 Master/Slave */
868 { 0x01F0, 0x01F0, 0x0000 }, /* R771 - AIF1 BCLK */
869 { 0x0FFF, 0x0FFF, 0x0000 }, /* R772 - AIF1ADC LRCLK */
870 { 0x0FFF, 0x0FFF, 0x0000 }, /* R773 - AIF1DAC LRCLK */
871 { 0x0003, 0x0003, 0x0000 }, /* R774 - AIF1DAC Data */
872 { 0x0003, 0x0003, 0x0000 }, /* R775 - AIF1ADC Data */
873 { 0x0000, 0x0000, 0x0000 }, /* R776 */
874 { 0x0000, 0x0000, 0x0000 }, /* R777 */
875 { 0x0000, 0x0000, 0x0000 }, /* R778 */
876 { 0x0000, 0x0000, 0x0000 }, /* R779 */
877 { 0x0000, 0x0000, 0x0000 }, /* R780 */
878 { 0x0000, 0x0000, 0x0000 }, /* R781 */
879 { 0x0000, 0x0000, 0x0000 }, /* R782 */
880 { 0x0000, 0x0000, 0x0000 }, /* R783 */
881 { 0xF1F8, 0xF1F8, 0x0000 }, /* R784 - AIF2 Control (1) */
882 { 0xFD1F, 0xFD1F, 0x0000 }, /* R785 - AIF2 Control (2) */
883 { 0xF000, 0xF000, 0x0000 }, /* R786 - AIF2 Master/Slave */
884 { 0x01F0, 0x01F0, 0x0000 }, /* R787 - AIF2 BCLK */
885 { 0x0FFF, 0x0FFF, 0x0000 }, /* R788 - AIF2ADC LRCLK */
886 { 0x0FFF, 0x0FFF, 0x0000 }, /* R789 - AIF2DAC LRCLK */
887 { 0x0003, 0x0003, 0x0000 }, /* R790 - AIF2DAC Data */
888 { 0x0003, 0x0003, 0x0000 }, /* R791 - AIF2ADC Data */
889 { 0x0000, 0x0000, 0x0000 }, /* R792 */
890 { 0x0000, 0x0000, 0x0000 }, /* R793 */
891 { 0x0000, 0x0000, 0x0000 }, /* R794 */
892 { 0x0000, 0x0000, 0x0000 }, /* R795 */
893 { 0x0000, 0x0000, 0x0000 }, /* R796 */
894 { 0x0000, 0x0000, 0x0000 }, /* R797 */
895 { 0x0000, 0x0000, 0x0000 }, /* R798 */
896 { 0x0000, 0x0000, 0x0000 }, /* R799 */
897 { 0x0000, 0x0000, 0x0000 }, /* R800 */
898 { 0x0000, 0x0000, 0x0000 }, /* R801 */
899 { 0x0000, 0x0000, 0x0000 }, /* R802 */
900 { 0x0000, 0x0000, 0x0000 }, /* R803 */
901 { 0x0000, 0x0000, 0x0000 }, /* R804 */
902 { 0x0000, 0x0000, 0x0000 }, /* R805 */
903 { 0x0000, 0x0000, 0x0000 }, /* R806 */
904 { 0x0000, 0x0000, 0x0000 }, /* R807 */
905 { 0x0000, 0x0000, 0x0000 }, /* R808 */
906 { 0x0000, 0x0000, 0x0000 }, /* R809 */
907 { 0x0000, 0x0000, 0x0000 }, /* R810 */
908 { 0x0000, 0x0000, 0x0000 }, /* R811 */
909 { 0x0000, 0x0000, 0x0000 }, /* R812 */
910 { 0x0000, 0x0000, 0x0000 }, /* R813 */
911 { 0x0000, 0x0000, 0x0000 }, /* R814 */
912 { 0x0000, 0x0000, 0x0000 }, /* R815 */
913 { 0x0000, 0x0000, 0x0000 }, /* R816 */
914 { 0x0000, 0x0000, 0x0000 }, /* R817 */
915 { 0x0000, 0x0000, 0x0000 }, /* R818 */
916 { 0x0000, 0x0000, 0x0000 }, /* R819 */
917 { 0x0000, 0x0000, 0x0000 }, /* R820 */
918 { 0x0000, 0x0000, 0x0000 }, /* R821 */
919 { 0x0000, 0x0000, 0x0000 }, /* R822 */
920 { 0x0000, 0x0000, 0x0000 }, /* R823 */
921 { 0x0000, 0x0000, 0x0000 }, /* R824 */
922 { 0x0000, 0x0000, 0x0000 }, /* R825 */
923 { 0x0000, 0x0000, 0x0000 }, /* R826 */
924 { 0x0000, 0x0000, 0x0000 }, /* R827 */
925 { 0x0000, 0x0000, 0x0000 }, /* R828 */
926 { 0x0000, 0x0000, 0x0000 }, /* R829 */
927 { 0x0000, 0x0000, 0x0000 }, /* R830 */
928 { 0x0000, 0x0000, 0x0000 }, /* R831 */
929 { 0x0000, 0x0000, 0x0000 }, /* R832 */
930 { 0x0000, 0x0000, 0x0000 }, /* R833 */
931 { 0x0000, 0x0000, 0x0000 }, /* R834 */
932 { 0x0000, 0x0000, 0x0000 }, /* R835 */
933 { 0x0000, 0x0000, 0x0000 }, /* R836 */
934 { 0x0000, 0x0000, 0x0000 }, /* R837 */
935 { 0x0000, 0x0000, 0x0000 }, /* R838 */
936 { 0x0000, 0x0000, 0x0000 }, /* R839 */
937 { 0x0000, 0x0000, 0x0000 }, /* R840 */
938 { 0x0000, 0x0000, 0x0000 }, /* R841 */
939 { 0x0000, 0x0000, 0x0000 }, /* R842 */
940 { 0x0000, 0x0000, 0x0000 }, /* R843 */
941 { 0x0000, 0x0000, 0x0000 }, /* R844 */
942 { 0x0000, 0x0000, 0x0000 }, /* R845 */
943 { 0x0000, 0x0000, 0x0000 }, /* R846 */
944 { 0x0000, 0x0000, 0x0000 }, /* R847 */
945 { 0x0000, 0x0000, 0x0000 }, /* R848 */
946 { 0x0000, 0x0000, 0x0000 }, /* R849 */
947 { 0x0000, 0x0000, 0x0000 }, /* R850 */
948 { 0x0000, 0x0000, 0x0000 }, /* R851 */
949 { 0x0000, 0x0000, 0x0000 }, /* R852 */
950 { 0x0000, 0x0000, 0x0000 }, /* R853 */
951 { 0x0000, 0x0000, 0x0000 }, /* R854 */
952 { 0x0000, 0x0000, 0x0000 }, /* R855 */
953 { 0x0000, 0x0000, 0x0000 }, /* R856 */
954 { 0x0000, 0x0000, 0x0000 }, /* R857 */
955 { 0x0000, 0x0000, 0x0000 }, /* R858 */
956 { 0x0000, 0x0000, 0x0000 }, /* R859 */
957 { 0x0000, 0x0000, 0x0000 }, /* R860 */
958 { 0x0000, 0x0000, 0x0000 }, /* R861 */
959 { 0x0000, 0x0000, 0x0000 }, /* R862 */
960 { 0x0000, 0x0000, 0x0000 }, /* R863 */
961 { 0x0000, 0x0000, 0x0000 }, /* R864 */
962 { 0x0000, 0x0000, 0x0000 }, /* R865 */
963 { 0x0000, 0x0000, 0x0000 }, /* R866 */
964 { 0x0000, 0x0000, 0x0000 }, /* R867 */
965 { 0x0000, 0x0000, 0x0000 }, /* R868 */
966 { 0x0000, 0x0000, 0x0000 }, /* R869 */
967 { 0x0000, 0x0000, 0x0000 }, /* R870 */
968 { 0x0000, 0x0000, 0x0000 }, /* R871 */
969 { 0x0000, 0x0000, 0x0000 }, /* R872 */
970 { 0x0000, 0x0000, 0x0000 }, /* R873 */
971 { 0x0000, 0x0000, 0x0000 }, /* R874 */
972 { 0x0000, 0x0000, 0x0000 }, /* R875 */
973 { 0x0000, 0x0000, 0x0000 }, /* R876 */
974 { 0x0000, 0x0000, 0x0000 }, /* R877 */
975 { 0x0000, 0x0000, 0x0000 }, /* R878 */
976 { 0x0000, 0x0000, 0x0000 }, /* R879 */
977 { 0x0000, 0x0000, 0x0000 }, /* R880 */
978 { 0x0000, 0x0000, 0x0000 }, /* R881 */
979 { 0x0000, 0x0000, 0x0000 }, /* R882 */
980 { 0x0000, 0x0000, 0x0000 }, /* R883 */
981 { 0x0000, 0x0000, 0x0000 }, /* R884 */
982 { 0x0000, 0x0000, 0x0000 }, /* R885 */
983 { 0x0000, 0x0000, 0x0000 }, /* R886 */
984 { 0x0000, 0x0000, 0x0000 }, /* R887 */
985 { 0x0000, 0x0000, 0x0000 }, /* R888 */
986 { 0x0000, 0x0000, 0x0000 }, /* R889 */
987 { 0x0000, 0x0000, 0x0000 }, /* R890 */
988 { 0x0000, 0x0000, 0x0000 }, /* R891 */
989 { 0x0000, 0x0000, 0x0000 }, /* R892 */
990 { 0x0000, 0x0000, 0x0000 }, /* R893 */
991 { 0x0000, 0x0000, 0x0000 }, /* R894 */
992 { 0x0000, 0x0000, 0x0000 }, /* R895 */
993 { 0x0000, 0x0000, 0x0000 }, /* R896 */
994 { 0x0000, 0x0000, 0x0000 }, /* R897 */
995 { 0x0000, 0x0000, 0x0000 }, /* R898 */
996 { 0x0000, 0x0000, 0x0000 }, /* R899 */
997 { 0x0000, 0x0000, 0x0000 }, /* R900 */
998 { 0x0000, 0x0000, 0x0000 }, /* R901 */
999 { 0x0000, 0x0000, 0x0000 }, /* R902 */
1000 { 0x0000, 0x0000, 0x0000 }, /* R903 */
1001 { 0x0000, 0x0000, 0x0000 }, /* R904 */
1002 { 0x0000, 0x0000, 0x0000 }, /* R905 */
1003 { 0x0000, 0x0000, 0x0000 }, /* R906 */
1004 { 0x0000, 0x0000, 0x0000 }, /* R907 */
1005 { 0x0000, 0x0000, 0x0000 }, /* R908 */
1006 { 0x0000, 0x0000, 0x0000 }, /* R909 */
1007 { 0x0000, 0x0000, 0x0000 }, /* R910 */
1008 { 0x0000, 0x0000, 0x0000 }, /* R911 */
1009 { 0x0000, 0x0000, 0x0000 }, /* R912 */
1010 { 0x0000, 0x0000, 0x0000 }, /* R913 */
1011 { 0x0000, 0x0000, 0x0000 }, /* R914 */
1012 { 0x0000, 0x0000, 0x0000 }, /* R915 */
1013 { 0x0000, 0x0000, 0x0000 }, /* R916 */
1014 { 0x0000, 0x0000, 0x0000 }, /* R917 */
1015 { 0x0000, 0x0000, 0x0000 }, /* R918 */
1016 { 0x0000, 0x0000, 0x0000 }, /* R919 */
1017 { 0x0000, 0x0000, 0x0000 }, /* R920 */
1018 { 0x0000, 0x0000, 0x0000 }, /* R921 */
1019 { 0x0000, 0x0000, 0x0000 }, /* R922 */
1020 { 0x0000, 0x0000, 0x0000 }, /* R923 */
1021 { 0x0000, 0x0000, 0x0000 }, /* R924 */
1022 { 0x0000, 0x0000, 0x0000 }, /* R925 */
1023 { 0x0000, 0x0000, 0x0000 }, /* R926 */
1024 { 0x0000, 0x0000, 0x0000 }, /* R927 */
1025 { 0x0000, 0x0000, 0x0000 }, /* R928 */
1026 { 0x0000, 0x0000, 0x0000 }, /* R929 */
1027 { 0x0000, 0x0000, 0x0000 }, /* R930 */
1028 { 0x0000, 0x0000, 0x0000 }, /* R931 */
1029 { 0x0000, 0x0000, 0x0000 }, /* R932 */
1030 { 0x0000, 0x0000, 0x0000 }, /* R933 */
1031 { 0x0000, 0x0000, 0x0000 }, /* R934 */
1032 { 0x0000, 0x0000, 0x0000 }, /* R935 */
1033 { 0x0000, 0x0000, 0x0000 }, /* R936 */
1034 { 0x0000, 0x0000, 0x0000 }, /* R937 */
1035 { 0x0000, 0x0000, 0x0000 }, /* R938 */
1036 { 0x0000, 0x0000, 0x0000 }, /* R939 */
1037 { 0x0000, 0x0000, 0x0000 }, /* R940 */
1038 { 0x0000, 0x0000, 0x0000 }, /* R941 */
1039 { 0x0000, 0x0000, 0x0000 }, /* R942 */
1040 { 0x0000, 0x0000, 0x0000 }, /* R943 */
1041 { 0x0000, 0x0000, 0x0000 }, /* R944 */
1042 { 0x0000, 0x0000, 0x0000 }, /* R945 */
1043 { 0x0000, 0x0000, 0x0000 }, /* R946 */
1044 { 0x0000, 0x0000, 0x0000 }, /* R947 */
1045 { 0x0000, 0x0000, 0x0000 }, /* R948 */
1046 { 0x0000, 0x0000, 0x0000 }, /* R949 */
1047 { 0x0000, 0x0000, 0x0000 }, /* R950 */
1048 { 0x0000, 0x0000, 0x0000 }, /* R951 */
1049 { 0x0000, 0x0000, 0x0000 }, /* R952 */
1050 { 0x0000, 0x0000, 0x0000 }, /* R953 */
1051 { 0x0000, 0x0000, 0x0000 }, /* R954 */
1052 { 0x0000, 0x0000, 0x0000 }, /* R955 */
1053 { 0x0000, 0x0000, 0x0000 }, /* R956 */
1054 { 0x0000, 0x0000, 0x0000 }, /* R957 */
1055 { 0x0000, 0x0000, 0x0000 }, /* R958 */
1056 { 0x0000, 0x0000, 0x0000 }, /* R959 */
1057 { 0x0000, 0x0000, 0x0000 }, /* R960 */
1058 { 0x0000, 0x0000, 0x0000 }, /* R961 */
1059 { 0x0000, 0x0000, 0x0000 }, /* R962 */
1060 { 0x0000, 0x0000, 0x0000 }, /* R963 */
1061 { 0x0000, 0x0000, 0x0000 }, /* R964 */
1062 { 0x0000, 0x0000, 0x0000 }, /* R965 */
1063 { 0x0000, 0x0000, 0x0000 }, /* R966 */
1064 { 0x0000, 0x0000, 0x0000 }, /* R967 */
1065 { 0x0000, 0x0000, 0x0000 }, /* R968 */
1066 { 0x0000, 0x0000, 0x0000 }, /* R969 */
1067 { 0x0000, 0x0000, 0x0000 }, /* R970 */
1068 { 0x0000, 0x0000, 0x0000 }, /* R971 */
1069 { 0x0000, 0x0000, 0x0000 }, /* R972 */
1070 { 0x0000, 0x0000, 0x0000 }, /* R973 */
1071 { 0x0000, 0x0000, 0x0000 }, /* R974 */
1072 { 0x0000, 0x0000, 0x0000 }, /* R975 */
1073 { 0x0000, 0x0000, 0x0000 }, /* R976 */
1074 { 0x0000, 0x0000, 0x0000 }, /* R977 */
1075 { 0x0000, 0x0000, 0x0000 }, /* R978 */
1076 { 0x0000, 0x0000, 0x0000 }, /* R979 */
1077 { 0x0000, 0x0000, 0x0000 }, /* R980 */
1078 { 0x0000, 0x0000, 0x0000 }, /* R981 */
1079 { 0x0000, 0x0000, 0x0000 }, /* R982 */
1080 { 0x0000, 0x0000, 0x0000 }, /* R983 */
1081 { 0x0000, 0x0000, 0x0000 }, /* R984 */
1082 { 0x0000, 0x0000, 0x0000 }, /* R985 */
1083 { 0x0000, 0x0000, 0x0000 }, /* R986 */
1084 { 0x0000, 0x0000, 0x0000 }, /* R987 */
1085 { 0x0000, 0x0000, 0x0000 }, /* R988 */
1086 { 0x0000, 0x0000, 0x0000 }, /* R989 */
1087 { 0x0000, 0x0000, 0x0000 }, /* R990 */
1088 { 0x0000, 0x0000, 0x0000 }, /* R991 */
1089 { 0x0000, 0x0000, 0x0000 }, /* R992 */
1090 { 0x0000, 0x0000, 0x0000 }, /* R993 */
1091 { 0x0000, 0x0000, 0x0000 }, /* R994 */
1092 { 0x0000, 0x0000, 0x0000 }, /* R995 */
1093 { 0x0000, 0x0000, 0x0000 }, /* R996 */
1094 { 0x0000, 0x0000, 0x0000 }, /* R997 */
1095 { 0x0000, 0x0000, 0x0000 }, /* R998 */
1096 { 0x0000, 0x0000, 0x0000 }, /* R999 */
1097 { 0x0000, 0x0000, 0x0000 }, /* R1000 */
1098 { 0x0000, 0x0000, 0x0000 }, /* R1001 */
1099 { 0x0000, 0x0000, 0x0000 }, /* R1002 */
1100 { 0x0000, 0x0000, 0x0000 }, /* R1003 */
1101 { 0x0000, 0x0000, 0x0000 }, /* R1004 */
1102 { 0x0000, 0x0000, 0x0000 }, /* R1005 */
1103 { 0x0000, 0x0000, 0x0000 }, /* R1006 */
1104 { 0x0000, 0x0000, 0x0000 }, /* R1007 */
1105 { 0x0000, 0x0000, 0x0000 }, /* R1008 */
1106 { 0x0000, 0x0000, 0x0000 }, /* R1009 */
1107 { 0x0000, 0x0000, 0x0000 }, /* R1010 */
1108 { 0x0000, 0x0000, 0x0000 }, /* R1011 */
1109 { 0x0000, 0x0000, 0x0000 }, /* R1012 */
1110 { 0x0000, 0x0000, 0x0000 }, /* R1013 */
1111 { 0x0000, 0x0000, 0x0000 }, /* R1014 */
1112 { 0x0000, 0x0000, 0x0000 }, /* R1015 */
1113 { 0x0000, 0x0000, 0x0000 }, /* R1016 */
1114 { 0x0000, 0x0000, 0x0000 }, /* R1017 */
1115 { 0x0000, 0x0000, 0x0000 }, /* R1018 */
1116 { 0x0000, 0x0000, 0x0000 }, /* R1019 */
1117 { 0x0000, 0x0000, 0x0000 }, /* R1020 */
1118 { 0x0000, 0x0000, 0x0000 }, /* R1021 */
1119 { 0x0000, 0x0000, 0x0000 }, /* R1022 */
1120 { 0x0000, 0x0000, 0x0000 }, /* R1023 */
1121 { 0x00FF, 0x01FF, 0x0000 }, /* R1024 - AIF1 ADC1 Left Volume */
1122 { 0x00FF, 0x01FF, 0x0000 }, /* R1025 - AIF1 ADC1 Right Volume */
1123 { 0x00FF, 0x01FF, 0x0000 }, /* R1026 - AIF1 DAC1 Left Volume */
1124 { 0x00FF, 0x01FF, 0x0000 }, /* R1027 - AIF1 DAC1 Right Volume */
1125 { 0x00FF, 0x01FF, 0x0000 }, /* R1028 - AIF1 ADC2 Left Volume */
1126 { 0x00FF, 0x01FF, 0x0000 }, /* R1029 - AIF1 ADC2 Right Volume */
1127 { 0x00FF, 0x01FF, 0x0000 }, /* R1030 - AIF1 DAC2 Left Volume */
1128 { 0x00FF, 0x01FF, 0x0000 }, /* R1031 - AIF1 DAC2 Right Volume */
1129 { 0x0000, 0x0000, 0x0000 }, /* R1032 */
1130 { 0x0000, 0x0000, 0x0000 }, /* R1033 */
1131 { 0x0000, 0x0000, 0x0000 }, /* R1034 */
1132 { 0x0000, 0x0000, 0x0000 }, /* R1035 */
1133 { 0x0000, 0x0000, 0x0000 }, /* R1036 */
1134 { 0x0000, 0x0000, 0x0000 }, /* R1037 */
1135 { 0x0000, 0x0000, 0x0000 }, /* R1038 */
1136 { 0x0000, 0x0000, 0x0000 }, /* R1039 */
1137 { 0xF800, 0xF800, 0x0000 }, /* R1040 - AIF1 ADC1 Filters */
1138 { 0x7800, 0x7800, 0x0000 }, /* R1041 - AIF1 ADC2 Filters */
1139 { 0x0000, 0x0000, 0x0000 }, /* R1042 */
1140 { 0x0000, 0x0000, 0x0000 }, /* R1043 */
1141 { 0x0000, 0x0000, 0x0000 }, /* R1044 */
1142 { 0x0000, 0x0000, 0x0000 }, /* R1045 */
1143 { 0x0000, 0x0000, 0x0000 }, /* R1046 */
1144 { 0x0000, 0x0000, 0x0000 }, /* R1047 */
1145 { 0x0000, 0x0000, 0x0000 }, /* R1048 */
1146 { 0x0000, 0x0000, 0x0000 }, /* R1049 */
1147 { 0x0000, 0x0000, 0x0000 }, /* R1050 */
1148 { 0x0000, 0x0000, 0x0000 }, /* R1051 */
1149 { 0x0000, 0x0000, 0x0000 }, /* R1052 */
1150 { 0x0000, 0x0000, 0x0000 }, /* R1053 */
1151 { 0x0000, 0x0000, 0x0000 }, /* R1054 */
1152 { 0x0000, 0x0000, 0x0000 }, /* R1055 */
1153 { 0x02B6, 0x02B6, 0x0000 }, /* R1056 - AIF1 DAC1 Filters (1) */
1154 { 0x3F00, 0x3F00, 0x0000 }, /* R1057 - AIF1 DAC1 Filters (2) */
1155 { 0x02B6, 0x02B6, 0x0000 }, /* R1058 - AIF1 DAC2 Filters (1) */
1156 { 0x3F00, 0x3F00, 0x0000 }, /* R1059 - AIF1 DAC2 Filters (2) */
1157 { 0x0000, 0x0000, 0x0000 }, /* R1060 */
1158 { 0x0000, 0x0000, 0x0000 }, /* R1061 */
1159 { 0x0000, 0x0000, 0x0000 }, /* R1062 */
1160 { 0x0000, 0x0000, 0x0000 }, /* R1063 */
1161 { 0x0000, 0x0000, 0x0000 }, /* R1064 */
1162 { 0x0000, 0x0000, 0x0000 }, /* R1065 */
1163 { 0x0000, 0x0000, 0x0000 }, /* R1066 */
1164 { 0x0000, 0x0000, 0x0000 }, /* R1067 */
1165 { 0x0000, 0x0000, 0x0000 }, /* R1068 */
1166 { 0x0000, 0x0000, 0x0000 }, /* R1069 */
1167 { 0x0000, 0x0000, 0x0000 }, /* R1070 */
1168 { 0x0000, 0x0000, 0x0000 }, /* R1071 */
1169 { 0x0000, 0x0000, 0x0000 }, /* R1072 */
1170 { 0x0000, 0x0000, 0x0000 }, /* R1073 */
1171 { 0x0000, 0x0000, 0x0000 }, /* R1074 */
1172 { 0x0000, 0x0000, 0x0000 }, /* R1075 */
1173 { 0x0000, 0x0000, 0x0000 }, /* R1076 */
1174 { 0x0000, 0x0000, 0x0000 }, /* R1077 */
1175 { 0x0000, 0x0000, 0x0000 }, /* R1078 */
1176 { 0x0000, 0x0000, 0x0000 }, /* R1079 */
1177 { 0x0000, 0x0000, 0x0000 }, /* R1080 */
1178 { 0x0000, 0x0000, 0x0000 }, /* R1081 */
1179 { 0x0000, 0x0000, 0x0000 }, /* R1082 */
1180 { 0x0000, 0x0000, 0x0000 }, /* R1083 */
1181 { 0x0000, 0x0000, 0x0000 }, /* R1084 */
1182 { 0x0000, 0x0000, 0x0000 }, /* R1085 */
1183 { 0x0000, 0x0000, 0x0000 }, /* R1086 */
1184 { 0x0000, 0x0000, 0x0000 }, /* R1087 */
1185 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1088 - AIF1 DRC1 (1) */
1186 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1089 - AIF1 DRC1 (2) */
1187 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1090 - AIF1 DRC1 (3) */
1188 { 0x07FF, 0x07FF, 0x0000 }, /* R1091 - AIF1 DRC1 (4) */
1189 { 0x03FF, 0x03FF, 0x0000 }, /* R1092 - AIF1 DRC1 (5) */
1190 { 0x0000, 0x0000, 0x0000 }, /* R1093 */
1191 { 0x0000, 0x0000, 0x0000 }, /* R1094 */
1192 { 0x0000, 0x0000, 0x0000 }, /* R1095 */
1193 { 0x0000, 0x0000, 0x0000 }, /* R1096 */
1194 { 0x0000, 0x0000, 0x0000 }, /* R1097 */
1195 { 0x0000, 0x0000, 0x0000 }, /* R1098 */
1196 { 0x0000, 0x0000, 0x0000 }, /* R1099 */
1197 { 0x0000, 0x0000, 0x0000 }, /* R1100 */
1198 { 0x0000, 0x0000, 0x0000 }, /* R1101 */
1199 { 0x0000, 0x0000, 0x0000 }, /* R1102 */
1200 { 0x0000, 0x0000, 0x0000 }, /* R1103 */
1201 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1104 - AIF1 DRC2 (1) */
1202 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1105 - AIF1 DRC2 (2) */
1203 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1106 - AIF1 DRC2 (3) */
1204 { 0x07FF, 0x07FF, 0x0000 }, /* R1107 - AIF1 DRC2 (4) */
1205 { 0x03FF, 0x03FF, 0x0000 }, /* R1108 - AIF1 DRC2 (5) */
1206 { 0x0000, 0x0000, 0x0000 }, /* R1109 */
1207 { 0x0000, 0x0000, 0x0000 }, /* R1110 */
1208 { 0x0000, 0x0000, 0x0000 }, /* R1111 */
1209 { 0x0000, 0x0000, 0x0000 }, /* R1112 */
1210 { 0x0000, 0x0000, 0x0000 }, /* R1113 */
1211 { 0x0000, 0x0000, 0x0000 }, /* R1114 */
1212 { 0x0000, 0x0000, 0x0000 }, /* R1115 */
1213 { 0x0000, 0x0000, 0x0000 }, /* R1116 */
1214 { 0x0000, 0x0000, 0x0000 }, /* R1117 */
1215 { 0x0000, 0x0000, 0x0000 }, /* R1118 */
1216 { 0x0000, 0x0000, 0x0000 }, /* R1119 */
1217 { 0x0000, 0x0000, 0x0000 }, /* R1120 */
1218 { 0x0000, 0x0000, 0x0000 }, /* R1121 */
1219 { 0x0000, 0x0000, 0x0000 }, /* R1122 */
1220 { 0x0000, 0x0000, 0x0000 }, /* R1123 */
1221 { 0x0000, 0x0000, 0x0000 }, /* R1124 */
1222 { 0x0000, 0x0000, 0x0000 }, /* R1125 */
1223 { 0x0000, 0x0000, 0x0000 }, /* R1126 */
1224 { 0x0000, 0x0000, 0x0000 }, /* R1127 */
1225 { 0x0000, 0x0000, 0x0000 }, /* R1128 */
1226 { 0x0000, 0x0000, 0x0000 }, /* R1129 */
1227 { 0x0000, 0x0000, 0x0000 }, /* R1130 */
1228 { 0x0000, 0x0000, 0x0000 }, /* R1131 */
1229 { 0x0000, 0x0000, 0x0000 }, /* R1132 */
1230 { 0x0000, 0x0000, 0x0000 }, /* R1133 */
1231 { 0x0000, 0x0000, 0x0000 }, /* R1134 */
1232 { 0x0000, 0x0000, 0x0000 }, /* R1135 */
1233 { 0x0000, 0x0000, 0x0000 }, /* R1136 */
1234 { 0x0000, 0x0000, 0x0000 }, /* R1137 */
1235 { 0x0000, 0x0000, 0x0000 }, /* R1138 */
1236 { 0x0000, 0x0000, 0x0000 }, /* R1139 */
1237 { 0x0000, 0x0000, 0x0000 }, /* R1140 */
1238 { 0x0000, 0x0000, 0x0000 }, /* R1141 */
1239 { 0x0000, 0x0000, 0x0000 }, /* R1142 */
1240 { 0x0000, 0x0000, 0x0000 }, /* R1143 */
1241 { 0x0000, 0x0000, 0x0000 }, /* R1144 */
1242 { 0x0000, 0x0000, 0x0000 }, /* R1145 */
1243 { 0x0000, 0x0000, 0x0000 }, /* R1146 */
1244 { 0x0000, 0x0000, 0x0000 }, /* R1147 */
1245 { 0x0000, 0x0000, 0x0000 }, /* R1148 */
1246 { 0x0000, 0x0000, 0x0000 }, /* R1149 */
1247 { 0x0000, 0x0000, 0x0000 }, /* R1150 */
1248 { 0x0000, 0x0000, 0x0000 }, /* R1151 */
1249 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1250 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1251 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1252 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1253 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1254 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1255 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1256 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1257 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1258 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1259 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1260 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1261 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1262 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1263 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1264 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1265 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1266 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1267 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1268 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1269 { 0x0000, 0x0000, 0x0000 }, /* R1172 */
1270 { 0x0000, 0x0000, 0x0000 }, /* R1173 */
1271 { 0x0000, 0x0000, 0x0000 }, /* R1174 */
1272 { 0x0000, 0x0000, 0x0000 }, /* R1175 */
1273 { 0x0000, 0x0000, 0x0000 }, /* R1176 */
1274 { 0x0000, 0x0000, 0x0000 }, /* R1177 */
1275 { 0x0000, 0x0000, 0x0000 }, /* R1178 */
1276 { 0x0000, 0x0000, 0x0000 }, /* R1179 */
1277 { 0x0000, 0x0000, 0x0000 }, /* R1180 */
1278 { 0x0000, 0x0000, 0x0000 }, /* R1181 */
1279 { 0x0000, 0x0000, 0x0000 }, /* R1182 */
1280 { 0x0000, 0x0000, 0x0000 }, /* R1183 */
1281 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1282 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1283 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1284 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1285 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1286 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1287 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1288 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1289 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1290 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1291 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1292 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1293 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1294 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1295 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1296 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1297 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1298 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1299 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1300 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1301 { 0x0000, 0x0000, 0x0000 }, /* R1204 */
1302 { 0x0000, 0x0000, 0x0000 }, /* R1205 */
1303 { 0x0000, 0x0000, 0x0000 }, /* R1206 */
1304 { 0x0000, 0x0000, 0x0000 }, /* R1207 */
1305 { 0x0000, 0x0000, 0x0000 }, /* R1208 */
1306 { 0x0000, 0x0000, 0x0000 }, /* R1209 */
1307 { 0x0000, 0x0000, 0x0000 }, /* R1210 */
1308 { 0x0000, 0x0000, 0x0000 }, /* R1211 */
1309 { 0x0000, 0x0000, 0x0000 }, /* R1212 */
1310 { 0x0000, 0x0000, 0x0000 }, /* R1213 */
1311 { 0x0000, 0x0000, 0x0000 }, /* R1214 */
1312 { 0x0000, 0x0000, 0x0000 }, /* R1215 */
1313 { 0x0000, 0x0000, 0x0000 }, /* R1216 */
1314 { 0x0000, 0x0000, 0x0000 }, /* R1217 */
1315 { 0x0000, 0x0000, 0x0000 }, /* R1218 */
1316 { 0x0000, 0x0000, 0x0000 }, /* R1219 */
1317 { 0x0000, 0x0000, 0x0000 }, /* R1220 */
1318 { 0x0000, 0x0000, 0x0000 }, /* R1221 */
1319 { 0x0000, 0x0000, 0x0000 }, /* R1222 */
1320 { 0x0000, 0x0000, 0x0000 }, /* R1223 */
1321 { 0x0000, 0x0000, 0x0000 }, /* R1224 */
1322 { 0x0000, 0x0000, 0x0000 }, /* R1225 */
1323 { 0x0000, 0x0000, 0x0000 }, /* R1226 */
1324 { 0x0000, 0x0000, 0x0000 }, /* R1227 */
1325 { 0x0000, 0x0000, 0x0000 }, /* R1228 */
1326 { 0x0000, 0x0000, 0x0000 }, /* R1229 */
1327 { 0x0000, 0x0000, 0x0000 }, /* R1230 */
1328 { 0x0000, 0x0000, 0x0000 }, /* R1231 */
1329 { 0x0000, 0x0000, 0x0000 }, /* R1232 */
1330 { 0x0000, 0x0000, 0x0000 }, /* R1233 */
1331 { 0x0000, 0x0000, 0x0000 }, /* R1234 */
1332 { 0x0000, 0x0000, 0x0000 }, /* R1235 */
1333 { 0x0000, 0x0000, 0x0000 }, /* R1236 */
1334 { 0x0000, 0x0000, 0x0000 }, /* R1237 */
1335 { 0x0000, 0x0000, 0x0000 }, /* R1238 */
1336 { 0x0000, 0x0000, 0x0000 }, /* R1239 */
1337 { 0x0000, 0x0000, 0x0000 }, /* R1240 */
1338 { 0x0000, 0x0000, 0x0000 }, /* R1241 */
1339 { 0x0000, 0x0000, 0x0000 }, /* R1242 */
1340 { 0x0000, 0x0000, 0x0000 }, /* R1243 */
1341 { 0x0000, 0x0000, 0x0000 }, /* R1244 */
1342 { 0x0000, 0x0000, 0x0000 }, /* R1245 */
1343 { 0x0000, 0x0000, 0x0000 }, /* R1246 */
1344 { 0x0000, 0x0000, 0x0000 }, /* R1247 */
1345 { 0x0000, 0x0000, 0x0000 }, /* R1248 */
1346 { 0x0000, 0x0000, 0x0000 }, /* R1249 */
1347 { 0x0000, 0x0000, 0x0000 }, /* R1250 */
1348 { 0x0000, 0x0000, 0x0000 }, /* R1251 */
1349 { 0x0000, 0x0000, 0x0000 }, /* R1252 */
1350 { 0x0000, 0x0000, 0x0000 }, /* R1253 */
1351 { 0x0000, 0x0000, 0x0000 }, /* R1254 */
1352 { 0x0000, 0x0000, 0x0000 }, /* R1255 */
1353 { 0x0000, 0x0000, 0x0000 }, /* R1256 */
1354 { 0x0000, 0x0000, 0x0000 }, /* R1257 */
1355 { 0x0000, 0x0000, 0x0000 }, /* R1258 */
1356 { 0x0000, 0x0000, 0x0000 }, /* R1259 */
1357 { 0x0000, 0x0000, 0x0000 }, /* R1260 */
1358 { 0x0000, 0x0000, 0x0000 }, /* R1261 */
1359 { 0x0000, 0x0000, 0x0000 }, /* R1262 */
1360 { 0x0000, 0x0000, 0x0000 }, /* R1263 */
1361 { 0x0000, 0x0000, 0x0000 }, /* R1264 */
1362 { 0x0000, 0x0000, 0x0000 }, /* R1265 */
1363 { 0x0000, 0x0000, 0x0000 }, /* R1266 */
1364 { 0x0000, 0x0000, 0x0000 }, /* R1267 */
1365 { 0x0000, 0x0000, 0x0000 }, /* R1268 */
1366 { 0x0000, 0x0000, 0x0000 }, /* R1269 */
1367 { 0x0000, 0x0000, 0x0000 }, /* R1270 */
1368 { 0x0000, 0x0000, 0x0000 }, /* R1271 */
1369 { 0x0000, 0x0000, 0x0000 }, /* R1272 */
1370 { 0x0000, 0x0000, 0x0000 }, /* R1273 */
1371 { 0x0000, 0x0000, 0x0000 }, /* R1274 */
1372 { 0x0000, 0x0000, 0x0000 }, /* R1275 */
1373 { 0x0000, 0x0000, 0x0000 }, /* R1276 */
1374 { 0x0000, 0x0000, 0x0000 }, /* R1277 */
1375 { 0x0000, 0x0000, 0x0000 }, /* R1278 */
1376 { 0x0000, 0x0000, 0x0000 }, /* R1279 */
1377 { 0x00FF, 0x01FF, 0x0000 }, /* R1280 - AIF2 ADC Left Volume */
1378 { 0x00FF, 0x01FF, 0x0000 }, /* R1281 - AIF2 ADC Right Volume */
1379 { 0x00FF, 0x01FF, 0x0000 }, /* R1282 - AIF2 DAC Left Volume */
1380 { 0x00FF, 0x01FF, 0x0000 }, /* R1283 - AIF2 DAC Right Volume */
1381 { 0x0000, 0x0000, 0x0000 }, /* R1284 */
1382 { 0x0000, 0x0000, 0x0000 }, /* R1285 */
1383 { 0x0000, 0x0000, 0x0000 }, /* R1286 */
1384 { 0x0000, 0x0000, 0x0000 }, /* R1287 */
1385 { 0x0000, 0x0000, 0x0000 }, /* R1288 */
1386 { 0x0000, 0x0000, 0x0000 }, /* R1289 */
1387 { 0x0000, 0x0000, 0x0000 }, /* R1290 */
1388 { 0x0000, 0x0000, 0x0000 }, /* R1291 */
1389 { 0x0000, 0x0000, 0x0000 }, /* R1292 */
1390 { 0x0000, 0x0000, 0x0000 }, /* R1293 */
1391 { 0x0000, 0x0000, 0x0000 }, /* R1294 */
1392 { 0x0000, 0x0000, 0x0000 }, /* R1295 */
1393 { 0xF800, 0xF800, 0x0000 }, /* R1296 - AIF2 ADC Filters */
1394 { 0x0000, 0x0000, 0x0000 }, /* R1297 */
1395 { 0x0000, 0x0000, 0x0000 }, /* R1298 */
1396 { 0x0000, 0x0000, 0x0000 }, /* R1299 */
1397 { 0x0000, 0x0000, 0x0000 }, /* R1300 */
1398 { 0x0000, 0x0000, 0x0000 }, /* R1301 */
1399 { 0x0000, 0x0000, 0x0000 }, /* R1302 */
1400 { 0x0000, 0x0000, 0x0000 }, /* R1303 */
1401 { 0x0000, 0x0000, 0x0000 }, /* R1304 */
1402 { 0x0000, 0x0000, 0x0000 }, /* R1305 */
1403 { 0x0000, 0x0000, 0x0000 }, /* R1306 */
1404 { 0x0000, 0x0000, 0x0000 }, /* R1307 */
1405 { 0x0000, 0x0000, 0x0000 }, /* R1308 */
1406 { 0x0000, 0x0000, 0x0000 }, /* R1309 */
1407 { 0x0000, 0x0000, 0x0000 }, /* R1310 */
1408 { 0x0000, 0x0000, 0x0000 }, /* R1311 */
1409 { 0x02B6, 0x02B6, 0x0000 }, /* R1312 - AIF2 DAC Filters (1) */
1410 { 0x3F00, 0x3F00, 0x0000 }, /* R1313 - AIF2 DAC Filters (2) */
1411 { 0x0000, 0x0000, 0x0000 }, /* R1314 */
1412 { 0x0000, 0x0000, 0x0000 }, /* R1315 */
1413 { 0x0000, 0x0000, 0x0000 }, /* R1316 */
1414 { 0x0000, 0x0000, 0x0000 }, /* R1317 */
1415 { 0x0000, 0x0000, 0x0000 }, /* R1318 */
1416 { 0x0000, 0x0000, 0x0000 }, /* R1319 */
1417 { 0x0000, 0x0000, 0x0000 }, /* R1320 */
1418 { 0x0000, 0x0000, 0x0000 }, /* R1321 */
1419 { 0x0000, 0x0000, 0x0000 }, /* R1322 */
1420 { 0x0000, 0x0000, 0x0000 }, /* R1323 */
1421 { 0x0000, 0x0000, 0x0000 }, /* R1324 */
1422 { 0x0000, 0x0000, 0x0000 }, /* R1325 */
1423 { 0x0000, 0x0000, 0x0000 }, /* R1326 */
1424 { 0x0000, 0x0000, 0x0000 }, /* R1327 */
1425 { 0x0000, 0x0000, 0x0000 }, /* R1328 */
1426 { 0x0000, 0x0000, 0x0000 }, /* R1329 */
1427 { 0x0000, 0x0000, 0x0000 }, /* R1330 */
1428 { 0x0000, 0x0000, 0x0000 }, /* R1331 */
1429 { 0x0000, 0x0000, 0x0000 }, /* R1332 */
1430 { 0x0000, 0x0000, 0x0000 }, /* R1333 */
1431 { 0x0000, 0x0000, 0x0000 }, /* R1334 */
1432 { 0x0000, 0x0000, 0x0000 }, /* R1335 */
1433 { 0x0000, 0x0000, 0x0000 }, /* R1336 */
1434 { 0x0000, 0x0000, 0x0000 }, /* R1337 */
1435 { 0x0000, 0x0000, 0x0000 }, /* R1338 */
1436 { 0x0000, 0x0000, 0x0000 }, /* R1339 */
1437 { 0x0000, 0x0000, 0x0000 }, /* R1340 */
1438 { 0x0000, 0x0000, 0x0000 }, /* R1341 */
1439 { 0x0000, 0x0000, 0x0000 }, /* R1342 */
1440 { 0x0000, 0x0000, 0x0000 }, /* R1343 */
1441 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1344 - AIF2 DRC (1) */
1442 { 0x1FFF, 0x1FFF, 0x0000 }, /* R1345 - AIF2 DRC (2) */
1443 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1346 - AIF2 DRC (3) */
1444 { 0x07FF, 0x07FF, 0x0000 }, /* R1347 - AIF2 DRC (4) */
1445 { 0x03FF, 0x03FF, 0x0000 }, /* R1348 - AIF2 DRC (5) */
1446 { 0x0000, 0x0000, 0x0000 }, /* R1349 */
1447 { 0x0000, 0x0000, 0x0000 }, /* R1350 */
1448 { 0x0000, 0x0000, 0x0000 }, /* R1351 */
1449 { 0x0000, 0x0000, 0x0000 }, /* R1352 */
1450 { 0x0000, 0x0000, 0x0000 }, /* R1353 */
1451 { 0x0000, 0x0000, 0x0000 }, /* R1354 */
1452 { 0x0000, 0x0000, 0x0000 }, /* R1355 */
1453 { 0x0000, 0x0000, 0x0000 }, /* R1356 */
1454 { 0x0000, 0x0000, 0x0000 }, /* R1357 */
1455 { 0x0000, 0x0000, 0x0000 }, /* R1358 */
1456 { 0x0000, 0x0000, 0x0000 }, /* R1359 */
1457 { 0x0000, 0x0000, 0x0000 }, /* R1360 */
1458 { 0x0000, 0x0000, 0x0000 }, /* R1361 */
1459 { 0x0000, 0x0000, 0x0000 }, /* R1362 */
1460 { 0x0000, 0x0000, 0x0000 }, /* R1363 */
1461 { 0x0000, 0x0000, 0x0000 }, /* R1364 */
1462 { 0x0000, 0x0000, 0x0000 }, /* R1365 */
1463 { 0x0000, 0x0000, 0x0000 }, /* R1366 */
1464 { 0x0000, 0x0000, 0x0000 }, /* R1367 */
1465 { 0x0000, 0x0000, 0x0000 }, /* R1368 */
1466 { 0x0000, 0x0000, 0x0000 }, /* R1369 */
1467 { 0x0000, 0x0000, 0x0000 }, /* R1370 */
1468 { 0x0000, 0x0000, 0x0000 }, /* R1371 */
1469 { 0x0000, 0x0000, 0x0000 }, /* R1372 */
1470 { 0x0000, 0x0000, 0x0000 }, /* R1373 */
1471 { 0x0000, 0x0000, 0x0000 }, /* R1374 */
1472 { 0x0000, 0x0000, 0x0000 }, /* R1375 */
1473 { 0x0000, 0x0000, 0x0000 }, /* R1376 */
1474 { 0x0000, 0x0000, 0x0000 }, /* R1377 */
1475 { 0x0000, 0x0000, 0x0000 }, /* R1378 */
1476 { 0x0000, 0x0000, 0x0000 }, /* R1379 */
1477 { 0x0000, 0x0000, 0x0000 }, /* R1380 */
1478 { 0x0000, 0x0000, 0x0000 }, /* R1381 */
1479 { 0x0000, 0x0000, 0x0000 }, /* R1382 */
1480 { 0x0000, 0x0000, 0x0000 }, /* R1383 */
1481 { 0x0000, 0x0000, 0x0000 }, /* R1384 */
1482 { 0x0000, 0x0000, 0x0000 }, /* R1385 */
1483 { 0x0000, 0x0000, 0x0000 }, /* R1386 */
1484 { 0x0000, 0x0000, 0x0000 }, /* R1387 */
1485 { 0x0000, 0x0000, 0x0000 }, /* R1388 */
1486 { 0x0000, 0x0000, 0x0000 }, /* R1389 */
1487 { 0x0000, 0x0000, 0x0000 }, /* R1390 */
1488 { 0x0000, 0x0000, 0x0000 }, /* R1391 */
1489 { 0x0000, 0x0000, 0x0000 }, /* R1392 */
1490 { 0x0000, 0x0000, 0x0000 }, /* R1393 */
1491 { 0x0000, 0x0000, 0x0000 }, /* R1394 */
1492 { 0x0000, 0x0000, 0x0000 }, /* R1395 */
1493 { 0x0000, 0x0000, 0x0000 }, /* R1396 */
1494 { 0x0000, 0x0000, 0x0000 }, /* R1397 */
1495 { 0x0000, 0x0000, 0x0000 }, /* R1398 */
1496 { 0x0000, 0x0000, 0x0000 }, /* R1399 */
1497 { 0x0000, 0x0000, 0x0000 }, /* R1400 */
1498 { 0x0000, 0x0000, 0x0000 }, /* R1401 */
1499 { 0x0000, 0x0000, 0x0000 }, /* R1402 */
1500 { 0x0000, 0x0000, 0x0000 }, /* R1403 */
1501 { 0x0000, 0x0000, 0x0000 }, /* R1404 */
1502 { 0x0000, 0x0000, 0x0000 }, /* R1405 */
1503 { 0x0000, 0x0000, 0x0000 }, /* R1406 */
1504 { 0x0000, 0x0000, 0x0000 }, /* R1407 */
1505 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1408 - AIF2 EQ Gains (1) */
1506 { 0xFFC0, 0xFFC0, 0x0000 }, /* R1409 - AIF2 EQ Gains (2) */
1507 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1410 - AIF2 EQ Band 1 A */
1508 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1411 - AIF2 EQ Band 1 B */
1509 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1412 - AIF2 EQ Band 1 PG */
1510 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1413 - AIF2 EQ Band 2 A */
1511 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1414 - AIF2 EQ Band 2 B */
1512 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1415 - AIF2 EQ Band 2 C */
1513 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1416 - AIF2 EQ Band 2 PG */
1514 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1417 - AIF2 EQ Band 3 A */
1515 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1418 - AIF2 EQ Band 3 B */
1516 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1419 - AIF2 EQ Band 3 C */
1517 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1420 - AIF2 EQ Band 3 PG */
1518 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1421 - AIF2 EQ Band 4 A */
1519 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1422 - AIF2 EQ Band 4 B */
1520 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1423 - AIF2 EQ Band 4 C */
1521 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1424 - AIF2 EQ Band 4 PG */
1522 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1425 - AIF2 EQ Band 5 A */
1523 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1426 - AIF2 EQ Band 5 B */
1524 { 0xFFFF, 0xFFFF, 0x0000 }, /* R1427 - AIF2 EQ Band 5 PG */
1525 { 0x0000, 0x0000, 0x0000 }, /* R1428 */
1526 { 0x0000, 0x0000, 0x0000 }, /* R1429 */
1527 { 0x0000, 0x0000, 0x0000 }, /* R1430 */
1528 { 0x0000, 0x0000, 0x0000 }, /* R1431 */
1529 { 0x0000, 0x0000, 0x0000 }, /* R1432 */
1530 { 0x0000, 0x0000, 0x0000 }, /* R1433 */
1531 { 0x0000, 0x0000, 0x0000 }, /* R1434 */
1532 { 0x0000, 0x0000, 0x0000 }, /* R1435 */
1533 { 0x0000, 0x0000, 0x0000 }, /* R1436 */
1534 { 0x0000, 0x0000, 0x0000 }, /* R1437 */
1535 { 0x0000, 0x0000, 0x0000 }, /* R1438 */
1536 { 0x0000, 0x0000, 0x0000 }, /* R1439 */
1537 { 0x0000, 0x0000, 0x0000 }, /* R1440 */
1538 { 0x0000, 0x0000, 0x0000 }, /* R1441 */
1539 { 0x0000, 0x0000, 0x0000 }, /* R1442 */
1540 { 0x0000, 0x0000, 0x0000 }, /* R1443 */
1541 { 0x0000, 0x0000, 0x0000 }, /* R1444 */
1542 { 0x0000, 0x0000, 0x0000 }, /* R1445 */
1543 { 0x0000, 0x0000, 0x0000 }, /* R1446 */
1544 { 0x0000, 0x0000, 0x0000 }, /* R1447 */
1545 { 0x0000, 0x0000, 0x0000 }, /* R1448 */
1546 { 0x0000, 0x0000, 0x0000 }, /* R1449 */
1547 { 0x0000, 0x0000, 0x0000 }, /* R1450 */
1548 { 0x0000, 0x0000, 0x0000 }, /* R1451 */
1549 { 0x0000, 0x0000, 0x0000 }, /* R1452 */
1550 { 0x0000, 0x0000, 0x0000 }, /* R1453 */
1551 { 0x0000, 0x0000, 0x0000 }, /* R1454 */
1552 { 0x0000, 0x0000, 0x0000 }, /* R1455 */
1553 { 0x0000, 0x0000, 0x0000 }, /* R1456 */
1554 { 0x0000, 0x0000, 0x0000 }, /* R1457 */
1555 { 0x0000, 0x0000, 0x0000 }, /* R1458 */
1556 { 0x0000, 0x0000, 0x0000 }, /* R1459 */
1557 { 0x0000, 0x0000, 0x0000 }, /* R1460 */
1558 { 0x0000, 0x0000, 0x0000 }, /* R1461 */
1559 { 0x0000, 0x0000, 0x0000 }, /* R1462 */
1560 { 0x0000, 0x0000, 0x0000 }, /* R1463 */
1561 { 0x0000, 0x0000, 0x0000 }, /* R1464 */
1562 { 0x0000, 0x0000, 0x0000 }, /* R1465 */
1563 { 0x0000, 0x0000, 0x0000 }, /* R1466 */
1564 { 0x0000, 0x0000, 0x0000 }, /* R1467 */
1565 { 0x0000, 0x0000, 0x0000 }, /* R1468 */
1566 { 0x0000, 0x0000, 0x0000 }, /* R1469 */
1567 { 0x0000, 0x0000, 0x0000 }, /* R1470 */
1568 { 0x0000, 0x0000, 0x0000 }, /* R1471 */
1569 { 0x0000, 0x0000, 0x0000 }, /* R1472 */
1570 { 0x0000, 0x0000, 0x0000 }, /* R1473 */
1571 { 0x0000, 0x0000, 0x0000 }, /* R1474 */
1572 { 0x0000, 0x0000, 0x0000 }, /* R1475 */
1573 { 0x0000, 0x0000, 0x0000 }, /* R1476 */
1574 { 0x0000, 0x0000, 0x0000 }, /* R1477 */
1575 { 0x0000, 0x0000, 0x0000 }, /* R1478 */
1576 { 0x0000, 0x0000, 0x0000 }, /* R1479 */
1577 { 0x0000, 0x0000, 0x0000 }, /* R1480 */
1578 { 0x0000, 0x0000, 0x0000 }, /* R1481 */
1579 { 0x0000, 0x0000, 0x0000 }, /* R1482 */
1580 { 0x0000, 0x0000, 0x0000 }, /* R1483 */
1581 { 0x0000, 0x0000, 0x0000 }, /* R1484 */
1582 { 0x0000, 0x0000, 0x0000 }, /* R1485 */
1583 { 0x0000, 0x0000, 0x0000 }, /* R1486 */
1584 { 0x0000, 0x0000, 0x0000 }, /* R1487 */
1585 { 0x0000, 0x0000, 0x0000 }, /* R1488 */
1586 { 0x0000, 0x0000, 0x0000 }, /* R1489 */
1587 { 0x0000, 0x0000, 0x0000 }, /* R1490 */
1588 { 0x0000, 0x0000, 0x0000 }, /* R1491 */
1589 { 0x0000, 0x0000, 0x0000 }, /* R1492 */
1590 { 0x0000, 0x0000, 0x0000 }, /* R1493 */
1591 { 0x0000, 0x0000, 0x0000 }, /* R1494 */
1592 { 0x0000, 0x0000, 0x0000 }, /* R1495 */
1593 { 0x0000, 0x0000, 0x0000 }, /* R1496 */
1594 { 0x0000, 0x0000, 0x0000 }, /* R1497 */
1595 { 0x0000, 0x0000, 0x0000 }, /* R1498 */
1596 { 0x0000, 0x0000, 0x0000 }, /* R1499 */
1597 { 0x0000, 0x0000, 0x0000 }, /* R1500 */
1598 { 0x0000, 0x0000, 0x0000 }, /* R1501 */
1599 { 0x0000, 0x0000, 0x0000 }, /* R1502 */
1600 { 0x0000, 0x0000, 0x0000 }, /* R1503 */
1601 { 0x0000, 0x0000, 0x0000 }, /* R1504 */
1602 { 0x0000, 0x0000, 0x0000 }, /* R1505 */
1603 { 0x0000, 0x0000, 0x0000 }, /* R1506 */
1604 { 0x0000, 0x0000, 0x0000 }, /* R1507 */
1605 { 0x0000, 0x0000, 0x0000 }, /* R1508 */
1606 { 0x0000, 0x0000, 0x0000 }, /* R1509 */
1607 { 0x0000, 0x0000, 0x0000 }, /* R1510 */
1608 { 0x0000, 0x0000, 0x0000 }, /* R1511 */
1609 { 0x0000, 0x0000, 0x0000 }, /* R1512 */
1610 { 0x0000, 0x0000, 0x0000 }, /* R1513 */
1611 { 0x0000, 0x0000, 0x0000 }, /* R1514 */
1612 { 0x0000, 0x0000, 0x0000 }, /* R1515 */
1613 { 0x0000, 0x0000, 0x0000 }, /* R1516 */
1614 { 0x0000, 0x0000, 0x0000 }, /* R1517 */
1615 { 0x0000, 0x0000, 0x0000 }, /* R1518 */
1616 { 0x0000, 0x0000, 0x0000 }, /* R1519 */
1617 { 0x0000, 0x0000, 0x0000 }, /* R1520 */
1618 { 0x0000, 0x0000, 0x0000 }, /* R1521 */
1619 { 0x0000, 0x0000, 0x0000 }, /* R1522 */
1620 { 0x0000, 0x0000, 0x0000 }, /* R1523 */
1621 { 0x0000, 0x0000, 0x0000 }, /* R1524 */
1622 { 0x0000, 0x0000, 0x0000 }, /* R1525 */
1623 { 0x0000, 0x0000, 0x0000 }, /* R1526 */
1624 { 0x0000, 0x0000, 0x0000 }, /* R1527 */
1625 { 0x0000, 0x0000, 0x0000 }, /* R1528 */
1626 { 0x0000, 0x0000, 0x0000 }, /* R1529 */
1627 { 0x0000, 0x0000, 0x0000 }, /* R1530 */
1628 { 0x0000, 0x0000, 0x0000 }, /* R1531 */
1629 { 0x0000, 0x0000, 0x0000 }, /* R1532 */
1630 { 0x0000, 0x0000, 0x0000 }, /* R1533 */
1631 { 0x0000, 0x0000, 0x0000 }, /* R1534 */
1632 { 0x0000, 0x0000, 0x0000 }, /* R1535 */
1633 { 0x01EF, 0x01EF, 0x0000 }, /* R1536 - DAC1 Mixer Volumes */
1634 { 0x0037, 0x0037, 0x0000 }, /* R1537 - DAC1 Left Mixer Routing */
1635 { 0x0037, 0x0037, 0x0000 }, /* R1538 - DAC1 Right Mixer Routing */
1636 { 0x01EF, 0x01EF, 0x0000 }, /* R1539 - DAC2 Mixer Volumes */
1637 { 0x0037, 0x0037, 0x0000 }, /* R1540 - DAC2 Left Mixer Routing */
1638 { 0x0037, 0x0037, 0x0000 }, /* R1541 - DAC2 Right Mixer Routing */
1639 { 0x0003, 0x0003, 0x0000 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1640 { 0x0003, 0x0003, 0x0000 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1641 { 0x0003, 0x0003, 0x0000 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1642 { 0x0003, 0x0003, 0x0000 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1643 { 0x0000, 0x0000, 0x0000 }, /* R1546 */
1644 { 0x0000, 0x0000, 0x0000 }, /* R1547 */
1645 { 0x0000, 0x0000, 0x0000 }, /* R1548 */
1646 { 0x0000, 0x0000, 0x0000 }, /* R1549 */
1647 { 0x0000, 0x0000, 0x0000 }, /* R1550 */
1648 { 0x0000, 0x0000, 0x0000 }, /* R1551 */
1649 { 0x02FF, 0x03FF, 0x0000 }, /* R1552 - DAC1 Left Volume */
1650 { 0x02FF, 0x03FF, 0x0000 }, /* R1553 - DAC1 Right Volume */
1651 { 0x02FF, 0x03FF, 0x0000 }, /* R1554 - DAC2 Left Volume */
1652 { 0x02FF, 0x03FF, 0x0000 }, /* R1555 - DAC2 Right Volume */
1653 { 0x0003, 0x0003, 0x0000 }, /* R1556 - DAC Softmute */
1654 { 0x0000, 0x0000, 0x0000 }, /* R1557 */
1655 { 0x0000, 0x0000, 0x0000 }, /* R1558 */
1656 { 0x0000, 0x0000, 0x0000 }, /* R1559 */
1657 { 0x0000, 0x0000, 0x0000 }, /* R1560 */
1658 { 0x0000, 0x0000, 0x0000 }, /* R1561 */
1659 { 0x0000, 0x0000, 0x0000 }, /* R1562 */
1660 { 0x0000, 0x0000, 0x0000 }, /* R1563 */
1661 { 0x0000, 0x0000, 0x0000 }, /* R1564 */
1662 { 0x0000, 0x0000, 0x0000 }, /* R1565 */
1663 { 0x0000, 0x0000, 0x0000 }, /* R1566 */
1664 { 0x0000, 0x0000, 0x0000 }, /* R1567 */
1665 { 0x0003, 0x0003, 0x0000 }, /* R1568 - Oversampling */
1666 { 0x03C3, 0x03C3, 0x0000 }, /* R1569 - Sidetone */
1667};
1668
1669static int wm8994_readable(unsigned int reg)
1670{
1671 if (reg >= ARRAY_SIZE(access_masks))
1672 return 0;
1673 return access_masks[reg].readable != 0;
1674}
1675
1676static int wm8994_volatile(unsigned int reg)
1677{
1678 if (reg >= WM8994_REG_CACHE_SIZE)
1679 return 1;
1680
1681 switch (reg) {
1682 case WM8994_SOFTWARE_RESET:
1683 case WM8994_CHIP_REVISION:
1684 case WM8994_DC_SERVO_1:
1685 case WM8994_DC_SERVO_READBACK:
1686 case WM8994_RATE_STATUS:
1687 case WM8994_LDO_1:
1688 case WM8994_LDO_2:
1689 return 1;
1690 default:
1691 return 0;
1692 }
1693}
1694
1695static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1696 unsigned int value)
1697{
1698 struct wm8994_priv *wm8994 = codec->private_data;
1699
1700 BUG_ON(reg > WM8994_MAX_REGISTER);
1701
1702 if (!wm8994_volatile(reg))
1703 wm8994->reg_cache[reg] = value;
1704
1705 return wm8994_reg_write(codec->control_data, reg, value);
1706}
1707
1708static unsigned int wm8994_read(struct snd_soc_codec *codec,
1709 unsigned int reg)
1710{
1711 u16 *reg_cache = codec->reg_cache;
1712
1713 BUG_ON(reg > WM8994_MAX_REGISTER);
1714
1715 if (wm8994_volatile(reg))
1716 return wm8994_reg_read(codec->control_data, reg);
1717 else
1718 return reg_cache[reg];
1719}
1720
1721static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
1722{
1723 struct wm8994_priv *wm8994 = codec->private_data;
1724 int rate;
1725 int reg1 = 0;
1726 int offset;
1727
1728 if (aif)
1729 offset = 4;
1730 else
1731 offset = 0;
1732
1733 switch (wm8994->sysclk[aif]) {
1734 case WM8994_SYSCLK_MCLK1:
1735 rate = wm8994->mclk[0];
1736 break;
1737
1738 case WM8994_SYSCLK_MCLK2:
1739 reg1 |= 0x8;
1740 rate = wm8994->mclk[1];
1741 break;
1742
1743 case WM8994_SYSCLK_FLL1:
1744 reg1 |= 0x10;
1745 rate = wm8994->fll[0].out;
1746 break;
1747
1748 case WM8994_SYSCLK_FLL2:
1749 reg1 |= 0x18;
1750 rate = wm8994->fll[1].out;
1751 break;
1752
1753 default:
1754 return -EINVAL;
1755 }
1756
1757 if (rate >= 13500000) {
1758 rate /= 2;
1759 reg1 |= WM8994_AIF1CLK_DIV;
1760
1761 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
1762 aif + 1, rate);
1763 }
1764 wm8994->aifclk[aif] = rate;
1765
1766 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1 + offset,
1767 WM8994_AIF1CLK_SRC_MASK | WM8994_AIF1CLK_DIV,
1768 reg1);
1769
1770 return 0;
1771}
1772
1773static int configure_clock(struct snd_soc_codec *codec)
1774{
1775 struct wm8994_priv *wm8994 = codec->private_data;
1776 int old, new;
1777
1778 /* Bring up the AIF clocks first */
1779 configure_aif_clock(codec, 0);
1780 configure_aif_clock(codec, 1);
1781
1782 /* Then switch CLK_SYS over to the higher of them; a change
1783 * can only happen as a result of a clocking change which can
1784 * only be made outside of DAPM so we can safely redo the
1785 * clocking.
1786 */
1787
1788 /* If they're equal it doesn't matter which is used */
1789 if (wm8994->aifclk[0] == wm8994->aifclk[1])
1790 return 0;
1791
1792 if (wm8994->aifclk[0] < wm8994->aifclk[1])
1793 new = WM8994_SYSCLK_SRC;
1794 else
1795 new = 0;
1796
1797 old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC;
1798
1799 /* If there's no change then we're done. */
1800 if (old == new)
1801 return 0;
1802
1803 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1804
1805 snd_soc_dapm_sync(codec);
1806
1807 return 0;
1808}
1809
1810static int check_clk_sys(struct snd_soc_dapm_widget *source,
1811 struct snd_soc_dapm_widget *sink)
1812{
1813 int reg = snd_soc_read(source->codec, WM8994_CLOCKING_1);
1814 const char *clk;
1815
1816 /* Check what we're currently using for CLK_SYS */
1817 if (reg & WM8994_SYSCLK_SRC)
1818 clk = "AIF2CLK";
1819 else
1820 clk = "AIF1CLK";
1821
1822 return strcmp(source->name, clk) == 0;
1823}
1824
1825static const char *sidetone_hpf_text[] = {
1826 "2.7kHz", "1.35kHz", "675Hz", "370Hz", "180Hz", "90Hz", "45Hz"
1827};
1828
1829static const struct soc_enum sidetone_hpf =
1830 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1831
1832static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1833static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1834static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
1835static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0);
1836static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
1837
1838#define WM8994_DRC_SWITCH(xname, reg, shift) \
1839{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
1840 .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\
1841 .put = wm8994_put_drc_sw, \
1842 .private_value = SOC_SINGLE_VALUE(reg, shift, 1, 0) }
1843
1844static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol,
1845 struct snd_ctl_elem_value *ucontrol)
1846{
1847 struct soc_mixer_control *mc =
1848 (struct soc_mixer_control *)kcontrol->private_value;
1849 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1850 int mask, ret;
1851
1852 /* Can't enable both ADC and DAC paths simultaneously */
1853 if (mc->shift == WM8994_AIF1DAC1_DRC_ENA_SHIFT)
1854 mask = WM8994_AIF1ADC1L_DRC_ENA_MASK |
1855 WM8994_AIF1ADC1R_DRC_ENA_MASK;
1856 else
1857 mask = WM8994_AIF1DAC1_DRC_ENA_MASK;
1858
1859 ret = snd_soc_read(codec, mc->reg);
1860 if (ret < 0)
1861 return ret;
1862 if (ret & mask)
1863 return -EINVAL;
1864
1865 return snd_soc_put_volsw(kcontrol, ucontrol);
1866}
1867
1868
1869
1870static void wm8994_set_drc(struct snd_soc_codec *codec, int drc)
1871{
1872 struct wm8994_priv *wm8994 = codec->private_data;
1873 struct wm8994_pdata *pdata = wm8994->pdata;
1874 int base = wm8994_drc_base[drc];
1875 int cfg = wm8994->drc_cfg[drc];
1876 int save, i;
1877
1878 /* Save any enables; the configuration should clear them. */
1879 save = snd_soc_read(codec, base);
1880 save &= WM8994_AIF1DAC1_DRC_ENA | WM8994_AIF1ADC1L_DRC_ENA |
1881 WM8994_AIF1ADC1R_DRC_ENA;
1882
1883 for (i = 0; i < WM8994_DRC_REGS; i++)
1884 snd_soc_update_bits(codec, base + i, 0xffff,
1885 pdata->drc_cfgs[cfg].regs[i]);
1886
1887 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_DRC_ENA |
1888 WM8994_AIF1ADC1L_DRC_ENA |
1889 WM8994_AIF1ADC1R_DRC_ENA, save);
1890}
1891
1892/* Icky as hell but saves code duplication */
1893static int wm8994_get_drc(const char *name)
1894{
1895 if (strcmp(name, "AIF1DRC1 Mode") == 0)
1896 return 0;
1897 if (strcmp(name, "AIF1DRC2 Mode") == 0)
1898 return 1;
1899 if (strcmp(name, "AIF2DRC Mode") == 0)
1900 return 2;
1901 return -EINVAL;
1902}
1903
1904static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol,
1905 struct snd_ctl_elem_value *ucontrol)
1906{
1907 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1908 struct wm8994_priv *wm8994 = codec->private_data;
1909 struct wm8994_pdata *pdata = wm8994->pdata;
1910 int drc = wm8994_get_drc(kcontrol->id.name);
1911 int value = ucontrol->value.integer.value[0];
1912
1913 if (drc < 0)
1914 return drc;
1915
1916 if (value >= pdata->num_drc_cfgs)
1917 return -EINVAL;
1918
1919 wm8994->drc_cfg[drc] = value;
1920
1921 wm8994_set_drc(codec, drc);
1922
1923 return 0;
1924}
1925
1926static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol,
1927 struct snd_ctl_elem_value *ucontrol)
1928{
1929 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1930 struct wm8994_priv *wm8994 = codec->private_data;
1931 int drc = wm8994_get_drc(kcontrol->id.name);
1932
1933 ucontrol->value.enumerated.item[0] = wm8994->drc_cfg[drc];
1934
1935 return 0;
1936}
1937
1938static void wm8994_set_retune_mobile(struct snd_soc_codec *codec, int block)
1939{
1940 struct wm8994_priv *wm8994 = codec->private_data;
1941 struct wm8994_pdata *pdata = wm8994->pdata;
1942 int base = wm8994_retune_mobile_base[block];
1943 int iface, best, best_val, save, i, cfg;
1944
1945 if (!pdata || !wm8994->num_retune_mobile_texts)
1946 return;
1947
1948 switch (block) {
1949 case 0:
1950 case 1:
1951 iface = 0;
1952 break;
1953 case 2:
1954 iface = 1;
1955 break;
1956 default:
1957 return;
1958 }
1959
1960 /* Find the version of the currently selected configuration
1961 * with the nearest sample rate. */
1962 cfg = wm8994->retune_mobile_cfg[block];
1963 best = 0;
1964 best_val = INT_MAX;
1965 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
1966 if (strcmp(pdata->retune_mobile_cfgs[i].name,
1967 wm8994->retune_mobile_texts[cfg]) == 0 &&
1968 abs(pdata->retune_mobile_cfgs[i].rate
1969 - wm8994->dac_rates[iface]) < best_val) {
1970 best = i;
1971 best_val = abs(pdata->retune_mobile_cfgs[i].rate
1972 - wm8994->dac_rates[iface]);
1973 }
1974 }
1975
1976 dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",
1977 block,
1978 pdata->retune_mobile_cfgs[best].name,
1979 pdata->retune_mobile_cfgs[best].rate,
1980 wm8994->dac_rates[iface]);
1981
1982 /* The EQ will be disabled while reconfiguring it, remember the
1983 * current configuration.
1984 */
1985 save = snd_soc_read(codec, base);
1986 save &= WM8994_AIF1DAC1_EQ_ENA;
1987
1988 for (i = 0; i < WM8994_EQ_REGS; i++)
1989 snd_soc_update_bits(codec, base + i, 0xffff,
1990 pdata->retune_mobile_cfgs[best].regs[i]);
1991
1992 snd_soc_update_bits(codec, base, WM8994_AIF1DAC1_EQ_ENA, save);
1993}
1994
1995/* Icky as hell but saves code duplication */
1996static int wm8994_get_retune_mobile_block(const char *name)
1997{
1998 if (strcmp(name, "AIF1.1 EQ Mode") == 0)
1999 return 0;
2000 if (strcmp(name, "AIF1.2 EQ Mode") == 0)
2001 return 1;
2002 if (strcmp(name, "AIF2 EQ Mode") == 0)
2003 return 2;
2004 return -EINVAL;
2005}
2006
2007static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2008 struct snd_ctl_elem_value *ucontrol)
2009{
2010 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2011 struct wm8994_priv *wm8994 = codec->private_data;
2012 struct wm8994_pdata *pdata = wm8994->pdata;
2013 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2014 int value = ucontrol->value.integer.value[0];
2015
2016 if (block < 0)
2017 return block;
2018
2019 if (value >= pdata->num_retune_mobile_cfgs)
2020 return -EINVAL;
2021
2022 wm8994->retune_mobile_cfg[block] = value;
2023
2024 wm8994_set_retune_mobile(codec, block);
2025
2026 return 0;
2027}
2028
2029static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2030 struct snd_ctl_elem_value *ucontrol)
2031{
2032 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2033 struct wm8994_priv *wm8994 = codec->private_data;
2034 int block = wm8994_get_retune_mobile_block(kcontrol->id.name);
2035
2036 ucontrol->value.enumerated.item[0] = wm8994->retune_mobile_cfg[block];
2037
2038 return 0;
2039}
2040
2041static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2042SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
2043 WM8994_AIF1_ADC1_RIGHT_VOLUME,
2044 1, 119, 0, digital_tlv),
2045SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8994_AIF1_ADC2_LEFT_VOLUME,
2046 WM8994_AIF1_ADC2_RIGHT_VOLUME,
2047 1, 119, 0, digital_tlv),
2048SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2049 WM8994_AIF2_ADC_RIGHT_VOLUME,
2050 1, 119, 0, digital_tlv),
2051
2052SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2053 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2054SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8994_AIF1_DAC2_LEFT_VOLUME,
2055 WM8994_AIF1_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2056SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8994_AIF2_DAC_LEFT_VOLUME,
2057 WM8994_AIF2_DAC_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2058
2059SOC_SINGLE_TLV("AIF1 Boost Volume", WM8994_AIF1_CONTROL_2, 10, 3, 0, aif_tlv),
2060SOC_SINGLE_TLV("AIF2 Boost Volume", WM8994_AIF2_CONTROL_2, 10, 3, 0, aif_tlv),
2061
2062SOC_SINGLE("AIF1DAC1 EQ Switch", WM8994_AIF1_DAC1_EQ_GAINS_1, 0, 1, 0),
2063SOC_SINGLE("AIF1DAC2 EQ Switch", WM8994_AIF1_DAC2_EQ_GAINS_1, 0, 1, 0),
2064SOC_SINGLE("AIF2 EQ Switch", WM8994_AIF2_EQ_GAINS_1, 0, 1, 0),
2065
2066WM8994_DRC_SWITCH("AIF1DAC1 DRC Switch", WM8994_AIF1_DRC1_1, 2),
2067WM8994_DRC_SWITCH("AIF1ADC1L DRC Switch", WM8994_AIF1_DRC1_1, 1),
2068WM8994_DRC_SWITCH("AIF1ADC1R DRC Switch", WM8994_AIF1_DRC1_1, 0),
2069
2070WM8994_DRC_SWITCH("AIF1DAC2 DRC Switch", WM8994_AIF1_DRC2_1, 2),
2071WM8994_DRC_SWITCH("AIF1ADC2L DRC Switch", WM8994_AIF1_DRC2_1, 1),
2072WM8994_DRC_SWITCH("AIF1ADC2R DRC Switch", WM8994_AIF1_DRC2_1, 0),
2073
2074WM8994_DRC_SWITCH("AIF2DAC DRC Switch", WM8994_AIF2_DRC_1, 2),
2075WM8994_DRC_SWITCH("AIF2ADCL DRC Switch", WM8994_AIF2_DRC_1, 1),
2076WM8994_DRC_SWITCH("AIF2ADCR DRC Switch", WM8994_AIF2_DRC_1, 0),
2077
2078SOC_SINGLE_TLV("DAC1 Right Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2079 5, 12, 0, st_tlv),
2080SOC_SINGLE_TLV("DAC1 Left Sidetone Volume", WM8994_DAC1_MIXER_VOLUMES,
2081 0, 12, 0, st_tlv),
2082SOC_SINGLE_TLV("DAC2 Right Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2083 5, 12, 0, st_tlv),
2084SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2085 0, 12, 0, st_tlv),
2086SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2087SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2088
2089SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2090 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2091SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
2092 WM8994_DAC1_RIGHT_VOLUME, 9, 1, 1),
2093
2094SOC_DOUBLE_R_TLV("DAC2 Volume", WM8994_DAC2_LEFT_VOLUME,
2095 WM8994_DAC2_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2096SOC_DOUBLE_R("DAC2 Switch", WM8994_DAC2_LEFT_VOLUME,
2097 WM8994_DAC2_RIGHT_VOLUME, 9, 1, 1),
2098
2099SOC_SINGLE_TLV("SPKL DAC2 Volume", WM8994_SPKMIXL_ATTENUATION,
2100 6, 1, 1, wm_hubs_spkmix_tlv),
2101SOC_SINGLE_TLV("SPKL DAC1 Volume", WM8994_SPKMIXL_ATTENUATION,
2102 2, 1, 1, wm_hubs_spkmix_tlv),
2103
2104SOC_SINGLE_TLV("SPKR DAC2 Volume", WM8994_SPKMIXR_ATTENUATION,
2105 6, 1, 1, wm_hubs_spkmix_tlv),
2106SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2107 2, 1, 1, wm_hubs_spkmix_tlv),
2108
2109SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2110 10, 15, 0, wm8994_3d_tlv),
2111SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2112 8, 1, 0),
2113SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2114 10, 15, 0, wm8994_3d_tlv),
2115SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2116 8, 1, 0),
2117SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2118 10, 15, 0, wm8994_3d_tlv),
2119SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2120 8, 1, 0),
2121};
2122
2123static const struct snd_kcontrol_new wm8994_eq_controls[] = {
2124SOC_SINGLE_TLV("AIF1DAC1 EQ1 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 11, 31, 0,
2125 eq_tlv),
2126SOC_SINGLE_TLV("AIF1DAC1 EQ2 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 6, 31, 0,
2127 eq_tlv),
2128SOC_SINGLE_TLV("AIF1DAC1 EQ3 Volume", WM8994_AIF1_DAC1_EQ_GAINS_1, 1, 31, 0,
2129 eq_tlv),
2130SOC_SINGLE_TLV("AIF1DAC1 EQ4 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 11, 31, 0,
2131 eq_tlv),
2132SOC_SINGLE_TLV("AIF1DAC1 EQ5 Volume", WM8994_AIF1_DAC1_EQ_GAINS_2, 6, 31, 0,
2133 eq_tlv),
2134
2135SOC_SINGLE_TLV("AIF1DAC2 EQ1 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 11, 31, 0,
2136 eq_tlv),
2137SOC_SINGLE_TLV("AIF1DAC2 EQ2 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 6, 31, 0,
2138 eq_tlv),
2139SOC_SINGLE_TLV("AIF1DAC2 EQ3 Volume", WM8994_AIF1_DAC2_EQ_GAINS_1, 1, 31, 0,
2140 eq_tlv),
2141SOC_SINGLE_TLV("AIF1DAC2 EQ4 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 11, 31, 0,
2142 eq_tlv),
2143SOC_SINGLE_TLV("AIF1DAC2 EQ5 Volume", WM8994_AIF1_DAC2_EQ_GAINS_2, 6, 31, 0,
2144 eq_tlv),
2145
2146SOC_SINGLE_TLV("AIF2 EQ1 Volume", WM8994_AIF2_EQ_GAINS_1, 11, 31, 0,
2147 eq_tlv),
2148SOC_SINGLE_TLV("AIF2 EQ2 Volume", WM8994_AIF2_EQ_GAINS_1, 6, 31, 0,
2149 eq_tlv),
2150SOC_SINGLE_TLV("AIF2 EQ3 Volume", WM8994_AIF2_EQ_GAINS_1, 1, 31, 0,
2151 eq_tlv),
2152SOC_SINGLE_TLV("AIF2 EQ4 Volume", WM8994_AIF2_EQ_GAINS_2, 11, 31, 0,
2153 eq_tlv),
2154SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2155 eq_tlv),
2156};
2157
2158static int clk_sys_event(struct snd_soc_dapm_widget *w,
2159 struct snd_kcontrol *kcontrol, int event)
2160{
2161 struct snd_soc_codec *codec = w->codec;
2162
2163 switch (event) {
2164 case SND_SOC_DAPM_PRE_PMU:
2165 return configure_clock(codec);
2166
2167 case SND_SOC_DAPM_POST_PMD:
2168 configure_clock(codec);
2169 break;
2170 }
2171
2172 return 0;
2173}
2174
2175static void wm8994_update_class_w(struct snd_soc_codec *codec)
2176{
2177 int enable = 1;
2178 int source = 0; /* GCC flow analysis can't track enable */
2179 int reg, reg_r;
2180
2181 /* Only support direct DAC->headphone paths */
2182 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_1);
2183 if (!(reg & WM8994_DAC1L_TO_HPOUT1L)) {
2184 dev_dbg(codec->dev, "HPL connected to output mixer\n");
2185 enable = 0;
2186 }
2187
2188 reg = snd_soc_read(codec, WM8994_OUTPUT_MIXER_2);
2189 if (!(reg & WM8994_DAC1R_TO_HPOUT1R)) {
2190 dev_dbg(codec->dev, "HPR connected to output mixer\n");
2191 enable = 0;
2192 }
2193
2194 /* We also need the same setting for L/R and only one path */
2195 reg = snd_soc_read(codec, WM8994_DAC1_LEFT_MIXER_ROUTING);
2196 switch (reg) {
2197 case WM8994_AIF2DACL_TO_DAC1L:
2198 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
2199 source = 2 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2200 break;
2201 case WM8994_AIF1DAC2L_TO_DAC1L:
2202 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
2203 source = 1 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2204 break;
2205 case WM8994_AIF1DAC1L_TO_DAC1L:
2206 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
2207 source = 0 << WM8994_CP_DYN_SRC_SEL_SHIFT;
2208 break;
2209 default:
2210 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
2211 enable = 0;
2212 break;
2213 }
2214
2215 reg_r = snd_soc_read(codec, WM8994_DAC1_RIGHT_MIXER_ROUTING);
2216 if (reg_r != reg) {
2217 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
2218 enable = 0;
2219 }
2220
2221 if (enable) {
2222 dev_dbg(codec->dev, "Class W enabled\n");
2223 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2224 WM8994_CP_DYN_PWR |
2225 WM8994_CP_DYN_SRC_SEL_MASK,
2226 source | WM8994_CP_DYN_PWR);
2227
2228 } else {
2229 dev_dbg(codec->dev, "Class W disabled\n");
2230 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2231 WM8994_CP_DYN_PWR, 0);
2232 }
2233}
2234
2235static const char *hp_mux_text[] = {
2236 "Mixer",
2237 "DAC",
2238};
2239
2240#define WM8994_HP_ENUM(xname, xenum) \
2241{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2242 .info = snd_soc_info_enum_double, \
2243 .get = snd_soc_dapm_get_enum_double, \
2244 .put = wm8994_put_hp_enum, \
2245 .private_value = (unsigned long)&xenum }
2246
2247static int wm8994_put_hp_enum(struct snd_kcontrol *kcontrol,
2248 struct snd_ctl_elem_value *ucontrol)
2249{
2250 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2251 struct snd_soc_codec *codec = w->codec;
2252 int ret;
2253
2254 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
2255
2256 wm8994_update_class_w(codec);
2257
2258 return ret;
2259}
2260
2261static const struct soc_enum hpl_enum =
2262 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_1, 8, 2, hp_mux_text);
2263
2264static const struct snd_kcontrol_new hpl_mux =
2265 WM8994_HP_ENUM("Left Headphone Mux", hpl_enum);
2266
2267static const struct soc_enum hpr_enum =
2268 SOC_ENUM_SINGLE(WM8994_OUTPUT_MIXER_2, 8, 2, hp_mux_text);
2269
2270static const struct snd_kcontrol_new hpr_mux =
2271 WM8994_HP_ENUM("Right Headphone Mux", hpr_enum);
2272
2273static const char *adc_mux_text[] = {
2274 "ADC",
2275 "DMIC",
2276};
2277
2278static const struct soc_enum adc_enum =
2279 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
2280
2281static const struct snd_kcontrol_new adcl_mux =
2282 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
2283
2284static const struct snd_kcontrol_new adcr_mux =
2285 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
2286
2287static const struct snd_kcontrol_new left_speaker_mixer[] = {
2288SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0),
2289SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 7, 1, 0),
2290SOC_DAPM_SINGLE("IN1LP Switch", WM8994_SPEAKER_MIXER, 5, 1, 0),
2291SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 3, 1, 0),
2292SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 1, 1, 0),
2293};
2294
2295static const struct snd_kcontrol_new right_speaker_mixer[] = {
2296SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 8, 1, 0),
2297SOC_DAPM_SINGLE("Input Switch", WM8994_SPEAKER_MIXER, 6, 1, 0),
2298SOC_DAPM_SINGLE("IN1RP Switch", WM8994_SPEAKER_MIXER, 4, 1, 0),
2299SOC_DAPM_SINGLE("Output Switch", WM8994_SPEAKER_MIXER, 2, 1, 0),
2300SOC_DAPM_SINGLE("DAC1 Switch", WM8994_SPEAKER_MIXER, 0, 1, 0),
2301};
2302
2303/* Debugging; dump chip status after DAPM transitions */
2304static int post_ev(struct snd_soc_dapm_widget *w,
2305 struct snd_kcontrol *kcontrol, int event)
2306{
2307 struct snd_soc_codec *codec = w->codec;
2308 dev_dbg(codec->dev, "SRC status: %x\n",
2309 snd_soc_read(codec,
2310 WM8994_RATE_STATUS));
2311 return 0;
2312}
2313
2314static const struct snd_kcontrol_new aif1adc1l_mix[] = {
2315SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2316 1, 1, 0),
2317SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_LEFT_MIXER_ROUTING,
2318 0, 1, 0),
2319};
2320
2321static const struct snd_kcontrol_new aif1adc1r_mix[] = {
2322SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2323 1, 1, 0),
2324SOC_DAPM_SINGLE("AIF2 Switch", WM8994_AIF1_ADC1_RIGHT_MIXER_ROUTING,
2325 0, 1, 0),
2326};
2327
2328static const struct snd_kcontrol_new aif2dac2l_mix[] = {
2329SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2330 5, 1, 0),
2331SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2332 4, 1, 0),
2333SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2334 2, 1, 0),
2335SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2336 1, 1, 0),
2337SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_LEFT_MIXER_ROUTING,
2338 0, 1, 0),
2339};
2340
2341static const struct snd_kcontrol_new aif2dac2r_mix[] = {
2342SOC_DAPM_SINGLE("Right Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2343 5, 1, 0),
2344SOC_DAPM_SINGLE("Left Sidetone Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2345 4, 1, 0),
2346SOC_DAPM_SINGLE("AIF2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2347 2, 1, 0),
2348SOC_DAPM_SINGLE("AIF1.2 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2349 1, 1, 0),
2350SOC_DAPM_SINGLE("AIF1.1 Switch", WM8994_DAC2_RIGHT_MIXER_ROUTING,
2351 0, 1, 0),
2352};
2353
2354#define WM8994_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
2355{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
2356 .info = snd_soc_info_volsw, \
2357 .get = snd_soc_dapm_get_volsw, .put = wm8994_put_class_w, \
2358 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
2359
2360static int wm8994_put_class_w(struct snd_kcontrol *kcontrol,
2361 struct snd_ctl_elem_value *ucontrol)
2362{
2363 struct snd_soc_dapm_widget *w = snd_kcontrol_chip(kcontrol);
2364 struct snd_soc_codec *codec = w->codec;
2365 int ret;
2366
2367 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
2368
2369 wm8994_update_class_w(codec);
2370
2371 return ret;
2372}
2373
2374static const struct snd_kcontrol_new dac1l_mix[] = {
2375WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2376 5, 1, 0),
2377WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2378 4, 1, 0),
2379WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2380 2, 1, 0),
2381WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2382 1, 1, 0),
2383WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_LEFT_MIXER_ROUTING,
2384 0, 1, 0),
2385};
2386
2387static const struct snd_kcontrol_new dac1r_mix[] = {
2388WM8994_CLASS_W_SWITCH("Right Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2389 5, 1, 0),
2390WM8994_CLASS_W_SWITCH("Left Sidetone Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2391 4, 1, 0),
2392WM8994_CLASS_W_SWITCH("AIF2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2393 2, 1, 0),
2394WM8994_CLASS_W_SWITCH("AIF1.2 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2395 1, 1, 0),
2396WM8994_CLASS_W_SWITCH("AIF1.1 Switch", WM8994_DAC1_RIGHT_MIXER_ROUTING,
2397 0, 1, 0),
2398};
2399
2400static const char *sidetone_text[] = {
2401 "ADC/DMIC1", "DMIC2",
2402};
2403
2404static const struct soc_enum sidetone1_enum =
2405 SOC_ENUM_SINGLE(WM8994_SIDETONE, 0, 2, sidetone_text);
2406
2407static const struct snd_kcontrol_new sidetone1_mux =
2408 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
2409
2410static const struct soc_enum sidetone2_enum =
2411 SOC_ENUM_SINGLE(WM8994_SIDETONE, 1, 2, sidetone_text);
2412
2413static const struct snd_kcontrol_new sidetone2_mux =
2414 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
2415
2416static const char *aif1dac_text[] = {
2417 "AIF1DACDAT", "AIF3DACDAT",
2418};
2419
2420static const struct soc_enum aif1dac_enum =
2421 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 0, 2, aif1dac_text);
2422
2423static const struct snd_kcontrol_new aif1dac_mux =
2424 SOC_DAPM_ENUM("AIF1DAC Mux", aif1dac_enum);
2425
2426static const char *aif2dac_text[] = {
2427 "AIF2DACDAT", "AIF3DACDAT",
2428};
2429
2430static const struct soc_enum aif2dac_enum =
2431 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 1, 2, aif2dac_text);
2432
2433static const struct snd_kcontrol_new aif2dac_mux =
2434 SOC_DAPM_ENUM("AIF2DAC Mux", aif2dac_enum);
2435
2436static const char *aif2adc_text[] = {
2437 "AIF2ADCDAT", "AIF3DACDAT",
2438};
2439
2440static const struct soc_enum aif2adc_enum =
2441 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 2, 2, aif2adc_text);
2442
2443static const struct snd_kcontrol_new aif2adc_mux =
2444 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2445
2446static const char *aif3adc_text[] = {
2447 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT",
2448};
2449
2450static const struct soc_enum aif3adc_enum =
2451 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2452
2453static const struct snd_kcontrol_new aif3adc_mux =
2454 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum);
2455
2456static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2457SND_SOC_DAPM_INPUT("DMIC1DAT"),
2458SND_SOC_DAPM_INPUT("DMIC2DAT"),
2459
2460SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
2461 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2462
2463SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8994_CLOCKING_1, 3, 0, NULL, 0),
2464SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8994_CLOCKING_1, 2, 0, NULL, 0),
2465SND_SOC_DAPM_SUPPLY("DSPINTCLK", WM8994_CLOCKING_1, 1, 0, NULL, 0),
2466
2467SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8994_AIF1_CLOCKING_1, 0, 0, NULL, 0),
2468SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8994_AIF2_CLOCKING_1, 0, 0, NULL, 0),
2469
2470SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2471 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2472SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2473 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2474SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0,
2475 WM8994_POWER_MANAGEMENT_5, 9, 0),
2476SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0,
2477 WM8994_POWER_MANAGEMENT_5, 8, 0),
2478
2479SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2480 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2481SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2482 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2483SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0,
2484 WM8994_POWER_MANAGEMENT_5, 11, 0),
2485SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0,
2486 WM8994_POWER_MANAGEMENT_5, 10, 0),
2487
2488SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2489 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
2490SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
2491 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
2492
2493SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
2494 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
2495SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
2496 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
2497
2498SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
2499SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
2500
2501SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,
2502 dac1l_mix, ARRAY_SIZE(dac1l_mix)),
2503SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,
2504 dac1r_mix, ARRAY_SIZE(dac1r_mix)),
2505
2506SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2507 WM8994_POWER_MANAGEMENT_4, 13, 0),
2508SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2509 WM8994_POWER_MANAGEMENT_4, 12, 0),
2510SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0,
2511 WM8994_POWER_MANAGEMENT_5, 13, 0),
2512SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0,
2513 WM8994_POWER_MANAGEMENT_5, 12, 0),
2514
2515SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2516SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
2517SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2518
2519SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2520SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2521SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2522SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2523
2524SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2525SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
2526
2527SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0),
2528
2529SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8994_POWER_MANAGEMENT_4, 5, 0),
2530SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8994_POWER_MANAGEMENT_4, 4, 0),
2531SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8994_POWER_MANAGEMENT_4, 3, 0),
2532SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8994_POWER_MANAGEMENT_4, 2, 0),
2533
2534/* Power is done with the muxes since the ADC power also controls the
2535 * downsampling chain, the chip will automatically manage the analogue
2536 * specific portions.
2537 */
2538SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 1, 0),
2539SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0),
2540
2541SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux),
2542SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux),
2543
2544SND_SOC_DAPM_DAC("DAC2L", NULL, WM8994_POWER_MANAGEMENT_5, 3, 0),
2545SND_SOC_DAPM_DAC("DAC2R", NULL, WM8994_POWER_MANAGEMENT_5, 2, 0),
2546SND_SOC_DAPM_DAC("DAC1L", NULL, WM8994_POWER_MANAGEMENT_5, 1, 0),
2547SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0),
2548
2549SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, &hpl_mux),
2550SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, &hpr_mux),
2551
2552SND_SOC_DAPM_MIXER("SPKL", WM8994_POWER_MANAGEMENT_3, 8, 0,
2553 left_speaker_mixer, ARRAY_SIZE(left_speaker_mixer)),
2554SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2555 right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)),
2556
2557SND_SOC_DAPM_POST("Debug log", post_ev),
2558};
2559
2560static const struct snd_soc_dapm_route intercon[] = {
2561
2562 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2563 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2564
2565 { "DSP1CLK", NULL, "CLK_SYS" },
2566 { "DSP2CLK", NULL, "CLK_SYS" },
2567 { "DSPINTCLK", NULL, "CLK_SYS" },
2568
2569 { "AIF1ADC1L", NULL, "AIF1CLK" },
2570 { "AIF1ADC1L", NULL, "DSP1CLK" },
2571 { "AIF1ADC1R", NULL, "AIF1CLK" },
2572 { "AIF1ADC1R", NULL, "DSP1CLK" },
2573 { "AIF1ADC1R", NULL, "DSPINTCLK" },
2574
2575 { "AIF1DAC1L", NULL, "AIF1CLK" },
2576 { "AIF1DAC1L", NULL, "DSP1CLK" },
2577 { "AIF1DAC1R", NULL, "AIF1CLK" },
2578 { "AIF1DAC1R", NULL, "DSP1CLK" },
2579 { "AIF1DAC1R", NULL, "DSPINTCLK" },
2580
2581 { "AIF1ADC2L", NULL, "AIF1CLK" },
2582 { "AIF1ADC2L", NULL, "DSP1CLK" },
2583 { "AIF1ADC2R", NULL, "AIF1CLK" },
2584 { "AIF1ADC2R", NULL, "DSP1CLK" },
2585 { "AIF1ADC2R", NULL, "DSPINTCLK" },
2586
2587 { "AIF1DAC2L", NULL, "AIF1CLK" },
2588 { "AIF1DAC2L", NULL, "DSP1CLK" },
2589 { "AIF1DAC2R", NULL, "AIF1CLK" },
2590 { "AIF1DAC2R", NULL, "DSP1CLK" },
2591 { "AIF1DAC2R", NULL, "DSPINTCLK" },
2592
2593 { "AIF2ADCL", NULL, "AIF2CLK" },
2594 { "AIF2ADCL", NULL, "DSP2CLK" },
2595 { "AIF2ADCR", NULL, "AIF2CLK" },
2596 { "AIF2ADCR", NULL, "DSP2CLK" },
2597 { "AIF2ADCR", NULL, "DSPINTCLK" },
2598
2599 { "AIF2DACL", NULL, "AIF2CLK" },
2600 { "AIF2DACL", NULL, "DSP2CLK" },
2601 { "AIF2DACR", NULL, "AIF2CLK" },
2602 { "AIF2DACR", NULL, "DSP2CLK" },
2603 { "AIF2DACR", NULL, "DSPINTCLK" },
2604
2605 { "DMIC1L", NULL, "DMIC1DAT" },
2606 { "DMIC1L", NULL, "CLK_SYS" },
2607 { "DMIC1R", NULL, "DMIC1DAT" },
2608 { "DMIC1R", NULL, "CLK_SYS" },
2609 { "DMIC2L", NULL, "DMIC2DAT" },
2610 { "DMIC2L", NULL, "CLK_SYS" },
2611 { "DMIC2R", NULL, "DMIC2DAT" },
2612 { "DMIC2R", NULL, "CLK_SYS" },
2613
2614 { "ADCL", NULL, "AIF1CLK" },
2615 { "ADCL", NULL, "DSP1CLK" },
2616 { "ADCL", NULL, "DSPINTCLK" },
2617
2618 { "ADCR", NULL, "AIF1CLK" },
2619 { "ADCR", NULL, "DSP1CLK" },
2620 { "ADCR", NULL, "DSPINTCLK" },
2621
2622 { "ADCL Mux", "ADC", "ADCL" },
2623 { "ADCL Mux", "DMIC", "DMIC1L" },
2624 { "ADCR Mux", "ADC", "ADCR" },
2625 { "ADCR Mux", "DMIC", "DMIC1R" },
2626
2627 { "DAC1L", NULL, "AIF1CLK" },
2628 { "DAC1L", NULL, "DSP1CLK" },
2629 { "DAC1L", NULL, "DSPINTCLK" },
2630
2631 { "DAC1R", NULL, "AIF1CLK" },
2632 { "DAC1R", NULL, "DSP1CLK" },
2633 { "DAC1R", NULL, "DSPINTCLK" },
2634
2635 { "DAC2L", NULL, "AIF2CLK" },
2636 { "DAC2L", NULL, "DSP2CLK" },
2637 { "DAC2L", NULL, "DSPINTCLK" },
2638
2639 { "DAC2R", NULL, "AIF2DACR" },
2640 { "DAC2R", NULL, "AIF2CLK" },
2641 { "DAC2R", NULL, "DSP2CLK" },
2642 { "DAC2R", NULL, "DSPINTCLK" },
2643
2644 { "TOCLK", NULL, "CLK_SYS" },
2645
2646 /* AIF1 outputs */
2647 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
2648 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
2649 { "AIF1ADC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2650
2651 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
2652 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
2653 { "AIF1ADC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2654
2655 /* Pin level routing for AIF3 */
2656 { "AIF1DAC1L", NULL, "AIF1DAC Mux" },
2657 { "AIF1DAC1R", NULL, "AIF1DAC Mux" },
2658 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2659 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2660
2661 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2662 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2663
2664 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2665 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2666 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
2667 { "AIF2DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2668 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCL" },
2669 { "AIF2ADC Mux", "AIF2ADCDAT", "AIF2ADCR" },
2670 { "AIF2ADC Mux", "AIF3DACDAT", "AIF3ADCDAT" },
2671
2672 /* DAC1 inputs */
2673 { "DAC1L", NULL, "DAC1L Mixer" },
2674 { "DAC1L Mixer", "AIF2 Switch", "AIF2DACL" },
2675 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2676 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2677 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2678 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2679
2680 { "DAC1R", NULL, "DAC1R Mixer" },
2681 { "DAC1R Mixer", "AIF2 Switch", "AIF2DACR" },
2682 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2683 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2684 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2685 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2686
2687 /* DAC2/AIF2 outputs */
2688 { "AIF2ADCL", NULL, "AIF2DAC2L Mixer" },
2689 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
2690 { "AIF2DAC2L Mixer", "AIF2 Switch", "AIF2DACL" },
2691 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
2692 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
2693 { "AIF2DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },
2694 { "AIF2DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },
2695
2696 { "AIF2ADCR", NULL, "AIF2DAC2R Mixer" },
2697 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
2698 { "AIF2DAC2R Mixer", "AIF2 Switch", "AIF2DACR" },
2699 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
2700 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
2701 { "AIF2DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },
2702 { "AIF2DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },
2703
2704 { "AIF2ADCDAT", NULL, "AIF2ADC Mux" },
2705
2706 /* AIF3 output */
2707 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1L" },
2708 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC1R" },
2709 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2L" },
2710 { "AIF3ADCDAT", "AIF1ADCDAT", "AIF1ADC2R" },
2711 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCL" },
2712 { "AIF3ADCDAT", "AIF2ADCDAT", "AIF2ADCR" },
2713 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACL" },
2714 { "AIF3ADCDAT", "AIF2DACDAT", "AIF2DACR" },
2715
2716 /* Sidetone */
2717 { "Left Sidetone", "ADC/DMIC1", "ADCL Mux" },
2718 { "Left Sidetone", "DMIC2", "DMIC2L" },
2719 { "Right Sidetone", "ADC/DMIC1", "ADCR Mux" },
2720 { "Right Sidetone", "DMIC2", "DMIC2R" },
2721
2722 /* Output stages */
2723 { "Left Output Mixer", "DAC Switch", "DAC1L" },
2724 { "Right Output Mixer", "DAC Switch", "DAC1R" },
2725
2726 { "SPKL", "DAC1 Switch", "DAC1L" },
2727 { "SPKL", "DAC2 Switch", "DAC2L" },
2728
2729 { "SPKR", "DAC1 Switch", "DAC1R" },
2730 { "SPKR", "DAC2 Switch", "DAC2R" },
2731
2732 { "Left Headphone Mux", "DAC", "DAC1L" },
2733 { "Right Headphone Mux", "DAC", "DAC1R" },
2734};
2735
2736/* The size in bits of the FLL divide multiplied by 10
2737 * to allow rounding later */
2738#define FIXED_FLL_SIZE ((1 << 16) * 10)
2739
2740struct fll_div {
2741 u16 outdiv;
2742 u16 n;
2743 u16 k;
2744 u16 clk_ref_div;
2745 u16 fll_fratio;
2746};
2747
2748static int wm8994_get_fll_config(struct fll_div *fll,
2749 int freq_in, int freq_out)
2750{
2751 u64 Kpart;
2752 unsigned int K, Ndiv, Nmod;
2753
2754 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
2755
2756 /* Scale the input frequency down to <= 13.5MHz */
2757 fll->clk_ref_div = 0;
2758 while (freq_in > 13500000) {
2759 fll->clk_ref_div++;
2760 freq_in /= 2;
2761
2762 if (fll->clk_ref_div > 3)
2763 return -EINVAL;
2764 }
2765 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
2766
2767 /* Scale the output to give 90MHz<=Fvco<=100MHz */
2768 fll->outdiv = 3;
2769 while (freq_out * (fll->outdiv + 1) < 90000000) {
2770 fll->outdiv++;
2771 if (fll->outdiv > 63)
2772 return -EINVAL;
2773 }
2774 freq_out *= fll->outdiv + 1;
2775 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
2776
2777 if (freq_in > 1000000) {
2778 fll->fll_fratio = 0;
2779 } else {
2780 fll->fll_fratio = 3;
2781 freq_in *= 8;
2782 }
2783 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
2784
2785 /* Now, calculate N.K */
2786 Ndiv = freq_out / freq_in;
2787
2788 fll->n = Ndiv;
2789 Nmod = freq_out % freq_in;
2790 pr_debug("Nmod=%d\n", Nmod);
2791
2792 /* Calculate fractional part - scale up so we can round. */
2793 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
2794
2795 do_div(Kpart, freq_in);
2796
2797 K = Kpart & 0xFFFFFFFF;
2798
2799 if ((K % 10) >= 5)
2800 K += 5;
2801
2802 /* Move down to proper range now rounding is done */
2803 fll->k = K / 10;
2804
2805 pr_debug("N=%x K=%x\n", fll->n, fll->k);
2806
2807 return 0;
2808}
2809
2810static int wm8994_set_fll(struct snd_soc_dai *dai, int id, int src,
2811 unsigned int freq_in, unsigned int freq_out)
2812{
2813 struct snd_soc_codec *codec = dai->codec;
2814 struct wm8994_priv *wm8994 = codec->private_data;
2815 int reg_offset, ret;
2816 struct fll_div fll;
2817 u16 reg, aif1, aif2;
2818
2819 aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1)
2820 & WM8994_AIF1CLK_ENA;
2821
2822 aif2 = snd_soc_read(codec, WM8994_AIF2_CLOCKING_1)
2823 & WM8994_AIF2CLK_ENA;
2824
2825 switch (id) {
2826 case WM8994_FLL1:
2827 reg_offset = 0;
2828 id = 0;
2829 break;
2830 case WM8994_FLL2:
2831 reg_offset = 0x20;
2832 id = 1;
2833 break;
2834 default:
2835 return -EINVAL;
2836 }
2837
2838 /* Are we changing anything? */
2839 if (wm8994->fll[id].src == src &&
2840 wm8994->fll[id].in == freq_in && wm8994->fll[id].out == freq_out)
2841 return 0;
2842
2843 /* If we're stopping the FLL redo the old config - no
2844 * registers will actually be written but we avoid GCC flow
2845 * analysis bugs spewing warnings.
2846 */
2847 if (freq_out)
2848 ret = wm8994_get_fll_config(&fll, freq_in, freq_out);
2849 else
2850 ret = wm8994_get_fll_config(&fll, wm8994->fll[id].in,
2851 wm8994->fll[id].out);
2852 if (ret < 0)
2853 return ret;
2854
2855 /* Gate the AIF clocks while we reclock */
2856 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2857 WM8994_AIF1CLK_ENA, 0);
2858 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2859 WM8994_AIF2CLK_ENA, 0);
2860
2861 /* We always need to disable the FLL while reconfiguring */
2862 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2863 WM8994_FLL1_ENA, 0);
2864
2865 reg = (fll.outdiv << WM8994_FLL1_OUTDIV_SHIFT) |
2866 (fll.fll_fratio << WM8994_FLL1_FRATIO_SHIFT);
2867 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_2 + reg_offset,
2868 WM8994_FLL1_OUTDIV_MASK |
2869 WM8994_FLL1_FRATIO_MASK, reg);
2870
2871 snd_soc_write(codec, WM8994_FLL1_CONTROL_3 + reg_offset, fll.k);
2872
2873 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_4 + reg_offset,
2874 WM8994_FLL1_N_MASK,
2875 fll.n << WM8994_FLL1_N_SHIFT);
2876
2877 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_5 + reg_offset,
2878 WM8994_FLL1_REFCLK_DIV_MASK,
2879 fll.clk_ref_div << WM8994_FLL1_REFCLK_DIV_SHIFT);
2880
2881 /* Enable (with fractional mode if required) */
2882 if (freq_out) {
2883 if (fll.k)
2884 reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC;
2885 else
2886 reg = WM8994_FLL1_ENA;
2887 snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset,
2888 WM8994_FLL1_ENA | WM8994_FLL1_FRAC,
2889 reg);
2890 }
2891
2892 wm8994->fll[id].in = freq_in;
2893 wm8994->fll[id].out = freq_out;
2894
2895 /* Enable any gated AIF clocks */
2896 snd_soc_update_bits(codec, WM8994_AIF1_CLOCKING_1,
2897 WM8994_AIF1CLK_ENA, aif1);
2898 snd_soc_update_bits(codec, WM8994_AIF2_CLOCKING_1,
2899 WM8994_AIF2CLK_ENA, aif2);
2900
2901 configure_clock(codec);
2902
2903 return 0;
2904}
2905
2906static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
2907 int clk_id, unsigned int freq, int dir)
2908{
2909 struct snd_soc_codec *codec = dai->codec;
2910 struct wm8994_priv *wm8994 = codec->private_data;
2911
2912 switch (dai->id) {
2913 case 1:
2914 case 2:
2915 break;
2916
2917 default:
2918 /* AIF3 shares clocking with AIF1/2 */
2919 return -EINVAL;
2920 }
2921
2922 switch (clk_id) {
2923 case WM8994_SYSCLK_MCLK1:
2924 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK1;
2925 wm8994->mclk[0] = freq;
2926 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
2927 dai->id, freq);
2928 break;
2929
2930 case WM8994_SYSCLK_MCLK2:
2931 /* TODO: Set GPIO AF */
2932 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_MCLK2;
2933 wm8994->mclk[1] = freq;
2934 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
2935 dai->id, freq);
2936 break;
2937
2938 case WM8994_SYSCLK_FLL1:
2939 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL1;
2940 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id);
2941 break;
2942
2943 case WM8994_SYSCLK_FLL2:
2944 wm8994->sysclk[dai->id - 1] = WM8994_SYSCLK_FLL2;
2945 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id);
2946 break;
2947
2948 default:
2949 return -EINVAL;
2950 }
2951
2952 configure_clock(codec);
2953
2954 return 0;
2955}
2956
2957static int wm8994_set_bias_level(struct snd_soc_codec *codec,
2958 enum snd_soc_bias_level level)
2959{
2960 switch (level) {
2961 case SND_SOC_BIAS_ON:
2962 break;
2963
2964 case SND_SOC_BIAS_PREPARE:
2965 /* VMID=2x40k */
2966 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2967 WM8994_VMID_SEL_MASK, 0x2);
2968 break;
2969
2970 case SND_SOC_BIAS_STANDBY:
2971 if (codec->bias_level == SND_SOC_BIAS_OFF) {
2972 /* Tweak DC servo configuration for improved
2973 * performance. */
2974 snd_soc_write(codec, 0x102, 0x3);
2975 snd_soc_write(codec, 0x56, 0x3);
2976 snd_soc_write(codec, 0x102, 0);
2977
2978 /* Discharge LINEOUT1 & 2 */
2979 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
2980 WM8994_LINEOUT1_DISCH |
2981 WM8994_LINEOUT2_DISCH,
2982 WM8994_LINEOUT1_DISCH |
2983 WM8994_LINEOUT2_DISCH);
2984
2985 /* Startup bias, VMID ramp & buffer */
2986 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2987 WM8994_STARTUP_BIAS_ENA |
2988 WM8994_VMID_BUF_ENA |
2989 WM8994_VMID_RAMP_MASK,
2990 WM8994_STARTUP_BIAS_ENA |
2991 WM8994_VMID_BUF_ENA |
2992 (0x11 << WM8994_VMID_RAMP_SHIFT));
2993
2994 /* Main bias enable, VMID=2x40k */
2995 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
2996 WM8994_BIAS_ENA |
2997 WM8994_VMID_SEL_MASK,
2998 WM8994_BIAS_ENA | 0x2);
2999
3000 msleep(20);
3001 }
3002
3003 /* VMID=2x500k */
3004 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3005 WM8994_VMID_SEL_MASK, 0x4);
3006
3007 break;
3008
3009 case SND_SOC_BIAS_OFF:
3010 /* Switch over to startup biases */
3011 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3012 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3013 WM8994_VMID_BUF_ENA |
3014 WM8994_VMID_RAMP_MASK,
3015 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3016 WM8994_VMID_BUF_ENA |
3017 (1 << WM8994_VMID_RAMP_SHIFT));
3018
3019 /* Disable main biases */
3020 snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
3021 WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
3022
3023 /* Discharge line */
3024 snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
3025 WM8994_LINEOUT1_DISCH |
3026 WM8994_LINEOUT2_DISCH,
3027 WM8994_LINEOUT1_DISCH |
3028 WM8994_LINEOUT2_DISCH);
3029
3030 msleep(5);
3031
3032 /* Switch off startup biases */
3033 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3034 WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
3035 WM8994_VMID_BUF_ENA |
3036 WM8994_VMID_RAMP_MASK, 0);
3037
3038 break;
3039 }
3040 codec->bias_level = level;
3041 return 0;
3042}
3043
3044static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3045{
3046 struct snd_soc_codec *codec = dai->codec;
3047 int ms_reg;
3048 int aif1_reg;
3049 int ms = 0;
3050 int aif1 = 0;
3051
3052 switch (dai->id) {
3053 case 1:
3054 ms_reg = WM8994_AIF1_MASTER_SLAVE;
3055 aif1_reg = WM8994_AIF1_CONTROL_1;
3056 break;
3057 case 2:
3058 ms_reg = WM8994_AIF2_MASTER_SLAVE;
3059 aif1_reg = WM8994_AIF2_CONTROL_1;
3060 break;
3061 default:
3062 return -EINVAL;
3063 }
3064
3065 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
3066 case SND_SOC_DAIFMT_CBS_CFS:
3067 break;
3068 case SND_SOC_DAIFMT_CBM_CFM:
3069 ms = WM8994_AIF1_MSTR;
3070 break;
3071 default:
3072 return -EINVAL;
3073 }
3074
3075 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3076 case SND_SOC_DAIFMT_DSP_B:
3077 aif1 |= WM8994_AIF1_LRCLK_INV;
3078 case SND_SOC_DAIFMT_DSP_A:
3079 aif1 |= 0x18;
3080 break;
3081 case SND_SOC_DAIFMT_I2S:
3082 aif1 |= 0x10;
3083 break;
3084 case SND_SOC_DAIFMT_RIGHT_J:
3085 break;
3086 case SND_SOC_DAIFMT_LEFT_J:
3087 aif1 |= 0x8;
3088 break;
3089 default:
3090 return -EINVAL;
3091 }
3092
3093 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
3094 case SND_SOC_DAIFMT_DSP_A:
3095 case SND_SOC_DAIFMT_DSP_B:
3096 /* frame inversion not valid for DSP modes */
3097 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3098 case SND_SOC_DAIFMT_NB_NF:
3099 break;
3100 case SND_SOC_DAIFMT_IB_NF:
3101 aif1 |= WM8994_AIF1_BCLK_INV;
3102 break;
3103 default:
3104 return -EINVAL;
3105 }
3106 break;
3107
3108 case SND_SOC_DAIFMT_I2S:
3109 case SND_SOC_DAIFMT_RIGHT_J:
3110 case SND_SOC_DAIFMT_LEFT_J:
3111 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
3112 case SND_SOC_DAIFMT_NB_NF:
3113 break;
3114 case SND_SOC_DAIFMT_IB_IF:
3115 aif1 |= WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV;
3116 break;
3117 case SND_SOC_DAIFMT_IB_NF:
3118 aif1 |= WM8994_AIF1_BCLK_INV;
3119 break;
3120 case SND_SOC_DAIFMT_NB_IF:
3121 aif1 |= WM8994_AIF1_LRCLK_INV;
3122 break;
3123 default:
3124 return -EINVAL;
3125 }
3126 break;
3127 default:
3128 return -EINVAL;
3129 }
3130
3131 snd_soc_update_bits(codec, aif1_reg,
3132 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3133 WM8994_AIF1_FMT_MASK,
3134 aif1);
3135 snd_soc_update_bits(codec, ms_reg, WM8994_AIF1_MSTR,
3136 ms);
3137
3138 return 0;
3139}
3140
3141static struct {
3142 int val, rate;
3143} srs[] = {
3144 { 0, 8000 },
3145 { 1, 11025 },
3146 { 2, 12000 },
3147 { 3, 16000 },
3148 { 4, 22050 },
3149 { 5, 24000 },
3150 { 6, 32000 },
3151 { 7, 44100 },
3152 { 8, 48000 },
3153 { 9, 88200 },
3154 { 10, 96000 },
3155};
3156
3157static int fs_ratios[] = {
3158 64, 128, 192, 256, 348, 512, 768, 1024, 1408, 1536
3159};
3160
3161static int bclk_divs[] = {
3162 10, 15, 20, 30, 40, 50, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480,
3163 640, 880, 960, 1280, 1760, 1920
3164};
3165
3166static int wm8994_hw_params(struct snd_pcm_substream *substream,
3167 struct snd_pcm_hw_params *params,
3168 struct snd_soc_dai *dai)
3169{
3170 struct snd_soc_codec *codec = dai->codec;
3171 struct wm8994_priv *wm8994 = codec->private_data;
3172 int aif1_reg;
3173 int bclk_reg;
3174 int lrclk_reg;
3175 int rate_reg;
3176 int aif1 = 0;
3177 int bclk = 0;
3178 int lrclk = 0;
3179 int rate_val = 0;
3180 int id = dai->id - 1;
3181
3182 int i, cur_val, best_val, bclk_rate, best;
3183
3184 switch (dai->id) {
3185 case 1:
3186 aif1_reg = WM8994_AIF1_CONTROL_1;
3187 bclk_reg = WM8994_AIF1_BCLK;
3188 rate_reg = WM8994_AIF1_RATE;
3189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3190 wm8994->lrclk_shared[0])
3191 lrclk_reg = WM8994_AIF1DAC_LRCLK;
3192 else
3193 lrclk_reg = WM8994_AIF1ADC_LRCLK;
3194 break;
3195 case 2:
3196 aif1_reg = WM8994_AIF2_CONTROL_1;
3197 bclk_reg = WM8994_AIF2_BCLK;
3198 rate_reg = WM8994_AIF2_RATE;
3199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
3200 wm8994->lrclk_shared[1])
3201 lrclk_reg = WM8994_AIF2DAC_LRCLK;
3202 else
3203 lrclk_reg = WM8994_AIF2ADC_LRCLK;
3204 break;
3205 default:
3206 return -EINVAL;
3207 }
3208
3209 bclk_rate = params_rate(params) * 2;
3210 switch (params_format(params)) {
3211 case SNDRV_PCM_FORMAT_S16_LE:
3212 bclk_rate *= 16;
3213 break;
3214 case SNDRV_PCM_FORMAT_S20_3LE:
3215 bclk_rate *= 20;
3216 aif1 |= 0x20;
3217 break;
3218 case SNDRV_PCM_FORMAT_S24_LE:
3219 bclk_rate *= 24;
3220 aif1 |= 0x40;
3221 break;
3222 case SNDRV_PCM_FORMAT_S32_LE:
3223 bclk_rate *= 32;
3224 aif1 |= 0x60;
3225 break;
3226 default:
3227 return -EINVAL;
3228 }
3229
3230 /* Try to find an appropriate sample rate; look for an exact match. */
3231 for (i = 0; i < ARRAY_SIZE(srs); i++)
3232 if (srs[i].rate == params_rate(params))
3233 break;
3234 if (i == ARRAY_SIZE(srs))
3235 return -EINVAL;
3236 rate_val |= srs[i].val << WM8994_AIF1_SR_SHIFT;
3237
3238 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i].rate);
3239 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3240 dai->id, wm8994->aifclk[id], bclk_rate);
3241
3242 if (wm8994->aifclk[id] == 0) {
3243 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3244 return -EINVAL;
3245 }
3246
3247 /* AIFCLK/fs ratio; look for a close match in either direction */
3248 best = 0;
3249 best_val = abs((fs_ratios[0] * params_rate(params))
3250 - wm8994->aifclk[id]);
3251 for (i = 1; i < ARRAY_SIZE(fs_ratios); i++) {
3252 cur_val = abs((fs_ratios[i] * params_rate(params))
3253 - wm8994->aifclk[id]);
3254 if (cur_val >= best_val)
3255 continue;
3256 best = i;
3257 best_val = cur_val;
3258 }
3259 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
3260 dai->id, fs_ratios[best]);
3261 rate_val |= best;
3262
3263 /* We may not get quite the right frequency if using
3264 * approximate clocks so look for the closest match that is
3265 * higher than the target (we need to ensure that there enough
3266 * BCLKs to clock out the samples).
3267 */
3268 best = 0;
3269 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
3270 cur_val = (wm8994->aifclk[id] * 10 / bclk_divs[i]) - bclk_rate;
3271 if (cur_val < 0) /* BCLK table is sorted */
3272 break;
3273 best = i;
3274 }
3275 bclk_rate = wm8994->aifclk[id] * 10 / bclk_divs[best];
3276 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
3277 bclk_divs[best], bclk_rate);
3278 bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT;
3279
3280 lrclk = bclk_rate / params_rate(params);
3281 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
3282 lrclk, bclk_rate / lrclk);
3283
3284 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
3285 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3286 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3287 lrclk);
3288 snd_soc_update_bits(codec, rate_reg, WM8994_AIF1_SR_MASK |
3289 WM8994_AIF1CLK_RATE_MASK, rate_val);
3290
3291 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3292 switch (dai->id) {
3293 case 1:
3294 wm8994->dac_rates[0] = params_rate(params);
3295 wm8994_set_retune_mobile(codec, 0);
3296 wm8994_set_retune_mobile(codec, 1);
3297 break;
3298 case 2:
3299 wm8994->dac_rates[1] = params_rate(params);
3300 wm8994_set_retune_mobile(codec, 2);
3301 break;
3302 }
3303 }
3304
3305 return 0;
3306}
3307
3308static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3309{
3310 struct snd_soc_codec *codec = codec_dai->codec;
3311 int mute_reg;
3312 int reg;
3313
3314 switch (codec_dai->id) {
3315 case 1:
3316 mute_reg = WM8994_AIF1_DAC1_FILTERS_1;
3317 break;
3318 case 2:
3319 mute_reg = WM8994_AIF2_DAC_FILTERS_1;
3320 break;
3321 default:
3322 return -EINVAL;
3323 }
3324
3325 if (mute)
3326 reg = WM8994_AIF1DAC1_MUTE;
3327 else
3328 reg = 0;
3329
3330 snd_soc_update_bits(codec, mute_reg, WM8994_AIF1DAC1_MUTE, reg);
3331
3332 return 0;
3333}
3334
3335#define WM8994_RATES SNDRV_PCM_RATE_8000_96000
3336
3337#define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
3338 SNDRV_PCM_FMTBIT_S24_LE)
3339
3340static struct snd_soc_dai_ops wm8994_aif1_dai_ops = {
3341 .set_sysclk = wm8994_set_dai_sysclk,
3342 .set_fmt = wm8994_set_dai_fmt,
3343 .hw_params = wm8994_hw_params,
3344 .digital_mute = wm8994_aif_mute,
3345 .set_pll = wm8994_set_fll,
3346};
3347
3348static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3349 .set_sysclk = wm8994_set_dai_sysclk,
3350 .set_fmt = wm8994_set_dai_fmt,
3351 .hw_params = wm8994_hw_params,
3352 .digital_mute = wm8994_aif_mute,
3353 .set_pll = wm8994_set_fll,
3354};
3355
3356struct snd_soc_dai wm8994_dai[] = {
3357 {
3358 .name = "WM8994 AIF1",
3359 .id = 1,
3360 .playback = {
3361 .stream_name = "AIF1 Playback",
3362 .channels_min = 2,
3363 .channels_max = 2,
3364 .rates = WM8994_RATES,
3365 .formats = WM8994_FORMATS,
3366 },
3367 .capture = {
3368 .stream_name = "AIF1 Capture",
3369 .channels_min = 2,
3370 .channels_max = 2,
3371 .rates = WM8994_RATES,
3372 .formats = WM8994_FORMATS,
3373 },
3374 .ops = &wm8994_aif1_dai_ops,
3375 },
3376 {
3377 .name = "WM8994 AIF2",
3378 .id = 2,
3379 .playback = {
3380 .stream_name = "AIF2 Playback",
3381 .channels_min = 2,
3382 .channels_max = 2,
3383 .rates = WM8994_RATES,
3384 .formats = WM8994_FORMATS,
3385 },
3386 .capture = {
3387 .stream_name = "AIF2 Capture",
3388 .channels_min = 2,
3389 .channels_max = 2,
3390 .rates = WM8994_RATES,
3391 .formats = WM8994_FORMATS,
3392 },
3393 .ops = &wm8994_aif2_dai_ops,
3394 },
3395 {
3396 .name = "WM8994 AIF3",
3397 .playback = {
3398 .stream_name = "AIF3 Playback",
3399 .channels_min = 2,
3400 .channels_max = 2,
3401 .rates = WM8994_RATES,
3402 .formats = WM8994_FORMATS,
3403 },
3404 .playback = {
3405 .stream_name = "AIF3 Capture",
3406 .channels_min = 2,
3407 .channels_max = 2,
3408 .rates = WM8994_RATES,
3409 .formats = WM8994_FORMATS,
3410 },
3411 }
3412};
3413EXPORT_SYMBOL_GPL(wm8994_dai);
3414
3415#ifdef CONFIG_PM
3416static int wm8994_suspend(struct platform_device *pdev, pm_message_t state)
3417{
3418 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3419 struct snd_soc_codec *codec = socdev->card->codec;
3420 struct wm8994_priv *wm8994 = codec->private_data;
3421 int i, ret;
3422
3423 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3424 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
3425 sizeof(struct fll_config));
3426 ret = wm8994_set_fll(&codec->dai[0], i + 1, 0, 0, 0);
3427 if (ret < 0)
3428 dev_warn(codec->dev, "Failed to stop FLL%d: %d\n",
3429 i + 1, ret);
3430 }
3431
3432 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3433
3434 return 0;
3435}
3436
3437static int wm8994_resume(struct platform_device *pdev)
3438{
3439 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3440 struct snd_soc_codec *codec = socdev->card->codec;
3441 struct wm8994_priv *wm8994 = codec->private_data;
3442 u16 *reg_cache = codec->reg_cache;
3443 int i, ret;
3444
3445 /* Restore the registers */
3446 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) {
3447 switch (i) {
3448 case WM8994_LDO_1:
3449 case WM8994_LDO_2:
3450 case WM8994_SOFTWARE_RESET:
3451 /* Handled by other MFD drivers */
3452 continue;
3453 default:
3454 break;
3455 }
3456
3457 if (!access_masks[i].writable)
3458 continue;
3459
3460 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3461 }
3462
3463 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3464
3465 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
3466 ret = wm8994_set_fll(&codec->dai[0], i + 1,
3467 wm8994->fll_suspend[i].src,
3468 wm8994->fll_suspend[i].in,
3469 wm8994->fll_suspend[i].out);
3470 if (ret < 0)
3471 dev_warn(codec->dev, "Failed to restore FLL%d: %d\n",
3472 i + 1, ret);
3473 }
3474
3475 return 0;
3476}
3477#else
3478#define wm8994_suspend NULL
3479#define wm8994_resume NULL
3480#endif
3481
3482static void wm8994_handle_retune_mobile_pdata(struct wm8994_priv *wm8994)
3483{
3484 struct snd_soc_codec *codec = &wm8994->codec;
3485 struct wm8994_pdata *pdata = wm8994->pdata;
3486 struct snd_kcontrol_new controls[] = {
3487 SOC_ENUM_EXT("AIF1.1 EQ Mode",
3488 wm8994->retune_mobile_enum,
3489 wm8994_get_retune_mobile_enum,
3490 wm8994_put_retune_mobile_enum),
3491 SOC_ENUM_EXT("AIF1.2 EQ Mode",
3492 wm8994->retune_mobile_enum,
3493 wm8994_get_retune_mobile_enum,
3494 wm8994_put_retune_mobile_enum),
3495 SOC_ENUM_EXT("AIF2 EQ Mode",
3496 wm8994->retune_mobile_enum,
3497 wm8994_get_retune_mobile_enum,
3498 wm8994_put_retune_mobile_enum),
3499 };
3500 int ret, i, j;
3501 const char **t;
3502
3503 /* We need an array of texts for the enum API but the number
3504 * of texts is likely to be less than the number of
3505 * configurations due to the sample rate dependency of the
3506 * configurations. */
3507 wm8994->num_retune_mobile_texts = 0;
3508 wm8994->retune_mobile_texts = NULL;
3509 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {
3510 for (j = 0; j < wm8994->num_retune_mobile_texts; j++) {
3511 if (strcmp(pdata->retune_mobile_cfgs[i].name,
3512 wm8994->retune_mobile_texts[j]) == 0)
3513 break;
3514 }
3515
3516 if (j != wm8994->num_retune_mobile_texts)
3517 continue;
3518
3519 /* Expand the array... */
3520 t = krealloc(wm8994->retune_mobile_texts,
3521 sizeof(char *) *
3522 (wm8994->num_retune_mobile_texts + 1),
3523 GFP_KERNEL);
3524 if (t == NULL)
3525 continue;
3526
3527 /* ...store the new entry... */
3528 t[wm8994->num_retune_mobile_texts] =
3529 pdata->retune_mobile_cfgs[i].name;
3530
3531 /* ...and remember the new version. */
3532 wm8994->num_retune_mobile_texts++;
3533 wm8994->retune_mobile_texts = t;
3534 }
3535
3536 dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n",
3537 wm8994->num_retune_mobile_texts);
3538
3539 wm8994->retune_mobile_enum.max = wm8994->num_retune_mobile_texts;
3540 wm8994->retune_mobile_enum.texts = wm8994->retune_mobile_texts;
3541
3542 ret = snd_soc_add_controls(&wm8994->codec, controls,
3543 ARRAY_SIZE(controls));
3544 if (ret != 0)
3545 dev_err(wm8994->codec.dev,
3546 "Failed to add ReTune Mobile controls: %d\n", ret);
3547}
3548
3549static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3550{
3551 struct snd_soc_codec *codec = &wm8994->codec;
3552 struct wm8994_pdata *pdata = wm8994->pdata;
3553 int ret, i;
3554
3555 if (!pdata)
3556 return;
3557
3558 wm_hubs_handle_analogue_pdata(codec, pdata->lineout1_diff,
3559 pdata->lineout2_diff,
3560 pdata->lineout1fb,
3561 pdata->lineout2fb,
3562 pdata->jd_scthr,
3563 pdata->jd_thr,
3564 pdata->micbias1_lvl,
3565 pdata->micbias2_lvl);
3566
3567 dev_dbg(codec->dev, "%d DRC configurations\n", pdata->num_drc_cfgs);
3568
3569 if (pdata->num_drc_cfgs) {
3570 struct snd_kcontrol_new controls[] = {
3571 SOC_ENUM_EXT("AIF1DRC1 Mode", wm8994->drc_enum,
3572 wm8994_get_drc_enum, wm8994_put_drc_enum),
3573 SOC_ENUM_EXT("AIF1DRC2 Mode", wm8994->drc_enum,
3574 wm8994_get_drc_enum, wm8994_put_drc_enum),
3575 SOC_ENUM_EXT("AIF2DRC Mode", wm8994->drc_enum,
3576 wm8994_get_drc_enum, wm8994_put_drc_enum),
3577 };
3578
3579 /* We need an array of texts for the enum API */
3580 wm8994->drc_texts = kmalloc(sizeof(char *)
3581 * pdata->num_drc_cfgs, GFP_KERNEL);
3582 if (!wm8994->drc_texts) {
3583 dev_err(wm8994->codec.dev,
3584 "Failed to allocate %d DRC config texts\n",
3585 pdata->num_drc_cfgs);
3586 return;
3587 }
3588
3589 for (i = 0; i < pdata->num_drc_cfgs; i++)
3590 wm8994->drc_texts[i] = pdata->drc_cfgs[i].name;
3591
3592 wm8994->drc_enum.max = pdata->num_drc_cfgs;
3593 wm8994->drc_enum.texts = wm8994->drc_texts;
3594
3595 ret = snd_soc_add_controls(&wm8994->codec, controls,
3596 ARRAY_SIZE(controls));
3597 if (ret != 0)
3598 dev_err(wm8994->codec.dev,
3599 "Failed to add DRC mode controls: %d\n", ret);
3600
3601 for (i = 0; i < WM8994_NUM_DRC; i++)
3602 wm8994_set_drc(codec, i);
3603 }
3604
3605 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3606 pdata->num_retune_mobile_cfgs);
3607
3608 if (pdata->num_retune_mobile_cfgs)
3609 wm8994_handle_retune_mobile_pdata(wm8994);
3610 else
3611 snd_soc_add_controls(&wm8994->codec, wm8994_eq_controls,
3612 ARRAY_SIZE(wm8994_eq_controls));
3613}
3614
3615static int wm8994_probe(struct platform_device *pdev)
3616{
3617 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3618 struct snd_soc_codec *codec;
3619 int ret = 0;
3620
3621 if (wm8994_codec == NULL) {
3622 dev_err(&pdev->dev, "Codec device not registered\n");
3623 return -ENODEV;
3624 }
3625
3626 socdev->card->codec = wm8994_codec;
3627 codec = wm8994_codec;
3628
3629 /* register pcms */
3630 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
3631 if (ret < 0) {
3632 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
3633 return ret;
3634 }
3635
3636 wm8994_handle_pdata(codec->private_data);
3637
3638 wm_hubs_add_analogue_controls(codec);
3639 snd_soc_add_controls(codec, wm8994_snd_controls,
3640 ARRAY_SIZE(wm8994_snd_controls));
3641 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets,
3642 ARRAY_SIZE(wm8994_dapm_widgets));
3643 wm_hubs_add_analogue_routes(codec, 0, 0);
3644 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
3645
3646 return 0;
3647}
3648
3649static int wm8994_remove(struct platform_device *pdev)
3650{
3651 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
3652
3653 snd_soc_free_pcms(socdev);
3654 snd_soc_dapm_free(socdev);
3655
3656 return 0;
3657}
3658
3659struct snd_soc_codec_device soc_codec_dev_wm8994 = {
3660 .probe = wm8994_probe,
3661 .remove = wm8994_remove,
3662 .suspend = wm8994_suspend,
3663 .resume = wm8994_resume,
3664};
3665EXPORT_SYMBOL_GPL(soc_codec_dev_wm8994);
3666
3667static int wm8994_codec_probe(struct platform_device *pdev)
3668{
3669 int ret;
3670 struct wm8994_priv *wm8994;
3671 struct snd_soc_codec *codec;
3672 int i;
3673 u16 rev;
3674
3675 if (wm8994_codec) {
3676 dev_err(&pdev->dev, "Another WM8994 is registered\n");
3677 return -EINVAL;
3678 }
3679
3680 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3681 if (!wm8994) {
3682 dev_err(&pdev->dev, "Failed to allocate private data\n");
3683 return -ENOMEM;
3684 }
3685
3686 codec = &wm8994->codec;
3687
3688 mutex_init(&codec->mutex);
3689 INIT_LIST_HEAD(&codec->dapm_widgets);
3690 INIT_LIST_HEAD(&codec->dapm_paths);
3691
3692 codec->private_data = wm8994;
3693 codec->control_data = dev_get_drvdata(pdev->dev.parent);
3694 codec->name = "WM8994";
3695 codec->owner = THIS_MODULE;
3696 codec->read = wm8994_read;
3697 codec->write = wm8994_write;
3698 codec->readable_register = wm8994_readable;
3699 codec->bias_level = SND_SOC_BIAS_OFF;
3700 codec->set_bias_level = wm8994_set_bias_level;
3701 codec->dai = &wm8994_dai[0];
3702 codec->num_dai = 3;
3703 codec->reg_cache_size = WM8994_MAX_REGISTER;
3704 codec->reg_cache = &wm8994->reg_cache;
3705 codec->dev = &pdev->dev;
3706
3707 wm8994->pdata = pdev->dev.parent->platform_data;
3708
3709 /* Fill the cache with physical values we inherited; don't reset */
3710 ret = wm8994_bulk_read(codec->control_data, 0,
3711 ARRAY_SIZE(wm8994->reg_cache) - 1,
3712 codec->reg_cache);
3713 if (ret < 0) {
3714 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3715 ret);
3716 goto err;
3717 }
3718
3719 /* Clear the cached values for unreadable/volatile registers to
3720 * avoid potential confusion.
3721 */
3722 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++)
3723 if (wm8994_volatile(i) || !wm8994_readable(i))
3724 wm8994->reg_cache[i] = 0;
3725
3726 /* Set revision-specific configuration */
3727 rev = snd_soc_read(codec, WM8994_CHIP_REVISION);
3728 switch (rev) {
3729 case 2:
3730 case 3:
3731 wm8994->hubs.dcs_codes = -5;
3732 wm8994->hubs.hp_startup_mode = 1;
3733 break;
3734 default:
3735 break;
3736 }
3737
3738
3739 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3740 * configured on init - if a system wants to do this dynamically
3741 * at runtime we can deal with that then.
3742 */
3743 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_1);
3744 if (ret < 0) {
3745 dev_err(codec->dev, "Failed to read GPIO1 state: %d\n", ret);
3746 goto err;
3747 }
3748 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3749 wm8994->lrclk_shared[0] = 1;
3750 wm8994_dai[0].symmetric_rates = 1;
3751 } else {
3752 wm8994->lrclk_shared[0] = 0;
3753 }
3754
3755 ret = wm8994_reg_read(codec->control_data, WM8994_GPIO_6);
3756 if (ret < 0) {
3757 dev_err(codec->dev, "Failed to read GPIO6 state: %d\n", ret);
3758 goto err;
3759 }
3760 if ((ret & WM8994_GPN_FN_MASK) != WM8994_GP_FN_PIN_SPECIFIC) {
3761 wm8994->lrclk_shared[1] = 1;
3762 wm8994_dai[1].symmetric_rates = 1;
3763 } else {
3764 wm8994->lrclk_shared[1] = 0;
3765 }
3766
3767 for (i = 0; i < ARRAY_SIZE(wm8994_dai); i++)
3768 wm8994_dai[i].dev = codec->dev;
3769
3770 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3771
3772 wm8994_codec = codec;
3773
3774 /* Latch volume updates (right only; we always do left then right). */
3775 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_RIGHT_VOLUME,
3776 WM8994_AIF1DAC1_VU, WM8994_AIF1DAC1_VU);
3777 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_RIGHT_VOLUME,
3778 WM8994_AIF1DAC2_VU, WM8994_AIF1DAC2_VU);
3779 snd_soc_update_bits(codec, WM8994_AIF2_DAC_RIGHT_VOLUME,
3780 WM8994_AIF2DAC_VU, WM8994_AIF2DAC_VU);
3781 snd_soc_update_bits(codec, WM8994_AIF1_ADC1_RIGHT_VOLUME,
3782 WM8994_AIF1ADC1_VU, WM8994_AIF1ADC1_VU);
3783 snd_soc_update_bits(codec, WM8994_AIF1_ADC2_RIGHT_VOLUME,
3784 WM8994_AIF1ADC2_VU, WM8994_AIF1ADC2_VU);
3785 snd_soc_update_bits(codec, WM8994_AIF2_ADC_RIGHT_VOLUME,
3786 WM8994_AIF2ADC_VU, WM8994_AIF1ADC2_VU);
3787 snd_soc_update_bits(codec, WM8994_DAC1_RIGHT_VOLUME,
3788 WM8994_DAC1_VU, WM8994_DAC1_VU);
3789 snd_soc_update_bits(codec, WM8994_DAC2_RIGHT_VOLUME,
3790 WM8994_DAC2_VU, WM8994_DAC2_VU);
3791
3792 /* Set the low bit of the 3D stereo depth so TLV matches */
3793 snd_soc_update_bits(codec, WM8994_AIF1_DAC1_FILTERS_2,
3794 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT,
3795 1 << WM8994_AIF1DAC1_3D_GAIN_SHIFT);
3796 snd_soc_update_bits(codec, WM8994_AIF1_DAC2_FILTERS_2,
3797 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT,
3798 1 << WM8994_AIF1DAC2_3D_GAIN_SHIFT);
3799 snd_soc_update_bits(codec, WM8994_AIF2_DAC_FILTERS_2,
3800 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT,
3801 1 << WM8994_AIF2DAC_3D_GAIN_SHIFT);
3802
3803 wm8994_update_class_w(codec);
3804
3805 ret = snd_soc_register_codec(codec);
3806 if (ret != 0) {
3807 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
3808 goto err;
3809 }
3810
3811 ret = snd_soc_register_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3812 if (ret != 0) {
3813 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
3814 goto err_codec;
3815 }
3816
3817 platform_set_drvdata(pdev, wm8994);
3818
3819 return 0;
3820
3821err_codec:
3822 snd_soc_unregister_codec(codec);
3823err:
3824 kfree(wm8994);
3825 return ret;
3826}
3827
3828static int __devexit wm8994_codec_remove(struct platform_device *pdev)
3829{
3830 struct wm8994_priv *wm8994 = platform_get_drvdata(pdev);
3831 struct snd_soc_codec *codec = &wm8994->codec;
3832
3833 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
3834 snd_soc_unregister_dais(wm8994_dai, ARRAY_SIZE(wm8994_dai));
3835 snd_soc_unregister_codec(&wm8994->codec);
3836 kfree(wm8994);
3837 wm8994_codec = NULL;
3838
3839 return 0;
3840}
3841
3842static struct platform_driver wm8994_codec_driver = {
3843 .driver = {
3844 .name = "wm8994-codec",
3845 .owner = THIS_MODULE,
3846 },
3847 .probe = wm8994_codec_probe,
3848 .remove = __devexit_p(wm8994_codec_remove),
3849};
3850
3851static __init int wm8994_init(void)
3852{
3853 return platform_driver_register(&wm8994_codec_driver);
3854}
3855module_init(wm8994_init);
3856
3857static __exit void wm8994_exit(void)
3858{
3859 platform_driver_unregister(&wm8994_codec_driver);
3860}
3861module_exit(wm8994_exit);
3862
3863
3864MODULE_DESCRIPTION("ASoC WM8994 driver");
3865MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
3866MODULE_LICENSE("GPL");
3867MODULE_ALIAS("platform:wm8994-codec");
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
new file mode 100644
index 000000000000..0a5e1424dea0
--- /dev/null
+++ b/sound/soc/codecs/wm8994.h
@@ -0,0 +1,26 @@
1/*
2 * wm8994.h -- WM8994 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 _WM8994_H
10#define _WM8994_H
11
12#include <sound/soc.h>
13
14extern struct snd_soc_codec_device soc_codec_dev_wm8994;
15extern struct snd_soc_dai wm8994_dai[];
16
17/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
18#define WM8994_SYSCLK_MCLK1 1
19#define WM8994_SYSCLK_MCLK2 2
20#define WM8994_SYSCLK_FLL1 3
21#define WM8994_SYSCLK_FLL2 4
22
23#define WM8994_FLL1 1
24#define WM8994_FLL2 2
25
26#endif
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index c58aab375edb..ceb86b4ddb25 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -23,13 +23,12 @@
23#include <sound/ac97_codec.h> 23#include <sound/ac97_codec.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/tlv.h>
26#include <sound/soc.h> 27#include <sound/soc.h>
27#include <sound/soc-dapm.h> 28#include <sound/soc-dapm.h>
28 29
29#include "wm9713.h" 30#include "wm9713.h"
30 31
31#define WM9713_VERSION "0.15"
32
33struct wm9713_priv { 32struct wm9713_priv {
34 u32 pll_in; /* PLL input frequency */ 33 u32 pll_in; /* PLL input frequency */
35}; 34};
@@ -115,15 +114,27 @@ SOC_ENUM_SINGLE(AC97_3D_CONTROL, 12, 3, wm9713_mic_select), /* mic selection 18
115SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */ 114SOC_ENUM_SINGLE(MICB_MUX, 0, 2, wm9713_micb_select), /* mic selection 19 */
116}; 115};
117 116
117static const DECLARE_TLV_DB_SCALE(out_tlv, -4650, 150, 0);
118static const DECLARE_TLV_DB_SCALE(main_tlv, -3450, 150, 0);
119static const DECLARE_TLV_DB_SCALE(misc_tlv, -1500, 300, 0);
120static unsigned int mic_tlv[] = {
121 TLV_DB_RANGE_HEAD(2),
122 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0),
123 3, 3, TLV_DB_SCALE_ITEM(3000, 0, 0),
124};
125
118static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = { 126static const struct snd_kcontrol_new wm9713_snd_ac97_controls[] = {
119SOC_DOUBLE("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1), 127SOC_DOUBLE_TLV("Speaker Playback Volume", AC97_MASTER, 8, 0, 31, 1, out_tlv),
120SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1), 128SOC_DOUBLE("Speaker Playback Switch", AC97_MASTER, 15, 7, 1, 1),
121SOC_DOUBLE("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1), 129SOC_DOUBLE_TLV("Headphone Playback Volume", AC97_HEADPHONE, 8, 0, 31, 1,
130 out_tlv),
122SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1), 131SOC_DOUBLE("Headphone Playback Switch", AC97_HEADPHONE, 15, 7, 1, 1),
123SOC_DOUBLE("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1), 132SOC_DOUBLE_TLV("Line In Volume", AC97_PC_BEEP, 8, 0, 31, 1, main_tlv),
124SOC_DOUBLE("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1), 133SOC_DOUBLE_TLV("PCM Playback Volume", AC97_PHONE, 8, 0, 31, 1, main_tlv),
125SOC_SINGLE("Mic 1 Volume", AC97_MIC, 8, 31, 1), 134SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv),
126SOC_SINGLE("Mic 2 Volume", AC97_MIC, 0, 31, 1), 135SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
136SOC_SINGLE_TLV("Mic 1 Preamp Volume", AC97_3D_CONTROL, 10, 3, 0, mic_tlv),
137SOC_SINGLE_TLV("Mic 2 Preamp Volume", AC97_3D_CONTROL, 12, 3, 0, mic_tlv),
127 138
128SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0), 139SOC_SINGLE("Mic Boost (+20dB) Switch", AC97_LINE, 5, 1, 0),
129SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1), 140SOC_SINGLE("Mic Headphone Mixer Volume", AC97_LINE, 0, 7, 1),
@@ -133,7 +144,7 @@ SOC_ENUM("Capture Volume Steps", wm9713_enum[5]),
133SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0), 144SOC_DOUBLE("Capture Volume", AC97_CD, 8, 0, 31, 0),
134SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0), 145SOC_SINGLE("Capture ZC Switch", AC97_CD, 7, 1, 0),
135 146
136SOC_SINGLE("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1), 147SOC_SINGLE_TLV("Capture to Headphone Volume", AC97_VIDEO, 11, 7, 1, misc_tlv),
137SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0), 148SOC_SINGLE("Capture to Mono Boost (+20dB) Switch", AC97_VIDEO, 8, 1, 0),
138SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0), 149SOC_SINGLE("Capture ADC Boost (+20dB) Switch", AC97_VIDEO, 6, 1, 0),
139 150
@@ -154,28 +165,43 @@ SOC_DOUBLE("Headphone Playback ZC Switch", AC97_HEADPHONE, 14, 6, 1, 0),
154 165
155SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1), 166SOC_SINGLE("Out4 Playback Switch", AC97_MASTER_MONO, 15, 1, 1),
156SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0), 167SOC_SINGLE("Out4 Playback ZC Switch", AC97_MASTER_MONO, 14, 1, 0),
157SOC_SINGLE("Out4 Playback Volume", AC97_MASTER_MONO, 8, 63, 1), 168SOC_SINGLE_TLV("Out4 Playback Volume", AC97_MASTER_MONO, 8, 31, 1, out_tlv),
158 169
159SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1), 170SOC_SINGLE("Out3 Playback Switch", AC97_MASTER_MONO, 7, 1, 1),
160SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0), 171SOC_SINGLE("Out3 Playback ZC Switch", AC97_MASTER_MONO, 6, 1, 0),
161SOC_SINGLE("Out3 Playback Volume", AC97_MASTER_MONO, 0, 63, 1), 172SOC_SINGLE_TLV("Out3 Playback Volume", AC97_MASTER_MONO, 0, 31, 1, out_tlv),
162 173
163SOC_SINGLE("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1), 174SOC_SINGLE_TLV("Mono Capture Volume", AC97_MASTER_TONE, 8, 31, 1, main_tlv),
164SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1), 175SOC_SINGLE("Mono Playback Switch", AC97_MASTER_TONE, 7, 1, 1),
165SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0), 176SOC_SINGLE("Mono Playback ZC Switch", AC97_MASTER_TONE, 6, 1, 0),
166SOC_SINGLE("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1), 177SOC_SINGLE_TLV("Mono Playback Volume", AC97_MASTER_TONE, 0, 31, 1, out_tlv),
167 178
168SOC_SINGLE("Beep Playback Headphone Volume", AC97_AUX, 12, 7, 1), 179SOC_SINGLE_TLV("Headphone Mixer Beep Playback Volume", AC97_AUX, 12, 7, 1,
169SOC_SINGLE("Beep Playback Speaker Volume", AC97_AUX, 8, 7, 1), 180 misc_tlv),
170SOC_SINGLE("Beep Playback Mono Volume", AC97_AUX, 4, 7, 1), 181SOC_SINGLE_TLV("Speaker Mixer Beep Playback Volume", AC97_AUX, 8, 7, 1,
182 misc_tlv),
183SOC_SINGLE_TLV("Mono Mixer Beep Playback Volume", AC97_AUX, 4, 7, 1, misc_tlv),
171 184
172SOC_SINGLE("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1), 185SOC_SINGLE_TLV("Voice Playback Headphone Volume", AC97_PCM, 12, 7, 1,
186 misc_tlv),
173SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1), 187SOC_SINGLE("Voice Playback Master Volume", AC97_PCM, 8, 7, 1),
174SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1), 188SOC_SINGLE("Voice Playback Mono Volume", AC97_PCM, 4, 7, 1),
175 189
190SOC_SINGLE_TLV("Headphone Mixer Aux Playback Volume", AC97_REC_SEL, 12, 7, 1,
191 misc_tlv),
192
193SOC_SINGLE_TLV("Speaker Mixer Voice Playback Volume", AC97_PCM, 8, 7, 1,
194 misc_tlv),
195SOC_SINGLE_TLV("Speaker Mixer Aux Playback Volume", AC97_REC_SEL, 8, 7, 1,
196 misc_tlv),
197
198SOC_SINGLE_TLV("Mono Mixer Voice Playback Volume", AC97_PCM, 4, 7, 1,
199 misc_tlv),
200SOC_SINGLE_TLV("Mono Mixer Aux Playback Volume", AC97_REC_SEL, 4, 7, 1,
201 misc_tlv),
202
176SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1), 203SOC_SINGLE("Aux Playback Headphone Volume", AC97_REC_SEL, 12, 7, 1),
177SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1), 204SOC_SINGLE("Aux Playback Master Volume", AC97_REC_SEL, 8, 7, 1),
178SOC_SINGLE("Aux Playback Mono Volume", AC97_REC_SEL, 4, 7, 1),
179 205
180SOC_ENUM("Bass Control", wm9713_enum[16]), 206SOC_ENUM("Bass Control", wm9713_enum[16]),
181SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1), 207SOC_SINGLE("Bass Cut-off Switch", AC97_GENERAL_PURPOSE, 12, 1, 1),
@@ -1186,8 +1212,6 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1186 struct snd_soc_codec *codec; 1212 struct snd_soc_codec *codec;
1187 int ret = 0, reg; 1213 int ret = 0, reg;
1188 1214
1189 printk(KERN_INFO "WM9713/WM9714 SoC Audio Codec %s\n", WM9713_VERSION);
1190
1191 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), 1215 socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec),
1192 GFP_KERNEL); 1216 GFP_KERNEL);
1193 if (socdev->card->codec == NULL) 1217 if (socdev->card->codec == NULL)
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index d73c30536a2c..0ad9f5d536c6 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -68,24 +68,77 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
68 int count = 0; 68 int count = 0;
69 69
70 dev_dbg(codec->dev, "Waiting for DC servo...\n"); 70 dev_dbg(codec->dev, "Waiting for DC servo...\n");
71
71 do { 72 do {
72 count++; 73 count++;
73 msleep(1); 74 msleep(1);
74 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); 75 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0);
75 dev_dbg(codec->dev, "DC servo status: %x\n", reg); 76 dev_dbg(codec->dev, "DC servo: %x\n", reg);
76 } while ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 77 } while (reg & WM8993_DCS_DATAPATH_BUSY);
77 != WM8993_DCS_CAL_COMPLETE_MASK && count < 1000);
78 78
79 if ((reg & WM8993_DCS_CAL_COMPLETE_MASK) 79 if (reg & WM8993_DCS_DATAPATH_BUSY)
80 != WM8993_DCS_CAL_COMPLETE_MASK)
81 dev_err(codec->dev, "Timed out waiting for DC Servo\n"); 80 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
82} 81}
83 82
84/* 83/*
84 * Startup calibration of the DC servo
85 */
86static void calibrate_dc_servo(struct snd_soc_codec *codec)
87{
88 struct wm_hubs_data *hubs = codec->private_data;
89 u16 reg, dcs_cfg;
90
91 /* Set for 32 series updates */
92 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
93 WM8993_DCS_SERIES_NO_01_MASK,
94 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
95
96 /* Enable the DC servo. Write all bits to avoid triggering startup
97 * or write calibration.
98 */
99 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
100 0xFFFF,
101 WM8993_DCS_ENA_CHAN_0 |
102 WM8993_DCS_ENA_CHAN_1 |
103 WM8993_DCS_TRIG_SERIES_1 |
104 WM8993_DCS_TRIG_SERIES_0);
105
106 wait_for_dc_servo(codec);
107
108 /* Apply correction to DC servo result */
109 if (hubs->dcs_codes) {
110 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
111 hubs->dcs_codes);
112
113 /* HPOUT1L */
114 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) &
115 WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg += hubs->dcs_codes;
117 dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
118
119 /* HPOUT1R */
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) &
121 WM8993_DCS_INTEG_CHAN_1_MASK;
122 reg += hubs->dcs_codes;
123 dcs_cfg |= reg;
124
125 /* Do it */
126 snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
127 snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
128 WM8993_DCS_TRIG_DAC_WR_0 |
129 WM8993_DCS_TRIG_DAC_WR_1,
130 WM8993_DCS_TRIG_DAC_WR_0 |
131 WM8993_DCS_TRIG_DAC_WR_1);
132
133 wait_for_dc_servo(codec);
134 }
135}
136
137/*
85 * Update the DC servo calibration on gain changes 138 * Update the DC servo calibration on gain changes
86 */ 139 */
87static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, 140static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
88 struct snd_ctl_elem_value *ucontrol) 141 struct snd_ctl_elem_value *ucontrol)
89{ 142{
90 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 143 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
91 int ret; 144 int ret;
@@ -251,6 +304,47 @@ SOC_SINGLE_TLV("LINEOUT2 Volume", WM8993_LINE_OUTPUTS_VOLUME, 0, 1, 1,
251 line_tlv), 304 line_tlv),
252}; 305};
253 306
307static int hp_supply_event(struct snd_soc_dapm_widget *w,
308 struct snd_kcontrol *kcontrol, int event)
309{
310 struct snd_soc_codec *codec = w->codec;
311 struct wm_hubs_data *hubs = codec->private_data;
312
313 switch (event) {
314 case SND_SOC_DAPM_PRE_PMU:
315 switch (hubs->hp_startup_mode) {
316 case 0:
317 break;
318 case 1:
319 /* Enable the headphone amp */
320 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
321 WM8993_HPOUT1L_ENA |
322 WM8993_HPOUT1R_ENA,
323 WM8993_HPOUT1L_ENA |
324 WM8993_HPOUT1R_ENA);
325
326 /* Enable the second stage */
327 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
328 WM8993_HPOUT1L_DLY |
329 WM8993_HPOUT1R_DLY,
330 WM8993_HPOUT1L_DLY |
331 WM8993_HPOUT1R_DLY);
332 break;
333 default:
334 dev_err(codec->dev, "Unknown HP startup mode %d\n",
335 hubs->hp_startup_mode);
336 break;
337 }
338
339 case SND_SOC_DAPM_PRE_PMD:
340 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
341 WM8993_CP_ENA, 0);
342 break;
343 }
344
345 return 0;
346}
347
254static int hp_event(struct snd_soc_dapm_widget *w, 348static int hp_event(struct snd_soc_dapm_widget *w,
255 struct snd_kcontrol *kcontrol, int event) 349 struct snd_kcontrol *kcontrol, int event)
256{ 350{
@@ -271,14 +365,11 @@ static int hp_event(struct snd_soc_dapm_widget *w,
271 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; 365 reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
272 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); 366 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
273 367
274 /* Start the DC servo */ 368 /* Smallest supported update interval */
275 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 369 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
276 0xFFFF, 370 WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
277 WM8993_DCS_ENA_CHAN_0 | 371
278 WM8993_DCS_ENA_CHAN_1 | 372 calibrate_dc_servo(codec);
279 WM8993_DCS_TRIG_STARTUP_1 |
280 WM8993_DCS_TRIG_STARTUP_0);
281 wait_for_dc_servo(codec);
282 373
283 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT | 374 reg |= WM8993_HPOUT1R_OUTP | WM8993_HPOUT1R_RMV_SHORT |
284 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT; 375 WM8993_HPOUT1L_OUTP | WM8993_HPOUT1L_RMV_SHORT;
@@ -286,23 +377,19 @@ static int hp_event(struct snd_soc_dapm_widget *w,
286 break; 377 break;
287 378
288 case SND_SOC_DAPM_PRE_PMD: 379 case SND_SOC_DAPM_PRE_PMD:
289 reg &= ~(WM8993_HPOUT1L_RMV_SHORT | 380 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
290 WM8993_HPOUT1L_DLY | 381 WM8993_HPOUT1L_DLY |
291 WM8993_HPOUT1L_OUTP | 382 WM8993_HPOUT1R_DLY |
292 WM8993_HPOUT1R_RMV_SHORT | 383 WM8993_HPOUT1L_RMV_SHORT |
293 WM8993_HPOUT1R_DLY | 384 WM8993_HPOUT1R_RMV_SHORT, 0);
294 WM8993_HPOUT1R_OUTP);
295 385
296 snd_soc_update_bits(codec, WM8993_DC_SERVO_0, 386 snd_soc_update_bits(codec, WM8993_ANALOGUE_HP_0,
297 0xffff, 0); 387 WM8993_HPOUT1L_OUTP |
388 WM8993_HPOUT1R_OUTP, 0);
298 389
299 snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
300 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 390 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1,
301 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA, 391 WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA,
302 0); 392 0);
303
304 snd_soc_update_bits(codec, WM8993_CHARGE_PUMP_1,
305 WM8993_CP_ENA, 0);
306 break; 393 break;
307 } 394 }
308 395
@@ -473,6 +560,8 @@ SND_SOC_DAPM_MIXER("Right Output Mixer", WM8993_POWER_MANAGEMENT_3, 4, 0,
473SND_SOC_DAPM_PGA("Left Output PGA", WM8993_POWER_MANAGEMENT_3, 7, 0, NULL, 0), 560SND_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), 561SND_SOC_DAPM_PGA("Right Output PGA", WM8993_POWER_MANAGEMENT_3, 6, 0, NULL, 0),
475 562
563SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, hp_supply_event,
564 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
476SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, 565SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0,
477 NULL, 0, 566 NULL, 0,
478 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 567 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -626,6 +715,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
626 { "Headphone PGA", NULL, "Left Headphone Mux" }, 715 { "Headphone PGA", NULL, "Left Headphone Mux" },
627 { "Headphone PGA", NULL, "Right Headphone Mux" }, 716 { "Headphone PGA", NULL, "Right Headphone Mux" },
628 { "Headphone PGA", NULL, "CLK_SYS" }, 717 { "Headphone PGA", NULL, "CLK_SYS" },
718 { "Headphone PGA", NULL, "Headphone Supply" },
629 719
630 { "HPOUT1L", NULL, "Headphone PGA" }, 720 { "HPOUT1L", NULL, "Headphone PGA" },
631 { "HPOUT1R", NULL, "Headphone PGA" }, 721 { "HPOUT1R", NULL, "Headphone PGA" },
@@ -753,6 +843,12 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
753 WM8993_LINEOUT2_MODE, 843 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE); 844 WM8993_LINEOUT2_MODE);
755 845
846 /* If the line outputs are differential then we aren't presenting
847 * VMID as an output and can disable it.
848 */
849 if (lineout1_diff && lineout2_diff)
850 codec->idle_bias_off = 1;
851
756 if (lineout1fb) 852 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 853 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB); 854 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index 36d3fba1de8b..420104fe9c90 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -18,6 +18,12 @@ struct snd_soc_codec;
18 18
19extern const unsigned int wm_hubs_spkmix_tlv[]; 19extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21/* This *must* be the first element of the codec->private_data struct */
22struct wm_hubs_data {
23 int dcs_codes;
24 int hp_startup_mode;
25};
26
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 27extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 28extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *, 29extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 0a302e1080d9..ab6518d86f18 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -767,14 +767,26 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream,
767 int ret = 0; 767 int ret = 0;
768 768
769 switch (cmd) { 769 switch (cmd) {
770 case SNDRV_PCM_TRIGGER_START:
771 case SNDRV_PCM_TRIGGER_RESUME: 770 case SNDRV_PCM_TRIGGER_RESUME:
771 case SNDRV_PCM_TRIGGER_START:
772 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 772 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
773 if (!dev->clk_active) {
774 clk_enable(dev->clk);
775 dev->clk_active = 1;
776 }
773 davinci_mcasp_start(dev, substream->stream); 777 davinci_mcasp_start(dev, substream->stream);
774 break; 778 break;
775 779
776 case SNDRV_PCM_TRIGGER_STOP:
777 case SNDRV_PCM_TRIGGER_SUSPEND: 780 case SNDRV_PCM_TRIGGER_SUSPEND:
781 davinci_mcasp_stop(dev, substream->stream);
782 if (dev->clk_active) {
783 clk_disable(dev->clk);
784 dev->clk_active = 0;
785 }
786
787 break;
788
789 case SNDRV_PCM_TRIGGER_STOP:
778 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 790 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
779 davinci_mcasp_stop(dev, substream->stream); 791 davinci_mcasp_stop(dev, substream->stream);
780 break; 792 break;
@@ -866,6 +878,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
866 } 878 }
867 879
868 clk_enable(dev->clk); 880 clk_enable(dev->clk);
881 dev->clk_active = 1;
869 882
870 dev->base = (void __iomem *)IO_ADDRESS(mem->start); 883 dev->base = (void __iomem *)IO_ADDRESS(mem->start);
871 dev->op_mode = pdata->op_mode; 884 dev->op_mode = pdata->op_mode;
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 582c9249ef09..e755b5121ec7 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -44,6 +44,7 @@ struct davinci_audio_dev {
44 int sample_rate; 44 int sample_rate;
45 struct clk *clk; 45 struct clk *clk;
46 unsigned int codec_fmt; 46 unsigned int codec_fmt;
47 u8 clk_active;
47 48
48 /* McASP specific data */ 49 /* McASP specific data */
49 int tdm_slots; 50 int tdm_slots;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index ad4d7f47a86b..80c7fdf2f521 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -49,7 +49,7 @@ static void print_buf_info(int slot, char *name)
49static struct snd_pcm_hardware pcm_hardware_playback = { 49static struct snd_pcm_hardware pcm_hardware_playback = {
50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
52 SNDRV_PCM_INFO_PAUSE), 52 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
53 .formats = (SNDRV_PCM_FMTBIT_S16_LE), 53 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | 54 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | 55 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index a700562e8692..c7d0fd9b7de8 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -1,21 +1,13 @@
1config SND_MX1_MX2_SOC 1config SND_IMX_SOC
2 tristate "SoC Audio for Freecale i.MX1x i.MX2x CPUs" 2 tristate "SoC Audio for Freescale i.MX CPUs"
3 depends on ARCH_MX2 || ARCH_MX1 3 depends on ARCH_MXC && BROKEN
4 select SND_PCM 4 select SND_PCM
5 select FIQ
6 select SND_SOC_AC97_BUS
5 help 7 help
6 Say Y or M if you want to add support for codecs attached to 8 Say Y or M if you want to add support for codecs attached to
7 the MX1 or MX2 SSI interface. 9 the i.MX SSI interface.
8 10
9config SND_MXC_SOC_SSI 11config SND_MXC_SOC_SSI
10 tristate 12 tristate
11 13
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
index c2ffd2c8df5a..9f8bb92ddfcc 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -1,10 +1,12 @@
1# i.MX Platform Support 1# i.MX Platform Support
2snd-soc-mx1_mx2-objs := mx1_mx2-pcm.o 2snd-soc-imx-objs := imx-ssi.o imx-pcm-fiq.o
3snd-soc-mxc-ssi-objs := mxc-ssi.o
4 3
5obj-$(CONFIG_SND_MX1_MX2_SOC) += snd-soc-mx1_mx2.o 4ifdef CONFIG_MACH_MX27
6obj-$(CONFIG_SND_MXC_SOC_SSI) += snd-soc-mxc-ssi.o 5snd-soc-imx-objs += imx-pcm-dma-mx2.o
6endif
7
8obj-$(CONFIG_SND_IMX_SOC) += snd-soc-imx.o
7 9
8# i.MX Machine Support 10# i.MX Machine Support
9snd-soc-mx27vis-wm8974-objs := mx27vis_wm8974.o 11snd-soc-phycore-ac97-objs := phycore-ac97.o
10obj-$(CONFIG_SND_SOC_MX27VIS_WM8974) += snd-soc-mx27vis-wm8974.o 12obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c
new file mode 100644
index 000000000000..19452e44afdc
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-dma-mx2.c
@@ -0,0 +1,313 @@
1/*
2 * imx-pcm-dma-mx2.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <sound/core.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <mach/dma-mx1-mx2.h>
30
31#include "imx-ssi.h"
32
33struct imx_pcm_runtime_data {
34 int sg_count;
35 struct scatterlist *sg_list;
36 int period;
37 int periods;
38 unsigned long dma_addr;
39 int dma;
40 struct snd_pcm_substream *substream;
41 unsigned long offset;
42 unsigned long size;
43 unsigned long period_cnt;
44 void *buf;
45 int period_time;
46};
47
48/* Called by the DMA framework when a period has elapsed */
49static void imx_ssi_dma_progression(int channel, void *data,
50 struct scatterlist *sg)
51{
52 struct snd_pcm_substream *substream = data;
53 struct snd_pcm_runtime *runtime = substream->runtime;
54 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
55
56 if (!sg)
57 return;
58
59 runtime = iprtd->substream->runtime;
60
61 iprtd->offset = sg->dma_address - runtime->dma_addr;
62
63 snd_pcm_period_elapsed(iprtd->substream);
64}
65
66static void imx_ssi_dma_callback(int channel, void *data)
67{
68 pr_err("%s shouldn't be called\n", __func__);
69}
70
71static void snd_imx_dma_err_callback(int channel, void *data, int err)
72{
73 pr_err("DMA error callback called\n");
74
75 pr_err("DMA timeout on channel %d -%s%s%s%s\n",
76 channel,
77 err & IMX_DMA_ERR_BURST ? " burst" : "",
78 err & IMX_DMA_ERR_REQUEST ? " request" : "",
79 err & IMX_DMA_ERR_TRANSFER ? " transfer" : "",
80 err & IMX_DMA_ERR_BUFFER ? " buffer" : "");
81}
82
83static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
84{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
87 struct snd_pcm_runtime *runtime = substream->runtime;
88 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
89 int ret;
90
91 iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
92 if (iprtd->dma < 0) {
93 pr_err("Failed to claim the audio DMA\n");
94 return -ENODEV;
95 }
96
97 ret = imx_dma_setup_handlers(iprtd->dma,
98 imx_ssi_dma_callback,
99 snd_imx_dma_err_callback, substream);
100 if (ret)
101 goto out;
102
103 ret = imx_dma_setup_progression_handler(iprtd->dma,
104 imx_ssi_dma_progression);
105 if (ret) {
106 pr_err("Failed to setup the DMA handler\n");
107 goto out;
108 }
109
110 ret = imx_dma_config_channel(iprtd->dma,
111 IMX_DMA_MEMSIZE_16 | IMX_DMA_TYPE_FIFO,
112 IMX_DMA_MEMSIZE_32 | IMX_DMA_TYPE_LINEAR,
113 dma_params->dma, 1);
114 if (ret < 0) {
115 pr_err("Cannot configure DMA channel: %d\n", ret);
116 goto out;
117 }
118
119 imx_dma_config_burstlen(iprtd->dma, dma_params->burstsize * 2);
120
121 return 0;
122out:
123 imx_dma_free(iprtd->dma);
124 return ret;
125}
126
127static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params)
129{
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132 int i;
133 unsigned long dma_addr;
134
135 imx_ssi_dma_alloc(substream);
136
137 iprtd->size = params_buffer_bytes(params);
138 iprtd->periods = params_periods(params);
139 iprtd->period = params_period_bytes(params);
140 iprtd->offset = 0;
141 iprtd->period_time = HZ / (params_rate(params) /
142 params_period_size(params));
143
144 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
145
146 if (iprtd->sg_count != iprtd->periods) {
147 kfree(iprtd->sg_list);
148
149 iprtd->sg_list = kcalloc(iprtd->periods + 1,
150 sizeof(struct scatterlist), GFP_KERNEL);
151 if (!iprtd->sg_list)
152 return -ENOMEM;
153 iprtd->sg_count = iprtd->periods + 1;
154 }
155
156 sg_init_table(iprtd->sg_list, iprtd->sg_count);
157 dma_addr = runtime->dma_addr;
158
159 for (i = 0; i < iprtd->periods; i++) {
160 iprtd->sg_list[i].page_link = 0;
161 iprtd->sg_list[i].offset = 0;
162 iprtd->sg_list[i].dma_address = dma_addr;
163 iprtd->sg_list[i].length = iprtd->period;
164 dma_addr += iprtd->period;
165 }
166
167 /* close the loop */
168 iprtd->sg_list[iprtd->sg_count - 1].offset = 0;
169 iprtd->sg_list[iprtd->sg_count - 1].length = 0;
170 iprtd->sg_list[iprtd->sg_count - 1].page_link =
171 ((unsigned long) iprtd->sg_list | 0x01) & ~0x02;
172 return 0;
173}
174
175static int snd_imx_pcm_hw_free(struct snd_pcm_substream *substream)
176{
177 struct snd_pcm_runtime *runtime = substream->runtime;
178 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
179
180 if (iprtd->dma >= 0) {
181 imx_dma_free(iprtd->dma);
182 iprtd->dma = -EINVAL;
183 }
184
185 kfree(iprtd->sg_list);
186 iprtd->sg_list = NULL;
187
188 return 0;
189}
190
191static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
192{
193 struct snd_pcm_runtime *runtime = substream->runtime;
194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
195 struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
196 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
197 int err;
198
199 iprtd->substream = substream;
200 iprtd->buf = (unsigned int *)substream->dma_buffer.area;
201 iprtd->period_cnt = 0;
202
203 pr_debug("%s: buf: %p period: %d periods: %d\n",
204 __func__, iprtd->buf, iprtd->period, iprtd->periods);
205
206 err = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count,
207 IMX_DMA_LENGTH_LOOP, dma_params->dma_addr,
208 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
209 DMA_MODE_WRITE : DMA_MODE_READ);
210 if (err)
211 return err;
212
213 return 0;
214}
215
216static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
217{
218 struct snd_pcm_runtime *runtime = substream->runtime;
219 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
220
221 switch (cmd) {
222 case SNDRV_PCM_TRIGGER_START:
223 case SNDRV_PCM_TRIGGER_RESUME:
224 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
225 imx_dma_enable(iprtd->dma);
226
227 break;
228
229 case SNDRV_PCM_TRIGGER_STOP:
230 case SNDRV_PCM_TRIGGER_SUSPEND:
231 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
232 imx_dma_disable(iprtd->dma);
233
234 break;
235 default:
236 return -EINVAL;
237 }
238
239 return 0;
240}
241
242static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
243{
244 struct snd_pcm_runtime *runtime = substream->runtime;
245 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
246
247 return bytes_to_frames(substream->runtime, iprtd->offset);
248}
249
250static struct snd_pcm_hardware snd_imx_hardware = {
251 .info = SNDRV_PCM_INFO_INTERLEAVED |
252 SNDRV_PCM_INFO_BLOCK_TRANSFER |
253 SNDRV_PCM_INFO_MMAP |
254 SNDRV_PCM_INFO_MMAP_VALID |
255 SNDRV_PCM_INFO_PAUSE |
256 SNDRV_PCM_INFO_RESUME,
257 .formats = SNDRV_PCM_FMTBIT_S16_LE,
258 .rate_min = 8000,
259 .channels_min = 2,
260 .channels_max = 2,
261 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
262 .period_bytes_min = 128,
263 .period_bytes_max = 16 * 1024,
264 .periods_min = 2,
265 .periods_max = 255,
266 .fifo_size = 0,
267};
268
269static int snd_imx_open(struct snd_pcm_substream *substream)
270{
271 struct snd_pcm_runtime *runtime = substream->runtime;
272 struct imx_pcm_runtime_data *iprtd;
273 int ret;
274
275 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
276 runtime->private_data = iprtd;
277
278 ret = snd_pcm_hw_constraint_integer(substream->runtime,
279 SNDRV_PCM_HW_PARAM_PERIODS);
280 if (ret < 0)
281 return ret;
282
283 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
284 return 0;
285}
286
287static struct snd_pcm_ops imx_pcm_ops = {
288 .open = snd_imx_open,
289 .ioctl = snd_pcm_lib_ioctl,
290 .hw_params = snd_imx_pcm_hw_params,
291 .hw_free = snd_imx_pcm_hw_free,
292 .prepare = snd_imx_pcm_prepare,
293 .trigger = snd_imx_pcm_trigger,
294 .pointer = snd_imx_pcm_pointer,
295 .mmap = snd_imx_pcm_mmap,
296};
297
298static struct snd_soc_platform imx_soc_platform_dma = {
299 .name = "imx-audio",
300 .pcm_ops = &imx_pcm_ops,
301 .pcm_new = imx_pcm_new,
302 .pcm_free = imx_pcm_free,
303};
304
305struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
306 struct imx_ssi *ssi)
307{
308 ssi->dma_params_tx.burstsize = DMA_TXFIFO_BURST;
309 ssi->dma_params_rx.burstsize = DMA_RXFIFO_BURST;
310
311 return &imx_soc_platform_dma;
312}
313
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c
new file mode 100644
index 000000000000..d9cb9849b033
--- /dev/null
+++ b/sound/soc/imx/imx-pcm-fiq.c
@@ -0,0 +1,297 @@
1/*
2 * imx-pcm-fiq.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14#include <linux/clk.h>
15#include <linux/delay.h>
16#include <linux/device.h>
17#include <linux/dma-mapping.h>
18#include <linux/init.h>
19#include <linux/interrupt.h>
20#include <linux/module.h>
21#include <linux/platform_device.h>
22
23#include <sound/core.h>
24#include <sound/initval.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28
29#include <asm/fiq.h>
30
31#include <mach/ssi.h>
32
33#include "imx-ssi.h"
34
35struct imx_pcm_runtime_data {
36 int period;
37 int periods;
38 unsigned long offset;
39 unsigned long last_offset;
40 unsigned long size;
41 struct timer_list timer;
42 int poll_time;
43};
44
45static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd)
46{
47 iprtd->timer.expires = jiffies + iprtd->poll_time;
48}
49
50static void imx_ssi_timer_callback(unsigned long data)
51{
52 struct snd_pcm_substream *substream = (void *)data;
53 struct snd_pcm_runtime *runtime = substream->runtime;
54 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
55 struct pt_regs regs;
56 unsigned long delta;
57
58 get_fiq_regs(&regs);
59
60 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
61 iprtd->offset = regs.ARM_r8 & 0xffff;
62 else
63 iprtd->offset = regs.ARM_r9 & 0xffff;
64
65 /* How much data have we transferred since the last period report? */
66 if (iprtd->offset >= iprtd->last_offset)
67 delta = iprtd->offset - iprtd->last_offset;
68 else
69 delta = runtime->buffer_size + iprtd->offset
70 - iprtd->last_offset;
71
72 /* If we've transferred at least a period then report it and
73 * reset our poll time */
74 if (delta >= runtime->period_size) {
75 snd_pcm_period_elapsed(substream);
76 iprtd->last_offset = iprtd->offset;
77
78 imx_ssi_set_next_poll(iprtd);
79 }
80
81 /* Restart the timer; if we didn't report we'll run on the next tick */
82 add_timer(&iprtd->timer);
83
84}
85
86static struct fiq_handler fh = {
87 .name = DRV_NAME,
88};
89
90static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream,
91 struct snd_pcm_hw_params *params)
92{
93 struct snd_pcm_runtime *runtime = substream->runtime;
94 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
95
96 iprtd->size = params_buffer_bytes(params);
97 iprtd->periods = params_periods(params);
98 iprtd->period = params_period_bytes(params) ;
99 iprtd->offset = 0;
100 iprtd->last_offset = 0;
101 iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params));
102
103 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
104
105 return 0;
106}
107
108static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
109{
110 struct snd_pcm_runtime *runtime = substream->runtime;
111 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
112 struct pt_regs regs;
113
114 get_fiq_regs(&regs);
115 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
116 regs.ARM_r8 = (iprtd->period * iprtd->periods - 1) << 16;
117 else
118 regs.ARM_r9 = (iprtd->period * iprtd->periods - 1) << 16;
119
120 set_fiq_regs(&regs);
121
122 return 0;
123}
124
125static int fiq_enable;
126static int imx_pcm_fiq;
127
128static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
129{
130 struct snd_pcm_runtime *runtime = substream->runtime;
131 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
132
133 switch (cmd) {
134 case SNDRV_PCM_TRIGGER_START:
135 case SNDRV_PCM_TRIGGER_RESUME:
136 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
137 imx_ssi_set_next_poll(iprtd);
138 add_timer(&iprtd->timer);
139 if (++fiq_enable == 1)
140 enable_fiq(imx_pcm_fiq);
141
142 break;
143
144 case SNDRV_PCM_TRIGGER_STOP:
145 case SNDRV_PCM_TRIGGER_SUSPEND:
146 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
147 del_timer(&iprtd->timer);
148 if (--fiq_enable == 0)
149 disable_fiq(imx_pcm_fiq);
150
151
152 break;
153 default:
154 return -EINVAL;
155 }
156
157 return 0;
158}
159
160static snd_pcm_uframes_t snd_imx_pcm_pointer(struct snd_pcm_substream *substream)
161{
162 struct snd_pcm_runtime *runtime = substream->runtime;
163 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
164
165 return bytes_to_frames(substream->runtime, iprtd->offset);
166}
167
168static struct snd_pcm_hardware snd_imx_hardware = {
169 .info = SNDRV_PCM_INFO_INTERLEAVED |
170 SNDRV_PCM_INFO_BLOCK_TRANSFER |
171 SNDRV_PCM_INFO_MMAP |
172 SNDRV_PCM_INFO_MMAP_VALID |
173 SNDRV_PCM_INFO_PAUSE |
174 SNDRV_PCM_INFO_RESUME,
175 .formats = SNDRV_PCM_FMTBIT_S16_LE,
176 .rate_min = 8000,
177 .channels_min = 2,
178 .channels_max = 2,
179 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
180 .period_bytes_min = 128,
181 .period_bytes_max = 16 * 1024,
182 .periods_min = 2,
183 .periods_max = 255,
184 .fifo_size = 0,
185};
186
187static int snd_imx_open(struct snd_pcm_substream *substream)
188{
189 struct snd_pcm_runtime *runtime = substream->runtime;
190 struct imx_pcm_runtime_data *iprtd;
191 int ret;
192
193 iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
194 runtime->private_data = iprtd;
195
196 init_timer(&iprtd->timer);
197 iprtd->timer.data = (unsigned long)substream;
198 iprtd->timer.function = imx_ssi_timer_callback;
199
200 ret = snd_pcm_hw_constraint_integer(substream->runtime,
201 SNDRV_PCM_HW_PARAM_PERIODS);
202 if (ret < 0)
203 return ret;
204
205 snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
206 return 0;
207}
208
209static int snd_imx_close(struct snd_pcm_substream *substream)
210{
211 struct snd_pcm_runtime *runtime = substream->runtime;
212 struct imx_pcm_runtime_data *iprtd = runtime->private_data;
213
214 del_timer_sync(&iprtd->timer);
215 kfree(iprtd);
216
217 return 0;
218}
219
220static struct snd_pcm_ops imx_pcm_ops = {
221 .open = snd_imx_open,
222 .close = snd_imx_close,
223 .ioctl = snd_pcm_lib_ioctl,
224 .hw_params = snd_imx_pcm_hw_params,
225 .prepare = snd_imx_pcm_prepare,
226 .trigger = snd_imx_pcm_trigger,
227 .pointer = snd_imx_pcm_pointer,
228 .mmap = snd_imx_pcm_mmap,
229};
230
231static int imx_pcm_fiq_new(struct snd_card *card, struct snd_soc_dai *dai,
232 struct snd_pcm *pcm)
233{
234 int ret;
235
236 ret = imx_pcm_new(card, dai, pcm);
237 if (ret)
238 return ret;
239
240 if (dai->playback.channels_min) {
241 struct snd_pcm_substream *substream =
242 pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
243 struct snd_dma_buffer *buf = &substream->dma_buffer;
244
245 imx_ssi_fiq_tx_buffer = (unsigned long)buf->area;
246 }
247
248 if (dai->capture.channels_min) {
249 struct snd_pcm_substream *substream =
250 pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
251 struct snd_dma_buffer *buf = &substream->dma_buffer;
252
253 imx_ssi_fiq_rx_buffer = (unsigned long)buf->area;
254 }
255
256 set_fiq_handler(&imx_ssi_fiq_start,
257 &imx_ssi_fiq_end - &imx_ssi_fiq_start);
258
259 return 0;
260}
261
262static struct snd_soc_platform imx_soc_platform_fiq = {
263 .pcm_ops = &imx_pcm_ops,
264 .pcm_new = imx_pcm_fiq_new,
265 .pcm_free = imx_pcm_free,
266};
267
268struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
269 struct imx_ssi *ssi)
270{
271 int ret = 0;
272
273 ret = claim_fiq(&fh);
274 if (ret) {
275 dev_err(&pdev->dev, "failed to claim fiq: %d", ret);
276 return ERR_PTR(ret);
277 }
278
279 mxc_set_irq_fiq(ssi->irq, 1);
280
281 imx_pcm_fiq = ssi->irq;
282
283 imx_ssi_fiq_base = (unsigned long)ssi->base;
284
285 ssi->dma_params_tx.burstsize = 4;
286 ssi->dma_params_rx.burstsize = 6;
287
288 return &imx_soc_platform_fiq;
289}
290
291void imx_ssi_fiq_exit(struct platform_device *pdev,
292 struct imx_ssi *ssi)
293{
294 mxc_set_irq_fiq(ssi->irq, 0);
295 release_fiq(&fh);
296}
297
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
new file mode 100644
index 000000000000..56f46a75d297
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.c
@@ -0,0 +1,758 @@
1/*
2 * imx-ssi.c -- ALSA Soc Audio Layer
3 *
4 * Copyright 2009 Sascha Hauer <s.hauer@pengutronix.de>
5 *
6 * This code is based on code copyrighted by Freescale,
7 * Liam Girdwood, Javier Martin and probably others.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 *
15 * The i.MX SSI core has some nasty limitations in AC97 mode. While most
16 * sane processor vendors have a FIFO per AC97 slot, the i.MX has only
17 * one FIFO which combines all valid receive slots. We cannot even select
18 * which slots we want to receive. The WM9712 with which this driver
19 * was developped with always sends GPIO status data in slot 12 which
20 * we receive in our (PCM-) data stream. The only chance we have is to
21 * manually skip this data in the FIQ handler. With sampling rates different
22 * from 48000Hz not every frame has valid receive data, so the ratio
23 * between pcm data and GPIO status data changes. Our FIQ handler is not
24 * able to handle this, hence this driver only works with 48000Hz sampling
25 * rate.
26 * Reading and writing AC97 registers is another challange. The core
27 * provides us status bits when the read register is updated with *another*
28 * value. When we read the same register two times (and the register still
29 * contains the same value) these status bits are not set. We work
30 * around this by not polling these bits but only wait a fixed delay.
31 *
32 */
33
34#include <linux/clk.h>
35#include <linux/delay.h>
36#include <linux/device.h>
37#include <linux/dma-mapping.h>
38#include <linux/init.h>
39#include <linux/interrupt.h>
40#include <linux/module.h>
41#include <linux/platform_device.h>
42
43#include <sound/core.h>
44#include <sound/initval.h>
45#include <sound/pcm.h>
46#include <sound/pcm_params.h>
47#include <sound/soc.h>
48
49#include <mach/ssi.h>
50#include <mach/hardware.h>
51
52#include "imx-ssi.h"
53
54#define SSI_SACNT_DEFAULT (SSI_SACNT_AC97EN | SSI_SACNT_FV)
55
56/*
57 * SSI Network Mode or TDM slots configuration.
58 * Should only be called when port is inactive (i.e. SSIEN = 0).
59 */
60static int imx_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
61 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
62{
63 struct imx_ssi *ssi = cpu_dai->private_data;
64 u32 sccr;
65
66 sccr = readl(ssi->base + SSI_STCCR);
67 sccr &= ~SSI_STCCR_DC_MASK;
68 sccr |= SSI_STCCR_DC(slots - 1);
69 writel(sccr, ssi->base + SSI_STCCR);
70
71 sccr = readl(ssi->base + SSI_SRCCR);
72 sccr &= ~SSI_STCCR_DC_MASK;
73 sccr |= SSI_STCCR_DC(slots - 1);
74 writel(sccr, ssi->base + SSI_SRCCR);
75
76 writel(tx_mask, ssi->base + SSI_STMSK);
77 writel(rx_mask, ssi->base + SSI_SRMSK);
78
79 return 0;
80}
81
82/*
83 * SSI DAI format configuration.
84 * Should only be called when port is inactive (i.e. SSIEN = 0).
85 * Note: We don't use the I2S modes but instead manually configure the
86 * SSI for I2S because the I2S mode is only a register preset.
87 */
88static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
89{
90 struct imx_ssi *ssi = cpu_dai->private_data;
91 u32 strcr = 0, scr;
92
93 scr = readl(ssi->base + SSI_SCR) & ~(SSI_SCR_SYN | SSI_SCR_NET);
94
95 /* DAI mode */
96 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
97 case SND_SOC_DAIFMT_I2S:
98 /* data on rising edge of bclk, frame low 1clk before data */
99 strcr |= SSI_STCR_TFSI | SSI_STCR_TEFS | SSI_STCR_TXBIT0;
100 scr |= SSI_SCR_NET;
101 break;
102 case SND_SOC_DAIFMT_LEFT_J:
103 /* data on rising edge of bclk, frame high with data */
104 strcr |= SSI_STCR_TXBIT0;
105 break;
106 case SND_SOC_DAIFMT_DSP_B:
107 /* data on rising edge of bclk, frame high with data */
108 strcr |= SSI_STCR_TFSL;
109 break;
110 case SND_SOC_DAIFMT_DSP_A:
111 /* data on rising edge of bclk, frame high 1clk before data */
112 strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
113 break;
114 }
115
116 /* DAI clock inversion */
117 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
118 case SND_SOC_DAIFMT_IB_IF:
119 strcr |= SSI_STCR_TFSI;
120 strcr &= ~SSI_STCR_TSCKP;
121 break;
122 case SND_SOC_DAIFMT_IB_NF:
123 strcr &= ~(SSI_STCR_TSCKP | SSI_STCR_TFSI);
124 break;
125 case SND_SOC_DAIFMT_NB_IF:
126 strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP;
127 break;
128 case SND_SOC_DAIFMT_NB_NF:
129 strcr &= ~SSI_STCR_TFSI;
130 strcr |= SSI_STCR_TSCKP;
131 break;
132 }
133
134 /* DAI clock master masks */
135 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
136 case SND_SOC_DAIFMT_CBM_CFM:
137 break;
138 default:
139 /* Master mode not implemented, needs handling of clocks. */
140 return -EINVAL;
141 }
142
143 strcr |= SSI_STCR_TFEN0;
144
145 writel(strcr, ssi->base + SSI_STCR);
146 writel(strcr, ssi->base + SSI_SRCR);
147 writel(scr, ssi->base + SSI_SCR);
148
149 return 0;
150}
151
152/*
153 * SSI system clock configuration.
154 * Should only be called when port is inactive (i.e. SSIEN = 0).
155 */
156static int imx_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
157 int clk_id, unsigned int freq, int dir)
158{
159 struct imx_ssi *ssi = cpu_dai->private_data;
160 u32 scr;
161
162 scr = readl(ssi->base + SSI_SCR);
163
164 switch (clk_id) {
165 case IMX_SSP_SYS_CLK:
166 if (dir == SND_SOC_CLOCK_OUT)
167 scr |= SSI_SCR_SYS_CLK_EN;
168 else
169 scr &= ~SSI_SCR_SYS_CLK_EN;
170 break;
171 default:
172 return -EINVAL;
173 }
174
175 writel(scr, ssi->base + SSI_SCR);
176
177 return 0;
178}
179
180/*
181 * SSI Clock dividers
182 * Should only be called when port is inactive (i.e. SSIEN = 0).
183 */
184static int imx_ssi_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
185 int div_id, int div)
186{
187 struct imx_ssi *ssi = cpu_dai->private_data;
188 u32 stccr, srccr;
189
190 stccr = readl(ssi->base + SSI_STCCR);
191 srccr = readl(ssi->base + SSI_SRCCR);
192
193 switch (div_id) {
194 case IMX_SSI_TX_DIV_2:
195 stccr &= ~SSI_STCCR_DIV2;
196 stccr |= div;
197 break;
198 case IMX_SSI_TX_DIV_PSR:
199 stccr &= ~SSI_STCCR_PSR;
200 stccr |= div;
201 break;
202 case IMX_SSI_TX_DIV_PM:
203 stccr &= ~0xff;
204 stccr |= SSI_STCCR_PM(div);
205 break;
206 case IMX_SSI_RX_DIV_2:
207 stccr &= ~SSI_STCCR_DIV2;
208 stccr |= div;
209 break;
210 case IMX_SSI_RX_DIV_PSR:
211 stccr &= ~SSI_STCCR_PSR;
212 stccr |= div;
213 break;
214 case IMX_SSI_RX_DIV_PM:
215 stccr &= ~0xff;
216 stccr |= SSI_STCCR_PM(div);
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 writel(stccr, ssi->base + SSI_STCCR);
223 writel(srccr, ssi->base + SSI_SRCCR);
224
225 return 0;
226}
227
228/*
229 * Should only be called when port is inactive (i.e. SSIEN = 0),
230 * although can be called multiple times by upper layers.
231 */
232static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
233 struct snd_pcm_hw_params *params,
234 struct snd_soc_dai *cpu_dai)
235{
236 struct imx_ssi *ssi = cpu_dai->private_data;
237 u32 reg, sccr;
238
239 /* Tx/Rx config */
240 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
241 reg = SSI_STCCR;
242 cpu_dai->dma_data = &ssi->dma_params_tx;
243 } else {
244 reg = SSI_SRCCR;
245 cpu_dai->dma_data = &ssi->dma_params_rx;
246 }
247
248 sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
249
250 /* DAI data (word) size */
251 switch (params_format(params)) {
252 case SNDRV_PCM_FORMAT_S16_LE:
253 sccr |= SSI_SRCCR_WL(16);
254 break;
255 case SNDRV_PCM_FORMAT_S20_3LE:
256 sccr |= SSI_SRCCR_WL(20);
257 break;
258 case SNDRV_PCM_FORMAT_S24_LE:
259 sccr |= SSI_SRCCR_WL(24);
260 break;
261 }
262
263 writel(sccr, ssi->base + reg);
264
265 return 0;
266}
267
268static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
269 struct snd_soc_dai *dai)
270{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
273 struct imx_ssi *ssi = cpu_dai->private_data;
274 unsigned int sier_bits, sier;
275 unsigned int scr;
276
277 scr = readl(ssi->base + SSI_SCR);
278 sier = readl(ssi->base + SSI_SIER);
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
281 if (ssi->flags & IMX_SSI_DMA)
282 sier_bits = SSI_SIER_TDMAE;
283 else
284 sier_bits = SSI_SIER_TIE | SSI_SIER_TFE0_EN;
285 } else {
286 if (ssi->flags & IMX_SSI_DMA)
287 sier_bits = SSI_SIER_RDMAE;
288 else
289 sier_bits = SSI_SIER_RIE | SSI_SIER_RFF0_EN;
290 }
291
292 switch (cmd) {
293 case SNDRV_PCM_TRIGGER_START:
294 case SNDRV_PCM_TRIGGER_RESUME:
295 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
296 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
297 scr |= SSI_SCR_TE;
298 else
299 scr |= SSI_SCR_RE;
300 sier |= sier_bits;
301
302 if (++ssi->enabled == 1)
303 scr |= SSI_SCR_SSIEN;
304
305 break;
306
307 case SNDRV_PCM_TRIGGER_STOP:
308 case SNDRV_PCM_TRIGGER_SUSPEND:
309 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
310 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
311 scr &= ~SSI_SCR_TE;
312 else
313 scr &= ~SSI_SCR_RE;
314 sier &= ~sier_bits;
315
316 if (--ssi->enabled == 0)
317 scr &= ~SSI_SCR_SSIEN;
318
319 break;
320 default:
321 return -EINVAL;
322 }
323
324 if (!(ssi->flags & IMX_SSI_USE_AC97))
325 /* rx/tx are always enabled to access ac97 registers */
326 writel(scr, ssi->base + SSI_SCR);
327
328 writel(sier, ssi->base + SSI_SIER);
329
330 return 0;
331}
332
333static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
334 .hw_params = imx_ssi_hw_params,
335 .set_fmt = imx_ssi_set_dai_fmt,
336 .set_clkdiv = imx_ssi_set_dai_clkdiv,
337 .set_sysclk = imx_ssi_set_dai_sysclk,
338 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
339 .trigger = imx_ssi_trigger,
340};
341
342static struct snd_soc_dai imx_ssi_dai = {
343 .playback = {
344 .channels_min = 2,
345 .channels_max = 2,
346 .rates = SNDRV_PCM_RATE_8000_96000,
347 .formats = SNDRV_PCM_FMTBIT_S16_LE,
348 },
349 .capture = {
350 .channels_min = 2,
351 .channels_max = 2,
352 .rates = SNDRV_PCM_RATE_8000_96000,
353 .formats = SNDRV_PCM_FMTBIT_S16_LE,
354 },
355 .ops = &imx_ssi_pcm_dai_ops,
356};
357
358int snd_imx_pcm_mmap(struct snd_pcm_substream *substream,
359 struct vm_area_struct *vma)
360{
361 struct snd_pcm_runtime *runtime = substream->runtime;
362 int ret;
363
364 ret = dma_mmap_coherent(NULL, vma, runtime->dma_area,
365 runtime->dma_addr, runtime->dma_bytes);
366
367 pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret,
368 runtime->dma_area,
369 runtime->dma_addr,
370 runtime->dma_bytes);
371 return ret;
372}
373
374static int imx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
375{
376 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
377 struct snd_dma_buffer *buf = &substream->dma_buffer;
378 size_t size = IMX_SSI_DMABUF_SIZE;
379
380 buf->dev.type = SNDRV_DMA_TYPE_DEV;
381 buf->dev.dev = pcm->card->dev;
382 buf->private_data = NULL;
383 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
384 &buf->addr, GFP_KERNEL);
385 if (!buf->area)
386 return -ENOMEM;
387 buf->bytes = size;
388
389 return 0;
390}
391
392static u64 imx_pcm_dmamask = DMA_BIT_MASK(32);
393
394int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
395 struct snd_pcm *pcm)
396{
397
398 int ret = 0;
399
400 if (!card->dev->dma_mask)
401 card->dev->dma_mask = &imx_pcm_dmamask;
402 if (!card->dev->coherent_dma_mask)
403 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
404 if (dai->playback.channels_min) {
405 ret = imx_pcm_preallocate_dma_buffer(pcm,
406 SNDRV_PCM_STREAM_PLAYBACK);
407 if (ret)
408 goto out;
409 }
410
411 if (dai->capture.channels_min) {
412 ret = imx_pcm_preallocate_dma_buffer(pcm,
413 SNDRV_PCM_STREAM_CAPTURE);
414 if (ret)
415 goto out;
416 }
417
418out:
419 return ret;
420}
421
422void imx_pcm_free(struct snd_pcm *pcm)
423{
424 struct snd_pcm_substream *substream;
425 struct snd_dma_buffer *buf;
426 int stream;
427
428 for (stream = 0; stream < 2; stream++) {
429 substream = pcm->streams[stream].substream;
430 if (!substream)
431 continue;
432
433 buf = &substream->dma_buffer;
434 if (!buf->area)
435 continue;
436
437 dma_free_writecombine(pcm->card->dev, buf->bytes,
438 buf->area, buf->addr);
439 buf->area = NULL;
440 }
441}
442
443struct snd_soc_platform imx_soc_platform = {
444 .name = "imx-audio",
445};
446EXPORT_SYMBOL_GPL(imx_soc_platform);
447
448static struct snd_soc_dai imx_ac97_dai = {
449 .name = "AC97",
450 .ac97_control = 1,
451 .playback = {
452 .stream_name = "AC97 Playback",
453 .channels_min = 2,
454 .channels_max = 2,
455 .rates = SNDRV_PCM_RATE_48000,
456 .formats = SNDRV_PCM_FMTBIT_S16_LE,
457 },
458 .capture = {
459 .stream_name = "AC97 Capture",
460 .channels_min = 2,
461 .channels_max = 2,
462 .rates = SNDRV_PCM_RATE_48000,
463 .formats = SNDRV_PCM_FMTBIT_S16_LE,
464 },
465 .ops = &imx_ssi_pcm_dai_ops,
466};
467
468static void setup_channel_to_ac97(struct imx_ssi *imx_ssi)
469{
470 void __iomem *base = imx_ssi->base;
471
472 writel(0x0, base + SSI_SCR);
473 writel(0x0, base + SSI_STCR);
474 writel(0x0, base + SSI_SRCR);
475
476 writel(SSI_SCR_SYN | SSI_SCR_NET, base + SSI_SCR);
477
478 writel(SSI_SFCSR_RFWM0(8) |
479 SSI_SFCSR_TFWM0(8) |
480 SSI_SFCSR_RFWM1(8) |
481 SSI_SFCSR_TFWM1(8), base + SSI_SFCSR);
482
483 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_STCCR);
484 writel(SSI_STCCR_WL(16) | SSI_STCCR_DC(12), base + SSI_SRCCR);
485
486 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN, base + SSI_SCR);
487 writel(SSI_SOR_WAIT(3), base + SSI_SOR);
488
489 writel(SSI_SCR_SYN | SSI_SCR_NET | SSI_SCR_SSIEN |
490 SSI_SCR_TE | SSI_SCR_RE,
491 base + SSI_SCR);
492
493 writel(SSI_SACNT_DEFAULT, base + SSI_SACNT);
494 writel(0xff, base + SSI_SACCDIS);
495 writel(0x300, base + SSI_SACCEN);
496}
497
498static struct imx_ssi *ac97_ssi;
499
500static void imx_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
501 unsigned short val)
502{
503 struct imx_ssi *imx_ssi = ac97_ssi;
504 void __iomem *base = imx_ssi->base;
505 unsigned int lreg;
506 unsigned int lval;
507
508 if (reg > 0x7f)
509 return;
510
511 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
512
513 lreg = reg << 12;
514 writel(lreg, base + SSI_SACADD);
515
516 lval = val << 4;
517 writel(lval , base + SSI_SACDAT);
518
519 writel(SSI_SACNT_DEFAULT | SSI_SACNT_WR, base + SSI_SACNT);
520 udelay(100);
521}
522
523static unsigned short imx_ssi_ac97_read(struct snd_ac97 *ac97,
524 unsigned short reg)
525{
526 struct imx_ssi *imx_ssi = ac97_ssi;
527 void __iomem *base = imx_ssi->base;
528
529 unsigned short val = -1;
530 unsigned int lreg;
531
532 lreg = (reg & 0x7f) << 12 ;
533 writel(lreg, base + SSI_SACADD);
534 writel(SSI_SACNT_DEFAULT | SSI_SACNT_RD, base + SSI_SACNT);
535
536 udelay(100);
537
538 val = (readl(base + SSI_SACDAT) >> 4) & 0xffff;
539
540 pr_debug("%s: 0x%02x 0x%04x\n", __func__, reg, val);
541
542 return val;
543}
544
545static void imx_ssi_ac97_reset(struct snd_ac97 *ac97)
546{
547 struct imx_ssi *imx_ssi = ac97_ssi;
548
549 if (imx_ssi->ac97_reset)
550 imx_ssi->ac97_reset(ac97);
551}
552
553static void imx_ssi_ac97_warm_reset(struct snd_ac97 *ac97)
554{
555 struct imx_ssi *imx_ssi = ac97_ssi;
556
557 if (imx_ssi->ac97_warm_reset)
558 imx_ssi->ac97_warm_reset(ac97);
559}
560
561struct snd_ac97_bus_ops soc_ac97_ops = {
562 .read = imx_ssi_ac97_read,
563 .write = imx_ssi_ac97_write,
564 .reset = imx_ssi_ac97_reset,
565 .warm_reset = imx_ssi_ac97_warm_reset
566};
567EXPORT_SYMBOL_GPL(soc_ac97_ops);
568
569struct snd_soc_dai imx_ssi_pcm_dai[2];
570EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
571
572static int imx_ssi_probe(struct platform_device *pdev)
573{
574 struct resource *res;
575 struct imx_ssi *ssi;
576 struct imx_ssi_platform_data *pdata = pdev->dev.platform_data;
577 struct snd_soc_platform *platform;
578 int ret = 0;
579 unsigned int val;
580 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
581
582 if (dai->id >= ARRAY_SIZE(imx_ssi_pcm_dai))
583 return -EINVAL;
584
585 ssi = kzalloc(sizeof(*ssi), GFP_KERNEL);
586 if (!ssi)
587 return -ENOMEM;
588
589 if (pdata) {
590 ssi->ac97_reset = pdata->ac97_reset;
591 ssi->ac97_warm_reset = pdata->ac97_warm_reset;
592 ssi->flags = pdata->flags;
593 }
594
595 ssi->irq = platform_get_irq(pdev, 0);
596
597 ssi->clk = clk_get(&pdev->dev, NULL);
598 if (IS_ERR(ssi->clk)) {
599 ret = PTR_ERR(ssi->clk);
600 dev_err(&pdev->dev, "Cannot get the clock: %d\n",
601 ret);
602 goto failed_clk;
603 }
604 clk_enable(ssi->clk);
605
606 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
607 if (!res) {
608 ret = -ENODEV;
609 goto failed_get_resource;
610 }
611
612 if (!request_mem_region(res->start, resource_size(res), DRV_NAME)) {
613 dev_err(&pdev->dev, "request_mem_region failed\n");
614 ret = -EBUSY;
615 goto failed_get_resource;
616 }
617
618 ssi->base = ioremap(res->start, resource_size(res));
619 if (!ssi->base) {
620 dev_err(&pdev->dev, "ioremap failed\n");
621 ret = -ENODEV;
622 goto failed_ioremap;
623 }
624
625 if (ssi->flags & IMX_SSI_USE_AC97) {
626 if (ac97_ssi) {
627 ret = -EBUSY;
628 goto failed_ac97;
629 }
630 ac97_ssi = ssi;
631 setup_channel_to_ac97(ssi);
632 memcpy(dai, &imx_ac97_dai, sizeof(imx_ac97_dai));
633 } else
634 memcpy(dai, &imx_ssi_dai, sizeof(imx_ssi_dai));
635
636 writel(0x0, ssi->base + SSI_SIER);
637
638 ssi->dma_params_rx.dma_addr = res->start + SSI_SRX0;
639 ssi->dma_params_tx.dma_addr = res->start + SSI_STX0;
640
641 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx0");
642 if (res)
643 ssi->dma_params_tx.dma = res->start;
644
645 res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx0");
646 if (res)
647 ssi->dma_params_rx.dma = res->start;
648
649 dai->id = pdev->id;
650 dai->dev = &pdev->dev;
651 dai->name = kasprintf(GFP_KERNEL, "imx-ssi.%d", pdev->id);
652 dai->private_data = ssi;
653
654 if ((cpu_is_mx27() || cpu_is_mx21()) &&
655 !(ssi->flags & IMX_SSI_USE_AC97)) {
656 ssi->flags |= IMX_SSI_DMA;
657 platform = imx_ssi_dma_mx2_init(pdev, ssi);
658 } else
659 platform = imx_ssi_fiq_init(pdev, ssi);
660
661 imx_soc_platform.pcm_ops = platform->pcm_ops;
662 imx_soc_platform.pcm_new = platform->pcm_new;
663 imx_soc_platform.pcm_free = platform->pcm_free;
664
665 val = SSI_SFCSR_TFWM0(ssi->dma_params_tx.burstsize) |
666 SSI_SFCSR_RFWM0(ssi->dma_params_rx.burstsize);
667 writel(val, ssi->base + SSI_SFCSR);
668
669 ret = snd_soc_register_dai(dai);
670 if (ret) {
671 dev_err(&pdev->dev, "register DAI failed\n");
672 goto failed_register;
673 }
674
675 platform_set_drvdata(pdev, ssi);
676
677 return 0;
678
679failed_register:
680failed_ac97:
681 iounmap(ssi->base);
682failed_ioremap:
683 release_mem_region(res->start, resource_size(res));
684failed_get_resource:
685 clk_disable(ssi->clk);
686 clk_put(ssi->clk);
687failed_clk:
688 kfree(ssi);
689
690 return ret;
691}
692
693static int __devexit imx_ssi_remove(struct platform_device *pdev)
694{
695 struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
696 struct imx_ssi *ssi = platform_get_drvdata(pdev);
697 struct snd_soc_dai *dai = &imx_ssi_pcm_dai[pdev->id];
698
699 snd_soc_unregister_dai(dai);
700
701 if (ssi->flags & IMX_SSI_USE_AC97)
702 ac97_ssi = NULL;
703
704 if (!(ssi->flags & IMX_SSI_DMA))
705 imx_ssi_fiq_exit(pdev, ssi);
706
707 iounmap(ssi->base);
708 release_mem_region(res->start, resource_size(res));
709 clk_disable(ssi->clk);
710 clk_put(ssi->clk);
711 kfree(ssi);
712
713 return 0;
714}
715
716static struct platform_driver imx_ssi_driver = {
717 .probe = imx_ssi_probe,
718 .remove = __devexit_p(imx_ssi_remove),
719
720 .driver = {
721 .name = DRV_NAME,
722 .owner = THIS_MODULE,
723 },
724};
725
726static int __init imx_ssi_init(void)
727{
728 int ret;
729
730 ret = snd_soc_register_platform(&imx_soc_platform);
731 if (ret) {
732 pr_err("failed to register soc platform: %d\n", ret);
733 return ret;
734 }
735
736 ret = platform_driver_register(&imx_ssi_driver);
737 if (ret) {
738 snd_soc_unregister_platform(&imx_soc_platform);
739 return ret;
740 }
741
742 return 0;
743}
744
745static void __exit imx_ssi_exit(void)
746{
747 platform_driver_unregister(&imx_ssi_driver);
748 snd_soc_unregister_platform(&imx_soc_platform);
749}
750
751module_init(imx_ssi_init);
752module_exit(imx_ssi_exit);
753
754/* Module information */
755MODULE_AUTHOR("Sascha Hauer, <s.hauer@pengutronix.de>");
756MODULE_DESCRIPTION("i.MX I2S/ac97 SoC Interface");
757MODULE_LICENSE("GPL");
758
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h
new file mode 100644
index 000000000000..55f26ebcd8c2
--- /dev/null
+++ b/sound/soc/imx/imx-ssi.h
@@ -0,0 +1,237 @@
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#define SSI_STX0 0x00
11#define SSI_STX1 0x04
12#define SSI_SRX0 0x08
13#define SSI_SRX1 0x0c
14
15#define SSI_SCR 0x10
16#define SSI_SCR_CLK_IST (1 << 9)
17#define SSI_SCR_CLK_IST_SHIFT 9
18#define SSI_SCR_TCH_EN (1 << 8)
19#define SSI_SCR_SYS_CLK_EN (1 << 7)
20#define SSI_SCR_I2S_MODE_NORM (0 << 5)
21#define SSI_SCR_I2S_MODE_MSTR (1 << 5)
22#define SSI_SCR_I2S_MODE_SLAVE (2 << 5)
23#define SSI_I2S_MODE_MASK (3 << 5)
24#define SSI_SCR_SYN (1 << 4)
25#define SSI_SCR_NET (1 << 3)
26#define SSI_SCR_RE (1 << 2)
27#define SSI_SCR_TE (1 << 1)
28#define SSI_SCR_SSIEN (1 << 0)
29
30#define SSI_SISR 0x14
31#define SSI_SISR_MASK ((1 << 19) - 1)
32#define SSI_SISR_CMDAU (1 << 18)
33#define SSI_SISR_CMDDU (1 << 17)
34#define SSI_SISR_RXT (1 << 16)
35#define SSI_SISR_RDR1 (1 << 15)
36#define SSI_SISR_RDR0 (1 << 14)
37#define SSI_SISR_TDE1 (1 << 13)
38#define SSI_SISR_TDE0 (1 << 12)
39#define SSI_SISR_ROE1 (1 << 11)
40#define SSI_SISR_ROE0 (1 << 10)
41#define SSI_SISR_TUE1 (1 << 9)
42#define SSI_SISR_TUE0 (1 << 8)
43#define SSI_SISR_TFS (1 << 7)
44#define SSI_SISR_RFS (1 << 6)
45#define SSI_SISR_TLS (1 << 5)
46#define SSI_SISR_RLS (1 << 4)
47#define SSI_SISR_RFF1 (1 << 3)
48#define SSI_SISR_RFF0 (1 << 2)
49#define SSI_SISR_TFE1 (1 << 1)
50#define SSI_SISR_TFE0 (1 << 0)
51
52#define SSI_SIER 0x18
53#define SSI_SIER_RDMAE (1 << 22)
54#define SSI_SIER_RIE (1 << 21)
55#define SSI_SIER_TDMAE (1 << 20)
56#define SSI_SIER_TIE (1 << 19)
57#define SSI_SIER_CMDAU_EN (1 << 18)
58#define SSI_SIER_CMDDU_EN (1 << 17)
59#define SSI_SIER_RXT_EN (1 << 16)
60#define SSI_SIER_RDR1_EN (1 << 15)
61#define SSI_SIER_RDR0_EN (1 << 14)
62#define SSI_SIER_TDE1_EN (1 << 13)
63#define SSI_SIER_TDE0_EN (1 << 12)
64#define SSI_SIER_ROE1_EN (1 << 11)
65#define SSI_SIER_ROE0_EN (1 << 10)
66#define SSI_SIER_TUE1_EN (1 << 9)
67#define SSI_SIER_TUE0_EN (1 << 8)
68#define SSI_SIER_TFS_EN (1 << 7)
69#define SSI_SIER_RFS_EN (1 << 6)
70#define SSI_SIER_TLS_EN (1 << 5)
71#define SSI_SIER_RLS_EN (1 << 4)
72#define SSI_SIER_RFF1_EN (1 << 3)
73#define SSI_SIER_RFF0_EN (1 << 2)
74#define SSI_SIER_TFE1_EN (1 << 1)
75#define SSI_SIER_TFE0_EN (1 << 0)
76
77#define SSI_STCR 0x1c
78#define SSI_STCR_TXBIT0 (1 << 9)
79#define SSI_STCR_TFEN1 (1 << 8)
80#define SSI_STCR_TFEN0 (1 << 7)
81#define SSI_FIFO_ENABLE_0_SHIFT 7
82#define SSI_STCR_TFDIR (1 << 6)
83#define SSI_STCR_TXDIR (1 << 5)
84#define SSI_STCR_TSHFD (1 << 4)
85#define SSI_STCR_TSCKP (1 << 3)
86#define SSI_STCR_TFSI (1 << 2)
87#define SSI_STCR_TFSL (1 << 1)
88#define SSI_STCR_TEFS (1 << 0)
89
90#define SSI_SRCR 0x20
91#define SSI_SRCR_RXBIT0 (1 << 9)
92#define SSI_SRCR_RFEN1 (1 << 8)
93#define SSI_SRCR_RFEN0 (1 << 7)
94#define SSI_FIFO_ENABLE_0_SHIFT 7
95#define SSI_SRCR_RFDIR (1 << 6)
96#define SSI_SRCR_RXDIR (1 << 5)
97#define SSI_SRCR_RSHFD (1 << 4)
98#define SSI_SRCR_RSCKP (1 << 3)
99#define SSI_SRCR_RFSI (1 << 2)
100#define SSI_SRCR_RFSL (1 << 1)
101#define SSI_SRCR_REFS (1 << 0)
102
103#define SSI_SRCCR 0x28
104#define SSI_SRCCR_DIV2 (1 << 18)
105#define SSI_SRCCR_PSR (1 << 17)
106#define SSI_SRCCR_WL(x) ((((x) - 2) >> 1) << 13)
107#define SSI_SRCCR_DC(x) (((x) & 0x1f) << 8)
108#define SSI_SRCCR_PM(x) (((x) & 0xff) << 0)
109#define SSI_SRCCR_WL_MASK (0xf << 13)
110#define SSI_SRCCR_DC_MASK (0x1f << 8)
111#define SSI_SRCCR_PM_MASK (0xff << 0)
112
113#define SSI_STCCR 0x24
114#define SSI_STCCR_DIV2 (1 << 18)
115#define SSI_STCCR_PSR (1 << 17)
116#define SSI_STCCR_WL(x) ((((x) - 2) >> 1) << 13)
117#define SSI_STCCR_DC(x) (((x) & 0x1f) << 8)
118#define SSI_STCCR_PM(x) (((x) & 0xff) << 0)
119#define SSI_STCCR_WL_MASK (0xf << 13)
120#define SSI_STCCR_DC_MASK (0x1f << 8)
121#define SSI_STCCR_PM_MASK (0xff << 0)
122
123#define SSI_SFCSR 0x2c
124#define SSI_SFCSR_RFCNT1(x) (((x) & 0xf) << 28)
125#define SSI_RX_FIFO_1_COUNT_SHIFT 28
126#define SSI_SFCSR_TFCNT1(x) (((x) & 0xf) << 24)
127#define SSI_TX_FIFO_1_COUNT_SHIFT 24
128#define SSI_SFCSR_RFWM1(x) (((x) & 0xf) << 20)
129#define SSI_SFCSR_TFWM1(x) (((x) & 0xf) << 16)
130#define SSI_SFCSR_RFCNT0(x) (((x) & 0xf) << 12)
131#define SSI_RX_FIFO_0_COUNT_SHIFT 12
132#define SSI_SFCSR_TFCNT0(x) (((x) & 0xf) << 8)
133#define SSI_TX_FIFO_0_COUNT_SHIFT 8
134#define SSI_SFCSR_RFWM0(x) (((x) & 0xf) << 4)
135#define SSI_SFCSR_TFWM0(x) (((x) & 0xf) << 0)
136#define SSI_SFCSR_RFWM0_MASK (0xf << 4)
137#define SSI_SFCSR_TFWM0_MASK (0xf << 0)
138
139#define SSI_STR 0x30
140#define SSI_STR_TEST (1 << 15)
141#define SSI_STR_RCK2TCK (1 << 14)
142#define SSI_STR_RFS2TFS (1 << 13)
143#define SSI_STR_RXSTATE(x) (((x) & 0xf) << 8)
144#define SSI_STR_TXD2RXD (1 << 7)
145#define SSI_STR_TCK2RCK (1 << 6)
146#define SSI_STR_TFS2RFS (1 << 5)
147#define SSI_STR_TXSTATE(x) (((x) & 0xf) << 0)
148
149#define SSI_SOR 0x34
150#define SSI_SOR_CLKOFF (1 << 6)
151#define SSI_SOR_RX_CLR (1 << 5)
152#define SSI_SOR_TX_CLR (1 << 4)
153#define SSI_SOR_INIT (1 << 3)
154#define SSI_SOR_WAIT(x) (((x) & 0x3) << 1)
155#define SSI_SOR_WAIT_MASK (0x3 << 1)
156#define SSI_SOR_SYNRST (1 << 0)
157
158#define SSI_SACNT 0x38
159#define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5)
160#define SSI_SACNT_WR (1 << 4)
161#define SSI_SACNT_RD (1 << 3)
162#define SSI_SACNT_TIF (1 << 2)
163#define SSI_SACNT_FV (1 << 1)
164#define SSI_SACNT_AC97EN (1 << 0)
165
166#define SSI_SACADD 0x3c
167#define SSI_SACDAT 0x40
168#define SSI_SATAG 0x44
169#define SSI_STMSK 0x48
170#define SSI_SRMSK 0x4c
171#define SSI_SACCST 0x50
172#define SSI_SACCEN 0x54
173#define SSI_SACCDIS 0x58
174
175/* SSI clock sources */
176#define IMX_SSP_SYS_CLK 0
177
178/* SSI audio dividers */
179#define IMX_SSI_TX_DIV_2 0
180#define IMX_SSI_TX_DIV_PSR 1
181#define IMX_SSI_TX_DIV_PM 2
182#define IMX_SSI_RX_DIV_2 3
183#define IMX_SSI_RX_DIV_PSR 4
184#define IMX_SSI_RX_DIV_PM 5
185
186extern struct snd_soc_dai imx_ssi_pcm_dai[2];
187extern struct snd_soc_platform imx_soc_platform;
188
189#define DRV_NAME "imx-ssi"
190
191struct imx_pcm_dma_params {
192 int dma;
193 unsigned long dma_addr;
194 int burstsize;
195};
196
197struct imx_ssi {
198 struct platform_device *ac97_dev;
199
200 struct snd_soc_device imx_ac97;
201 struct clk *clk;
202 void __iomem *base;
203 int irq;
204 int fiq_enable;
205 unsigned int offset;
206
207 unsigned int flags;
208
209 void (*ac97_reset) (struct snd_ac97 *ac97);
210 void (*ac97_warm_reset)(struct snd_ac97 *ac97);
211
212 struct imx_pcm_dma_params dma_params_rx;
213 struct imx_pcm_dma_params dma_params_tx;
214
215 int enabled;
216};
217
218struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev,
219 struct imx_ssi *ssi);
220void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi);
221struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev,
222 struct imx_ssi *ssi);
223
224int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma);
225int imx_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
226 struct snd_pcm *pcm);
227void imx_pcm_free(struct snd_pcm *pcm);
228
229/*
230 * Do not change this as the FIQ handler depends on this size
231 */
232#define IMX_SSI_DMABUF_SIZE (64 * 1024)
233
234#define DMA_RXFIFO_BURST 0x4
235#define DMA_TXFIFO_BURST 0x6
236
237#endif /* _IMX_SSI_H */
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
deleted file mode 100644
index bffffcd5ff34..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.c
+++ /dev/null
@@ -1,488 +0,0 @@
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 ret = imx_dma_request_by_prio(prtd->dma_params->name, DMA_PRIO_HIGH);
326 if (ret < 0) {
327 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
328 return ret;
329 }
330 prtd->dma_ch = ret;
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
deleted file mode 100644
index 2e528106570b..000000000000
--- a/sound/soc/imx/mx1_mx2-pcm.h
+++ /dev/null
@@ -1,26 +0,0 @@
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
deleted file mode 100644
index 07d2a248438c..000000000000
--- a/sound/soc/imx/mx27vis_wm8974.c
+++ /dev/null
@@ -1,318 +0,0 @@
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, 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, IGNORED_ARG,
184 0, 0);
185}
186
187/*
188 * mx27vis WM8974 HiFi DAI opserations.
189 */
190static struct snd_soc_ops mx27vis_hifi_ops = {
191 .hw_params = mx27vis_hifi_hw_params,
192 .hw_free = mx27vis_hifi_hw_free,
193};
194
195
196static int mx27vis_suspend(struct platform_device *pdev, pm_message_t state)
197{
198 return 0;
199}
200
201static int mx27vis_resume(struct platform_device *pdev)
202{
203 return 0;
204}
205
206static int mx27vis_probe(struct platform_device *pdev)
207{
208 int ret = 0;
209
210 ret = get_ssi_clk(0, &pdev->dev);
211
212 if (ret < 0) {
213 printk(KERN_ERR "%s: cant get ssi clock\n", __func__);
214 return ret;
215 }
216
217
218 return 0;
219}
220
221static int mx27vis_remove(struct platform_device *pdev)
222{
223 put_ssi_clk(0);
224 return 0;
225}
226
227static struct snd_soc_dai_link mx27vis_dai[] = {
228{ /* Hifi Playback*/
229 .name = "WM8974",
230 .stream_name = "WM8974 HiFi",
231 .cpu_dai = &imx_ssi_pcm_dai[0],
232 .codec_dai = &wm8974_dai,
233 .ops = &mx27vis_hifi_ops,
234},
235};
236
237static struct snd_soc_card mx27vis = {
238 .name = "mx27vis",
239 .platform = &mx1_mx2_soc_platform,
240 .probe = mx27vis_probe,
241 .remove = mx27vis_remove,
242 .suspend_pre = mx27vis_suspend,
243 .resume_post = mx27vis_resume,
244 .dai_link = mx27vis_dai,
245 .num_links = ARRAY_SIZE(mx27vis_dai),
246};
247
248static struct snd_soc_device mx27vis_snd_devdata = {
249 .card = &mx27vis,
250 .codec_dev = &soc_codec_dev_wm8974,
251};
252
253static struct platform_device *mx27vis_snd_device;
254
255/* Temporal definition of board specific behaviour */
256void gpio_ssi_active(int ssi_num)
257{
258 int ret = 0;
259
260 unsigned int ssi1_pins[] = {
261 PC20_PF_SSI1_FS,
262 PC21_PF_SSI1_RXD,
263 PC22_PF_SSI1_TXD,
264 PC23_PF_SSI1_CLK,
265 };
266 unsigned int ssi2_pins[] = {
267 PC24_PF_SSI2_FS,
268 PC25_PF_SSI2_RXD,
269 PC26_PF_SSI2_TXD,
270 PC27_PF_SSI2_CLK,
271 };
272 if (ssi_num == 0)
273 ret = mxc_gpio_setup_multiple_pins(ssi1_pins,
274 ARRAY_SIZE(ssi1_pins), "USB OTG");
275 else
276 ret = mxc_gpio_setup_multiple_pins(ssi2_pins,
277 ARRAY_SIZE(ssi2_pins), "USB OTG");
278 if (ret)
279 printk(KERN_ERR "Error requesting ssi %x pins\n", ssi_num);
280}
281
282
283static int __init mx27vis_init(void)
284{
285 int ret;
286
287 mx27vis_snd_device = platform_device_alloc("soc-audio", -1);
288 if (!mx27vis_snd_device)
289 return -ENOMEM;
290
291 platform_set_drvdata(mx27vis_snd_device, &mx27vis_snd_devdata);
292 mx27vis_snd_devdata.dev = &mx27vis_snd_device->dev;
293 ret = platform_device_add(mx27vis_snd_device);
294
295 if (ret) {
296 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
297 platform_device_put(mx27vis_snd_device);
298 }
299
300 /* WM8974 uses SSI1 (HPCR1) via AUDMUX port 4 for audio (PPCR1) */
301 gpio_ssi_active(0);
302 audmux_connect_1_4();
303
304 return ret;
305}
306
307static void __exit mx27vis_exit(void)
308{
309 /* We should call some "ssi_gpio_inactive()" properly */
310}
311
312module_init(mx27vis_init);
313module_exit(mx27vis_exit);
314
315
316MODULE_AUTHOR("Javier Martin, javier.martin@vista-silicon.com");
317MODULE_DESCRIPTION("ALSA SoC WM8974 mx27vis");
318MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.c b/sound/soc/imx/mxc-ssi.c
deleted file mode 100644
index ccdefe60e752..000000000000
--- a/sound/soc/imx/mxc-ssi.c
+++ /dev/null
@@ -1,860 +0,0 @@
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 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
401 SSI1_STCR = stcr;
402 SSI1_SRCR = srcr;
403 SSI1_SCR = scr;
404 } else {
405 SSI2_STCR = stcr;
406 SSI2_SRCR = srcr;
407 SSI2_SCR = scr;
408 }
409
410 return 0;
411}
412
413static int imx_ssi_startup(struct snd_pcm_substream *substream,
414 struct snd_soc_dai *dai)
415{
416 struct snd_soc_pcm_runtime *rtd = substream->private_data;
417 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
418
419 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
420 /* set up TX DMA params */
421 switch (cpu_dai->id) {
422 case IMX_DAI_SSI0:
423 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out0;
424 break;
425 case IMX_DAI_SSI1:
426 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_out1;
427 break;
428 case IMX_DAI_SSI2:
429 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out0;
430 break;
431 case IMX_DAI_SSI3:
432 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_out1;
433 }
434 pr_debug("%s: (playback)\n", __func__);
435 } else {
436 /* set up RX DMA params */
437 switch (cpu_dai->id) {
438 case IMX_DAI_SSI0:
439 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in0;
440 break;
441 case IMX_DAI_SSI1:
442 cpu_dai->dma_data = &imx_ssi1_pcm_stereo_in1;
443 break;
444 case IMX_DAI_SSI2:
445 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in0;
446 break;
447 case IMX_DAI_SSI3:
448 cpu_dai->dma_data = &imx_ssi2_pcm_stereo_in1;
449 }
450 pr_debug("%s: (capture)\n", __func__);
451 }
452
453 /*
454 * we cant really change any SSI values after SSI is enabled
455 * need to fix in software for max flexibility - lrg
456 */
457 if (cpu_dai->active) {
458 printk(KERN_WARNING "Warning ssi already enabled\n");
459 return 0;
460 }
461
462 /* reset the SSI port - Sect 45.4.4 */
463 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
464
465 if (!ssi_clk0)
466 return -EINVAL;
467
468 if (ssi_active[SSI1_PORT]++) {
469 pr_debug("%s: exit before reset\n", __func__);
470 return 0;
471 }
472
473 /* SSI1 Reset */
474 SSI1_SCR = 0;
475
476 SSI1_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
477 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
478 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
479 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
480 } else {
481
482 if (!ssi_clk1)
483 return -EINVAL;
484
485 if (ssi_active[SSI2_PORT]++) {
486 pr_debug("%s: exit before reset\n", __func__);
487 return 0;
488 }
489
490 /* SSI2 Reset */
491 SSI2_SCR = 0;
492
493 SSI2_SFCSR = SSI_SFCSR_RFWM1(RXFIFO_WATERMARK) |
494 SSI_SFCSR_RFWM0(RXFIFO_WATERMARK) |
495 SSI_SFCSR_TFWM1(TXFIFO_WATERMARK) |
496 SSI_SFCSR_TFWM0(TXFIFO_WATERMARK);
497 }
498
499 return 0;
500}
501
502int imx_ssi_hw_tx_params(struct snd_pcm_substream *substream,
503 struct snd_pcm_hw_params *params)
504{
505 struct snd_soc_pcm_runtime *rtd = substream->private_data;
506 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
507 u32 stccr, stcr, sier;
508
509 pr_debug("%s\n", __func__);
510
511 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
512 stccr = SSI1_STCCR & ~SSI_STCCR_WL_MASK;
513 stcr = SSI1_STCR;
514 sier = SSI1_SIER;
515 } else {
516 stccr = SSI2_STCCR & ~SSI_STCCR_WL_MASK;
517 stcr = SSI2_STCR;
518 sier = SSI2_SIER;
519 }
520
521 /* DAI data (word) size */
522 switch (params_format(params)) {
523 case SNDRV_PCM_FORMAT_S16_LE:
524 stccr |= SSI_STCCR_WL(16);
525 break;
526 case SNDRV_PCM_FORMAT_S20_3LE:
527 stccr |= SSI_STCCR_WL(20);
528 break;
529 case SNDRV_PCM_FORMAT_S24_LE:
530 stccr |= SSI_STCCR_WL(24);
531 break;
532 }
533
534 /* enable interrupts */
535 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
536 stcr |= SSI_STCR_TFEN0;
537 else
538 stcr |= SSI_STCR_TFEN1;
539 sier |= SSI_SIER_TDMAE;
540
541 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
542 SSI1_STCR = stcr;
543 SSI1_STCCR = stccr;
544 SSI1_SIER = sier;
545 } else {
546 SSI2_STCR = stcr;
547 SSI2_STCCR = stccr;
548 SSI2_SIER = sier;
549 }
550
551 return 0;
552}
553
554int imx_ssi_hw_rx_params(struct snd_pcm_substream *substream,
555 struct snd_pcm_hw_params *params)
556{
557 struct snd_soc_pcm_runtime *rtd = substream->private_data;
558 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
559 u32 srccr, srcr, sier;
560
561 pr_debug("%s\n", __func__);
562
563 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
564 srccr = SSI1_SRCCR & ~SSI_SRCCR_WL_MASK;
565 srcr = SSI1_SRCR;
566 sier = SSI1_SIER;
567 } else {
568 srccr = SSI2_SRCCR & ~SSI_SRCCR_WL_MASK;
569 srcr = SSI2_SRCR;
570 sier = SSI2_SIER;
571 }
572
573 /* DAI data (word) size */
574 switch (params_format(params)) {
575 case SNDRV_PCM_FORMAT_S16_LE:
576 srccr |= SSI_SRCCR_WL(16);
577 break;
578 case SNDRV_PCM_FORMAT_S20_3LE:
579 srccr |= SSI_SRCCR_WL(20);
580 break;
581 case SNDRV_PCM_FORMAT_S24_LE:
582 srccr |= SSI_SRCCR_WL(24);
583 break;
584 }
585
586 /* enable interrupts */
587 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
588 srcr |= SSI_SRCR_RFEN0;
589 else
590 srcr |= SSI_SRCR_RFEN1;
591 sier |= SSI_SIER_RDMAE;
592
593 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
594 SSI1_SRCR = srcr;
595 SSI1_SRCCR = srccr;
596 SSI1_SIER = sier;
597 } else {
598 SSI2_SRCR = srcr;
599 SSI2_SRCCR = srccr;
600 SSI2_SIER = sier;
601 }
602
603 return 0;
604}
605
606/*
607 * Should only be called when port is inactive (i.e. SSIEN = 0),
608 * although can be called multiple times by upper layers.
609 */
610int imx_ssi_hw_params(struct snd_pcm_substream *substream,
611 struct snd_pcm_hw_params *params,
612 struct snd_soc_dai *dai)
613{
614 struct snd_soc_pcm_runtime *rtd = substream->private_data;
615 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
616
617 int ret;
618
619 /* cant change any parameters when SSI is running */
620 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
621 if (SSI1_SCR & SSI_SCR_SSIEN) {
622 printk(KERN_WARNING "Warning ssi already enabled\n");
623 return 0;
624 }
625 } else {
626 if (SSI2_SCR & SSI_SCR_SSIEN) {
627 printk(KERN_WARNING "Warning ssi already enabled\n");
628 return 0;
629 }
630 }
631
632 /*
633 * Configure both tx and rx params with the same settings. This is
634 * really a harware restriction because SSI must be disabled until
635 * we can change those values. If there is an active audio stream in
636 * one direction, enabling the other direction with different
637 * settings would mean disturbing the running one.
638 */
639 ret = imx_ssi_hw_tx_params(substream, params);
640 if (ret < 0)
641 return ret;
642 return imx_ssi_hw_rx_params(substream, params);
643}
644
645int imx_ssi_prepare(struct snd_pcm_substream *substream,
646 struct snd_soc_dai *dai)
647{
648 struct snd_soc_pcm_runtime *rtd = substream->private_data;
649 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
650 int ret;
651
652 pr_debug("%s\n", __func__);
653
654 /* Enable clks here to follow SSI recommended init sequence */
655 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2) {
656 ret = clk_enable(ssi_clk0);
657 if (ret < 0)
658 printk(KERN_ERR "Unable to enable ssi_clk0\n");
659 } else {
660 ret = clk_enable(ssi_clk1);
661 if (ret < 0)
662 printk(KERN_ERR "Unable to enable ssi_clk1\n");
663 }
664
665 return 0;
666}
667
668static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
669 struct snd_soc_dai *dai)
670{
671 struct snd_soc_pcm_runtime *rtd = substream->private_data;
672 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
673 u32 scr;
674
675 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
676 scr = SSI1_SCR;
677 else
678 scr = SSI2_SCR;
679
680 switch (cmd) {
681 case SNDRV_PCM_TRIGGER_START:
682 case SNDRV_PCM_TRIGGER_RESUME:
683 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
684 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
685 scr |= SSI_SCR_TE | SSI_SCR_SSIEN;
686 else
687 scr |= SSI_SCR_RE | SSI_SCR_SSIEN;
688 break;
689 case SNDRV_PCM_TRIGGER_SUSPEND:
690 case SNDRV_PCM_TRIGGER_STOP:
691 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
692 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
693 scr &= ~SSI_SCR_TE;
694 else
695 scr &= ~SSI_SCR_RE;
696 break;
697 default:
698 return -EINVAL;
699 }
700
701 if (cpu_dai->id == IMX_DAI_SSI0 || cpu_dai->id == IMX_DAI_SSI2)
702 SSI1_SCR = scr;
703 else
704 SSI2_SCR = scr;
705
706 return 0;
707}
708
709static void imx_ssi_shutdown(struct snd_pcm_substream *substream,
710 struct snd_soc_dai *dai)
711{
712 struct snd_soc_pcm_runtime *rtd = substream->private_data;
713 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
714
715 /* shutdown SSI if neither Tx or Rx is active */
716 if (!cpu_dai->active) {
717
718 if (cpu_dai->id == IMX_DAI_SSI0 ||
719 cpu_dai->id == IMX_DAI_SSI2) {
720
721 if (--ssi_active[SSI1_PORT] > 1)
722 return;
723
724 SSI1_SCR = 0;
725 clk_disable(ssi_clk0);
726 } else {
727 if (--ssi_active[SSI2_PORT])
728 return;
729 SSI2_SCR = 0;
730 clk_disable(ssi_clk1);
731 }
732 }
733}
734
735#ifdef CONFIG_PM
736static int imx_ssi_suspend(struct platform_device *dev,
737 struct snd_soc_dai *dai)
738{
739 return 0;
740}
741
742static int imx_ssi_resume(struct platform_device *pdev,
743 struct snd_soc_dai *dai)
744{
745 return 0;
746}
747
748#else
749#define imx_ssi_suspend NULL
750#define imx_ssi_resume NULL
751#endif
752
753#define IMX_SSI_RATES \
754 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | \
755 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
756 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
757 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | \
758 SNDRV_PCM_RATE_96000)
759
760#define IMX_SSI_BITS \
761 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
762 SNDRV_PCM_FMTBIT_S24_LE)
763
764static struct snd_soc_dai_ops imx_ssi_pcm_dai_ops = {
765 .startup = imx_ssi_startup,
766 .shutdown = imx_ssi_shutdown,
767 .trigger = imx_ssi_trigger,
768 .prepare = imx_ssi_prepare,
769 .hw_params = imx_ssi_hw_params,
770 .set_sysclk = imx_ssi_set_dai_sysclk,
771 .set_clkdiv = imx_ssi_set_dai_clkdiv,
772 .set_fmt = imx_ssi_set_dai_fmt,
773 .set_tdm_slot = imx_ssi_set_dai_tdm_slot,
774};
775
776struct snd_soc_dai imx_ssi_pcm_dai[] = {
777{
778 .name = "imx-i2s-1-0",
779 .id = IMX_DAI_SSI0,
780 .suspend = imx_ssi_suspend,
781 .resume = imx_ssi_resume,
782 .playback = {
783 .channels_min = 1,
784 .channels_max = 2,
785 .formats = IMX_SSI_BITS,
786 .rates = IMX_SSI_RATES,},
787 .capture = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .formats = IMX_SSI_BITS,
791 .rates = IMX_SSI_RATES,},
792 .ops = &imx_ssi_pcm_dai_ops,
793},
794{
795 .name = "imx-i2s-2-0",
796 .id = IMX_DAI_SSI1,
797 .playback = {
798 .channels_min = 1,
799 .channels_max = 2,
800 .formats = IMX_SSI_BITS,
801 .rates = IMX_SSI_RATES,},
802 .capture = {
803 .channels_min = 1,
804 .channels_max = 2,
805 .formats = IMX_SSI_BITS,
806 .rates = IMX_SSI_RATES,},
807 .ops = &imx_ssi_pcm_dai_ops,
808},
809{
810 .name = "imx-i2s-1-1",
811 .id = IMX_DAI_SSI2,
812 .suspend = imx_ssi_suspend,
813 .resume = imx_ssi_resume,
814 .playback = {
815 .channels_min = 1,
816 .channels_max = 2,
817 .formats = IMX_SSI_BITS,
818 .rates = IMX_SSI_RATES,},
819 .capture = {
820 .channels_min = 1,
821 .channels_max = 2,
822 .formats = IMX_SSI_BITS,
823 .rates = IMX_SSI_RATES,},
824 .ops = &imx_ssi_pcm_dai_ops,
825},
826{
827 .name = "imx-i2s-2-1",
828 .id = IMX_DAI_SSI3,
829 .playback = {
830 .channels_min = 1,
831 .channels_max = 2,
832 .formats = IMX_SSI_BITS,
833 .rates = IMX_SSI_RATES,},
834 .capture = {
835 .channels_min = 1,
836 .channels_max = 2,
837 .formats = IMX_SSI_BITS,
838 .rates = IMX_SSI_RATES,},
839 .ops = &imx_ssi_pcm_dai_ops,
840},
841};
842EXPORT_SYMBOL_GPL(imx_ssi_pcm_dai);
843
844static int __init imx_ssi_init(void)
845{
846 return snd_soc_register_dais(imx_ssi_pcm_dai,
847 ARRAY_SIZE(imx_ssi_pcm_dai));
848}
849
850static void __exit imx_ssi_exit(void)
851{
852 snd_soc_unregister_dais(imx_ssi_pcm_dai,
853 ARRAY_SIZE(imx_ssi_pcm_dai));
854}
855
856module_init(imx_ssi_init);
857module_exit(imx_ssi_exit);
858MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com");
859MODULE_DESCRIPTION("i.MX ASoC I2S driver");
860MODULE_LICENSE("GPL");
diff --git a/sound/soc/imx/mxc-ssi.h b/sound/soc/imx/mxc-ssi.h
deleted file mode 100644
index 12bbdc9c7ecd..000000000000
--- a/sound/soc/imx/mxc-ssi.h
+++ /dev/null
@@ -1,238 +0,0 @@
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/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
new file mode 100644
index 000000000000..a8307d55c70e
--- /dev/null
+++ b/sound/soc/imx/phycore-ac97.c
@@ -0,0 +1,90 @@
1/*
2 * phycore-ac97.c -- SoC audio for imx_phycore in AC97 mode
3 *
4 * Copyright 2009 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/device.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <asm/mach-types.h>
22
23#include "../codecs/wm9712.h"
24#include "imx-ssi.h"
25
26static struct snd_soc_card imx_phycore;
27
28static struct snd_soc_ops imx_phycore_hifi_ops = {
29};
30
31static struct snd_soc_dai_link imx_phycore_dai_ac97[] = {
32 {
33 .name = "HiFi",
34 .stream_name = "HiFi",
35 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
36 .ops = &imx_phycore_hifi_ops,
37 },
38};
39
40static struct snd_soc_card imx_phycore = {
41 .name = "PhyCORE-audio",
42 .platform = &imx_soc_platform,
43 .dai_link = imx_phycore_dai_ac97,
44 .num_links = ARRAY_SIZE(imx_phycore_dai_ac97),
45};
46
47static struct snd_soc_device imx_phycore_snd_devdata = {
48 .card = &imx_phycore,
49 .codec_dev = &soc_codec_dev_wm9712,
50};
51
52static struct platform_device *imx_phycore_snd_device;
53
54static int __init imx_phycore_init(void)
55{
56 int ret;
57
58 if (!machine_is_pcm043() && !machine_is_pca100())
59 /* return happy. We might run on a totally different machine */
60 return 0;
61
62 imx_phycore_snd_device = platform_device_alloc("soc-audio", -1);
63 if (!imx_phycore_snd_device)
64 return -ENOMEM;
65
66 imx_phycore_dai_ac97[0].cpu_dai = &imx_ssi_pcm_dai[0];
67
68 platform_set_drvdata(imx_phycore_snd_device, &imx_phycore_snd_devdata);
69 imx_phycore_snd_devdata.dev = &imx_phycore_snd_device->dev;
70 ret = platform_device_add(imx_phycore_snd_device);
71
72 if (ret) {
73 printk(KERN_ERR "ASoC: Platform device allocation failed\n");
74 platform_device_put(imx_phycore_snd_device);
75 }
76
77 return ret;
78}
79
80static void __exit imx_phycore_exit(void)
81{
82 platform_device_unregister(imx_phycore_snd_device);
83}
84
85late_initcall(imx_phycore_init);
86module_exit(imx_phycore_exit);
87
88MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
89MODULE_DESCRIPTION("PhyCORE ALSA SoC driver");
90MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 61952aa6cd5a..f11963c21873 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -6,6 +6,9 @@ config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
7 select OMAP_MCBSP 7 select OMAP_MCBSP
8 8
9config SND_OMAP_SOC_MCPDM
10 tristate
11
9config SND_OMAP_SOC_N810 12config SND_OMAP_SOC_N810
10 tristate "SoC Audio support for Nokia N810" 13 tristate "SoC Audio support for Nokia N810"
11 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C 14 depends on SND_OMAP_SOC && MACH_NOKIA_N810 && I2C
@@ -94,12 +97,14 @@ config SND_OMAP_SOC_OMAP3_PANDORA
94 Say Y if you want to add support for SoC audio on the OMAP3 Pandora. 97 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
95 98
96config SND_OMAP_SOC_OMAP3_BEAGLE 99config SND_OMAP_SOC_OMAP3_BEAGLE
97 tristate "SoC Audio support for OMAP3 Beagle" 100 tristate "SoC Audio support for OMAP3 Beagle and Devkit8000"
98 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE 101 depends on TWL4030_CORE && SND_OMAP_SOC
102 depends on (MACH_OMAP3_BEAGLE || MACH_DEVKIT8000)
99 select SND_OMAP_SOC_MCBSP 103 select SND_OMAP_SOC_MCBSP
100 select SND_SOC_TWL4030 104 select SND_SOC_TWL4030
101 help 105 help
102 Say Y if you want to add support for SoC audio on the Beagleboard. 106 Say Y if you want to add support for SoC audio on the Beagleboard or
107 the clone Devkit8000.
103 108
104config SND_OMAP_SOC_ZOOM2 109config SND_OMAP_SOC_ZOOM2
105 tristate "SoC Audio support for Zoom2" 110 tristate "SoC Audio support for Zoom2"
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 19283e5edfbf..0bc00ca14b37 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -1,9 +1,11 @@
1# OMAP Platform Support 1# OMAP Platform Support
2snd-soc-omap-objs := omap-pcm.o 2snd-soc-omap-objs := omap-pcm.o
3snd-soc-omap-mcbsp-objs := omap-mcbsp.o 3snd-soc-omap-mcbsp-objs := omap-mcbsp.o
4snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o
4 5
5obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o 6obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o
6obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o 7obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
8obj-$(CONFIG_SND_OMAP_SOC_MCPDM) += snd-soc-omap-mcpdm.o
7 9
8# OMAP Machine Support 10# OMAP Machine Support
9snd-soc-n810-objs := n810.o 11snd-soc-n810-objs := n810.o
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c
new file mode 100644
index 000000000000..ad8df6cfae88
--- /dev/null
+++ b/sound/soc/omap/mcpdm.c
@@ -0,0 +1,484 @@
1/*
2 * mcpdm.c -- McPDM interface driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@ti.com>
5 * Copyright (C) 2009 - Texas Instruments, Inc.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * 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., 51 Franklin St, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/platform_device.h>
27#include <linux/wait.h>
28#include <linux/interrupt.h>
29#include <linux/err.h>
30#include <linux/clk.h>
31#include <linux/delay.h>
32#include <linux/io.h>
33#include <linux/irq.h>
34
35#include "mcpdm.h"
36
37static struct omap_mcpdm *mcpdm;
38
39static inline void omap_mcpdm_write(u16 reg, u32 val)
40{
41 __raw_writel(val, mcpdm->io_base + reg);
42}
43
44static inline int omap_mcpdm_read(u16 reg)
45{
46 return __raw_readl(mcpdm->io_base + reg);
47}
48
49static void omap_mcpdm_reg_dump(void)
50{
51 dev_dbg(mcpdm->dev, "***********************\n");
52 dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n",
53 omap_mcpdm_read(MCPDM_IRQSTATUS_RAW));
54 dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n",
55 omap_mcpdm_read(MCPDM_IRQSTATUS));
56 dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n",
57 omap_mcpdm_read(MCPDM_IRQENABLE_SET));
58 dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n",
59 omap_mcpdm_read(MCPDM_IRQENABLE_CLR));
60 dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n",
61 omap_mcpdm_read(MCPDM_IRQWAKE_EN));
62 dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n",
63 omap_mcpdm_read(MCPDM_DMAENABLE_SET));
64 dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n",
65 omap_mcpdm_read(MCPDM_DMAENABLE_CLR));
66 dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n",
67 omap_mcpdm_read(MCPDM_DMAWAKEEN));
68 dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n",
69 omap_mcpdm_read(MCPDM_CTRL));
70 dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n",
71 omap_mcpdm_read(MCPDM_DN_DATA));
72 dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n",
73 omap_mcpdm_read(MCPDM_UP_DATA));
74 dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n",
75 omap_mcpdm_read(MCPDM_FIFO_CTRL_DN));
76 dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n",
77 omap_mcpdm_read(MCPDM_FIFO_CTRL_UP));
78 dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n",
79 omap_mcpdm_read(MCPDM_DN_OFFSET));
80 dev_dbg(mcpdm->dev, "***********************\n");
81}
82
83/*
84 * Takes the McPDM module in and out of reset state.
85 * Uplink and downlink can be reset individually.
86 */
87static void omap_mcpdm_reset_capture(int reset)
88{
89 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
90
91 if (reset)
92 ctrl |= SW_UP_RST;
93 else
94 ctrl &= ~SW_UP_RST;
95
96 omap_mcpdm_write(MCPDM_CTRL, ctrl);
97}
98
99static void omap_mcpdm_reset_playback(int reset)
100{
101 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
102
103 if (reset)
104 ctrl |= SW_DN_RST;
105 else
106 ctrl &= ~SW_DN_RST;
107
108 omap_mcpdm_write(MCPDM_CTRL, ctrl);
109}
110
111/*
112 * Enables the transfer through the PDM interface to/from the Phoenix
113 * codec by enabling the corresponding UP or DN channels.
114 */
115void omap_mcpdm_start(int stream)
116{
117 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
118
119 if (stream)
120 ctrl |= mcpdm->up_channels;
121 else
122 ctrl |= mcpdm->dn_channels;
123
124 omap_mcpdm_write(MCPDM_CTRL, ctrl);
125}
126
127/*
128 * Disables the transfer through the PDM interface to/from the Phoenix
129 * codec by disabling the corresponding UP or DN channels.
130 */
131void omap_mcpdm_stop(int stream)
132{
133 int ctrl = omap_mcpdm_read(MCPDM_CTRL);
134
135 if (stream)
136 ctrl &= ~mcpdm->up_channels;
137 else
138 ctrl &= ~mcpdm->dn_channels;
139
140 omap_mcpdm_write(MCPDM_CTRL, ctrl);
141}
142
143/*
144 * Configures McPDM uplink for audio recording.
145 * This function should be called before omap_mcpdm_start.
146 */
147int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink)
148{
149 int irq_mask = 0;
150 int ctrl;
151
152 if (!uplink)
153 return -EINVAL;
154
155 mcpdm->uplink = uplink;
156
157 /* Enable irq request generation */
158 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
159 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
160
161 /* Configure uplink threshold */
162 if (uplink->threshold > UP_THRES_MAX)
163 uplink->threshold = UP_THRES_MAX;
164
165 omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold);
166
167 /* Configure DMA controller */
168 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE);
169
170 /* Set pdm out format */
171 ctrl = omap_mcpdm_read(MCPDM_CTRL);
172 ctrl &= ~PDMOUTFORMAT;
173 ctrl |= uplink->format & PDMOUTFORMAT;
174
175 /* Uplink channels */
176 mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK);
177
178 omap_mcpdm_write(MCPDM_CTRL, ctrl);
179
180 return 0;
181}
182
183/*
184 * Configures McPDM downlink for audio playback.
185 * This function should be called before omap_mcpdm_start.
186 */
187int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink)
188{
189 int irq_mask = 0;
190 int ctrl;
191
192 if (!downlink)
193 return -EINVAL;
194
195 mcpdm->downlink = downlink;
196
197 /* Enable irq request generation */
198 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
199 omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask);
200
201 /* Configure uplink threshold */
202 if (downlink->threshold > DN_THRES_MAX)
203 downlink->threshold = DN_THRES_MAX;
204
205 omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold);
206
207 /* Enable DMA request generation */
208 omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE);
209
210 /* Set pdm out format */
211 ctrl = omap_mcpdm_read(MCPDM_CTRL);
212 ctrl &= ~PDMOUTFORMAT;
213 ctrl |= downlink->format & PDMOUTFORMAT;
214
215 /* Downlink channels */
216 mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK);
217
218 omap_mcpdm_write(MCPDM_CTRL, ctrl);
219
220 return 0;
221}
222
223/*
224 * Cleans McPDM uplink configuration.
225 * This function should be called when the stream is closed.
226 */
227int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink)
228{
229 int irq_mask = 0;
230
231 if (!uplink)
232 return -EINVAL;
233
234 /* Disable irq request generation */
235 irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK;
236 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
237
238 /* Disable DMA request generation */
239 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE);
240
241 /* Clear Downlink channels */
242 mcpdm->up_channels = 0;
243
244 mcpdm->uplink = NULL;
245
246 return 0;
247}
248
249/*
250 * Cleans McPDM downlink configuration.
251 * This function should be called when the stream is closed.
252 */
253int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink)
254{
255 int irq_mask = 0;
256
257 if (!downlink)
258 return -EINVAL;
259
260 /* Disable irq request generation */
261 irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK;
262 omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask);
263
264 /* Disable DMA request generation */
265 omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE);
266
267 /* clear Downlink channels */
268 mcpdm->dn_channels = 0;
269
270 mcpdm->downlink = NULL;
271
272 return 0;
273}
274
275static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id)
276{
277 struct omap_mcpdm *mcpdm_irq = dev_id;
278 int irq_status;
279
280 irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS);
281
282 /* Acknowledge irq event */
283 omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status);
284
285 if (irq & MCPDM_DN_IRQ_FULL) {
286 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
287 omap_mcpdm_reset_playback(1);
288 omap_mcpdm_playback_open(mcpdm_irq->downlink);
289 omap_mcpdm_reset_playback(0);
290 }
291
292 if (irq & MCPDM_DN_IRQ_EMPTY) {
293 dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status);
294 omap_mcpdm_reset_playback(1);
295 omap_mcpdm_playback_open(mcpdm_irq->downlink);
296 omap_mcpdm_reset_playback(0);
297 }
298
299 if (irq & MCPDM_DN_IRQ) {
300 dev_dbg(mcpdm_irq->dev, "DN write request\n");
301 }
302
303 if (irq & MCPDM_UP_IRQ_FULL) {
304 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
305 omap_mcpdm_reset_capture(1);
306 omap_mcpdm_capture_open(mcpdm_irq->uplink);
307 omap_mcpdm_reset_capture(0);
308 }
309
310 if (irq & MCPDM_UP_IRQ_EMPTY) {
311 dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status);
312 omap_mcpdm_reset_capture(1);
313 omap_mcpdm_capture_open(mcpdm_irq->uplink);
314 omap_mcpdm_reset_capture(0);
315 }
316
317 if (irq & MCPDM_UP_IRQ) {
318 dev_dbg(mcpdm_irq->dev, "UP write request\n");
319 }
320
321 return IRQ_HANDLED;
322}
323
324int omap_mcpdm_request(void)
325{
326 int ret;
327
328 clk_enable(mcpdm->clk);
329
330 spin_lock(&mcpdm->lock);
331
332 if (!mcpdm->free) {
333 dev_err(mcpdm->dev, "McPDM interface is in use\n");
334 spin_unlock(&mcpdm->lock);
335 ret = -EBUSY;
336 goto err;
337 }
338 mcpdm->free = 0;
339
340 spin_unlock(&mcpdm->lock);
341
342 /* Disable lines while request is ongoing */
343 omap_mcpdm_write(MCPDM_CTRL, 0x00);
344
345 ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler,
346 0, "McPDM", (void *)mcpdm);
347 if (ret) {
348 dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n");
349 goto err;
350 }
351
352 return 0;
353
354err:
355 clk_disable(mcpdm->clk);
356 return ret;
357}
358
359void omap_mcpdm_free(void)
360{
361 spin_lock(&mcpdm->lock);
362 if (mcpdm->free) {
363 dev_err(mcpdm->dev, "McPDM interface is already free\n");
364 spin_unlock(&mcpdm->lock);
365 return;
366 }
367 mcpdm->free = 1;
368 spin_unlock(&mcpdm->lock);
369
370 clk_disable(mcpdm->clk);
371
372 free_irq(mcpdm->irq, (void *)mcpdm);
373}
374
375/* Enable/disable DC offset cancelation for the analog
376 * headset path (PDM channels 1 and 2).
377 */
378int omap_mcpdm_set_offset(int offset1, int offset2)
379{
380 int offset;
381
382 if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX))
383 return -EINVAL;
384
385 offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2);
386
387 /* offset cancellation for channel 1 */
388 if (offset1)
389 offset |= DN_OFST_RX1_EN;
390 else
391 offset &= ~DN_OFST_RX1_EN;
392
393 /* offset cancellation for channel 2 */
394 if (offset2)
395 offset |= DN_OFST_RX2_EN;
396 else
397 offset &= ~DN_OFST_RX2_EN;
398
399 omap_mcpdm_write(MCPDM_DN_OFFSET, offset);
400
401 return 0;
402}
403
404static int __devinit omap_mcpdm_probe(struct platform_device *pdev)
405{
406 struct resource *res;
407 int ret = 0;
408
409 mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL);
410 if (!mcpdm) {
411 ret = -ENOMEM;
412 goto exit;
413 }
414
415 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
416 if (res == NULL) {
417 dev_err(&pdev->dev, "no resource\n");
418 goto err_resource;
419 }
420
421 spin_lock_init(&mcpdm->lock);
422 mcpdm->free = 1;
423 mcpdm->io_base = ioremap(res->start, resource_size(res));
424 if (!mcpdm->io_base) {
425 ret = -ENOMEM;
426 goto err_resource;
427 }
428
429 mcpdm->irq = platform_get_irq(pdev, 0);
430
431 mcpdm->clk = clk_get(&pdev->dev, "pdm_ck");
432 if (IS_ERR(mcpdm->clk)) {
433 ret = PTR_ERR(mcpdm->clk);
434 dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret);
435 goto err_clk;
436 }
437
438 mcpdm->dev = &pdev->dev;
439 platform_set_drvdata(pdev, mcpdm);
440
441 return 0;
442
443err_clk:
444 iounmap(mcpdm->io_base);
445err_resource:
446 kfree(mcpdm);
447exit:
448 return ret;
449}
450
451static int __devexit omap_mcpdm_remove(struct platform_device *pdev)
452{
453 struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev);
454
455 platform_set_drvdata(pdev, NULL);
456
457 clk_put(mcpdm_ptr->clk);
458
459 iounmap(mcpdm_ptr->io_base);
460
461 mcpdm_ptr->clk = NULL;
462 mcpdm_ptr->free = 0;
463 mcpdm_ptr->dev = NULL;
464
465 kfree(mcpdm_ptr);
466
467 return 0;
468}
469
470static struct platform_driver omap_mcpdm_driver = {
471 .probe = omap_mcpdm_probe,
472 .remove = __devexit_p(omap_mcpdm_remove),
473 .driver = {
474 .name = "omap-mcpdm",
475 },
476};
477
478static struct platform_device *omap_mcpdm_device;
479
480static int __init omap_mcpdm_init(void)
481{
482 return platform_driver_register(&omap_mcpdm_driver);
483}
484arch_initcall(omap_mcpdm_init);
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h
new file mode 100644
index 000000000000..7bb326ef0886
--- /dev/null
+++ b/sound/soc/omap/mcpdm.h
@@ -0,0 +1,151 @@
1/*
2 * mcpdm.h -- Defines for McPDM driver
3 *
4 * Author: Jorge Eduardo Candelaria <x0107209@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/* McPDM registers */
23
24#define MCPDM_REVISION 0x00
25#define MCPDM_SYSCONFIG 0x10
26#define MCPDM_IRQSTATUS_RAW 0x24
27#define MCPDM_IRQSTATUS 0x28
28#define MCPDM_IRQENABLE_SET 0x2C
29#define MCPDM_IRQENABLE_CLR 0x30
30#define MCPDM_IRQWAKE_EN 0x34
31#define MCPDM_DMAENABLE_SET 0x38
32#define MCPDM_DMAENABLE_CLR 0x3C
33#define MCPDM_DMAWAKEEN 0x40
34#define MCPDM_CTRL 0x44
35#define MCPDM_DN_DATA 0x48
36#define MCPDM_UP_DATA 0x4C
37#define MCPDM_FIFO_CTRL_DN 0x50
38#define MCPDM_FIFO_CTRL_UP 0x54
39#define MCPDM_DN_OFFSET 0x58
40
41/*
42 * MCPDM_IRQ bit fields
43 * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR
44 */
45
46#define MCPDM_DN_IRQ (1 << 0)
47#define MCPDM_DN_IRQ_EMPTY (1 << 1)
48#define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2)
49#define MCPDM_DN_IRQ_FULL (1 << 3)
50
51#define MCPDM_UP_IRQ (1 << 8)
52#define MCPDM_UP_IRQ_EMPTY (1 << 9)
53#define MCPDM_UP_IRQ_ALMST_FULL (1 << 10)
54#define MCPDM_UP_IRQ_FULL (1 << 11)
55
56#define MCPDM_DOWNLINK_IRQ_MASK 0x00F
57#define MCPDM_UPLINK_IRQ_MASK 0xF00
58
59/*
60 * MCPDM_DMAENABLE bit fields
61 */
62
63#define DMA_DN_ENABLE 0x1
64#define DMA_UP_ENABLE 0x2
65
66/*
67 * MCPDM_CTRL bit fields
68 */
69
70#define PDM_UP1_EN 0x0001
71#define PDM_UP2_EN 0x0002
72#define PDM_UP3_EN 0x0004
73#define PDM_DN1_EN 0x0008
74#define PDM_DN2_EN 0x0010
75#define PDM_DN3_EN 0x0020
76#define PDM_DN4_EN 0x0040
77#define PDM_DN5_EN 0x0080
78#define PDMOUTFORMAT 0x0100
79#define CMD_INT 0x0200
80#define STATUS_INT 0x0400
81#define SW_UP_RST 0x0800
82#define SW_DN_RST 0x1000
83#define PDM_UP_MASK 0x007
84#define PDM_DN_MASK 0x0F8
85#define PDM_CMD_MASK 0x200
86#define PDM_STATUS_MASK 0x400
87
88
89#define PDMOUTFORMAT_LJUST (0 << 8)
90#define PDMOUTFORMAT_RJUST (1 << 8)
91
92/*
93 * MCPDM_FIFO_CTRL bit fields
94 */
95
96#define UP_THRES_MAX 0xF
97#define DN_THRES_MAX 0xF
98
99/*
100 * MCPDM_DN_OFFSET bit fields
101 */
102
103#define DN_OFST_RX1_EN 0x0001
104#define DN_OFST_RX2_EN 0x0100
105
106#define DN_OFST_RX1 1
107#define DN_OFST_RX2 9
108#define DN_OFST_MAX 0x1F
109
110#define MCPDM_UPLINK 1
111#define MCPDM_DOWNLINK 2
112
113struct omap_mcpdm_link {
114 int irq_mask;
115 int threshold;
116 int format;
117 int channels;
118};
119
120struct omap_mcpdm_platform_data {
121 unsigned long phys_base;
122 u16 irq;
123};
124
125struct omap_mcpdm {
126 struct device *dev;
127 unsigned long phys_base;
128 void __iomem *io_base;
129 u8 free;
130 int irq;
131
132 spinlock_t lock;
133 struct omap_mcpdm_platform_data *pdata;
134 struct clk *clk;
135 struct omap_mcpdm_link *downlink;
136 struct omap_mcpdm_link *uplink;
137 struct completion irq_completion;
138
139 int dn_channels;
140 int up_channels;
141};
142
143extern void omap_mcpdm_start(int stream);
144extern void omap_mcpdm_stop(int stream);
145extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink);
146extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink);
147extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink);
148extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink);
149extern int omap_mcpdm_request(void);
150extern void omap_mcpdm_free(void);
151extern int omap_mcpdm_set_offset(int offset1, int offset2);
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6bbbd2ab0ee7..d29725664185 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -287,6 +287,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
287 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma; 287 omap_mcbsp_dai_dma_params[id][substream->stream].dma_req = dma;
288 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port; 288 omap_mcbsp_dai_dma_params[id][substream->stream].port_addr = port;
289 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; 289 omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
290 omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
291 OMAP_DMA_DATA_TYPE_S16;
290 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; 292 cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
291 293
292 if (mcbsp_data->configured) { 294 if (mcbsp_data->configured) {
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
new file mode 100644
index 000000000000..25f19e4728bf
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -0,0 +1,251 @@
1/*
2 * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Author: Misael Lopez Cruz <x0052729@ti.com>
7 * Contact: Jorge Eduardo Candelaria <x0107209@ti.com>
8 * Margarita Olaya <magi.olaya@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 *
24 */
25
26#include <linux/init.h>
27#include <linux/module.h>
28#include <linux/device.h>
29#include <sound/core.h>
30#include <sound/pcm.h>
31#include <sound/pcm_params.h>
32#include <sound/initval.h>
33#include <sound/soc.h>
34
35#include <plat/control.h>
36#include <plat/dma.h>
37#include <plat/mcbsp.h>
38#include "mcpdm.h"
39#include "omap-mcpdm.h"
40#include "omap-pcm.h"
41
42struct omap_mcpdm_data {
43 struct omap_mcpdm_link *links;
44 int active;
45};
46
47static struct omap_mcpdm_link omap_mcpdm_links[] = {
48 /* downlink */
49 {
50 .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL,
51 .threshold = 1,
52 .format = PDMOUTFORMAT_LJUST,
53 },
54 /* uplink */
55 {
56 .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL,
57 .threshold = 1,
58 .format = PDMOUTFORMAT_LJUST,
59 },
60};
61
62static struct omap_mcpdm_data mcpdm_data = {
63 .links = omap_mcpdm_links,
64 .active = 0,
65};
66
67/*
68 * Stream DMA parameters
69 */
70static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = {
71 {
72 .name = "Audio playback",
73 .dma_req = OMAP44XX_DMA_MCPDM_DL,
74 .data_type = OMAP_DMA_DATA_TYPE_S32,
75 .sync_mode = OMAP_DMA_SYNC_PACKET,
76 .packet_size = 16,
77 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA,
78 },
79 {
80 .name = "Audio capture",
81 .dma_req = OMAP44XX_DMA_MCPDM_UP,
82 .data_type = OMAP_DMA_DATA_TYPE_S32,
83 .sync_mode = OMAP_DMA_SYNC_PACKET,
84 .packet_size = 16,
85 .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA,
86 },
87};
88
89static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
90 struct snd_soc_dai *dai)
91{
92 struct snd_soc_pcm_runtime *rtd = substream->private_data;
93 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
94 int err = 0;
95
96 if (!cpu_dai->active)
97 err = omap_mcpdm_request();
98
99 return err;
100}
101
102static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai)
104{
105 struct snd_soc_pcm_runtime *rtd = substream->private_data;
106 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
107
108 if (!cpu_dai->active)
109 omap_mcpdm_free();
110}
111
112static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd,
113 struct snd_soc_dai *dai)
114{
115 struct snd_soc_pcm_runtime *rtd = substream->private_data;
116 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
117 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
118 int stream = substream->stream;
119 int err = 0;
120
121 switch (cmd) {
122 case SNDRV_PCM_TRIGGER_START:
123 case SNDRV_PCM_TRIGGER_RESUME:
124 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
125 if (!mcpdm_priv->active++)
126 omap_mcpdm_start(stream);
127 break;
128
129 case SNDRV_PCM_TRIGGER_STOP:
130 case SNDRV_PCM_TRIGGER_SUSPEND:
131 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
132 if (!--mcpdm_priv->active)
133 omap_mcpdm_stop(stream);
134 break;
135 default:
136 err = -EINVAL;
137 }
138
139 return err;
140}
141
142static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
143 struct snd_pcm_hw_params *params,
144 struct snd_soc_dai *dai)
145{
146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
148 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
149 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
150 int stream = substream->stream;
151 int channels, err, link_mask = 0;
152
153 cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream];
154
155 channels = params_channels(params);
156 switch (channels) {
157 case 4:
158 if (stream == SNDRV_PCM_STREAM_CAPTURE)
159 /* up to 2 channels for capture */
160 return -EINVAL;
161 link_mask |= 1 << 3;
162 case 3:
163 if (stream == SNDRV_PCM_STREAM_CAPTURE)
164 /* up to 2 channels for capture */
165 return -EINVAL;
166 link_mask |= 1 << 2;
167 case 2:
168 link_mask |= 1 << 1;
169 case 1:
170 link_mask |= 1 << 0;
171 break;
172 default:
173 /* unsupported number of channels */
174 return -EINVAL;
175 }
176
177 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
178 mcpdm_links[stream].channels = link_mask << 3;
179 err = omap_mcpdm_playback_open(&mcpdm_links[stream]);
180 } else {
181 mcpdm_links[stream].channels = link_mask << 0;
182 err = omap_mcpdm_capture_open(&mcpdm_links[stream]);
183 }
184
185 return err;
186}
187
188static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream,
189 struct snd_soc_dai *dai)
190{
191 struct snd_soc_pcm_runtime *rtd = substream->private_data;
192 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
193 struct omap_mcpdm_data *mcpdm_priv = cpu_dai->private_data;
194 struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links;
195 int stream = substream->stream;
196 int err;
197
198 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
199 err = omap_mcpdm_playback_close(&mcpdm_links[stream]);
200 else
201 err = omap_mcpdm_capture_close(&mcpdm_links[stream]);
202
203 return err;
204}
205
206static struct snd_soc_dai_ops omap_mcpdm_dai_ops = {
207 .startup = omap_mcpdm_dai_startup,
208 .shutdown = omap_mcpdm_dai_shutdown,
209 .trigger = omap_mcpdm_dai_trigger,
210 .hw_params = omap_mcpdm_dai_hw_params,
211 .hw_free = omap_mcpdm_dai_hw_free,
212};
213
214#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
215#define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
216
217struct snd_soc_dai omap_mcpdm_dai = {
218 .name = "omap-mcpdm",
219 .id = -1,
220 .playback = {
221 .channels_min = 1,
222 .channels_max = 4,
223 .rates = OMAP_MCPDM_RATES,
224 .formats = OMAP_MCPDM_FORMATS,
225 },
226 .capture = {
227 .channels_min = 1,
228 .channels_max = 2,
229 .rates = OMAP_MCPDM_RATES,
230 .formats = OMAP_MCPDM_FORMATS,
231 },
232 .ops = &omap_mcpdm_dai_ops,
233 .private_data = &mcpdm_data,
234};
235EXPORT_SYMBOL_GPL(omap_mcpdm_dai);
236
237static int __init snd_omap_mcpdm_init(void)
238{
239 return snd_soc_register_dai(&omap_mcpdm_dai);
240}
241module_init(snd_omap_mcpdm_init);
242
243static void __exit snd_omap_mcpdm_exit(void)
244{
245 snd_soc_unregister_dai(&omap_mcpdm_dai);
246}
247module_exit(snd_omap_mcpdm_exit);
248
249MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
250MODULE_DESCRIPTION("OMAP PDM SoC Interface");
251MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h
new file mode 100644
index 000000000000..73b80d559345
--- /dev/null
+++ b/sound/soc/omap/omap-mcpdm.h
@@ -0,0 +1,29 @@
1/*
2 * omap-mcpdm.h
3 *
4 * Copyright (C) 2009 Texas Instruments
5 *
6 * Contact: Misael Lopez Cruz <x0052729@ti.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __OMAP_MCPDM_H__
25#define __OMAP_MCPDM_H__
26
27extern struct snd_soc_dai omap_mcpdm_dai;
28
29#endif /* End of __OMAP_MCPDM_H__ */
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 9db2770e9640..825db385f01f 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -37,7 +37,8 @@ static const struct snd_pcm_hardware omap_pcm_hardware = {
37 SNDRV_PCM_INFO_INTERLEAVED | 37 SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_PAUSE | 38 SNDRV_PCM_INFO_PAUSE |
39 SNDRV_PCM_INFO_RESUME, 39 SNDRV_PCM_INFO_RESUME,
40 .formats = SNDRV_PCM_FMTBIT_S16_LE, 40 .formats = SNDRV_PCM_FMTBIT_S16_LE |
41 SNDRV_PCM_FMTBIT_S32_LE,
41 .period_bytes_min = 32, 42 .period_bytes_min = 32,
42 .period_bytes_max = 64 * 1024, 43 .period_bytes_max = 64 * 1024,
43 .periods_min = 2, 44 .periods_min = 2,
@@ -149,6 +150,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
149 struct omap_runtime_data *prtd = runtime->private_data; 150 struct omap_runtime_data *prtd = runtime->private_data;
150 struct omap_pcm_dma_data *dma_data = prtd->dma_data; 151 struct omap_pcm_dma_data *dma_data = prtd->dma_data;
151 struct omap_dma_channel_params dma_params; 152 struct omap_dma_channel_params dma_params;
153 int bytes;
152 154
153 /* return if this is a bufferless transfer e.g. 155 /* return if this is a bufferless transfer e.g.
154 * codec <--> BT codec or GSM modem -- lg FIXME */ 156 * codec <--> BT codec or GSM modem -- lg FIXME */
@@ -156,11 +158,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
156 return 0; 158 return 0;
157 159
158 memset(&dma_params, 0, sizeof(dma_params)); 160 memset(&dma_params, 0, sizeof(dma_params));
159 /* 161 dma_params.data_type = dma_data->data_type;
160 * Note: Regardless of interface data formats supported by OMAP McBSP
161 * or EAC blocks, internal representation is always fixed 16-bit/sample
162 */
163 dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
164 dma_params.trigger = dma_data->dma_req; 162 dma_params.trigger = dma_data->dma_req;
165 dma_params.sync_mode = dma_data->sync_mode; 163 dma_params.sync_mode = dma_data->sync_mode;
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 164 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -170,6 +168,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
170 dma_params.src_start = runtime->dma_addr; 168 dma_params.src_start = runtime->dma_addr;
171 dma_params.dst_start = dma_data->port_addr; 169 dma_params.dst_start = dma_data->port_addr;
172 dma_params.dst_port = OMAP_DMA_PORT_MPUI; 170 dma_params.dst_port = OMAP_DMA_PORT_MPUI;
171 dma_params.dst_fi = dma_data->packet_size;
173 } else { 172 } else {
174 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; 173 dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT;
175 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; 174 dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC;
@@ -177,6 +176,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
177 dma_params.src_start = dma_data->port_addr; 176 dma_params.src_start = dma_data->port_addr;
178 dma_params.dst_start = runtime->dma_addr; 177 dma_params.dst_start = runtime->dma_addr;
179 dma_params.src_port = OMAP_DMA_PORT_MPUI; 178 dma_params.src_port = OMAP_DMA_PORT_MPUI;
179 dma_params.src_fi = dma_data->packet_size;
180 } 180 }
181 /* 181 /*
182 * Set DMA transfer frame size equal to ALSA period size and frame 182 * Set DMA transfer frame size equal to ALSA period size and frame
@@ -184,7 +184,8 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
184 * we can transfer the whole ALSA buffer with single DMA transfer but 184 * we can transfer the whole ALSA buffer with single DMA transfer but
185 * still can get an interrupt at each period bounary 185 * still can get an interrupt at each period bounary
186 */ 186 */
187 dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; 187 bytes = snd_pcm_lib_period_bytes(substream);
188 dma_params.elem_count = bytes >> dma_data->data_type;
188 dma_params.frame_count = runtime->periods; 189 dma_params.frame_count = runtime->periods;
189 omap_set_dma_params(prtd->dma_ch, &dma_params); 190 omap_set_dma_params(prtd->dma_ch, &dma_params);
190 191
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h
index 38a821dd4118..b19975d26907 100644
--- a/sound/soc/omap/omap-pcm.h
+++ b/sound/soc/omap/omap-pcm.h
@@ -29,8 +29,10 @@ 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 void (*set_threshold)(struct snd_pcm_substream *substream);
33 int data_type; /* data type 8,16,32 */
34 int sync_mode; /* DMA sync mode */
35 int packet_size; /* packet size only in PACKET mode */
34}; 36};
35 37
36extern struct snd_soc_platform omap_soc_platform; 38extern struct snd_soc_platform omap_soc_platform;
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index d88ad5ca526c..240e0975dd6a 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -117,11 +117,11 @@ static int __init omap3beagle_soc_init(void)
117{ 117{
118 int ret; 118 int ret;
119 119
120 if (!machine_is_omap3_beagle()) { 120 if (!(machine_is_omap3_beagle() || machine_is_devkit8000())) {
121 pr_debug("Not OMAP3 Beagle!\n"); 121 pr_debug("Not OMAP3 Beagle or Devkit8000!\n");
122 return -ENODEV; 122 return -ENODEV;
123 } 123 }
124 pr_info("OMAP3 Beagle SoC init\n"); 124 pr_info("OMAP3 Beagle/Devkit8000 SoC init\n");
125 125
126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1); 126 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
127 if (!omap3beagle_snd_device) { 127 if (!omap3beagle_snd_device) {
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 68980c19a3bc..de10f76baded 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <linux/regulator/consumer.h>
26 27
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/pcm.h> 29#include <sound/pcm.h>
@@ -40,6 +41,8 @@
40 41
41#define PREFIX "ASoC omap3pandora: " 42#define PREFIX "ASoC omap3pandora: "
42 43
44static struct regulator *omap3pandora_dac_reg;
45
43static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream, 46static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream,
44 struct snd_pcm_hw_params *params, unsigned int fmt) 47 struct snd_pcm_hw_params *params, unsigned int fmt)
45{ 48{
@@ -106,21 +109,37 @@ static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
106 SND_SOC_DAIFMT_CBS_CFS); 109 SND_SOC_DAIFMT_CBS_CFS);
107} 110}
108 111
109static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, 112static int omap3pandora_dac_event(struct snd_soc_dapm_widget *w,
110 struct snd_kcontrol *k, int event) 113 struct snd_kcontrol *k, int event)
111{ 114{
115 /*
116 * The PCM1773 DAC datasheet requires 1ms delay between switching
117 * VCC power on/off and /PD pin high/low
118 */
112 if (SND_SOC_DAPM_EVENT_ON(event)) { 119 if (SND_SOC_DAPM_EVENT_ON(event)) {
120 regulator_enable(omap3pandora_dac_reg);
121 mdelay(1);
113 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1); 122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
114 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
115 } else { 123 } else {
116 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
117 mdelay(1);
118 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0); 124 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
125 mdelay(1);
126 regulator_disable(omap3pandora_dac_reg);
119 } 127 }
120 128
121 return 0; 129 return 0;
122} 130}
123 131
132static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
133 struct snd_kcontrol *k, int event)
134{
135 if (SND_SOC_DAPM_EVENT_ON(event))
136 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
137 else
138 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
139
140 return 0;
141}
142
124/* 143/*
125 * Audio paths on Pandora board: 144 * Audio paths on Pandora board:
126 * 145 *
@@ -130,7 +149,9 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
130 * |P| <--- TWL4030 <--------- Line In and MICs 149 * |P| <--- TWL4030 <--------- Line In and MICs
131 */ 150 */
132static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { 151static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
133 SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0), 152 SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM,
153 0, 0, omap3pandora_dac_event,
154 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
134 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, 155 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
135 0, 0, NULL, 0, omap3pandora_hp_event, 156 0, 0, NULL, 0, omap3pandora_hp_event,
136 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 157 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -306,8 +327,18 @@ static int __init omap3pandora_soc_init(void)
306 goto fail2; 327 goto fail2;
307 } 328 }
308 329
330 omap3pandora_dac_reg = regulator_get(&omap3pandora_snd_device->dev, "vcc");
331 if (IS_ERR(omap3pandora_dac_reg)) {
332 pr_err(PREFIX "Failed to get DAC regulator from %s: %ld\n",
333 dev_name(&omap3pandora_snd_device->dev),
334 PTR_ERR(omap3pandora_dac_reg));
335 goto fail3;
336 }
337
309 return 0; 338 return 0;
310 339
340fail3:
341 platform_device_del(omap3pandora_snd_device);
311fail2: 342fail2:
312 platform_device_put(omap3pandora_snd_device); 343 platform_device_put(omap3pandora_snd_device);
313fail1: 344fail1:
@@ -320,6 +351,7 @@ module_init(omap3pandora_soc_init);
320 351
321static void __exit omap3pandora_soc_exit(void) 352static void __exit omap3pandora_soc_exit(void)
322{ 353{
354 regulator_put(omap3pandora_dac_reg);
323 platform_device_unregister(omap3pandora_snd_device); 355 platform_device_unregister(omap3pandora_snd_device);
324 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO); 356 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
325 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO); 357 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index 3bd7712f029b..e69397f40f72 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -135,10 +135,11 @@ static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
135 struct ssp_priv *priv = cpu_dai->private_data; 135 struct ssp_priv *priv = cpu_dai->private_data;
136 136
137 if (!cpu_dai->active) 137 if (!cpu_dai->active)
138 return 0; 138 clk_enable(priv->dev.ssp->clk);
139 139
140 ssp_save_state(&priv->dev, &priv->state); 140 ssp_save_state(&priv->dev, &priv->state);
141 clk_disable(priv->dev.ssp->clk); 141 clk_disable(priv->dev.ssp->clk);
142
142 return 0; 143 return 0;
143} 144}
144 145
@@ -146,12 +147,13 @@ static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
146{ 147{
147 struct ssp_priv *priv = cpu_dai->private_data; 148 struct ssp_priv *priv = cpu_dai->private_data;
148 149
149 if (!cpu_dai->active)
150 return 0;
151
152 clk_enable(priv->dev.ssp->clk); 150 clk_enable(priv->dev.ssp->clk);
153 ssp_restore_state(&priv->dev, &priv->state); 151 ssp_restore_state(&priv->dev, &priv->state);
154 ssp_enable(&priv->dev); 152
153 if (cpu_dai->active)
154 ssp_enable(&priv->dev);
155 else
156 clk_disable(priv->dev.ssp->clk);
155 157
156 return 0; 158 return 0;
157} 159}
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index acfce1c0f1c9..7e3f41696c41 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -41,7 +41,9 @@ static struct i2c_board_info max9486_hwmon_info = {
41}; 41};
42 42
43#define MAX9485_MCLK_FREQ_112896 0x22 43#define MAX9485_MCLK_FREQ_112896 0x22
44#define MAX9485_MCLK_FREQ_122880 0x23 44#define MAX9485_MCLK_FREQ_122880 0x23
45#define MAX9485_MCLK_FREQ_225792 0x32
46#define MAX9485_MCLK_FREQ_245760 0x33
45 47
46static void set_max9485_clk(char clk) 48static void set_max9485_clk(char clk)
47{ 49{
@@ -71,9 +73,17 @@ static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
71 struct snd_soc_pcm_runtime *rtd = substream->private_data; 73 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 74 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
73 75
74 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 76 /* set freq to 0 to enable all possible codec sample rates */
77 return snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
78}
75 79
76 return snd_soc_dai_set_sysclk(codec_dai, 0, 11289600, 0); 80static void raumfeld_cs4270_shutdown(struct snd_pcm_substream *substream)
81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
84
85 /* set freq to 0 to enable all possible codec sample rates */
86 snd_soc_dai_set_sysclk(codec_dai, 0, 0, 0);
77} 87}
78 88
79static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream, 89static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
@@ -86,20 +96,24 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
86 int ret = 0; 96 int ret = 0;
87 97
88 switch (params_rate(params)) { 98 switch (params_rate(params)) {
89 case 8000: 99 case 44100:
90 case 16000: 100 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
101 clk = 11289600;
102 break;
91 case 48000: 103 case 48000:
92 case 96000:
93 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 104 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
94 clk = 12288000; 105 clk = 12288000;
95 break; 106 break;
96 case 11025:
97 case 22050:
98 case 44100:
99 case 88200: 107 case 88200:
100 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 108 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
101 clk = 11289600; 109 clk = 22579200;
102 break; 110 break;
111 case 96000:
112 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
113 clk = 24576000;
114 break;
115 default:
116 return -EINVAL;
103 } 117 }
104 118
105 fmt = SND_SOC_DAIFMT_I2S | 119 fmt = SND_SOC_DAIFMT_I2S |
@@ -128,7 +142,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 142 if (ret < 0)
129 return ret; 143 return ret;
130 144
131 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 145 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
132 if (ret < 0) 146 if (ret < 0)
133 return ret; 147 return ret;
134 148
@@ -137,6 +151,7 @@ static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
137 151
138static struct snd_soc_ops raumfeld_cs4270_ops = { 152static struct snd_soc_ops raumfeld_cs4270_ops = {
139 .startup = raumfeld_cs4270_startup, 153 .startup = raumfeld_cs4270_startup,
154 .shutdown = raumfeld_cs4270_shutdown,
140 .hw_params = raumfeld_cs4270_hw_params, 155 .hw_params = raumfeld_cs4270_hw_params,
141}; 156};
142 157
@@ -181,20 +196,24 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
181 int fmt, ret = 0, clk = 0; 196 int fmt, ret = 0, clk = 0;
182 197
183 switch (params_rate(params)) { 198 switch (params_rate(params)) {
184 case 8000: 199 case 44100:
185 case 16000: 200 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
201 clk = 11289600;
202 break;
186 case 48000: 203 case 48000:
187 case 96000:
188 set_max9485_clk(MAX9485_MCLK_FREQ_122880); 204 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
189 clk = 12288000; 205 clk = 12288000;
190 break; 206 break;
191 case 11025:
192 case 22050:
193 case 44100:
194 case 88200: 207 case 88200:
195 set_max9485_clk(MAX9485_MCLK_FREQ_112896); 208 set_max9485_clk(MAX9485_MCLK_FREQ_225792);
196 clk = 11289600; 209 clk = 22579200;
210 break;
211 case 96000:
212 set_max9485_clk(MAX9485_MCLK_FREQ_245760);
213 clk = 24576000;
197 break; 214 break;
215 default:
216 return -EINVAL;
198 } 217 }
199 218
200 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF; 219 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
@@ -217,7 +236,7 @@ static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
217 if (ret < 0) 236 if (ret < 0)
218 return ret; 237 return ret;
219 238
220 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1); 239 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, clk, 1);
221 if (ret < 0) 240 if (ret < 0)
222 return ret; 241 return ret;
223 242
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b489f1ae103d..15fe57e5a232 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -27,12 +27,10 @@ config SND_S3C64XX_SOC_I2S
27config SND_S3C_SOC_PCM 27config SND_S3C_SOC_PCM
28 tristate 28 tristate
29 29
30config SND_S3C2443_SOC_AC97 30config SND_S3C_SOC_AC97
31 tristate 31 tristate
32 select S3C2410_DMA
33 select AC97_BUS
34 select SND_SOC_AC97_BUS 32 select SND_SOC_AC97_BUS
35 33
36config SND_S3C24XX_SOC_NEO1973_WM8753 34config SND_S3C24XX_SOC_NEO1973_WM8753
37 tristate "SoC I2S Audio support for NEO1973 - WM8753" 35 tristate "SoC I2S Audio support for NEO1973 - WM8753"
38 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 36 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
@@ -71,8 +69,10 @@ config SND_S3C64XX_SOC_WM8580
71config SND_S3C24XX_SOC_SMDK2443_WM9710 69config SND_S3C24XX_SOC_SMDK2443_WM9710
72 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 70 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
73 depends on SND_S3C24XX_SOC && MACH_SMDK2443 71 depends on SND_S3C24XX_SOC && MACH_SMDK2443
74 select SND_S3C2443_SOC_AC97 72 select S3C2410_DMA
73 select AC97_BUS
75 select SND_SOC_AC97_CODEC 74 select SND_SOC_AC97_CODEC
75 select SND_S3C_SOC_AC97
76 help 76 help
77 Say Y if you want to add support for SoC audio on smdk2443 77 Say Y if you want to add support for SoC audio on smdk2443
78 with the WM9710. 78 with the WM9710.
@@ -80,8 +80,10 @@ config SND_S3C24XX_SOC_SMDK2443_WM9710
80config SND_S3C24XX_SOC_LN2440SBC_ALC650 80config SND_S3C24XX_SOC_LN2440SBC_ALC650
81 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" 81 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
82 depends on SND_S3C24XX_SOC && ARCH_S3C2410 82 depends on SND_S3C24XX_SOC && ARCH_S3C2410
83 select SND_S3C2443_SOC_AC97 83 select S3C2410_DMA
84 select AC97_BUS
84 select SND_SOC_AC97_CODEC 85 select SND_SOC_AC97_CODEC
86 select SND_S3C_SOC_AC97
85 help 87 help
86 Say Y if you want to add support for SoC audio on ln2440sbc 88 Say Y if you want to add support for SoC audio on ln2440sbc
87 with the ALC650. 89 with the ALC650.
@@ -111,3 +113,11 @@ config SND_S3C24XX_SOC_SIMTEC_HERMES
111 select SND_S3C24XX_SOC_I2S 113 select SND_S3C24XX_SOC_I2S
112 select SND_SOC_TLV320AIC3X 114 select SND_SOC_TLV320AIC3X
113 select SND_S3C24XX_SOC_SIMTEC 115 select SND_S3C24XX_SOC_SIMTEC
116
117config SND_SOC_SMDK_WM9713
118 tristate "SoC AC97 Audio support for SMDK with WM9713"
119 depends on SND_S3C24XX_SOC && MACH_SMDK6410
120 select SND_SOC_WM9713
121 select SND_S3C_SOC_AC97
122 help
123 Sat Y if you want to add support for SoC audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index b744657733d7..df071a376fa2 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -3,13 +3,13 @@ snd-soc-s3c24xx-objs := s3c-dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o 6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o 8snd-soc-s3c-pcm-objs := s3c-pcm.o
9 9
10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
12obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o 12obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
@@ -26,6 +26,7 @@ snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o 26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o 28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
29snd-soc-smdk-wm9713-objs := smdk_wm9713.o
29 30
30obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 31obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
31obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 32obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -37,4 +38,4 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
37obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o 38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 39obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
39obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o 40obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
40 41obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index d00d359a03e6..ffa954fe6931 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -25,7 +25,7 @@
25 25
26#include "../codecs/ac97.h" 26#include "../codecs/ac97.h"
27#include "s3c-dma.h" 27#include "s3c-dma.h"
28#include "s3c24xx-ac97.h" 28#include "s3c-ac97.h"
29 29
30static struct snd_soc_card ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
34 .name = "AC97", 34 .name = "AC97",
35 .stream_name = "AC97 HiFi", 35 .stream_name = "AC97 HiFi",
36 .cpu_dai = &s3c2443_ac97_dai[0], 36 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
37 .codec_dai = &ac97_dai, 37 .codec_dai = &ac97_dai,
38}, 38},
39}; 39};
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c
new file mode 100644
index 000000000000..ee8ed9d7e703
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.c
@@ -0,0 +1,518 @@
1/* sound/soc/s3c24xx/s3c-ac97.c
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.c
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
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/io.h>
18#include <linux/delay.h>
19#include <linux/clk.h>
20
21#include <sound/soc.h>
22
23#include <plat/regs-ac97.h>
24#include <mach/dma.h>
25#include <plat/audio.h>
26
27#include "s3c-dma.h"
28#include "s3c-ac97.h"
29
30#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff)
32
33struct s3c_ac97_info {
34 unsigned state;
35 struct clk *ac97_clk;
36 void __iomem *regs;
37 struct mutex lock;
38 struct completion done;
39};
40static struct s3c_ac97_info s3c_ac97;
41
42static struct s3c2410_dma_client s3c_dma_client_out = {
43 .name = "AC97 PCMOut"
44};
45
46static struct s3c2410_dma_client s3c_dma_client_in = {
47 .name = "AC97 PCMIn"
48};
49
50static struct s3c2410_dma_client s3c_dma_client_micin = {
51 .name = "AC97 MicIn"
52};
53
54static struct s3c_dma_params s3c_ac97_pcm_out = {
55 .client = &s3c_dma_client_out,
56 .dma_size = 4,
57};
58
59static struct s3c_dma_params s3c_ac97_pcm_in = {
60 .client = &s3c_dma_client_in,
61 .dma_size = 4,
62};
63
64static struct s3c_dma_params s3c_ac97_mic_in = {
65 .client = &s3c_dma_client_micin,
66 .dma_size = 4,
67};
68
69static void s3c_ac97_activate(struct snd_ac97 *ac97)
70{
71 u32 ac_glbctrl, stat;
72
73 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
74 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
75 return; /* Return if already active */
76
77 INIT_COMPLETION(s3c_ac97.done);
78
79 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
80 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
81 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
82 msleep(1);
83
84 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
85 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
86 msleep(1);
87
88 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
89 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
90 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
91
92 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
93 printk(KERN_ERR "AC97: Unable to activate!");
94}
95
96static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
97 unsigned short reg)
98{
99 u32 ac_glbctrl, ac_codec_cmd;
100 u32 stat, addr, data;
101
102 mutex_lock(&s3c_ac97.lock);
103
104 s3c_ac97_activate(ac97);
105
106 INIT_COMPLETION(s3c_ac97.done);
107
108 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
109 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
110 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
111
112 udelay(50);
113
114 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
115 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
116 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
117
118 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
119 printk(KERN_ERR "AC97: Unable to read!");
120
121 stat = readl(s3c_ac97.regs + S3C_AC97_STAT);
122 addr = (stat >> 16) & 0x7f;
123 data = (stat & 0xffff);
124
125 if (addr != reg)
126 printk(KERN_ERR "s3c-ac97: req addr = %02x, rep addr = %02x\n", reg, addr);
127
128 mutex_unlock(&s3c_ac97.lock);
129
130 return (unsigned short)data;
131}
132
133static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
134 unsigned short val)
135{
136 u32 ac_glbctrl, ac_codec_cmd;
137
138 mutex_lock(&s3c_ac97.lock);
139
140 s3c_ac97_activate(ac97);
141
142 INIT_COMPLETION(s3c_ac97.done);
143
144 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
145 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
146 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
147
148 udelay(50);
149
150 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
151 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
152 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
153
154 if (!wait_for_completion_timeout(&s3c_ac97.done, HZ))
155 printk(KERN_ERR "AC97: Unable to write!");
156
157 ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD);
158 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
159 writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD);
160
161 mutex_unlock(&s3c_ac97.lock);
162}
163
164static void s3c_ac97_cold_reset(struct snd_ac97 *ac97)
165{
166 writel(S3C_AC97_GLBCTRL_COLDRESET,
167 s3c_ac97.regs + S3C_AC97_GLBCTRL);
168 msleep(1);
169
170 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
171 msleep(1);
172}
173
174static void s3c_ac97_warm_reset(struct snd_ac97 *ac97)
175{
176 u32 stat;
177
178 stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7;
179 if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE)
180 return; /* Return if already active */
181
182 writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL);
183 msleep(1);
184
185 writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL);
186 msleep(1);
187
188 s3c_ac97_activate(ac97);
189}
190
191static irqreturn_t s3c_ac97_irq(int irq, void *dev_id)
192{
193 u32 ac_glbctrl, ac_glbstat;
194
195 ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT);
196
197 if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) {
198
199 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
200 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
201 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
202
203 complete(&s3c_ac97.done);
204 }
205
206 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
207 ac_glbctrl |= (1<<30); /* Clear interrupt */
208 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
209
210 return IRQ_HANDLED;
211}
212
213struct snd_ac97_bus_ops soc_ac97_ops = {
214 .read = s3c_ac97_read,
215 .write = s3c_ac97_write,
216 .warm_reset = s3c_ac97_warm_reset,
217 .reset = s3c_ac97_cold_reset,
218};
219EXPORT_SYMBOL_GPL(soc_ac97_ops);
220
221static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params,
223 struct snd_soc_dai *dai)
224{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
227
228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
229 cpu_dai->dma_data = &s3c_ac97_pcm_out;
230 else
231 cpu_dai->dma_data = &s3c_ac97_pcm_in;
232
233 return 0;
234}
235
236static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
237 struct snd_soc_dai *dai)
238{
239 u32 ac_glbctrl;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 int channel = ((struct s3c_dma_params *)
242 rtd->dai->cpu_dai->dma_data)->channel;
243
244 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
245 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
246 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
247 else
248 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
249
250 switch (cmd) {
251 case SNDRV_PCM_TRIGGER_START:
252 case SNDRV_PCM_TRIGGER_RESUME:
253 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
254 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
255 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
256 else
257 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
258 break;
259
260 case SNDRV_PCM_TRIGGER_STOP:
261 case SNDRV_PCM_TRIGGER_SUSPEND:
262 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
263 break;
264 }
265
266 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
267
268 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
269
270 return 0;
271}
272
273static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
281 return -ENODEV;
282 else
283 cpu_dai->dma_data = &s3c_ac97_mic_in;
284
285 return 0;
286}
287
288static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
289 int cmd, struct snd_soc_dai *dai)
290{
291 u32 ac_glbctrl;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 int channel = ((struct s3c_dma_params *)
294 rtd->dai->cpu_dai->dma_data)->channel;
295
296 ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
297 ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
298
299 switch (cmd) {
300 case SNDRV_PCM_TRIGGER_START:
301 case SNDRV_PCM_TRIGGER_RESUME:
302 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
303 ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA;
304 break;
305
306 case SNDRV_PCM_TRIGGER_STOP:
307 case SNDRV_PCM_TRIGGER_SUSPEND:
308 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
309 break;
310 }
311
312 writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
313
314 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
315
316 return 0;
317}
318
319static struct snd_soc_dai_ops s3c_ac97_dai_ops = {
320 .hw_params = s3c_ac97_hw_params,
321 .trigger = s3c_ac97_trigger,
322};
323
324static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
325 .hw_params = s3c_ac97_hw_mic_params,
326 .trigger = s3c_ac97_mic_trigger,
327};
328
329struct snd_soc_dai s3c_ac97_dai[] = {
330 [S3C_AC97_DAI_PCM] = {
331 .name = "s3c-ac97",
332 .id = S3C_AC97_DAI_PCM,
333 .ac97_control = 1,
334 .playback = {
335 .stream_name = "AC97 Playback",
336 .channels_min = 2,
337 .channels_max = 2,
338 .rates = SNDRV_PCM_RATE_8000_48000,
339 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
340 .capture = {
341 .stream_name = "AC97 Capture",
342 .channels_min = 2,
343 .channels_max = 2,
344 .rates = SNDRV_PCM_RATE_8000_48000,
345 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
346 .ops = &s3c_ac97_dai_ops,
347 },
348 [S3C_AC97_DAI_MIC] = {
349 .name = "s3c-ac97-mic",
350 .id = S3C_AC97_DAI_MIC,
351 .ac97_control = 1,
352 .capture = {
353 .stream_name = "AC97 Mic Capture",
354 .channels_min = 1,
355 .channels_max = 1,
356 .rates = SNDRV_PCM_RATE_8000_48000,
357 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
358 .ops = &s3c_ac97_mic_dai_ops,
359 },
360};
361EXPORT_SYMBOL_GPL(s3c_ac97_dai);
362
363static __devinit int s3c_ac97_probe(struct platform_device *pdev)
364{
365 struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res;
366 struct s3c_audio_pdata *ac97_pdata;
367 int ret;
368
369 ac97_pdata = pdev->dev.platform_data;
370 if (!ac97_pdata || !ac97_pdata->cfg_gpio) {
371 dev_err(&pdev->dev, "cfg_gpio callback not provided!\n");
372 return -EINVAL;
373 }
374
375 /* Check for availability of necessary resource */
376 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
377 if (!dmatx_res) {
378 dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n");
379 return -ENXIO;
380 }
381
382 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
383 if (!dmarx_res) {
384 dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n");
385 return -ENXIO;
386 }
387
388 dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
389 if (!dmamic_res) {
390 dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n");
391 return -ENXIO;
392 }
393
394 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
395 if (!mem_res) {
396 dev_err(&pdev->dev, "Unable to get register resource\n");
397 return -ENXIO;
398 }
399
400 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
401 if (!irq_res) {
402 dev_err(&pdev->dev, "AC97 IRQ not provided!\n");
403 return -ENXIO;
404 }
405
406 if (!request_mem_region(mem_res->start,
407 resource_size(mem_res), "s3c-ac97")) {
408 dev_err(&pdev->dev, "Unable to request register region\n");
409 return -EBUSY;
410 }
411
412 s3c_ac97_pcm_out.channel = dmatx_res->start;
413 s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
414 s3c_ac97_pcm_in.channel = dmarx_res->start;
415 s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA;
416 s3c_ac97_mic_in.channel = dmamic_res->start;
417 s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA;
418
419 init_completion(&s3c_ac97.done);
420 mutex_init(&s3c_ac97.lock);
421
422 s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res));
423 if (s3c_ac97.regs == NULL) {
424 dev_err(&pdev->dev, "Unable to ioremap register region\n");
425 ret = -ENXIO;
426 goto err1;
427 }
428
429 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
430 if (IS_ERR(s3c_ac97.ac97_clk)) {
431 dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n");
432 ret = -ENODEV;
433 goto err2;
434 }
435 clk_enable(s3c_ac97.ac97_clk);
436
437 if (ac97_pdata->cfg_gpio(pdev)) {
438 dev_err(&pdev->dev, "Unable to configure gpio\n");
439 ret = -EINVAL;
440 goto err3;
441 }
442
443 ret = request_irq(irq_res->start, s3c_ac97_irq,
444 IRQF_DISABLED, "AC97", NULL);
445 if (ret < 0) {
446 printk(KERN_ERR "s3c-ac97: interrupt request failed.\n");
447 goto err4;
448 }
449
450 s3c_ac97_dai[S3C_AC97_DAI_PCM].dev = &pdev->dev;
451 s3c_ac97_dai[S3C_AC97_DAI_MIC].dev = &pdev->dev;
452
453 ret = snd_soc_register_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
454 if (ret)
455 goto err5;
456
457 return 0;
458
459err5:
460 free_irq(irq_res->start, NULL);
461err4:
462err3:
463 clk_disable(s3c_ac97.ac97_clk);
464 clk_put(s3c_ac97.ac97_clk);
465err2:
466 iounmap(s3c_ac97.regs);
467err1:
468 release_mem_region(mem_res->start, resource_size(mem_res));
469
470 return ret;
471}
472
473static __devexit int s3c_ac97_remove(struct platform_device *pdev)
474{
475 struct resource *mem_res, *irq_res;
476
477 snd_soc_unregister_dais(s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
478
479 irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
480 if (irq_res)
481 free_irq(irq_res->start, NULL);
482
483 clk_disable(s3c_ac97.ac97_clk);
484 clk_put(s3c_ac97.ac97_clk);
485
486 iounmap(s3c_ac97.regs);
487
488 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
489 if (mem_res)
490 release_mem_region(mem_res->start, resource_size(mem_res));
491
492 return 0;
493}
494
495static struct platform_driver s3c_ac97_driver = {
496 .probe = s3c_ac97_probe,
497 .remove = s3c_ac97_remove,
498 .driver = {
499 .name = "s3c-ac97",
500 .owner = THIS_MODULE,
501 },
502};
503
504static int __init s3c_ac97_init(void)
505{
506 return platform_driver_register(&s3c_ac97_driver);
507}
508module_init(s3c_ac97_init);
509
510static void __exit s3c_ac97_exit(void)
511{
512 platform_driver_unregister(&s3c_ac97_driver);
513}
514module_exit(s3c_ac97_exit);
515
516MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
517MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
518MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h
new file mode 100644
index 000000000000..278198379def
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-ac97.h
@@ -0,0 +1,23 @@
1/* sound/soc/s3c24xx/s3c-ac97.h
2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.h
5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi
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 __S3C_AC97_H_
16#define __S3C_AC97_H_
17
18#define S3C_AC97_DAI_PCM 0
19#define S3C_AC97_DAI_MIC 1
20
21extern struct snd_soc_dai s3c_ac97_dai[];
22
23#endif /* __S3C_AC97_H_ */
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
index 9e61a7c2d9ac..a98f40c3cd29 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -229,8 +229,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
229 229
230 spin_unlock_irqrestore(&pcm->lock, flags); 230 spin_unlock_irqrestore(&pcm->lock, flags);
231 231
232 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs \ 232 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n",
233 SCLK_DIV=%d SYNC_DIV=%d\n",
234 clk_get_rate(clk), pcm->sclk_per_fs, 233 clk_get_rate(clk), pcm->sclk_per_fs,
235 sclk_div, sync_div); 234 sclk_div, sync_div);
236 235
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
deleted file mode 100644
index 0191e3acb0b4..000000000000
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ /dev/null
@@ -1,432 +0,0 @@
1/*
2 * s3c2443-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
6 *
7 * Copyright (C) 2005, Sean Choi <sh428.choi@samsung.com>
8 * All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License 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/interrupt.h>
19#include <linux/io.h>
20#include <linux/wait.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <linux/clk.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/ac97_codec.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <plat/regs-ac97.h>
33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h>
35#include <asm/dma.h>
36#include <mach/dma.h>
37
38#include "s3c-dma.h"
39#include "s3c24xx-ac97.h"
40
41struct s3c24xx_ac97_info {
42 void __iomem *regs;
43 struct clk *ac97_clk;
44};
45static struct s3c24xx_ac97_info s3c24xx_ac97;
46
47static DECLARE_COMPLETION(ac97_completion);
48static u32 codec_ready;
49static DEFINE_MUTEX(ac97_mutex);
50
51static unsigned short s3c2443_ac97_read(struct snd_ac97 *ac97,
52 unsigned short reg)
53{
54 u32 ac_glbctrl;
55 u32 ac_codec_cmd;
56 u32 stat, addr, data;
57
58 mutex_lock(&ac97_mutex);
59
60 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
61 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
62 ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg);
63 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
64
65 udelay(50);
66
67 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
68 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
69 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
70
71 wait_for_completion(&ac97_completion);
72
73 stat = readl(s3c24xx_ac97.regs + S3C_AC97_STAT);
74 addr = (stat >> 16) & 0x7f;
75 data = (stat & 0xffff);
76
77 if (addr != reg)
78 printk(KERN_ERR "s3c24xx-ac97: req addr = %02x,"
79 " rep addr = %02x\n", reg, addr);
80
81 mutex_unlock(&ac97_mutex);
82
83 return (unsigned short)data;
84}
85
86static void s3c2443_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
87 unsigned short val)
88{
89 u32 ac_glbctrl;
90 u32 ac_codec_cmd;
91
92 mutex_lock(&ac97_mutex);
93
94 codec_ready = S3C_AC97_GLBSTAT_CODECREADY;
95 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
96 ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val);
97 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
98
99 udelay(50);
100
101 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
102 ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE;
103 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
104
105 wait_for_completion(&ac97_completion);
106
107 ac_codec_cmd = readl(s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
108 ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ;
109 writel(ac_codec_cmd, s3c24xx_ac97.regs + S3C_AC97_CODEC_CMD);
110
111 mutex_unlock(&ac97_mutex);
112
113}
114
115static void s3c2443_ac97_warm_reset(struct snd_ac97 *ac97)
116{
117 u32 ac_glbctrl;
118
119 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
120 ac_glbctrl = S3C_AC97_GLBCTRL_WARMRESET;
121 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
122 msleep(1);
123
124 ac_glbctrl = 0;
125 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
126 msleep(1);
127}
128
129static void s3c2443_ac97_cold_reset(struct snd_ac97 *ac97)
130{
131 u32 ac_glbctrl;
132
133 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
134 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
135 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
136 msleep(1);
137
138 ac_glbctrl = 0;
139 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
140 msleep(1);
141
142 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
143 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
144 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
145 msleep(1);
146
147 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
148 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
149 msleep(1);
150
151 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA |
152 S3C_AC97_GLBCTRL_PCMINTM_DMA | S3C_AC97_GLBCTRL_MICINTM_DMA;
153 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
154}
155
156static irqreturn_t s3c2443_ac97_irq(int irq, void *dev_id)
157{
158 int status;
159 u32 ac_glbctrl;
160
161 status = readl(s3c24xx_ac97.regs + S3C_AC97_GLBSTAT) & codec_ready;
162
163 if (status) {
164 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
165 ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE;
166 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
167 complete(&ac97_completion);
168 }
169 return IRQ_HANDLED;
170}
171
172struct snd_ac97_bus_ops soc_ac97_ops = {
173 .read = s3c2443_ac97_read,
174 .write = s3c2443_ac97_write,
175 .warm_reset = s3c2443_ac97_warm_reset,
176 .reset = s3c2443_ac97_cold_reset,
177};
178
179static struct s3c2410_dma_client s3c2443_dma_client_out = {
180 .name = "AC97 PCM Stereo out"
181};
182
183static struct s3c2410_dma_client s3c2443_dma_client_in = {
184 .name = "AC97 PCM Stereo in"
185};
186
187static struct s3c2410_dma_client s3c2443_dma_client_micin = {
188 .name = "AC97 Mic Mono in"
189};
190
191static struct s3c_dma_params s3c2443_ac97_pcm_stereo_out = {
192 .client = &s3c2443_dma_client_out,
193 .channel = DMACH_PCM_OUT,
194 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
195 .dma_size = 4,
196};
197
198static struct s3c_dma_params s3c2443_ac97_pcm_stereo_in = {
199 .client = &s3c2443_dma_client_in,
200 .channel = DMACH_PCM_IN,
201 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
202 .dma_size = 4,
203};
204
205static struct s3c_dma_params s3c2443_ac97_mic_mono_in = {
206 .client = &s3c2443_dma_client_micin,
207 .channel = DMACH_MIC_IN,
208 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
209 .dma_size = 4,
210};
211
212static int s3c2443_ac97_probe(struct platform_device *pdev,
213 struct snd_soc_dai *dai)
214{
215 int ret;
216 u32 ac_glbctrl;
217
218 s3c24xx_ac97.regs = ioremap(S3C2440_PA_AC97, 0x100);
219 if (s3c24xx_ac97.regs == NULL)
220 return -ENXIO;
221
222 s3c24xx_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
223 if (s3c24xx_ac97.ac97_clk == NULL) {
224 printk(KERN_ERR "s3c2443-ac97 failed to get ac97_clock\n");
225 iounmap(s3c24xx_ac97.regs);
226 return -ENODEV;
227 }
228 clk_enable(s3c24xx_ac97.ac97_clk);
229
230 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2443_GPE0_AC_nRESET);
231 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2443_GPE1_AC_SYNC);
232 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2443_GPE2_AC_BITCLK);
233 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2443_GPE3_AC_SDI);
234 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2443_GPE4_AC_SDO);
235
236 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
237 ac_glbctrl = S3C_AC97_GLBCTRL_COLDRESET;
238 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
239 msleep(1);
240
241 ac_glbctrl = 0;
242 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
243 msleep(1);
244
245 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
246 ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON;
247 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
248 msleep(1);
249
250 ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE;
251 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
252
253 ret = request_irq(IRQ_S3C244x_AC97, s3c2443_ac97_irq,
254 IRQF_DISABLED, "AC97", NULL);
255 if (ret < 0) {
256 printk(KERN_ERR "s3c24xx-ac97: interrupt request failed.\n");
257 clk_disable(s3c24xx_ac97.ac97_clk);
258 clk_put(s3c24xx_ac97.ac97_clk);
259 iounmap(s3c24xx_ac97.regs);
260 }
261 return ret;
262}
263
264static void s3c2443_ac97_remove(struct platform_device *pdev,
265 struct snd_soc_dai *dai)
266{
267 free_irq(IRQ_S3C244x_AC97, NULL);
268 clk_disable(s3c24xx_ac97.ac97_clk);
269 clk_put(s3c24xx_ac97.ac97_clk);
270 iounmap(s3c24xx_ac97.regs);
271}
272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
276{
277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
279
280 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
281 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_out;
282 else
283 cpu_dai->dma_data = &s3c2443_ac97_pcm_stereo_in;
284
285 return 0;
286}
287
288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
290{
291 u32 ac_glbctrl;
292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
293 int channel = ((struct s3c_dma_params *)
294 rtd->dai->cpu_dai->dma_data)->channel;
295
296 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
297 switch (cmd) {
298 case SNDRV_PCM_TRIGGER_START:
299 case SNDRV_PCM_TRIGGER_RESUME:
300 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
301 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
302 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
303 else
304 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA;
305 break;
306 case SNDRV_PCM_TRIGGER_STOP:
307 case SNDRV_PCM_TRIGGER_SUSPEND:
308 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
309 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
310 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
311 else
312 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK;
313 break;
314 }
315 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
316
317 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
318
319 return 0;
320}
321
322static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
323 struct snd_pcm_hw_params *params,
324 struct snd_soc_dai *dai)
325{
326 struct snd_soc_pcm_runtime *rtd = substream->private_data;
327 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
328
329 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
330 return -ENODEV;
331 else
332 cpu_dai->dma_data = &s3c2443_ac97_mic_mono_in;
333
334 return 0;
335}
336
337static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
338 int cmd, struct snd_soc_dai *dai)
339{
340 u32 ac_glbctrl;
341 struct snd_soc_pcm_runtime *rtd = substream->private_data;
342 int channel = ((struct s3c_dma_params *)
343 rtd->dai->cpu_dai->dma_data)->channel;
344
345 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
346 switch (cmd) {
347 case SNDRV_PCM_TRIGGER_START:
348 case SNDRV_PCM_TRIGGER_RESUME:
349 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
350 ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA;
351 break;
352 case SNDRV_PCM_TRIGGER_STOP:
353 case SNDRV_PCM_TRIGGER_SUSPEND:
354 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
355 ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK;
356 }
357 writel(ac_glbctrl, s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
358
359 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED);
360
361 return 0;
362}
363
364#define s3c2443_AC97_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
365 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
366 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
367
368static struct snd_soc_dai_ops s3c2443_ac97_dai_ops = {
369 .hw_params = s3c2443_ac97_hw_params,
370 .trigger = s3c2443_ac97_trigger,
371};
372
373static struct snd_soc_dai_ops s3c2443_ac97_mic_dai_ops = {
374 .hw_params = s3c2443_ac97_hw_mic_params,
375 .trigger = s3c2443_ac97_mic_trigger,
376};
377
378struct snd_soc_dai s3c2443_ac97_dai[] = {
379{
380 .name = "s3c2443-ac97",
381 .id = 0,
382 .ac97_control = 1,
383 .probe = s3c2443_ac97_probe,
384 .remove = s3c2443_ac97_remove,
385 .playback = {
386 .stream_name = "AC97 Playback",
387 .channels_min = 2,
388 .channels_max = 2,
389 .rates = s3c2443_AC97_RATES,
390 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
391 .capture = {
392 .stream_name = "AC97 Capture",
393 .channels_min = 2,
394 .channels_max = 2,
395 .rates = s3c2443_AC97_RATES,
396 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
397 .ops = &s3c2443_ac97_dai_ops,
398},
399{
400 .name = "pxa2xx-ac97-mic",
401 .id = 1,
402 .ac97_control = 1,
403 .capture = {
404 .stream_name = "AC97 Mic Capture",
405 .channels_min = 1,
406 .channels_max = 1,
407 .rates = s3c2443_AC97_RATES,
408 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
409 .ops = &s3c2443_ac97_mic_dai_ops,
410},
411};
412EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
413EXPORT_SYMBOL_GPL(soc_ac97_ops);
414
415static int __init s3c2443_ac97_init(void)
416{
417 return snd_soc_register_dais(s3c2443_ac97_dai,
418 ARRAY_SIZE(s3c2443_ac97_dai));
419}
420module_init(s3c2443_ac97_init);
421
422static void __exit s3c2443_ac97_exit(void)
423{
424 snd_soc_unregister_dais(s3c2443_ac97_dai,
425 ARRAY_SIZE(s3c2443_ac97_dai));
426}
427module_exit(s3c2443_ac97_exit);
428
429
430MODULE_AUTHOR("Graeme Gregory");
431MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
432MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-ac97.h b/sound/soc/s3c24xx/s3c24xx-ac97.h
deleted file mode 100644
index e96f941a810b..000000000000
--- a/sound/soc/s3c24xx/s3c24xx-ac97.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * s3c24xx-ac97.c -- ALSA Soc Audio Layer
3 *
4 * (c) 2007 Wolfson Microelectronics PLC.
5 * Author: Graeme Gregory
6 * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 10th Nov 2006 Initial version.
15 */
16
17#ifndef S3C24XXAC97_H_
18#define S3C24XXAC97_H_
19
20#define AC_CMD_ADDR(x) (x << 16)
21#define AC_CMD_DATA(x) (x & 0xffff)
22
23extern struct snd_soc_dai s3c2443_ac97_dai[];
24
25#endif /*S3C24XXAC97_H_*/
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index cc7edb5f792d..93ed3aad1631 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -15,16 +15,10 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/delay.h>
19#include <linux/clk.h> 18#include <linux/clk.h>
20#include <linux/kernel.h>
21#include <linux/gpio.h> 19#include <linux/gpio.h>
22#include <linux/io.h> 20#include <linux/io.h>
23 21
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> 22#include <sound/soc.h>
29 23
30#include <plat/regs-s3c2412-iis.h> 24#include <plat/regs-s3c2412-iis.h>
@@ -38,6 +32,11 @@
38#include "s3c-dma.h" 32#include "s3c-dma.h"
39#include "s3c64xx-i2s.h" 33#include "s3c64xx-i2s.h"
40 34
35/* The value should be set to maximum of the total number
36 * of I2Sv3 controllers that any supported SoC has.
37 */
38#define MAX_I2SV3 2
39
41static struct s3c2410_dma_client s3c64xx_dma_client_out = { 40static struct s3c2410_dma_client s3c64xx_dma_client_out = {
42 .name = "I2S PCM Stereo out" 41 .name = "I2S PCM Stereo out"
43}; 42};
@@ -46,37 +45,12 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = {
46 .name = "I2S PCM Stereo in" 45 .name = "I2S PCM Stereo in"
47}; 46};
48 47
49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { 48static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
50 [0] = { 49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
51 .channel = DMACH_I2S0_OUT, 50static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
52 .client = &s3c64xx_dma_client_out,
53 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD,
54 .dma_size = 4,
55 },
56 [1] = {
57 .channel = DMACH_I2S1_OUT,
58 .client = &s3c64xx_dma_client_out,
59 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD,
60 .dma_size = 4,
61 },
62};
63
64static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[2] = {
65 [0] = {
66 .channel = DMACH_I2S0_IN,
67 .client = &s3c64xx_dma_client_in,
68 .dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD,
69 .dma_size = 4,
70 },
71 [1] = {
72 .channel = DMACH_I2S1_IN,
73 .client = &s3c64xx_dma_client_in,
74 .dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD,
75 .dma_size = 4,
76 },
77};
78 51
79static struct s3c_i2sv2_info s3c64xx_i2s[2]; 52struct snd_soc_dai s3c64xx_i2s_dai[MAX_I2SV3];
53EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
80 54
81static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) 55static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai)
82{ 56{
@@ -169,55 +143,13 @@ static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = {
169 .set_sysclk = s3c64xx_i2s_set_sysclk, 143 .set_sysclk = s3c64xx_i2s_set_sysclk,
170}; 144};
171 145
172struct snd_soc_dai s3c64xx_i2s_dai[] = {
173 {
174 .name = "s3c64xx-i2s",
175 .id = 0,
176 .probe = s3c64xx_i2s_probe,
177 .playback = {
178 .channels_min = 2,
179 .channels_max = 2,
180 .rates = S3C64XX_I2S_RATES,
181 .formats = S3C64XX_I2S_FMTS,
182 },
183 .capture = {
184 .channels_min = 2,
185 .channels_max = 2,
186 .rates = S3C64XX_I2S_RATES,
187 .formats = S3C64XX_I2S_FMTS,
188 },
189 .ops = &s3c64xx_i2s_dai_ops,
190 .symmetric_rates = 1,
191 },
192 {
193 .name = "s3c64xx-i2s",
194 .id = 1,
195 .probe = s3c64xx_i2s_probe,
196 .playback = {
197 .channels_min = 2,
198 .channels_max = 2,
199 .rates = S3C64XX_I2S_RATES,
200 .formats = S3C64XX_I2S_FMTS,
201 },
202 .capture = {
203 .channels_min = 2,
204 .channels_max = 2,
205 .rates = S3C64XX_I2S_RATES,
206 .formats = S3C64XX_I2S_FMTS,
207 },
208 .ops = &s3c64xx_i2s_dai_ops,
209 .symmetric_rates = 1,
210 },
211};
212EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai);
213
214static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) 146static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
215{ 147{
216 struct s3c_i2sv2_info *i2s; 148 struct s3c_i2sv2_info *i2s;
217 struct snd_soc_dai *dai; 149 struct snd_soc_dai *dai;
218 int ret; 150 int ret;
219 151
220 if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { 152 if (pdev->id >= MAX_I2SV3) {
221 dev_err(&pdev->dev, "id %d out of range\n", pdev->id); 153 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
222 return -EINVAL; 154 return -EINVAL;
223 } 155 }
@@ -225,10 +157,40 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
225 i2s = &s3c64xx_i2s[pdev->id]; 157 i2s = &s3c64xx_i2s[pdev->id];
226 dai = &s3c64xx_i2s_dai[pdev->id]; 158 dai = &s3c64xx_i2s_dai[pdev->id];
227 dai->dev = &pdev->dev; 159 dai->dev = &pdev->dev;
160 dai->name = "s3c64xx-i2s";
161 dai->id = pdev->id;
162 dai->symmetric_rates = 1;
163 dai->playback.channels_min = 2;
164 dai->playback.channels_max = 2;
165 dai->playback.rates = S3C64XX_I2S_RATES;
166 dai->playback.formats = S3C64XX_I2S_FMTS;
167 dai->capture.channels_min = 2;
168 dai->capture.channels_max = 2;
169 dai->capture.rates = S3C64XX_I2S_RATES;
170 dai->capture.formats = S3C64XX_I2S_FMTS;
171 dai->probe = s3c64xx_i2s_probe;
172 dai->ops = &s3c64xx_i2s_dai_ops;
228 173
229 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; 174 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
230 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; 175 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
231 176
177 if (pdev->id == 0) {
178 i2s->dma_capture->channel = DMACH_I2S0_IN;
179 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISRXD;
180 i2s->dma_playback->channel = DMACH_I2S0_OUT;
181 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS0 + S3C2412_IISTXD;
182 } else {
183 i2s->dma_capture->channel = DMACH_I2S1_IN;
184 i2s->dma_capture->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISRXD;
185 i2s->dma_playback->channel = DMACH_I2S1_OUT;
186 i2s->dma_playback->dma_addr = S3C64XX_PA_IIS1 + S3C2412_IISTXD;
187 }
188
189 i2s->dma_capture->client = &s3c64xx_dma_client_in;
190 i2s->dma_capture->dma_size = 4;
191 i2s->dma_playback->client = &s3c64xx_dma_client_out;
192 i2s->dma_playback->dma_size = 4;
193
232 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); 194 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
233 if (IS_ERR(i2s->iis_cclk)) { 195 if (IS_ERR(i2s->iis_cclk)) {
234 dev_err(&pdev->dev, "failed to get audio-bus\n"); 196 dev_err(&pdev->dev, "failed to get audio-bus\n");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 12b783b12fcb..362258835e8d 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -21,7 +21,7 @@
21 21
22#include "../codecs/ac97.h" 22#include "../codecs/ac97.h"
23#include "s3c-dma.h" 23#include "s3c-dma.h"
24#include "s3c24xx-ac97.h" 24#include "s3c-ac97.h"
25 25
26static struct snd_soc_card smdk2443; 26static struct snd_soc_card smdk2443;
27 27
@@ -29,7 +29,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
30 .name = "AC97", 30 .name = "AC97",
31 .stream_name = "AC97 HiFi", 31 .stream_name = "AC97 HiFi",
32 .cpu_dai = &s3c2443_ac97_dai[0], 32 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
33 .codec_dai = &ac97_dai, 33 .codec_dai = &ac97_dai,
34}, 34},
35}; 35};
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c
new file mode 100644
index 000000000000..24fd39f38ccb
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk_wm9713.c
@@ -0,0 +1,94 @@
1/*
2 * smdk_wm9713.c -- SoC audio for SMDK
3 *
4 * Copyright 2010 Samsung Electronics Co. Ltd.
5 * Author: Jaswinder Singh Brar <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/device.h>
16#include <sound/soc.h>
17
18#include "../codecs/wm9713.h"
19#include "s3c-dma.h"
20#include "s3c-ac97.h"
21
22static struct snd_soc_card smdk;
23
24/*
25 * Default CFG switch settings to use this driver:
26 *
27 * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off
28 */
29
30/*
31 Playback (HeadPhone):-
32 $ amixer sset 'Headphone' unmute
33 $ amixer sset 'Right Headphone Out Mux' 'Headphone'
34 $ amixer sset 'Left Headphone Out Mux' 'Headphone'
35 $ amixer sset 'Right HP Mixer PCM' unmute
36 $ amixer sset 'Left HP Mixer PCM' unmute
37
38 Capture (LineIn):-
39 $ amixer sset 'Right Capture Source' 'Line'
40 $ amixer sset 'Left Capture Source' 'Line'
41*/
42
43static struct snd_soc_dai_link smdk_dai = {
44 .name = "AC97",
45 .stream_name = "AC97 PCM",
46 .cpu_dai = &s3c_ac97_dai[S3C_AC97_DAI_PCM],
47 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
48};
49
50static struct snd_soc_card smdk = {
51 .name = "SMDK",
52 .platform = &s3c24xx_soc_platform,
53 .dai_link = &smdk_dai,
54 .num_links = 1,
55};
56
57static struct snd_soc_device smdk_snd_ac97_devdata = {
58 .card = &smdk,
59 .codec_dev = &soc_codec_dev_wm9713,
60};
61
62static struct platform_device *smdk_snd_ac97_device;
63
64static int __init smdk_init(void)
65{
66 int ret;
67
68 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
69 if (!smdk_snd_ac97_device)
70 return -ENOMEM;
71
72 platform_set_drvdata(smdk_snd_ac97_device,
73 &smdk_snd_ac97_devdata);
74 smdk_snd_ac97_devdata.dev = &smdk_snd_ac97_device->dev;
75
76 ret = platform_device_add(smdk_snd_ac97_device);
77 if (ret)
78 platform_device_put(smdk_snd_ac97_device);
79
80 return ret;
81}
82
83static void __exit smdk_exit(void)
84{
85 platform_device_unregister(smdk_snd_ac97_device);
86}
87
88module_init(smdk_init);
89module_exit(smdk_exit);
90
91/* Module information */
92MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com");
93MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713");
94MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9e6976586554..106674979b53 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -26,6 +26,13 @@ config SND_SOC_SH4_FSI
26 help 26 help
27 This option enables FSI sound support 27 This option enables FSI sound support
28 28
29config SND_SOC_SH4_SIU
30 tristate
31 depends on (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
32 select DMA_ENGINE
33 select DMADEVICES
34 select SH_DMAE
35
29## 36##
30## Boards 37## Boards
31## 38##
@@ -47,4 +54,20 @@ config SND_FSI_AK4642
47 This option enables generic sound support for the 54 This option enables generic sound support for the
48 FSI - AK4642 unit 55 FSI - AK4642 unit
49 56
57config SND_FSI_DA7210
58 bool "FSI-DA7210 sound support"
59 depends on SND_SOC_SH4_FSI
60 select SND_SOC_DA7210
61 help
62 This option enables generic sound support for the
63 FSI - DA7210 unit
64
65config SND_SIU_MIGOR
66 tristate "SIU sound support on Migo-R"
67 depends on SH_MIGOR
68 select SND_SOC_SH4_SIU
69 select SND_SOC_WM8978
70 help
71 This option enables sound support for the SH7722 Migo-R board
72
50endmenu 73endmenu
diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile
index a6997872f24e..8a5a19293bda 100644
--- a/sound/soc/sh/Makefile
+++ b/sound/soc/sh/Makefile
@@ -6,13 +6,19 @@ obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o
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 8snd-soc-fsi-objs := fsi.o
9snd-soc-siu-objs := siu_pcm.o siu_dai.o
9obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o 10obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o
10obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o 11obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o
11obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o 12obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o
13obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o
12 14
13## boards 15## boards
14snd-soc-sh7760-ac97-objs := sh7760-ac97.o 16snd-soc-sh7760-ac97-objs := sh7760-ac97.o
15snd-soc-fsi-ak4642-objs := fsi-ak4642.o 17snd-soc-fsi-ak4642-objs := fsi-ak4642.o
18snd-soc-fsi-da7210-objs := fsi-da7210.o
19snd-soc-migor-objs := migor.o
16 20
17obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o 21obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o
18obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o 22obj-$(CONFIG_SND_FSI_AK4642) += snd-soc-fsi-ak4642.o
23obj-$(CONFIG_SND_FSI_DA7210) += snd-soc-fsi-da7210.o
24obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
new file mode 100644
index 000000000000..33b4d177f466
--- /dev/null
+++ b/sound/soc/sh/fsi-da7210.c
@@ -0,0 +1,83 @@
1/*
2 * fsi-da7210.c
3 *
4 * Copyright (C) 2009 Renesas Solutions Corp.
5 * Kuninori Morimoto <morimoto.kuninori@renesas.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/interrupt.h>
14#include <linux/platform_device.h>
15#include <linux/io.h>
16#include <linux/i2c.h>
17#include <sound/core.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22
23#include <sound/sh_fsi.h>
24#include "../codecs/da7210.h"
25
26static int fsi_da7210_init(struct snd_soc_codec *codec)
27{
28 return snd_soc_dai_set_fmt(&da7210_dai,
29 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
30 SND_SOC_DAIFMT_CBM_CFM);
31}
32
33static struct snd_soc_dai_link fsi_da7210_dai = {
34 .name = "DA7210",
35 .stream_name = "DA7210",
36 .cpu_dai = &fsi_soc_dai[1], /* FSI B */
37 .codec_dai = &da7210_dai,
38 .init = fsi_da7210_init,
39};
40
41static struct snd_soc_card fsi_soc_card = {
42 .name = "FSI",
43 .platform = &fsi_soc_platform,
44 .dai_link = &fsi_da7210_dai,
45 .num_links = 1,
46};
47
48static struct snd_soc_device fsi_da7210_snd_devdata = {
49 .card = &fsi_soc_card,
50 .codec_dev = &soc_codec_dev_da7210,
51};
52
53static struct platform_device *fsi_da7210_snd_device;
54
55static int __init fsi_da7210_sound_init(void)
56{
57 int ret;
58
59 fsi_da7210_snd_device = platform_device_alloc("soc-audio", -1);
60 if (!fsi_da7210_snd_device)
61 return -ENOMEM;
62
63 platform_set_drvdata(fsi_da7210_snd_device, &fsi_da7210_snd_devdata);
64 fsi_da7210_snd_devdata.dev = &fsi_da7210_snd_device->dev;
65 ret = platform_device_add(fsi_da7210_snd_device);
66 if (ret)
67 platform_device_put(fsi_da7210_snd_device);
68
69 return ret;
70}
71
72static void __exit fsi_da7210_sound_exit(void)
73{
74 platform_device_unregister(fsi_da7210_snd_device);
75}
76
77module_init(fsi_da7210_sound_init);
78module_exit(fsi_da7210_sound_exit);
79
80/* Module information */
81MODULE_DESCRIPTION("ALSA SoC FSI DA2710");
82MODULE_AUTHOR("Kuninori Morimoto <morimoto.kuninori@renesas.com>");
83MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 42813b808389..993abb730dfa 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -67,6 +67,7 @@
67/* DOFF_ST */ 67/* DOFF_ST */
68#define ERR_OVER 0x00000010 68#define ERR_OVER 0x00000010
69#define ERR_UNDER 0x00000001 69#define ERR_UNDER 0x00000001
70#define ST_ERR (ERR_OVER | ERR_UNDER)
70 71
71/* CLK_RST */ 72/* CLK_RST */
72#define B_CLK 0x00000010 73#define B_CLK 0x00000010
@@ -92,6 +93,7 @@
92struct fsi_priv { 93struct fsi_priv {
93 void __iomem *base; 94 void __iomem *base;
94 struct snd_pcm_substream *substream; 95 struct snd_pcm_substream *substream;
96 struct fsi_master *master;
95 97
96 int fifo_max; 98 int fifo_max;
97 int chan; 99 int chan;
@@ -108,10 +110,9 @@ struct fsi_master {
108 struct fsi_priv fsia; 110 struct fsi_priv fsia;
109 struct fsi_priv fsib; 111 struct fsi_priv fsib;
110 struct sh_fsi_platform_info *info; 112 struct sh_fsi_platform_info *info;
113 spinlock_t lock;
111}; 114};
112 115
113static struct fsi_master *master;
114
115/************************************************************************ 116/************************************************************************
116 117
117 118
@@ -119,35 +120,35 @@ static struct fsi_master *master;
119 120
120 121
121************************************************************************/ 122************************************************************************/
122static int __fsi_reg_write(u32 reg, u32 data) 123static void __fsi_reg_write(u32 reg, u32 data)
123{ 124{
124 /* valid data area is 24bit */ 125 /* valid data area is 24bit */
125 data &= 0x00ffffff; 126 data &= 0x00ffffff;
126 127
127 return ctrl_outl(data, reg); 128 __raw_writel(data, reg);
128} 129}
129 130
130static u32 __fsi_reg_read(u32 reg) 131static u32 __fsi_reg_read(u32 reg)
131{ 132{
132 return ctrl_inl(reg); 133 return __raw_readl(reg);
133} 134}
134 135
135static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 136static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
136{ 137{
137 u32 val = __fsi_reg_read(reg); 138 u32 val = __fsi_reg_read(reg);
138 139
139 val &= ~mask; 140 val &= ~mask;
140 val |= data & mask; 141 val |= data & mask;
141 142
142 return __fsi_reg_write(reg, val); 143 __fsi_reg_write(reg, val);
143} 144}
144 145
145static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 146static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
146{ 147{
147 if (reg > REG_END) 148 if (reg > REG_END)
148 return -1; 149 return;
149 150
150 return __fsi_reg_write((u32)(fsi->base + reg), data); 151 __fsi_reg_write((u32)(fsi->base + reg), data);
151} 152}
152 153
153static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 154static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
@@ -158,39 +159,55 @@ static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
158 return __fsi_reg_read((u32)(fsi->base + reg)); 159 return __fsi_reg_read((u32)(fsi->base + reg));
159} 160}
160 161
161static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 162static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
162{ 163{
163 if (reg > REG_END) 164 if (reg > REG_END)
164 return -1; 165 return;
165 166
166 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 167 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
167} 168}
168 169
169static int fsi_master_write(u32 reg, u32 data) 170static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
170{ 171{
172 unsigned long flags;
173
171 if ((reg < MREG_START) || 174 if ((reg < MREG_START) ||
172 (reg > MREG_END)) 175 (reg > MREG_END))
173 return -1; 176 return;
174 177
175 return __fsi_reg_write((u32)(master->base + reg), data); 178 spin_lock_irqsave(&master->lock, flags);
179 __fsi_reg_write((u32)(master->base + reg), data);
180 spin_unlock_irqrestore(&master->lock, flags);
176} 181}
177 182
178static u32 fsi_master_read(u32 reg) 183static u32 fsi_master_read(struct fsi_master *master, u32 reg)
179{ 184{
185 u32 ret;
186 unsigned long flags;
187
180 if ((reg < MREG_START) || 188 if ((reg < MREG_START) ||
181 (reg > MREG_END)) 189 (reg > MREG_END))
182 return 0; 190 return 0;
183 191
184 return __fsi_reg_read((u32)(master->base + reg)); 192 spin_lock_irqsave(&master->lock, flags);
193 ret = __fsi_reg_read((u32)(master->base + reg));
194 spin_unlock_irqrestore(&master->lock, flags);
195
196 return ret;
185} 197}
186 198
187static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 199static void fsi_master_mask_set(struct fsi_master *master,
200 u32 reg, u32 mask, u32 data)
188{ 201{
202 unsigned long flags;
203
189 if ((reg < MREG_START) || 204 if ((reg < MREG_START) ||
190 (reg > MREG_END)) 205 (reg > MREG_END))
191 return -1; 206 return;
192 207
193 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 208 spin_lock_irqsave(&master->lock, flags);
209 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
210 spin_unlock_irqrestore(&master->lock, flags);
194} 211}
195 212
196/************************************************************************ 213/************************************************************************
@@ -200,43 +217,35 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
200 217
201 218
202************************************************************************/ 219************************************************************************/
203static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 220static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
204{ 221{
205 struct snd_soc_pcm_runtime *rtd; 222 return fsi->master;
206 struct fsi_priv *fsi = NULL; 223}
207 224
208 if (!substream || !master) 225static int fsi_is_port_a(struct fsi_priv *fsi)
209 return NULL; 226{
227 return fsi->master->base == fsi->base;
228}
210 229
211 rtd = substream->private_data; 230static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
212 switch (rtd->dai->cpu_dai->id) { 231{
213 case 0: 232 struct snd_soc_pcm_runtime *rtd = substream->private_data;
214 fsi = &master->fsia; 233 struct snd_soc_dai_link *machine = rtd->dai;
215 break;
216 case 1:
217 fsi = &master->fsib;
218 break;
219 }
220 234
221 return fsi; 235 return machine->cpu_dai;
222} 236}
223 237
224static int fsi_is_port_a(struct fsi_priv *fsi) 238static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
225{ 239{
226 /* return 240 struct snd_soc_dai *dai = fsi_get_dai(substream);
227 * 1 : port a
228 * 0 : port b
229 */
230 241
231 if (fsi == &master->fsia) 242 return dai->private_data;
232 return 1;
233
234 return 0;
235} 243}
236 244
237static u32 fsi_get_info_flags(struct fsi_priv *fsi) 245static u32 fsi_get_info_flags(struct fsi_priv *fsi)
238{ 246{
239 int is_porta = fsi_is_port_a(fsi); 247 int is_porta = fsi_is_port_a(fsi);
248 struct fsi_master *master = fsi_get_master(fsi);
240 249
241 return is_porta ? master->info->porta_flags : 250 return is_porta ? master->info->porta_flags :
242 master->info->portb_flags; 251 master->info->portb_flags;
@@ -314,27 +323,30 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
314static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 323static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
315{ 324{
316 u32 data = fsi_port_ab_io_bit(fsi, is_play); 325 u32 data = fsi_port_ab_io_bit(fsi, is_play);
326 struct fsi_master *master = fsi_get_master(fsi);
317 327
318 fsi_master_mask_set(IMSK, data, data); 328 fsi_master_mask_set(master, IMSK, data, data);
319 fsi_master_mask_set(IEMSK, data, data); 329 fsi_master_mask_set(master, IEMSK, data, data);
320} 330}
321 331
322static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 332static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
323{ 333{
324 u32 data = fsi_port_ab_io_bit(fsi, is_play); 334 u32 data = fsi_port_ab_io_bit(fsi, is_play);
335 struct fsi_master *master = fsi_get_master(fsi);
325 336
326 fsi_master_mask_set(IMSK, data, 0); 337 fsi_master_mask_set(master, IMSK, data, 0);
327 fsi_master_mask_set(IEMSK, data, 0); 338 fsi_master_mask_set(master, IEMSK, data, 0);
328} 339}
329 340
330static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 341static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
331{ 342{
332 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 343 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
344 struct fsi_master *master = fsi_get_master(fsi);
333 345
334 if (enable) 346 if (enable)
335 fsi_master_mask_set(CLK_RST, val, val); 347 fsi_master_mask_set(master, CLK_RST, val, val);
336 else 348 else
337 fsi_master_mask_set(CLK_RST, val, 0); 349 fsi_master_mask_set(master, CLK_RST, val, 0);
338} 350}
339 351
340static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 352static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -355,43 +367,46 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
355 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 367 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
356 368
357 /* clear interrupt factor */ 369 /* clear interrupt factor */
358 fsi_master_mask_set(INT_ST, data, 0); 370 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
359} 371}
360 372
361static void fsi_soft_all_reset(void) 373static void fsi_soft_all_reset(struct fsi_master *master)
362{ 374{
363 u32 status = fsi_master_read(SOFT_RST); 375 u32 status = fsi_master_read(master, SOFT_RST);
364 376
365 /* port AB reset */ 377 /* port AB reset */
366 status &= 0x000000ff; 378 status &= 0x000000ff;
367 fsi_master_write(SOFT_RST, status); 379 fsi_master_write(master, SOFT_RST, status);
368 mdelay(10); 380 mdelay(10);
369 381
370 /* soft reset */ 382 /* soft reset */
371 status &= 0x000000f0; 383 status &= 0x000000f0;
372 fsi_master_write(SOFT_RST, status); 384 fsi_master_write(master, SOFT_RST, status);
373 status |= 0x00000001; 385 status |= 0x00000001;
374 fsi_master_write(SOFT_RST, status); 386 fsi_master_write(master, SOFT_RST, status);
375 mdelay(10); 387 mdelay(10);
376} 388}
377 389
378/* playback interrupt */ 390/* playback interrupt */
379static int fsi_data_push(struct fsi_priv *fsi) 391static int fsi_data_push(struct fsi_priv *fsi, int startup)
380{ 392{
381 struct snd_pcm_runtime *runtime; 393 struct snd_pcm_runtime *runtime;
382 struct snd_pcm_substream *substream = NULL; 394 struct snd_pcm_substream *substream = NULL;
395 u32 status;
383 int send; 396 int send;
384 int fifo_free; 397 int fifo_free;
385 int width; 398 int width;
386 u8 *start; 399 u8 *start;
387 int i; 400 int i, over_period;
388 401
389 if (!fsi || 402 if (!fsi ||
390 !fsi->substream || 403 !fsi->substream ||
391 !fsi->substream->runtime) 404 !fsi->substream->runtime)
392 return -EINVAL; 405 return -EINVAL;
393 406
394 runtime = fsi->substream->runtime; 407 over_period = 0;
408 substream = fsi->substream;
409 runtime = substream->runtime;
395 410
396 /* FSI FIFO has limit. 411 /* FSI FIFO has limit.
397 * So, this driver can not send periods data at a time 412 * So, this driver can not send periods data at a time
@@ -399,7 +414,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
399 if (fsi->byte_offset >= 414 if (fsi->byte_offset >=
400 fsi->period_len * (fsi->periods + 1)) { 415 fsi->period_len * (fsi->periods + 1)) {
401 416
402 substream = fsi->substream; 417 over_period = 1;
403 fsi->periods = (fsi->periods + 1) % runtime->periods; 418 fsi->periods = (fsi->periods + 1) % runtime->periods;
404 419
405 if (0 == fsi->periods) 420 if (0 == fsi->periods)
@@ -438,30 +453,44 @@ static int fsi_data_push(struct fsi_priv *fsi)
438 453
439 fsi->byte_offset += send * width; 454 fsi->byte_offset += send * width;
440 455
456 status = fsi_reg_read(fsi, DOFF_ST);
457 if (!startup) {
458 struct snd_soc_dai *dai = fsi_get_dai(substream);
459
460 if (status & ERR_OVER)
461 dev_err(dai->dev, "over run\n");
462 if (status & ERR_UNDER)
463 dev_err(dai->dev, "under run\n");
464 }
465 fsi_reg_write(fsi, DOFF_ST, 0);
466
441 fsi_irq_enable(fsi, 1); 467 fsi_irq_enable(fsi, 1);
442 468
443 if (substream) 469 if (over_period)
444 snd_pcm_period_elapsed(substream); 470 snd_pcm_period_elapsed(substream);
445 471
446 return 0; 472 return 0;
447} 473}
448 474
449static int fsi_data_pop(struct fsi_priv *fsi) 475static int fsi_data_pop(struct fsi_priv *fsi, int startup)
450{ 476{
451 struct snd_pcm_runtime *runtime; 477 struct snd_pcm_runtime *runtime;
452 struct snd_pcm_substream *substream = NULL; 478 struct snd_pcm_substream *substream = NULL;
479 u32 status;
453 int free; 480 int free;
454 int fifo_fill; 481 int fifo_fill;
455 int width; 482 int width;
456 u8 *start; 483 u8 *start;
457 int i; 484 int i, over_period;
458 485
459 if (!fsi || 486 if (!fsi ||
460 !fsi->substream || 487 !fsi->substream ||
461 !fsi->substream->runtime) 488 !fsi->substream->runtime)
462 return -EINVAL; 489 return -EINVAL;
463 490
464 runtime = fsi->substream->runtime; 491 over_period = 0;
492 substream = fsi->substream;
493 runtime = substream->runtime;
465 494
466 /* FSI FIFO has limit. 495 /* FSI FIFO has limit.
467 * So, this driver can not send periods data at a time 496 * So, this driver can not send periods data at a time
@@ -469,7 +498,7 @@ static int fsi_data_pop(struct fsi_priv *fsi)
469 if (fsi->byte_offset >= 498 if (fsi->byte_offset >=
470 fsi->period_len * (fsi->periods + 1)) { 499 fsi->period_len * (fsi->periods + 1)) {
471 500
472 substream = fsi->substream; 501 over_period = 1;
473 fsi->periods = (fsi->periods + 1) % runtime->periods; 502 fsi->periods = (fsi->periods + 1) % runtime->periods;
474 503
475 if (0 == fsi->periods) 504 if (0 == fsi->periods)
@@ -507,9 +536,20 @@ static int fsi_data_pop(struct fsi_priv *fsi)
507 536
508 fsi->byte_offset += fifo_fill * width; 537 fsi->byte_offset += fifo_fill * width;
509 538
539 status = fsi_reg_read(fsi, DIFF_ST);
540 if (!startup) {
541 struct snd_soc_dai *dai = fsi_get_dai(substream);
542
543 if (status & ERR_OVER)
544 dev_err(dai->dev, "over run\n");
545 if (status & ERR_UNDER)
546 dev_err(dai->dev, "under run\n");
547 }
548 fsi_reg_write(fsi, DIFF_ST, 0);
549
510 fsi_irq_enable(fsi, 0); 550 fsi_irq_enable(fsi, 0);
511 551
512 if (substream) 552 if (over_period)
513 snd_pcm_period_elapsed(substream); 553 snd_pcm_period_elapsed(substream);
514 554
515 return 0; 555 return 0;
@@ -517,23 +557,24 @@ static int fsi_data_pop(struct fsi_priv *fsi)
517 557
518static irqreturn_t fsi_interrupt(int irq, void *data) 558static irqreturn_t fsi_interrupt(int irq, void *data)
519{ 559{
520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 560 struct fsi_master *master = data;
521 u32 int_st = fsi_master_read(INT_ST); 561 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
562 u32 int_st = fsi_master_read(master, INT_ST);
522 563
523 /* clear irq status */ 564 /* clear irq status */
524 fsi_master_write(SOFT_RST, status); 565 fsi_master_write(master, SOFT_RST, status);
525 fsi_master_write(SOFT_RST, status | 0x00000010); 566 fsi_master_write(master, SOFT_RST, status | 0x00000010);
526 567
527 if (int_st & INT_A_OUT) 568 if (int_st & INT_A_OUT)
528 fsi_data_push(&master->fsia); 569 fsi_data_push(&master->fsia, 0);
529 if (int_st & INT_B_OUT) 570 if (int_st & INT_B_OUT)
530 fsi_data_push(&master->fsib); 571 fsi_data_push(&master->fsib, 0);
531 if (int_st & INT_A_IN) 572 if (int_st & INT_A_IN)
532 fsi_data_pop(&master->fsia); 573 fsi_data_pop(&master->fsia, 0);
533 if (int_st & INT_B_IN) 574 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib); 575 fsi_data_pop(&master->fsib, 0);
535 576
536 fsi_master_write(INT_ST, 0x0000000); 577 fsi_master_write(master, INT_ST, 0x0000000);
537 578
538 return IRQ_HANDLED; 579 return IRQ_HANDLED;
539} 580}
@@ -548,7 +589,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
548static int fsi_dai_startup(struct snd_pcm_substream *substream, 589static int fsi_dai_startup(struct snd_pcm_substream *substream,
549 struct snd_soc_dai *dai) 590 struct snd_soc_dai *dai)
550{ 591{
551 struct fsi_priv *fsi = fsi_get(substream); 592 struct fsi_priv *fsi = fsi_get_priv(substream);
552 const char *msg; 593 const char *msg;
553 u32 flags = fsi_get_info_flags(fsi); 594 u32 flags = fsi_get_info_flags(fsi);
554 u32 fmt; 595 u32 fmt;
@@ -667,7 +708,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
667static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 708static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
668 struct snd_soc_dai *dai) 709 struct snd_soc_dai *dai)
669{ 710{
670 struct fsi_priv *fsi = fsi_get(substream); 711 struct fsi_priv *fsi = fsi_get_priv(substream);
671 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 712 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
672 713
673 fsi_irq_disable(fsi, is_play); 714 fsi_irq_disable(fsi, is_play);
@@ -679,7 +720,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 720static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
680 struct snd_soc_dai *dai) 721 struct snd_soc_dai *dai)
681{ 722{
682 struct fsi_priv *fsi = fsi_get(substream); 723 struct fsi_priv *fsi = fsi_get_priv(substream);
683 struct snd_pcm_runtime *runtime = substream->runtime; 724 struct snd_pcm_runtime *runtime = substream->runtime;
684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 725 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
685 int ret = 0; 726 int ret = 0;
@@ -689,7 +730,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
689 fsi_stream_push(fsi, substream, 730 fsi_stream_push(fsi, substream,
690 frames_to_bytes(runtime, runtime->buffer_size), 731 frames_to_bytes(runtime, runtime->buffer_size),
691 frames_to_bytes(runtime, runtime->period_size)); 732 frames_to_bytes(runtime, runtime->period_size));
692 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 733 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
693 break; 734 break;
694 case SNDRV_PCM_TRIGGER_STOP: 735 case SNDRV_PCM_TRIGGER_STOP:
695 fsi_irq_disable(fsi, is_play); 736 fsi_irq_disable(fsi, is_play);
@@ -760,7 +801,7 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
760static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 801static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
761{ 802{
762 struct snd_pcm_runtime *runtime = substream->runtime; 803 struct snd_pcm_runtime *runtime = substream->runtime;
763 struct fsi_priv *fsi = fsi_get(substream); 804 struct fsi_priv *fsi = fsi_get_priv(substream);
764 long location; 805 long location;
765 806
766 location = (fsi->byte_offset - 1); 807 location = (fsi->byte_offset - 1);
@@ -870,10 +911,16 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
870************************************************************************/ 911************************************************************************/
871static int fsi_probe(struct platform_device *pdev) 912static int fsi_probe(struct platform_device *pdev)
872{ 913{
914 struct fsi_master *master;
873 struct resource *res; 915 struct resource *res;
874 unsigned int irq; 916 unsigned int irq;
875 int ret; 917 int ret;
876 918
919 if (0 != pdev->id) {
920 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
921 return -ENODEV;
922 }
923
877 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 924 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
878 irq = platform_get_irq(pdev, 0); 925 irq = platform_get_irq(pdev, 0);
879 if (!res || (int)irq <= 0) { 926 if (!res || (int)irq <= 0) {
@@ -899,15 +946,20 @@ static int fsi_probe(struct platform_device *pdev)
899 master->irq = irq; 946 master->irq = irq;
900 master->info = pdev->dev.platform_data; 947 master->info = pdev->dev.platform_data;
901 master->fsia.base = master->base; 948 master->fsia.base = master->base;
949 master->fsia.master = master;
902 master->fsib.base = master->base + 0x40; 950 master->fsib.base = master->base + 0x40;
951 master->fsib.master = master;
952 spin_lock_init(&master->lock);
903 953
904 pm_runtime_enable(&pdev->dev); 954 pm_runtime_enable(&pdev->dev);
905 pm_runtime_resume(&pdev->dev); 955 pm_runtime_resume(&pdev->dev);
906 956
907 fsi_soc_dai[0].dev = &pdev->dev; 957 fsi_soc_dai[0].dev = &pdev->dev;
958 fsi_soc_dai[0].private_data = &master->fsia;
908 fsi_soc_dai[1].dev = &pdev->dev; 959 fsi_soc_dai[1].dev = &pdev->dev;
960 fsi_soc_dai[1].private_data = &master->fsib;
909 961
910 fsi_soft_all_reset(); 962 fsi_soft_all_reset(master);
911 963
912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 964 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
913 if (ret) { 965 if (ret) {
@@ -937,6 +989,10 @@ exit:
937 989
938static int fsi_remove(struct platform_device *pdev) 990static int fsi_remove(struct platform_device *pdev)
939{ 991{
992 struct fsi_master *master;
993
994 master = fsi_get_master(fsi_soc_dai[0].private_data);
995
940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 996 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
941 snd_soc_unregister_platform(&fsi_soc_platform); 997 snd_soc_unregister_platform(&fsi_soc_platform);
942 998
@@ -946,7 +1002,12 @@ static int fsi_remove(struct platform_device *pdev)
946 1002
947 iounmap(master->base); 1003 iounmap(master->base);
948 kfree(master); 1004 kfree(master);
949 master = NULL; 1005
1006 fsi_soc_dai[0].dev = NULL;
1007 fsi_soc_dai[0].private_data = NULL;
1008 fsi_soc_dai[1].dev = NULL;
1009 fsi_soc_dai[1].private_data = NULL;
1010
950 return 0; 1011 return 0;
951} 1012}
952 1013
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
new file mode 100644
index 000000000000..b823a5c9b9bc
--- /dev/null
+++ b/sound/soc/sh/migor.c
@@ -0,0 +1,218 @@
1/*
2 * ALSA SoC driver for Migo-R
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#include <linux/device.h>
12#include <linux/firmware.h>
13#include <linux/module.h>
14
15#include <asm/clock.h>
16
17#include <cpu/sh7722.h>
18
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm8978.h"
25#include "siu.h"
26
27/* Default 8000Hz sampling frequency */
28static unsigned long codec_freq = 8000 * 512;
29
30static unsigned int use_count;
31
32/* External clock, sourced from the codec at the SIUMCKB pin */
33static unsigned long siumckb_recalc(struct clk *clk)
34{
35 return codec_freq;
36}
37
38static struct clk_ops siumckb_clk_ops = {
39 .recalc = siumckb_recalc,
40};
41
42static struct clk siumckb_clk = {
43 .name = "siumckb_clk",
44 .id = -1,
45 .ops = &siumckb_clk_ops,
46 .rate = 0, /* initialised at run-time */
47};
48
49static int migor_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 *codec_dai = rtd->dai->codec_dai;
54 int ret;
55 unsigned int rate = params_rate(params);
56
57 ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000,
58 SND_SOC_CLOCK_IN);
59 if (ret < 0)
60 return ret;
61
62 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512);
63 if (ret < 0)
64 return ret;
65
66 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_NB_IF |
67 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 ret = snd_soc_dai_set_fmt(rtd->dai->cpu_dai, SND_SOC_DAIFMT_NB_IF |
72 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS);
73 if (ret < 0)
74 return ret;
75
76 codec_freq = rate * 512;
77 /*
78 * This propagates the parent frequency change to children and
79 * recalculates the frequency table
80 */
81 clk_set_rate(&siumckb_clk, codec_freq);
82 dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq);
83
84 ret = snd_soc_dai_set_sysclk(rtd->dai->cpu_dai, SIU_CLKB_EXT,
85 codec_freq / 2, SND_SOC_CLOCK_IN);
86
87 if (!ret)
88 use_count++;
89
90 return ret;
91}
92
93static int migor_hw_free(struct snd_pcm_substream *substream)
94{
95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
96 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
97
98 if (use_count) {
99 use_count--;
100
101 if (!use_count)
102 snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0,
103 SND_SOC_CLOCK_IN);
104 } else {
105 dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n");
106 }
107
108 return 0;
109}
110
111static struct snd_soc_ops migor_dai_ops = {
112 .hw_params = migor_hw_params,
113 .hw_free = migor_hw_free,
114};
115
116static const struct snd_soc_dapm_widget migor_dapm_widgets[] = {
117 SND_SOC_DAPM_HP("Headphone", NULL),
118 SND_SOC_DAPM_MIC("Onboard Microphone", NULL),
119 SND_SOC_DAPM_MIC("External Microphone", NULL),
120};
121
122static const struct snd_soc_dapm_route audio_map[] = {
123 /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */
124 { "Headphone", NULL, "OUT4 VMID" },
125 { "OUT4 VMID", NULL, "LHP" },
126 { "OUT4 VMID", NULL, "RHP" },
127
128 /* On-board microphone */
129 { "RMICN", NULL, "Mic Bias" },
130 { "RMICP", NULL, "Mic Bias" },
131 { "Mic Bias", NULL, "Onboard Microphone" },
132
133 /* External microphone */
134 { "LMICN", NULL, "Mic Bias" },
135 { "LMICP", NULL, "Mic Bias" },
136 { "Mic Bias", NULL, "External Microphone" },
137};
138
139static int migor_dai_init(struct snd_soc_codec *codec)
140{
141 snd_soc_dapm_new_controls(codec, migor_dapm_widgets,
142 ARRAY_SIZE(migor_dapm_widgets));
143
144 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
145
146 return 0;
147}
148
149/* migor digital audio interface glue - connects codec <--> CPU */
150static struct snd_soc_dai_link migor_dai = {
151 .name = "wm8978",
152 .stream_name = "WM8978",
153 .cpu_dai = &siu_i2s_dai,
154 .codec_dai = &wm8978_dai,
155 .ops = &migor_dai_ops,
156 .init = migor_dai_init,
157};
158
159/* migor audio machine driver */
160static struct snd_soc_card snd_soc_migor = {
161 .name = "Migo-R",
162 .platform = &siu_platform,
163 .dai_link = &migor_dai,
164 .num_links = 1,
165};
166
167/* migor audio subsystem */
168static struct snd_soc_device migor_snd_devdata = {
169 .card = &snd_soc_migor,
170 .codec_dev = &soc_codec_dev_wm8978,
171};
172
173static struct platform_device *migor_snd_device;
174
175static int __init migor_init(void)
176{
177 int ret;
178
179 ret = clk_register(&siumckb_clk);
180 if (ret < 0)
181 return ret;
182
183 /* Port number used on this machine: port B */
184 migor_snd_device = platform_device_alloc("soc-audio", 1);
185 if (!migor_snd_device) {
186 ret = -ENOMEM;
187 goto epdevalloc;
188 }
189
190 platform_set_drvdata(migor_snd_device, &migor_snd_devdata);
191
192 migor_snd_devdata.dev = &migor_snd_device->dev;
193
194 ret = platform_device_add(migor_snd_device);
195 if (ret)
196 goto epdevadd;
197
198 return 0;
199
200epdevadd:
201 platform_device_put(migor_snd_device);
202epdevalloc:
203 clk_unregister(&siumckb_clk);
204 return ret;
205}
206
207static void __exit migor_exit(void)
208{
209 clk_unregister(&siumckb_clk);
210 platform_device_unregister(migor_snd_device);
211}
212
213module_init(migor_init);
214module_exit(migor_exit);
215
216MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>");
217MODULE_DESCRIPTION("ALSA SoC Migor");
218MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
new file mode 100644
index 000000000000..9cc04ab2bce7
--- /dev/null
+++ b/sound/soc/sh/siu.h
@@ -0,0 +1,193 @@
1/*
2 * siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef SIU_H
23#define SIU_H
24
25/* Common kernel and user-space firmware-building defines and types */
26
27#define YRAM0_SIZE (0x0040 / 4) /* 16 */
28#define YRAM1_SIZE (0x0080 / 4) /* 32 */
29#define YRAM2_SIZE (0x0040 / 4) /* 16 */
30#define YRAM3_SIZE (0x0080 / 4) /* 32 */
31#define YRAM4_SIZE (0x0080 / 4) /* 32 */
32#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \
33 YRAM3_SIZE + YRAM4_SIZE)
34#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */
35#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */
36
37#define XRAM0_SIZE (0x0400 / 4) /* 256 */
38#define XRAM1_SIZE (0x0200 / 4) /* 128 */
39#define XRAM2_SIZE (0x0200 / 4) /* 128 */
40
41/* PRAM program array size */
42#define PRAM0_SIZE (0x0100 / 4) /* 64 */
43#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */
44
45#include <linux/types.h>
46
47struct siu_spb_param {
48 __u32 ab1a; /* input FIFO address */
49 __u32 ab0a; /* output FIFO address */
50 __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */
51 __u32 event; /* SPB program starting conditions */
52 __u32 stfifo; /* STFIFO register setting value */
53 __u32 trdat; /* TRDAT register setting value */
54};
55
56struct siu_firmware {
57 __u32 yram_fir_coeff[YRAM_FIR_SIZE];
58 __u32 pram0[PRAM0_SIZE];
59 __u32 pram1[PRAM1_SIZE];
60 __u32 yram0[YRAM0_SIZE];
61 __u32 yram1[YRAM1_SIZE];
62 __u32 yram2[YRAM2_SIZE];
63 __u32 yram3[YRAM3_SIZE];
64 __u32 yram4[YRAM4_SIZE];
65 __u32 spbpar_num;
66 struct siu_spb_param spbpar[32];
67};
68
69#ifdef __KERNEL__
70
71#include <linux/dmaengine.h>
72#include <linux/interrupt.h>
73#include <linux/io.h>
74
75#include <asm/dma-sh.h>
76
77#include <sound/core.h>
78#include <sound/pcm.h>
79#include <sound/soc-dai.h>
80
81#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
82#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
83#define SIU_PERIODS_MAX 64 /* Max periods in buffer */
84#define SIU_PERIODS_MIN 4 /* Min periods in buffer */
85#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX)
86
87/* SIU ports: only one can be used at a time */
88enum {
89 SIU_PORT_A,
90 SIU_PORT_B,
91 SIU_PORT_NUM,
92};
93
94/* SIU clock configuration */
95enum {
96 SIU_CLKA_PLL,
97 SIU_CLKA_EXT,
98 SIU_CLKB_PLL,
99 SIU_CLKB_EXT
100};
101
102struct siu_info {
103 int port_id;
104 u32 __iomem *pram;
105 u32 __iomem *xram;
106 u32 __iomem *yram;
107 u32 __iomem *reg;
108 struct siu_firmware fw;
109};
110
111struct siu_stream {
112 struct tasklet_struct tasklet;
113 struct snd_pcm_substream *substream;
114 snd_pcm_format_t format;
115 size_t buf_bytes;
116 size_t period_bytes;
117 int cur_period; /* Period currently in dma */
118 u32 volume;
119 snd_pcm_sframes_t xfer_cnt; /* Number of frames */
120 u8 rw_flg; /* transfer status */
121 /* DMA status */
122 struct dma_chan *chan; /* DMA channel */
123 struct dma_async_tx_descriptor *tx_desc;
124 dma_cookie_t cookie;
125 struct sh_dmae_slave param;
126};
127
128struct siu_port {
129 unsigned long play_cap; /* Used to track full duplex */
130 struct snd_pcm *pcm;
131 struct siu_stream playback;
132 struct siu_stream capture;
133 u32 stfifo; /* STFIFO value from firmware */
134 u32 trdat; /* TRDAT value from firmware */
135};
136
137extern struct siu_port *siu_ports[SIU_PORT_NUM];
138
139static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream)
140{
141 struct platform_device *pdev =
142 to_platform_device(substream->pcm->card->dev);
143 return siu_ports[pdev->id];
144}
145
146/* Register access */
147static inline void siu_write32(u32 __iomem *addr, u32 val)
148{
149 __raw_writel(val, addr);
150}
151
152static inline u32 siu_read32(u32 __iomem *addr)
153{
154 return __raw_readl(addr);
155}
156
157/* SIU registers */
158#define SIU_IFCTL (0x000 / sizeof(u32))
159#define SIU_SRCTL (0x004 / sizeof(u32))
160#define SIU_SFORM (0x008 / sizeof(u32))
161#define SIU_CKCTL (0x00c / sizeof(u32))
162#define SIU_TRDAT (0x010 / sizeof(u32))
163#define SIU_STFIFO (0x014 / sizeof(u32))
164#define SIU_DPAK (0x01c / sizeof(u32))
165#define SIU_CKREV (0x020 / sizeof(u32))
166#define SIU_EVNTC (0x028 / sizeof(u32))
167#define SIU_SBCTL (0x040 / sizeof(u32))
168#define SIU_SBPSET (0x044 / sizeof(u32))
169#define SIU_SBFSTS (0x068 / sizeof(u32))
170#define SIU_SBDVCA (0x06c / sizeof(u32))
171#define SIU_SBDVCB (0x070 / sizeof(u32))
172#define SIU_SBACTIV (0x074 / sizeof(u32))
173#define SIU_DMAIA (0x090 / sizeof(u32))
174#define SIU_DMAIB (0x094 / sizeof(u32))
175#define SIU_DMAOA (0x098 / sizeof(u32))
176#define SIU_DMAOB (0x09c / sizeof(u32))
177#define SIU_DMAML (0x0a0 / sizeof(u32))
178#define SIU_SPSTS (0x0cc / sizeof(u32))
179#define SIU_SPCTL (0x0d0 / sizeof(u32))
180#define SIU_BRGASEL (0x100 / sizeof(u32))
181#define SIU_BRRA (0x104 / sizeof(u32))
182#define SIU_BRGBSEL (0x108 / sizeof(u32))
183#define SIU_BRRB (0x10c / sizeof(u32))
184
185extern struct snd_soc_platform siu_platform;
186extern struct snd_soc_dai siu_i2s_dai;
187
188int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card);
189void siu_free_port(struct siu_port *port_info);
190
191#endif
192
193#endif /* SIU_H */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
new file mode 100644
index 000000000000..5452d19607e1
--- /dev/null
+++ b/sound/soc/sh/siu_dai.c
@@ -0,0 +1,847 @@
1/*
2 * siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/delay.h>
23#include <linux/firmware.h>
24#include <linux/pm_runtime.h>
25
26#include <asm/clock.h>
27#include <asm/siu.h>
28
29#include <sound/control.h>
30#include <sound/soc-dai.h>
31
32#include "siu.h"
33
34/* Board specifics */
35#if defined(CONFIG_CPU_SUBTYPE_SH7722)
36# define SIU_MAX_VOLUME 0x1000
37#else
38# define SIU_MAX_VOLUME 0x7fff
39#endif
40
41#define PRAM_SIZE 0x2000
42#define XRAM_SIZE 0x800
43#define YRAM_SIZE 0x800
44
45#define XRAM_OFFSET 0x4000
46#define YRAM_OFFSET 0x6000
47#define REG_OFFSET 0xc000
48
49#define PLAYBACK_ENABLED 1
50#define CAPTURE_ENABLED 2
51
52#define VOLUME_CAPTURE 0
53#define VOLUME_PLAYBACK 1
54#define DFLT_VOLUME_LEVEL 0x08000800
55
56/*
57 * SPDIF is only available on port A and on some SIU implementations it is only
58 * available for input. Due to the lack of hardware to test it, SPDIF is left
59 * disabled in this driver version
60 */
61struct format_flag {
62 u32 i2s;
63 u32 pcm;
64 u32 spdif;
65 u32 mask;
66};
67
68struct port_flag {
69 struct format_flag playback;
70 struct format_flag capture;
71};
72
73static struct port_flag siu_flags[SIU_PORT_NUM] = {
74 [SIU_PORT_A] = {
75 .playback = {
76 .i2s = 0x50000000,
77 .pcm = 0x40000000,
78 .spdif = 0x80000000, /* not on all SIU versions */
79 .mask = 0xd0000000,
80 },
81 .capture = {
82 .i2s = 0x05000000,
83 .pcm = 0x04000000,
84 .spdif = 0x08000000,
85 .mask = 0x0d000000,
86 },
87 },
88 [SIU_PORT_B] = {
89 .playback = {
90 .i2s = 0x00500000,
91 .pcm = 0x00400000,
92 .spdif = 0, /* impossible - turn off */
93 .mask = 0x00500000,
94 },
95 .capture = {
96 .i2s = 0x00050000,
97 .pcm = 0x00040000,
98 .spdif = 0, /* impossible - turn off */
99 .mask = 0x00050000,
100 },
101 },
102};
103
104static void siu_dai_start(struct siu_port *port_info)
105{
106 struct siu_info *info = siu_i2s_dai.private_data;
107 u32 __iomem *base = info->reg;
108
109 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
110
111 /* Turn on SIU clock */
112 pm_runtime_get_sync(siu_i2s_dai.dev);
113
114 /* Issue software reset to siu */
115 siu_write32(base + SIU_SRCTL, 0);
116
117 /* Wait for the reset to take effect */
118 udelay(1);
119
120 port_info->stfifo = 0;
121 port_info->trdat = 0;
122
123 /* portA, portB, SIU operate */
124 siu_write32(base + SIU_SRCTL, 0x301);
125
126 /* portA=256fs, portB=256fs */
127 siu_write32(base + SIU_CKCTL, 0x40400000);
128
129 /* portA's BRG does not divide SIUCKA */
130 siu_write32(base + SIU_BRGASEL, 0);
131 siu_write32(base + SIU_BRRA, 0);
132
133 /* portB's BRG divides SIUCKB by half */
134 siu_write32(base + SIU_BRGBSEL, 1);
135 siu_write32(base + SIU_BRRB, 0);
136
137 siu_write32(base + SIU_IFCTL, 0x44440000);
138
139 /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */
140 siu_write32(base + SIU_SFORM, 0x0c0c0000);
141
142 /*
143 * Volume levels: looks like the DSP firmware implements volume controls
144 * differently from what's described in the datasheet
145 */
146 siu_write32(base + SIU_SBDVCA, port_info->playback.volume);
147 siu_write32(base + SIU_SBDVCB, port_info->capture.volume);
148}
149
150static void siu_dai_stop(void)
151{
152 struct siu_info *info = siu_i2s_dai.private_data;
153 u32 __iomem *base = info->reg;
154
155 /* SIU software reset */
156 siu_write32(base + SIU_SRCTL, 0);
157
158 /* Turn off SIU clock */
159 pm_runtime_put_sync(siu_i2s_dai.dev);
160}
161
162static void siu_dai_spbAselect(struct siu_port *port_info)
163{
164 struct siu_info *info = siu_i2s_dai.private_data;
165 struct siu_firmware *fw = &info->fw;
166 u32 *ydef = fw->yram0;
167 u32 idx;
168
169 /* path A use */
170 if (!info->port_id)
171 idx = 1; /* portA */
172 else
173 idx = 2; /* portB */
174
175 ydef[0] = (fw->spbpar[idx].ab1a << 16) |
176 (fw->spbpar[idx].ab0a << 8) |
177 (fw->spbpar[idx].dir << 7) | 3;
178 ydef[1] = fw->yram0[1]; /* 0x03000300 */
179 ydef[2] = (16 / 2) << 24;
180 ydef[3] = fw->yram0[3]; /* 0 */
181 ydef[4] = fw->yram0[4]; /* 0 */
182 ydef[7] = fw->spbpar[idx].event;
183 port_info->stfifo |= fw->spbpar[idx].stfifo;
184 port_info->trdat |= fw->spbpar[idx].trdat;
185}
186
187static void siu_dai_spbBselect(struct siu_port *port_info)
188{
189 struct siu_info *info = siu_i2s_dai.private_data;
190 struct siu_firmware *fw = &info->fw;
191 u32 *ydef = fw->yram0;
192 u32 idx;
193
194 /* path B use */
195 if (!info->port_id)
196 idx = 7; /* portA */
197 else
198 idx = 8; /* portB */
199
200 ydef[5] = (fw->spbpar[idx].ab1a << 16) |
201 (fw->spbpar[idx].ab0a << 8) | 1;
202 ydef[6] = fw->spbpar[idx].event;
203 port_info->stfifo |= fw->spbpar[idx].stfifo;
204 port_info->trdat |= fw->spbpar[idx].trdat;
205}
206
207static void siu_dai_open(struct siu_stream *siu_stream)
208{
209 struct siu_info *info = siu_i2s_dai.private_data;
210 u32 __iomem *base = info->reg;
211 u32 srctl, ifctl;
212
213 srctl = siu_read32(base + SIU_SRCTL);
214 ifctl = siu_read32(base + SIU_IFCTL);
215
216 switch (info->port_id) {
217 case SIU_PORT_A:
218 /* portA operates */
219 srctl |= 0x200;
220 ifctl &= ~0xc2;
221 break;
222 case SIU_PORT_B:
223 /* portB operates */
224 srctl |= 0x100;
225 ifctl &= ~0x31;
226 break;
227 }
228
229 siu_write32(base + SIU_SRCTL, srctl);
230 /* Unmute and configure portA */
231 siu_write32(base + SIU_IFCTL, ifctl);
232}
233
234/*
235 * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower
236 * packing is supported
237 */
238static void siu_dai_pcmdatapack(struct siu_stream *siu_stream)
239{
240 struct siu_info *info = siu_i2s_dai.private_data;
241 u32 __iomem *base = info->reg;
242 u32 dpak;
243
244 dpak = siu_read32(base + SIU_DPAK);
245
246 switch (info->port_id) {
247 case SIU_PORT_A:
248 dpak &= ~0xc0000000;
249 break;
250 case SIU_PORT_B:
251 dpak &= ~0x00c00000;
252 break;
253 }
254
255 siu_write32(base + SIU_DPAK, dpak);
256}
257
258static int siu_dai_spbstart(struct siu_port *port_info)
259{
260 struct siu_info *info = siu_i2s_dai.private_data;
261 u32 __iomem *base = info->reg;
262 struct siu_firmware *fw = &info->fw;
263 u32 *ydef = fw->yram0;
264 int cnt;
265 u32 __iomem *add;
266 u32 *ptr;
267
268 /* Load SPB Program in PRAM */
269 ptr = fw->pram0;
270 add = info->pram;
271 for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++)
272 siu_write32(add, *ptr);
273
274 ptr = fw->pram1;
275 add = info->pram + (0x0100 / sizeof(u32));
276 for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++)
277 siu_write32(add, *ptr);
278
279 /* XRAM initialization */
280 add = info->xram;
281 for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++)
282 siu_write32(add, 0);
283
284 /* YRAM variable area initialization */
285 add = info->yram;
286 for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++)
287 siu_write32(add, ydef[cnt]);
288
289 /* YRAM FIR coefficient area initialization */
290 add = info->yram + (0x0200 / sizeof(u32));
291 for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++)
292 siu_write32(add, fw->yram_fir_coeff[cnt]);
293
294 /* YRAM IIR coefficient area initialization */
295 add = info->yram + (0x0600 / sizeof(u32));
296 for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++)
297 siu_write32(add, 0);
298
299 siu_write32(base + SIU_TRDAT, port_info->trdat);
300 port_info->trdat = 0x0;
301
302
303 /* SPB start condition: software */
304 siu_write32(base + SIU_SBACTIV, 0);
305 /* Start SPB */
306 siu_write32(base + SIU_SBCTL, 0xc0000000);
307 /* Wait for program to halt */
308 cnt = 0x10000;
309 while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000)
310 cpu_relax();
311
312 if (!cnt)
313 return -EBUSY;
314
315 /* SPB program start address setting */
316 siu_write32(base + SIU_SBPSET, 0x00400000);
317 /* SPB hardware start(FIFOCTL source) */
318 siu_write32(base + SIU_SBACTIV, 0xc0000000);
319
320 return 0;
321}
322
323static void siu_dai_spbstop(struct siu_port *port_info)
324{
325 struct siu_info *info = siu_i2s_dai.private_data;
326 u32 __iomem *base = info->reg;
327
328 siu_write32(base + SIU_SBACTIV, 0);
329 /* SPB stop */
330 siu_write32(base + SIU_SBCTL, 0);
331
332 port_info->stfifo = 0;
333}
334
335/* API functions */
336
337/* Playback and capture hardware properties are identical */
338static struct snd_pcm_hardware siu_dai_pcm_hw = {
339 .info = SNDRV_PCM_INFO_INTERLEAVED,
340 .formats = SNDRV_PCM_FMTBIT_S16,
341 .rates = SNDRV_PCM_RATE_8000_48000,
342 .rate_min = 8000,
343 .rate_max = 48000,
344 .channels_min = 2,
345 .channels_max = 2,
346 .buffer_bytes_max = SIU_BUFFER_BYTES_MAX,
347 .period_bytes_min = SIU_PERIOD_BYTES_MIN,
348 .period_bytes_max = SIU_PERIOD_BYTES_MAX,
349 .periods_min = SIU_PERIODS_MIN,
350 .periods_max = SIU_PERIODS_MAX,
351};
352
353static int siu_dai_info_volume(struct snd_kcontrol *kctrl,
354 struct snd_ctl_elem_info *uinfo)
355{
356 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
357
358 dev_dbg(port_info->pcm->card->dev, "%s\n", __func__);
359
360 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
361 uinfo->count = 2;
362 uinfo->value.integer.min = 0;
363 uinfo->value.integer.max = SIU_MAX_VOLUME;
364
365 return 0;
366}
367
368static int siu_dai_get_volume(struct snd_kcontrol *kctrl,
369 struct snd_ctl_elem_value *ucontrol)
370{
371 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
372 struct device *dev = port_info->pcm->card->dev;
373 u32 vol;
374
375 dev_dbg(dev, "%s\n", __func__);
376
377 switch (kctrl->private_value) {
378 case VOLUME_PLAYBACK:
379 /* Playback is always on port 0 */
380 vol = port_info->playback.volume;
381 ucontrol->value.integer.value[0] = vol & 0xffff;
382 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
383 break;
384 case VOLUME_CAPTURE:
385 /* Capture is always on port 1 */
386 vol = port_info->capture.volume;
387 ucontrol->value.integer.value[0] = vol & 0xffff;
388 ucontrol->value.integer.value[1] = vol >> 16 & 0xffff;
389 break;
390 default:
391 dev_err(dev, "%s() invalid private_value=%ld\n",
392 __func__, kctrl->private_value);
393 return -EINVAL;
394 }
395
396 return 0;
397}
398
399static int siu_dai_put_volume(struct snd_kcontrol *kctrl,
400 struct snd_ctl_elem_value *ucontrol)
401{
402 struct siu_port *port_info = snd_kcontrol_chip(kctrl);
403 struct device *dev = port_info->pcm->card->dev;
404 struct siu_info *info = siu_i2s_dai.private_data;
405 u32 __iomem *base = info->reg;
406 u32 new_vol;
407 u32 cur_vol;
408
409 dev_dbg(dev, "%s\n", __func__);
410
411 if (ucontrol->value.integer.value[0] < 0 ||
412 ucontrol->value.integer.value[0] > SIU_MAX_VOLUME ||
413 ucontrol->value.integer.value[1] < 0 ||
414 ucontrol->value.integer.value[1] > SIU_MAX_VOLUME)
415 return -EINVAL;
416
417 new_vol = ucontrol->value.integer.value[0] |
418 ucontrol->value.integer.value[1] << 16;
419
420 /* See comment above - DSP firmware implementation */
421 switch (kctrl->private_value) {
422 case VOLUME_PLAYBACK:
423 /* Playback is always on port 0 */
424 cur_vol = port_info->playback.volume;
425 siu_write32(base + SIU_SBDVCA, new_vol);
426 port_info->playback.volume = new_vol;
427 break;
428 case VOLUME_CAPTURE:
429 /* Capture is always on port 1 */
430 cur_vol = port_info->capture.volume;
431 siu_write32(base + SIU_SBDVCB, new_vol);
432 port_info->capture.volume = new_vol;
433 break;
434 default:
435 dev_err(dev, "%s() invalid private_value=%ld\n",
436 __func__, kctrl->private_value);
437 return -EINVAL;
438 }
439
440 if (cur_vol != new_vol)
441 return 1;
442
443 return 0;
444}
445
446static struct snd_kcontrol_new playback_controls = {
447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
448 .name = "PCM Playback Volume",
449 .index = 0,
450 .info = siu_dai_info_volume,
451 .get = siu_dai_get_volume,
452 .put = siu_dai_put_volume,
453 .private_value = VOLUME_PLAYBACK,
454};
455
456static struct snd_kcontrol_new capture_controls = {
457 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
458 .name = "PCM Capture Volume",
459 .index = 0,
460 .info = siu_dai_info_volume,
461 .get = siu_dai_get_volume,
462 .put = siu_dai_put_volume,
463 .private_value = VOLUME_CAPTURE,
464};
465
466int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card)
467{
468 struct device *dev = card->dev;
469 struct snd_kcontrol *kctrl;
470 int ret;
471
472 *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL);
473 if (!*port_info)
474 return -ENOMEM;
475
476 dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info);
477
478 (*port_info)->playback.volume = DFLT_VOLUME_LEVEL;
479 (*port_info)->capture.volume = DFLT_VOLUME_LEVEL;
480
481 /*
482 * Add mixer support. The SPB is used to change the volume. Both
483 * ports use the same SPB. Therefore, we only register one
484 * control instance since it will be used by both channels.
485 * In error case we continue without controls.
486 */
487 kctrl = snd_ctl_new1(&playback_controls, *port_info);
488 ret = snd_ctl_add(card, kctrl);
489 if (ret < 0)
490 dev_err(dev,
491 "failed to add playback controls %p port=%d err=%d\n",
492 kctrl, port, ret);
493
494 kctrl = snd_ctl_new1(&capture_controls, *port_info);
495 ret = snd_ctl_add(card, kctrl);
496 if (ret < 0)
497 dev_err(dev,
498 "failed to add capture controls %p port=%d err=%d\n",
499 kctrl, port, ret);
500
501 return 0;
502}
503
504void siu_free_port(struct siu_port *port_info)
505{
506 kfree(port_info);
507}
508
509static int siu_dai_startup(struct snd_pcm_substream *substream,
510 struct snd_soc_dai *dai)
511{
512 struct siu_info *info = siu_i2s_dai.private_data;
513 struct snd_pcm_runtime *rt = substream->runtime;
514 struct siu_port *port_info = siu_port_info(substream);
515 int ret;
516
517 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
518 info->port_id, port_info);
519
520 snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw);
521
522 ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
523 if (unlikely(ret < 0))
524 return ret;
525
526 siu_dai_start(port_info);
527
528 return 0;
529}
530
531static void siu_dai_shutdown(struct snd_pcm_substream *substream,
532 struct snd_soc_dai *dai)
533{
534 struct siu_info *info = siu_i2s_dai.private_data;
535 struct siu_port *port_info = siu_port_info(substream);
536
537 dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__,
538 info->port_id, port_info);
539
540 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
541 port_info->play_cap &= ~PLAYBACK_ENABLED;
542 else
543 port_info->play_cap &= ~CAPTURE_ENABLED;
544
545 /* Stop the siu if the other stream is not using it */
546 if (!port_info->play_cap) {
547 /* during stmread or stmwrite ? */
548 BUG_ON(port_info->playback.rw_flg || port_info->capture.rw_flg);
549 siu_dai_spbstop(port_info);
550 siu_dai_stop();
551 }
552}
553
554/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */
555static int siu_dai_prepare(struct snd_pcm_substream *substream,
556 struct snd_soc_dai *dai)
557{
558 struct siu_info *info = siu_i2s_dai.private_data;
559 struct snd_pcm_runtime *rt = substream->runtime;
560 struct siu_port *port_info = siu_port_info(substream);
561 struct siu_stream *siu_stream;
562 int self, ret;
563
564 dev_dbg(substream->pcm->card->dev,
565 "%s: port %d, active streams %lx, %d channels\n",
566 __func__, info->port_id, port_info->play_cap, rt->channels);
567
568 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
569 self = PLAYBACK_ENABLED;
570 siu_stream = &port_info->playback;
571 } else {
572 self = CAPTURE_ENABLED;
573 siu_stream = &port_info->capture;
574 }
575
576 /* Set up the siu if not already done */
577 if (!port_info->play_cap) {
578 siu_stream->rw_flg = 0; /* stream-data transfer flag */
579
580 siu_dai_spbAselect(port_info);
581 siu_dai_spbBselect(port_info);
582
583 siu_dai_open(siu_stream);
584
585 siu_dai_pcmdatapack(siu_stream);
586
587 ret = siu_dai_spbstart(port_info);
588 if (ret < 0)
589 goto fail;
590 }
591
592 port_info->play_cap |= self;
593
594fail:
595 return ret;
596}
597
598/*
599 * SIU can set bus format to I2S / PCM / SPDIF independently for playback and
600 * capture, however, the current API sets the bus format globally for a DAI.
601 */
602static int siu_dai_set_fmt(struct snd_soc_dai *dai,
603 unsigned int fmt)
604{
605 struct siu_info *info = siu_i2s_dai.private_data;
606 u32 __iomem *base = info->reg;
607 u32 ifctl;
608
609 dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n",
610 __func__, fmt, info->port_id);
611
612 if (info->port_id < 0)
613 return -ENODEV;
614
615 /* Here select between I2S / PCM / SPDIF */
616 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
617 case SND_SOC_DAIFMT_I2S:
618 ifctl = siu_flags[info->port_id].playback.i2s |
619 siu_flags[info->port_id].capture.i2s;
620 break;
621 case SND_SOC_DAIFMT_LEFT_J:
622 ifctl = siu_flags[info->port_id].playback.pcm |
623 siu_flags[info->port_id].capture.pcm;
624 break;
625 /* SPDIF disabled - see comment at the top */
626 default:
627 return -EINVAL;
628 }
629
630 ifctl |= ~(siu_flags[info->port_id].playback.mask |
631 siu_flags[info->port_id].capture.mask) &
632 siu_read32(base + SIU_IFCTL);
633 siu_write32(base + SIU_IFCTL, ifctl);
634
635 return 0;
636}
637
638static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
639 unsigned int freq, int dir)
640{
641 struct clk *siu_clk, *parent_clk;
642 char *siu_name, *parent_name;
643 int ret;
644
645 if (dir != SND_SOC_CLOCK_IN)
646 return -EINVAL;
647
648 dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id);
649
650 switch (clk_id) {
651 case SIU_CLKA_PLL:
652 siu_name = "siua_clk";
653 parent_name = "pll_clk";
654 break;
655 case SIU_CLKA_EXT:
656 siu_name = "siua_clk";
657 parent_name = "siumcka_clk";
658 break;
659 case SIU_CLKB_PLL:
660 siu_name = "siub_clk";
661 parent_name = "pll_clk";
662 break;
663 case SIU_CLKB_EXT:
664 siu_name = "siub_clk";
665 parent_name = "siumckb_clk";
666 break;
667 default:
668 return -EINVAL;
669 }
670
671 siu_clk = clk_get(siu_i2s_dai.dev, siu_name);
672 if (IS_ERR(siu_clk))
673 return PTR_ERR(siu_clk);
674
675 parent_clk = clk_get(siu_i2s_dai.dev, parent_name);
676 if (!IS_ERR(parent_clk)) {
677 ret = clk_set_parent(siu_clk, parent_clk);
678 if (!ret)
679 clk_set_rate(siu_clk, freq);
680 clk_put(parent_clk);
681 }
682
683 clk_put(siu_clk);
684
685 return 0;
686}
687
688static struct snd_soc_dai_ops siu_dai_ops = {
689 .startup = siu_dai_startup,
690 .shutdown = siu_dai_shutdown,
691 .prepare = siu_dai_prepare,
692 .set_sysclk = siu_dai_set_sysclk,
693 .set_fmt = siu_dai_set_fmt,
694};
695
696struct snd_soc_dai siu_i2s_dai = {
697 .name = "sh-siu",
698 .id = 0,
699 .playback = {
700 .channels_min = 2,
701 .channels_max = 2,
702 .formats = SNDRV_PCM_FMTBIT_S16,
703 .rates = SNDRV_PCM_RATE_8000_48000,
704 },
705 .capture = {
706 .channels_min = 2,
707 .channels_max = 2,
708 .formats = SNDRV_PCM_FMTBIT_S16,
709 .rates = SNDRV_PCM_RATE_8000_48000,
710 },
711 .ops = &siu_dai_ops,
712};
713EXPORT_SYMBOL_GPL(siu_i2s_dai);
714
715static int __devinit siu_probe(struct platform_device *pdev)
716{
717 const struct firmware *fw_entry;
718 struct resource *res, *region;
719 struct siu_info *info;
720 int ret;
721
722 info = kmalloc(sizeof(*info), GFP_KERNEL);
723 if (!info)
724 return -ENOMEM;
725
726 ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev);
727 if (ret)
728 goto ereqfw;
729
730 /*
731 * Loaded firmware is "const" - read only, but we have to modify it in
732 * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect()
733 */
734 memcpy(&info->fw, fw_entry->data, fw_entry->size);
735
736 release_firmware(fw_entry);
737
738 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739 if (!res) {
740 ret = -ENODEV;
741 goto egetres;
742 }
743
744 region = request_mem_region(res->start, resource_size(res),
745 pdev->name);
746 if (!region) {
747 dev_err(&pdev->dev, "SIU region already claimed\n");
748 ret = -EBUSY;
749 goto ereqmemreg;
750 }
751
752 ret = -ENOMEM;
753 info->pram = ioremap(res->start, PRAM_SIZE);
754 if (!info->pram)
755 goto emappram;
756 info->xram = ioremap(res->start + XRAM_OFFSET, XRAM_SIZE);
757 if (!info->xram)
758 goto emapxram;
759 info->yram = ioremap(res->start + YRAM_OFFSET, YRAM_SIZE);
760 if (!info->yram)
761 goto emapyram;
762 info->reg = ioremap(res->start + REG_OFFSET, resource_size(res) -
763 REG_OFFSET);
764 if (!info->reg)
765 goto emapreg;
766
767 siu_i2s_dai.dev = &pdev->dev;
768 siu_i2s_dai.private_data = info;
769
770 ret = snd_soc_register_dais(&siu_i2s_dai, 1);
771 if (ret < 0)
772 goto edaiinit;
773
774 ret = snd_soc_register_platform(&siu_platform);
775 if (ret < 0)
776 goto esocregp;
777
778 pm_runtime_enable(&pdev->dev);
779
780 return ret;
781
782esocregp:
783 snd_soc_unregister_dais(&siu_i2s_dai, 1);
784edaiinit:
785 iounmap(info->reg);
786emapreg:
787 iounmap(info->yram);
788emapyram:
789 iounmap(info->xram);
790emapxram:
791 iounmap(info->pram);
792emappram:
793 release_mem_region(res->start, resource_size(res));
794ereqmemreg:
795egetres:
796ereqfw:
797 kfree(info);
798
799 return ret;
800}
801
802static int __devexit siu_remove(struct platform_device *pdev)
803{
804 struct siu_info *info = siu_i2s_dai.private_data;
805 struct resource *res;
806
807 pm_runtime_disable(&pdev->dev);
808
809 snd_soc_unregister_platform(&siu_platform);
810 snd_soc_unregister_dais(&siu_i2s_dai, 1);
811
812 iounmap(info->reg);
813 iounmap(info->yram);
814 iounmap(info->xram);
815 iounmap(info->pram);
816 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
817 if (res)
818 release_mem_region(res->start, resource_size(res));
819 kfree(info);
820
821 return 0;
822}
823
824static struct platform_driver siu_driver = {
825 .driver = {
826 .name = "sh_siu",
827 },
828 .probe = siu_probe,
829 .remove = __devexit_p(siu_remove),
830};
831
832static int __init siu_init(void)
833{
834 return platform_driver_register(&siu_driver);
835}
836
837static void __exit siu_exit(void)
838{
839 platform_driver_unregister(&siu_driver);
840}
841
842module_init(siu_init)
843module_exit(siu_exit)
844
845MODULE_AUTHOR("Carlos Munoz <carlos@kenati.com>");
846MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver");
847MODULE_LICENSE("GPL");
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
new file mode 100644
index 000000000000..c5efc30f0136
--- /dev/null
+++ b/sound/soc/sh/siu_pcm.c
@@ -0,0 +1,616 @@
1/*
2 * siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral.
3 *
4 * Copyright (C) 2009-2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
5 * Copyright (C) 2006 Carlos Munoz <carlos@kenati.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21#include <linux/delay.h>
22#include <linux/dma-mapping.h>
23#include <linux/dmaengine.h>
24#include <linux/interrupt.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/slab.h>
28
29#include <sound/control.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc-dai.h>
34
35#include <asm/dma-sh.h>
36#include <asm/siu.h>
37
38#include "siu.h"
39
40#define GET_MAX_PERIODS(buf_bytes, period_bytes) \
41 ((buf_bytes) / (period_bytes))
42#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \
43 ((buf_addr) + ((period_num) * (period_bytes)))
44
45#define RWF_STM_RD 0x01 /* Read in progress */
46#define RWF_STM_WT 0x02 /* Write in progress */
47
48struct siu_port *siu_ports[SIU_PORT_NUM];
49
50/* transfersize is number of u32 dma transfers per period */
51static int siu_pcm_stmwrite_stop(struct siu_port *port_info)
52{
53 struct siu_info *info = siu_i2s_dai.private_data;
54 u32 __iomem *base = info->reg;
55 struct siu_stream *siu_stream = &port_info->playback;
56 u32 stfifo;
57
58 if (!siu_stream->rw_flg)
59 return -EPERM;
60
61 /* output FIFO disable */
62 stfifo = siu_read32(base + SIU_STFIFO);
63 siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18);
64 pr_debug("%s: STFIFO %x -> %x\n", __func__,
65 stfifo, stfifo & ~0x0c180c18);
66
67 /* during stmwrite clear */
68 siu_stream->rw_flg = 0;
69
70 return 0;
71}
72
73static int siu_pcm_stmwrite_start(struct siu_port *port_info)
74{
75 struct siu_stream *siu_stream = &port_info->playback;
76
77 if (siu_stream->rw_flg)
78 return -EPERM;
79
80 /* Current period in buffer */
81 port_info->playback.cur_period = 0;
82
83 /* during stmwrite flag set */
84 siu_stream->rw_flg = RWF_STM_WT;
85
86 /* DMA transfer start */
87 tasklet_schedule(&siu_stream->tasklet);
88
89 return 0;
90}
91
92static void siu_dma_tx_complete(void *arg)
93{
94 struct siu_stream *siu_stream = arg;
95
96 if (!siu_stream->rw_flg)
97 return;
98
99 /* Update completed period count */
100 if (++siu_stream->cur_period >=
101 GET_MAX_PERIODS(siu_stream->buf_bytes,
102 siu_stream->period_bytes))
103 siu_stream->cur_period = 0;
104
105 pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n",
106 __func__, siu_stream->cur_period,
107 siu_stream->cur_period * siu_stream->period_bytes,
108 siu_stream->buf_bytes, siu_stream->cookie);
109
110 tasklet_schedule(&siu_stream->tasklet);
111
112 /* Notify alsa: a period is done */
113 snd_pcm_period_elapsed(siu_stream->substream);
114}
115
116static int siu_pcm_wr_set(struct siu_port *port_info,
117 dma_addr_t buff, u32 size)
118{
119 struct siu_info *info = siu_i2s_dai.private_data;
120 u32 __iomem *base = info->reg;
121 struct siu_stream *siu_stream = &port_info->playback;
122 struct snd_pcm_substream *substream = siu_stream->substream;
123 struct device *dev = substream->pcm->card->dev;
124 struct dma_async_tx_descriptor *desc;
125 dma_cookie_t cookie;
126 struct scatterlist sg;
127 u32 stfifo;
128
129 sg_init_table(&sg, 1);
130 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
131 size, offset_in_page(buff));
132 sg_dma_address(&sg) = buff;
133
134 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
135 &sg, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
136 if (!desc) {
137 dev_err(dev, "Failed to allocate a dma descriptor\n");
138 return -ENOMEM;
139 }
140
141 desc->callback = siu_dma_tx_complete;
142 desc->callback_param = siu_stream;
143 cookie = desc->tx_submit(desc);
144 if (cookie < 0) {
145 dev_err(dev, "Failed to submit a dma transfer\n");
146 return cookie;
147 }
148
149 siu_stream->tx_desc = desc;
150 siu_stream->cookie = cookie;
151
152 dma_async_issue_pending(siu_stream->chan);
153
154 /* only output FIFO enable */
155 stfifo = siu_read32(base + SIU_STFIFO);
156 siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18));
157 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
158 stfifo, stfifo | (port_info->stfifo & 0x0c180c18));
159
160 return 0;
161}
162
163static int siu_pcm_rd_set(struct siu_port *port_info,
164 dma_addr_t buff, size_t size)
165{
166 struct siu_info *info = siu_i2s_dai.private_data;
167 u32 __iomem *base = info->reg;
168 struct siu_stream *siu_stream = &port_info->capture;
169 struct snd_pcm_substream *substream = siu_stream->substream;
170 struct device *dev = substream->pcm->card->dev;
171 struct dma_async_tx_descriptor *desc;
172 dma_cookie_t cookie;
173 struct scatterlist sg;
174 u32 stfifo;
175
176 dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff);
177
178 sg_init_table(&sg, 1);
179 sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)),
180 size, offset_in_page(buff));
181 sg_dma_address(&sg) = buff;
182
183 desc = siu_stream->chan->device->device_prep_slave_sg(siu_stream->chan,
184 &sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
185 if (!desc) {
186 dev_err(dev, "Failed to allocate dma descriptor\n");
187 return -ENOMEM;
188 }
189
190 desc->callback = siu_dma_tx_complete;
191 desc->callback_param = siu_stream;
192 cookie = desc->tx_submit(desc);
193 if (cookie < 0) {
194 dev_err(dev, "Failed to submit dma descriptor\n");
195 return cookie;
196 }
197
198 siu_stream->tx_desc = desc;
199 siu_stream->cookie = cookie;
200
201 dma_async_issue_pending(siu_stream->chan);
202
203 /* only input FIFO enable */
204 stfifo = siu_read32(base + SIU_STFIFO);
205 siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) |
206 (port_info->stfifo & 0x13071307));
207 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
208 stfifo, stfifo | (port_info->stfifo & 0x13071307));
209
210 return 0;
211}
212
213static void siu_io_tasklet(unsigned long data)
214{
215 struct siu_stream *siu_stream = (struct siu_stream *)data;
216 struct snd_pcm_substream *substream = siu_stream->substream;
217 struct device *dev = substream->pcm->card->dev;
218 struct snd_pcm_runtime *rt = substream->runtime;
219 struct siu_port *port_info = siu_port_info(substream);
220
221 dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg);
222
223 if (!siu_stream->rw_flg) {
224 dev_dbg(dev, "%s: stream inactive\n", __func__);
225 return;
226 }
227
228 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
229 dma_addr_t buff;
230 size_t count;
231 u8 *virt;
232
233 buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
234 siu_stream->cur_period,
235 siu_stream->period_bytes);
236 virt = PERIOD_OFFSET(rt->dma_area,
237 siu_stream->cur_period,
238 siu_stream->period_bytes);
239 count = siu_stream->period_bytes;
240
241 /* DMA transfer start */
242 siu_pcm_rd_set(port_info, buff, count);
243 } else {
244 siu_pcm_wr_set(port_info,
245 (dma_addr_t)PERIOD_OFFSET(rt->dma_addr,
246 siu_stream->cur_period,
247 siu_stream->period_bytes),
248 siu_stream->period_bytes);
249 }
250}
251
252/* Capture */
253static int siu_pcm_stmread_start(struct siu_port *port_info)
254{
255 struct siu_stream *siu_stream = &port_info->capture;
256
257 if (siu_stream->xfer_cnt > 0x1000000)
258 return -EINVAL;
259 if (siu_stream->rw_flg)
260 return -EPERM;
261
262 /* Current period in buffer */
263 siu_stream->cur_period = 0;
264
265 /* during stmread flag set */
266 siu_stream->rw_flg = RWF_STM_RD;
267
268 tasklet_schedule(&siu_stream->tasklet);
269
270 return 0;
271}
272
273static int siu_pcm_stmread_stop(struct siu_port *port_info)
274{
275 struct siu_info *info = siu_i2s_dai.private_data;
276 u32 __iomem *base = info->reg;
277 struct siu_stream *siu_stream = &port_info->capture;
278 struct device *dev = siu_stream->substream->pcm->card->dev;
279 u32 stfifo;
280
281 if (!siu_stream->rw_flg)
282 return -EPERM;
283
284 /* input FIFO disable */
285 stfifo = siu_read32(base + SIU_STFIFO);
286 siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307);
287 dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__,
288 stfifo, stfifo & ~0x13071307);
289
290 /* during stmread flag clear */
291 siu_stream->rw_flg = 0;
292
293 return 0;
294}
295
296static int siu_pcm_hw_params(struct snd_pcm_substream *ss,
297 struct snd_pcm_hw_params *hw_params)
298{
299 struct siu_info *info = siu_i2s_dai.private_data;
300 struct device *dev = ss->pcm->card->dev;
301 int ret;
302
303 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
304
305 ret = snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
306 if (ret < 0)
307 dev_err(dev, "snd_pcm_lib_malloc_pages() failed\n");
308
309 return ret;
310}
311
312static int siu_pcm_hw_free(struct snd_pcm_substream *ss)
313{
314 struct siu_info *info = siu_i2s_dai.private_data;
315 struct siu_port *port_info = siu_port_info(ss);
316 struct device *dev = ss->pcm->card->dev;
317 struct siu_stream *siu_stream;
318
319 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
320 siu_stream = &port_info->playback;
321 else
322 siu_stream = &port_info->capture;
323
324 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
325
326 return snd_pcm_lib_free_pages(ss);
327}
328
329static bool filter(struct dma_chan *chan, void *slave)
330{
331 struct sh_dmae_slave *param = slave;
332
333 pr_debug("%s: slave ID %d\n", __func__, param->slave_id);
334
335 if (unlikely(param->dma_dev != chan->device->dev))
336 return false;
337
338 chan->private = param;
339 return true;
340}
341
342static int siu_pcm_open(struct snd_pcm_substream *ss)
343{
344 /* Playback / Capture */
345 struct siu_info *info = siu_i2s_dai.private_data;
346 struct siu_port *port_info = siu_port_info(ss);
347 struct siu_stream *siu_stream;
348 u32 port = info->port_id;
349 struct siu_platform *pdata = siu_i2s_dai.dev->platform_data;
350 struct device *dev = ss->pcm->card->dev;
351 dma_cap_mask_t mask;
352 struct sh_dmae_slave *param;
353
354 dma_cap_zero(mask);
355 dma_cap_set(DMA_SLAVE, mask);
356
357 dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info);
358
359 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
360 siu_stream = &port_info->playback;
361 param = &siu_stream->param;
362 param->slave_id = port ? SHDMA_SLAVE_SIUB_TX :
363 SHDMA_SLAVE_SIUA_TX;
364 } else {
365 siu_stream = &port_info->capture;
366 param = &siu_stream->param;
367 param->slave_id = port ? SHDMA_SLAVE_SIUB_RX :
368 SHDMA_SLAVE_SIUA_RX;
369 }
370
371 param->dma_dev = pdata->dma_dev;
372 /* Get DMA channel */
373 siu_stream->chan = dma_request_channel(mask, filter, param);
374 if (!siu_stream->chan) {
375 dev_err(dev, "DMA channel allocation failed!\n");
376 return -EBUSY;
377 }
378
379 siu_stream->substream = ss;
380
381 return 0;
382}
383
384static int siu_pcm_close(struct snd_pcm_substream *ss)
385{
386 struct siu_info *info = siu_i2s_dai.private_data;
387 struct device *dev = ss->pcm->card->dev;
388 struct siu_port *port_info = siu_port_info(ss);
389 struct siu_stream *siu_stream;
390
391 dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id);
392
393 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
394 siu_stream = &port_info->playback;
395 else
396 siu_stream = &port_info->capture;
397
398 dma_release_channel(siu_stream->chan);
399 siu_stream->chan = NULL;
400
401 siu_stream->substream = NULL;
402
403 return 0;
404}
405
406static int siu_pcm_prepare(struct snd_pcm_substream *ss)
407{
408 struct siu_info *info = siu_i2s_dai.private_data;
409 struct siu_port *port_info = siu_port_info(ss);
410 struct device *dev = ss->pcm->card->dev;
411 struct snd_pcm_runtime *rt = ss->runtime;
412 struct siu_stream *siu_stream;
413 snd_pcm_sframes_t xfer_cnt;
414
415 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
416 siu_stream = &port_info->playback;
417 else
418 siu_stream = &port_info->capture;
419
420 rt = siu_stream->substream->runtime;
421
422 siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss);
423 siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss);
424
425 dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__,
426 info->port_id, rt->channels, siu_stream->period_bytes);
427
428 /* We only support buffers that are multiples of the period */
429 if (siu_stream->buf_bytes % siu_stream->period_bytes) {
430 dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n",
431 __func__, siu_stream->buf_bytes,
432 siu_stream->period_bytes);
433 return -EINVAL;
434 }
435
436 xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes);
437 if (!xfer_cnt || xfer_cnt > 0x1000000)
438 return -EINVAL;
439
440 siu_stream->format = rt->format;
441 siu_stream->xfer_cnt = xfer_cnt;
442
443 dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d "
444 "format=%d channels=%d xfer_cnt=%d\n", info->port_id,
445 (unsigned long)rt->dma_addr, siu_stream->buf_bytes,
446 siu_stream->period_bytes,
447 siu_stream->format, rt->channels, (int)xfer_cnt);
448
449 return 0;
450}
451
452static int siu_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
453{
454 struct siu_info *info = siu_i2s_dai.private_data;
455 struct device *dev = ss->pcm->card->dev;
456 struct siu_port *port_info = siu_port_info(ss);
457 int ret;
458
459 dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__,
460 info->port_id, port_info, cmd);
461
462 switch (cmd) {
463 case SNDRV_PCM_TRIGGER_START:
464 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
465 ret = siu_pcm_stmwrite_start(port_info);
466 else
467 ret = siu_pcm_stmread_start(port_info);
468
469 if (ret < 0)
470 dev_warn(dev, "%s: start failed on port=%d\n",
471 __func__, info->port_id);
472
473 break;
474 case SNDRV_PCM_TRIGGER_STOP:
475 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
476 siu_pcm_stmwrite_stop(port_info);
477 else
478 siu_pcm_stmread_stop(port_info);
479 ret = 0;
480
481 break;
482 default:
483 dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd);
484 ret = -EINVAL;
485 }
486
487 return ret;
488}
489
490/*
491 * So far only resolution of one period is supported, subject to extending the
492 * dmangine API
493 */
494static snd_pcm_uframes_t siu_pcm_pointer_dma(struct snd_pcm_substream *ss)
495{
496 struct device *dev = ss->pcm->card->dev;
497 struct siu_info *info = siu_i2s_dai.private_data;
498 u32 __iomem *base = info->reg;
499 struct siu_port *port_info = siu_port_info(ss);
500 struct snd_pcm_runtime *rt = ss->runtime;
501 size_t ptr;
502 struct siu_stream *siu_stream;
503
504 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
505 siu_stream = &port_info->playback;
506 else
507 siu_stream = &port_info->capture;
508
509 /*
510 * ptr is the offset into the buffer where the dma is currently at. We
511 * check if the dma buffer has just wrapped.
512 */
513 ptr = PERIOD_OFFSET(rt->dma_addr,
514 siu_stream->cur_period,
515 siu_stream->period_bytes) - rt->dma_addr;
516
517 dev_dbg(dev,
518 "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n",
519 __func__, info->port_id, siu_read32(base + SIU_EVNTC),
520 siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes,
521 siu_stream->cookie);
522
523 if (ptr >= siu_stream->buf_bytes)
524 ptr = 0;
525
526 return bytes_to_frames(ss->runtime, ptr);
527}
528
529static int siu_pcm_new(struct snd_card *card, struct snd_soc_dai *dai,
530 struct snd_pcm *pcm)
531{
532 /* card->dev == socdev->dev, see snd_soc_new_pcms() */
533 struct siu_info *info = siu_i2s_dai.private_data;
534 struct platform_device *pdev = to_platform_device(card->dev);
535 int ret;
536 int i;
537
538 /* pdev->id selects between SIUA and SIUB */
539 if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM)
540 return -EINVAL;
541
542 info->port_id = pdev->id;
543
544 /*
545 * While the siu has 2 ports, only one port can be on at a time (only 1
546 * SPB). So far all the boards using the siu had only one of the ports
547 * wired to a codec. To simplify things, we only register one port with
548 * alsa. In case both ports are needed, it should be changed here
549 */
550 for (i = pdev->id; i < pdev->id + 1; i++) {
551 struct siu_port **port_info = &siu_ports[i];
552
553 ret = siu_init_port(i, port_info, card);
554 if (ret < 0)
555 return ret;
556
557 ret = snd_pcm_lib_preallocate_pages_for_all(pcm,
558 SNDRV_DMA_TYPE_DEV, NULL,
559 SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX);
560 if (ret < 0) {
561 dev_err(card->dev,
562 "snd_pcm_lib_preallocate_pages_for_all() err=%d",
563 ret);
564 goto fail;
565 }
566
567 (*port_info)->pcm = pcm;
568
569 /* IO tasklets */
570 tasklet_init(&(*port_info)->playback.tasklet, siu_io_tasklet,
571 (unsigned long)&(*port_info)->playback);
572 tasklet_init(&(*port_info)->capture.tasklet, siu_io_tasklet,
573 (unsigned long)&(*port_info)->capture);
574 }
575
576 dev_info(card->dev, "SuperH SIU driver initialized.\n");
577 return 0;
578
579fail:
580 siu_free_port(siu_ports[pdev->id]);
581 dev_err(card->dev, "SIU: failed to initialize.\n");
582 return ret;
583}
584
585static void siu_pcm_free(struct snd_pcm *pcm)
586{
587 struct platform_device *pdev = to_platform_device(pcm->card->dev);
588 struct siu_port *port_info = siu_ports[pdev->id];
589
590 tasklet_kill(&port_info->capture.tasklet);
591 tasklet_kill(&port_info->playback.tasklet);
592
593 siu_free_port(port_info);
594 snd_pcm_lib_preallocate_free_for_all(pcm);
595
596 dev_dbg(pcm->card->dev, "%s\n", __func__);
597}
598
599static struct snd_pcm_ops siu_pcm_ops = {
600 .open = siu_pcm_open,
601 .close = siu_pcm_close,
602 .ioctl = snd_pcm_lib_ioctl,
603 .hw_params = siu_pcm_hw_params,
604 .hw_free = siu_pcm_hw_free,
605 .prepare = siu_pcm_prepare,
606 .trigger = siu_pcm_trigger,
607 .pointer = siu_pcm_pointer_dma,
608};
609
610struct snd_soc_platform siu_platform = {
611 .name = "siu-audio",
612 .pcm_ops = &siu_pcm_ops,
613 .pcm_new = siu_pcm_new,
614 .pcm_free = siu_pcm_free,
615};
616EXPORT_SYMBOL_GPL(siu_platform);
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d2505e8b06c9..5869dc3be781 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -15,6 +15,74 @@
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18static unsigned int snd_soc_4_12_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_4_12_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 << 4) | ((value >> 8) & 0x000f);
37 data[1] = value & 0x00ff;
38
39 if (reg < codec->reg_cache_size)
40 cache[reg] = value;
41
42 if (codec->cache_only) {
43 codec->cache_sync = 1;
44 return 0;
45 }
46
47 ret = codec->hw_write(codec->control_data, data, 2);
48 if (ret == 2)
49 return 0;
50 if (ret < 0)
51 return ret;
52 else
53 return -EIO;
54}
55
56#if defined(CONFIG_SPI_MASTER)
57static int snd_soc_4_12_spi_write(void *control_data, const char *data,
58 int len)
59{
60 struct spi_device *spi = control_data;
61 struct spi_transfer t;
62 struct spi_message m;
63 u8 msg[2];
64
65 if (len <= 0)
66 return 0;
67
68 msg[0] = data[1];
69 msg[1] = data[0];
70
71 spi_message_init(&m);
72 memset(&t, 0, (sizeof t));
73
74 t.tx_buf = &msg[0];
75 t.len = len;
76
77 spi_message_add_tail(&t, &m);
78 spi_sync(spi, &m);
79
80 return len;
81}
82#else
83#define snd_soc_4_12_spi_write NULL
84#endif
85
18static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 86static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
19 unsigned int reg) 87 unsigned int reg)
20{ 88{
@@ -38,6 +106,12 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
38 106
39 if (reg < codec->reg_cache_size) 107 if (reg < codec->reg_cache_size)
40 cache[reg] = value; 108 cache[reg] = value;
109
110 if (codec->cache_only) {
111 codec->cache_sync = 1;
112 return 0;
113 }
114
41 ret = codec->hw_write(codec->control_data, data, 2); 115 ret = codec->hw_write(codec->control_data, data, 2);
42 if (ret == 2) 116 if (ret == 2)
43 return 0; 117 return 0;
@@ -91,6 +165,11 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
91 if (reg < codec->reg_cache_size) 165 if (reg < codec->reg_cache_size)
92 cache[reg] = value; 166 cache[reg] = value;
93 167
168 if (codec->cache_only) {
169 codec->cache_sync = 1;
170 return 0;
171 }
172
94 if (codec->hw_write(codec->control_data, data, 2) == 2) 173 if (codec->hw_write(codec->control_data, data, 2) == 2)
95 return 0; 174 return 0;
96 else 175 else
@@ -119,6 +198,11 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
119 if (!snd_soc_codec_volatile_register(codec, reg)) 198 if (!snd_soc_codec_volatile_register(codec, reg))
120 reg_cache[reg] = value; 199 reg_cache[reg] = value;
121 200
201 if (codec->cache_only) {
202 codec->cache_sync = 1;
203 return 0;
204 }
205
122 if (codec->hw_write(codec->control_data, data, 3) == 3) 206 if (codec->hw_write(codec->control_data, data, 3) == 3)
123 return 0; 207 return 0;
124 else 208 else
@@ -131,10 +215,14 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
131 u16 *cache = codec->reg_cache; 215 u16 *cache = codec->reg_cache;
132 216
133 if (reg >= codec->reg_cache_size || 217 if (reg >= codec->reg_cache_size ||
134 snd_soc_codec_volatile_register(codec, reg)) 218 snd_soc_codec_volatile_register(codec, reg)) {
219 if (codec->cache_only)
220 return -EINVAL;
221
135 return codec->hw_read(codec, reg); 222 return codec->hw_read(codec, reg);
136 else 223 } else {
137 return cache[reg]; 224 return cache[reg];
225 }
138} 226}
139 227
140#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) 228#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
@@ -171,6 +259,114 @@ static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec,
171#define snd_soc_8_16_read_i2c NULL 259#define snd_soc_8_16_read_i2c NULL
172#endif 260#endif
173 261
262#if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE))
263static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
264 unsigned int r)
265{
266 struct i2c_msg xfer[2];
267 u16 reg = r;
268 u8 data;
269 int ret;
270 struct i2c_client *client = codec->control_data;
271
272 /* Write register */
273 xfer[0].addr = client->addr;
274 xfer[0].flags = 0;
275 xfer[0].len = 2;
276 xfer[0].buf = (u8 *)&reg;
277
278 /* Read data */
279 xfer[1].addr = client->addr;
280 xfer[1].flags = I2C_M_RD;
281 xfer[1].len = 1;
282 xfer[1].buf = &data;
283
284 ret = i2c_transfer(client->adapter, xfer, 2);
285 if (ret != 2) {
286 dev_err(&client->dev, "i2c_transfer() returned %d\n", ret);
287 return 0;
288 }
289
290 return data;
291}
292#else
293#define snd_soc_16_8_read_i2c NULL
294#endif
295
296static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
297 unsigned int reg)
298{
299 u16 *cache = codec->reg_cache;
300
301 reg &= 0xff;
302 if (reg >= codec->reg_cache_size)
303 return -1;
304 return cache[reg];
305}
306
307static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
308 unsigned int value)
309{
310 u16 *cache = codec->reg_cache;
311 u8 data[3];
312 int ret;
313
314 BUG_ON(codec->volatile_register);
315
316 data[0] = (reg >> 8) & 0xff;
317 data[1] = reg & 0xff;
318 data[2] = value;
319
320 reg &= 0xff;
321 if (reg < codec->reg_cache_size)
322 cache[reg] = value;
323
324 if (codec->cache_only) {
325 codec->cache_sync = 1;
326 return 0;
327 }
328
329 ret = codec->hw_write(codec->control_data, data, 3);
330 if (ret == 3)
331 return 0;
332 if (ret < 0)
333 return ret;
334 else
335 return -EIO;
336}
337
338#if defined(CONFIG_SPI_MASTER)
339static int snd_soc_16_8_spi_write(void *control_data, const char *data,
340 int len)
341{
342 struct spi_device *spi = control_data;
343 struct spi_transfer t;
344 struct spi_message m;
345 u8 msg[3];
346
347 if (len <= 0)
348 return 0;
349
350 msg[0] = data[0];
351 msg[1] = data[1];
352 msg[2] = data[2];
353
354 spi_message_init(&m);
355 memset(&t, 0, (sizeof t));
356
357 t.tx_buf = &msg[0];
358 t.len = len;
359
360 spi_message_add_tail(&t, &m);
361 spi_sync(spi, &m);
362
363 return len;
364}
365#else
366#define snd_soc_16_8_spi_write NULL
367#endif
368
369
174static struct { 370static struct {
175 int addr_bits; 371 int addr_bits;
176 int data_bits; 372 int data_bits;
@@ -180,9 +376,14 @@ static struct {
180 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 376 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
181} io_types[] = { 377} io_types[] = {
182 { 378 {
379 .addr_bits = 4, .data_bits = 12,
380 .write = snd_soc_4_12_write, .read = snd_soc_4_12_read,
381 .spi_write = snd_soc_4_12_spi_write,
382 },
383 {
183 .addr_bits = 7, .data_bits = 9, 384 .addr_bits = 7, .data_bits = 9,
184 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read, 385 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
185 .spi_write = snd_soc_7_9_spi_write 386 .spi_write = snd_soc_7_9_spi_write,
186 }, 387 },
187 { 388 {
188 .addr_bits = 8, .data_bits = 8, 389 .addr_bits = 8, .data_bits = 8,
@@ -193,6 +394,12 @@ static struct {
193 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read, 394 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
194 .i2c_read = snd_soc_8_16_read_i2c, 395 .i2c_read = snd_soc_8_16_read_i2c,
195 }, 396 },
397 {
398 .addr_bits = 16, .data_bits = 8,
399 .write = snd_soc_16_8_write, .read = snd_soc_16_8_read,
400 .i2c_read = snd_soc_16_8_read_i2c,
401 .spi_write = snd_soc_16_8_spi_write,
402 },
196}; 403};
197 404
198/** 405/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 0a6440c6f54a..c8b0556ef431 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -130,6 +130,29 @@ static ssize_t codec_reg_show(struct device *dev,
130 130
131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
132 132
133static ssize_t pmdown_time_show(struct device *dev,
134 struct device_attribute *attr, char *buf)
135{
136 struct snd_soc_device *socdev = dev_get_drvdata(dev);
137 struct snd_soc_card *card = socdev->card;
138
139 return sprintf(buf, "%ld\n", card->pmdown_time);
140}
141
142static ssize_t pmdown_time_set(struct device *dev,
143 struct device_attribute *attr,
144 const char *buf, size_t count)
145{
146 struct snd_soc_device *socdev = dev_get_drvdata(dev);
147 struct snd_soc_card *card = socdev->card;
148
149 strict_strtol(buf, 10, &card->pmdown_time);
150
151 return count;
152}
153
154static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
155
133#ifdef CONFIG_DEBUG_FS 156#ifdef CONFIG_DEBUG_FS
134static int codec_reg_open_file(struct inode *inode, struct file *file) 157static int codec_reg_open_file(struct inode *inode, struct file *file)
135{ 158{
@@ -404,24 +427,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
404 if (!runtime->hw.rates) { 427 if (!runtime->hw.rates) {
405 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n", 428 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
406 codec_dai->name, cpu_dai->name); 429 codec_dai->name, cpu_dai->name);
407 goto machine_err; 430 goto config_err;
408 } 431 }
409 if (!runtime->hw.formats) { 432 if (!runtime->hw.formats) {
410 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n", 433 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
411 codec_dai->name, cpu_dai->name); 434 codec_dai->name, cpu_dai->name);
412 goto machine_err; 435 goto config_err;
413 } 436 }
414 if (!runtime->hw.channels_min || !runtime->hw.channels_max) { 437 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
415 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n", 438 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
416 codec_dai->name, cpu_dai->name); 439 codec_dai->name, cpu_dai->name);
417 goto machine_err; 440 goto config_err;
418 } 441 }
419 442
420 /* Symmetry only applies if we've already got an active stream. */ 443 /* Symmetry only applies if we've already got an active stream. */
421 if (cpu_dai->active || codec_dai->active) { 444 if (cpu_dai->active || codec_dai->active) {
422 ret = soc_pcm_apply_symmetry(substream); 445 ret = soc_pcm_apply_symmetry(substream);
423 if (ret != 0) 446 if (ret != 0)
424 goto machine_err; 447 goto config_err;
425 } 448 }
426 449
427 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 450 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -441,10 +464,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
441 mutex_unlock(&pcm_mutex); 464 mutex_unlock(&pcm_mutex);
442 return 0; 465 return 0;
443 466
444machine_err: 467config_err:
445 if (machine->ops && machine->ops->shutdown) 468 if (machine->ops && machine->ops->shutdown)
446 machine->ops->shutdown(substream); 469 machine->ops->shutdown(substream);
447 470
471machine_err:
472 if (codec_dai->ops->shutdown)
473 codec_dai->ops->shutdown(substream, codec_dai);
474
448codec_dai_err: 475codec_dai_err:
449 if (platform->pcm_ops->close) 476 if (platform->pcm_ops->close)
450 platform->pcm_ops->close(substream); 477 platform->pcm_ops->close(substream);
@@ -542,7 +569,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
542 /* start delayed pop wq here for playback streams */ 569 /* start delayed pop wq here for playback streams */
543 codec_dai->pop_wait = 1; 570 codec_dai->pop_wait = 1;
544 schedule_delayed_work(&card->delayed_work, 571 schedule_delayed_work(&card->delayed_work,
545 msecs_to_jiffies(pmdown_time)); 572 msecs_to_jiffies(card->pmdown_time));
546 } else { 573 } else {
547 /* capture streams can be powered down now */ 574 /* capture streams can be powered down now */
548 snd_soc_dapm_stream_event(codec, 575 snd_soc_dapm_stream_event(codec,
@@ -940,6 +967,12 @@ static int soc_resume(struct device *dev)
940 struct snd_soc_card *card = socdev->card; 967 struct snd_soc_card *card = socdev->card;
941 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai; 968 struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
942 969
970 /* If the initialization of this soc device failed, there is no codec
971 * associated with it. Just bail out in this case.
972 */
973 if (!card->codec)
974 return 0;
975
943 /* AC97 devices might have other drivers hanging off them so 976 /* AC97 devices might have other drivers hanging off them so
944 * need to resume immediately. Other drivers don't have that 977 * need to resume immediately. Other drivers don't have that
945 * problem and may take a substantial amount of time to resume 978 * problem and may take a substantial amount of time to resume
@@ -1039,6 +1072,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1039 dev_dbg(card->dev, "All components present, instantiating\n"); 1072 dev_dbg(card->dev, "All components present, instantiating\n");
1040 1073
1041 /* Found everything, bring it up */ 1074 /* Found everything, bring it up */
1075 card->pmdown_time = pmdown_time;
1076
1042 if (card->probe) { 1077 if (card->probe) {
1043 ret = card->probe(pdev); 1078 ret = card->probe(pdev);
1044 if (ret < 0) 1079 if (ret < 0)
@@ -1122,6 +1157,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1122 if (ret < 0) 1157 if (ret < 0)
1123 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n"); 1158 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1124 1159
1160 ret = device_create_file(card->socdev->dev, &dev_attr_pmdown_time);
1161 if (ret < 0)
1162 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1163
1125 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg); 1164 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
1126 if (ret < 0) 1165 if (ret < 0)
1127 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1166 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
@@ -1276,8 +1315,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
1276 codec_dai->codec = card->codec; 1315 codec_dai->codec = card->codec;
1277 1316
1278 /* check client and interface hw capabilities */ 1317 /* check client and interface hw capabilities */
1279 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name, 1318 snprintf(new_name, sizeof(new_name), "%s %s-%d",
1280 num); 1319 dai_link->stream_name, codec_dai->name, num);
1281 1320
1282 if (codec_dai->playback.channels_min) 1321 if (codec_dai->playback.channels_min)
1283 playback = 1; 1322 playback = 1;
@@ -1368,6 +1407,7 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1368 1407
1369 codec->ac97->bus->ops = ops; 1408 codec->ac97->bus->ops = ops;
1370 codec->ac97->num = num; 1409 codec->ac97->num = num;
1410 codec->dev = &codec->ac97->dev;
1371 mutex_unlock(&codec->mutex); 1411 mutex_unlock(&codec->mutex);
1372 return 0; 1412 return 0;
1373} 1413}
@@ -1427,9 +1467,9 @@ EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1427 * 1467 *
1428 * Returns 1 for change else 0. 1468 * Returns 1 for change else 0.
1429 */ 1469 */
1430static int snd_soc_update_bits_locked(struct snd_soc_codec *codec, 1470int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1431 unsigned short reg, unsigned int mask, 1471 unsigned short reg, unsigned int mask,
1432 unsigned int value) 1472 unsigned int value)
1433{ 1473{
1434 int change; 1474 int change;
1435 1475
@@ -1439,6 +1479,7 @@ static int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1439 1479
1440 return change; 1480 return change;
1441} 1481}
1482EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
1442 1483
1443/** 1484/**
1444 * snd_soc_test_bits - test register for change 1485 * snd_soc_test_bits - test register for change
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 0d294ef72590..6c3351095786 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -44,13 +44,6 @@
44#include <sound/soc-dapm.h> 44#include <sound/soc-dapm.h>
45#include <sound/initval.h> 45#include <sound/initval.h>
46 46
47/* debug */
48#ifdef DEBUG
49#define dump_dapm(codec, action) dbg_dump_dapm(codec, action)
50#else
51#define dump_dapm(codec, action)
52#endif
53
54/* dapm power sequences - make this per codec in the future */ 47/* dapm power sequences - make this per codec in the future */
55static int dapm_up_seq[] = { 48static int dapm_up_seq[] = {
56 [snd_soc_dapm_pre] = 0, 49 [snd_soc_dapm_pre] = 0,
@@ -739,6 +732,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
739 struct snd_soc_dapm_widget *b, 732 struct snd_soc_dapm_widget *b,
740 int sort[]) 733 int sort[])
741{ 734{
735 if (a->codec != b->codec)
736 return (unsigned long)a - (unsigned long)b;
742 if (sort[a->id] != sort[b->id]) 737 if (sort[a->id] != sort[b->id])
743 return sort[a->id] - sort[b->id]; 738 return sort[a->id] - sort[b->id];
744 if (a->reg != b->reg) 739 if (a->reg != b->reg)
@@ -1017,13 +1012,28 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1017 sys_power = 0; 1012 sys_power = 0;
1018 break; 1013 break;
1019 case SND_SOC_DAPM_STREAM_NOP: 1014 case SND_SOC_DAPM_STREAM_NOP:
1020 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; 1015 switch (codec->bias_level) {
1016 case SND_SOC_BIAS_STANDBY:
1017 case SND_SOC_BIAS_OFF:
1018 sys_power = 0;
1019 break;
1020 default:
1021 sys_power = 1;
1022 break;
1023 }
1021 break; 1024 break;
1022 default: 1025 default:
1023 break; 1026 break;
1024 } 1027 }
1025 } 1028 }
1026 1029
1030 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) {
1031 ret = snd_soc_dapm_set_bias_level(socdev,
1032 SND_SOC_BIAS_STANDBY);
1033 if (ret != 0)
1034 pr_err("Failed to turn on bias: %d\n", ret);
1035 }
1036
1027 /* If we're changing to all on or all off then prepare */ 1037 /* If we're changing to all on or all off then prepare */
1028 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1038 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) ||
1029 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1039 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) {
@@ -1047,6 +1057,14 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1047 pr_err("Failed to apply standby bias: %d\n", ret); 1057 pr_err("Failed to apply standby bias: %d\n", ret);
1048 } 1058 }
1049 1059
1060 /* If we're in standby and can support bias off then do that */
1061 if (codec->bias_level == SND_SOC_BIAS_STANDBY &&
1062 codec->idle_bias_off) {
1063 ret = snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_OFF);
1064 if (ret != 0)
1065 pr_err("Failed to turn off bias: %d\n", ret);
1066 }
1067
1050 /* If we just powered up then move to active bias */ 1068 /* If we just powered up then move to active bias */
1051 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1069 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) {
1052 ret = snd_soc_dapm_set_bias_level(socdev, 1070 ret = snd_soc_dapm_set_bias_level(socdev,
@@ -1061,66 +1079,6 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
1061 return 0; 1079 return 0;
1062} 1080}
1063 1081
1064#ifdef DEBUG
1065static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action)
1066{
1067 struct snd_soc_dapm_widget *w;
1068 struct snd_soc_dapm_path *p = NULL;
1069 int in, out;
1070
1071 printk("DAPM %s %s\n", codec->name, action);
1072
1073 list_for_each_entry(w, &codec->dapm_widgets, list) {
1074
1075 /* only display widgets that effect routing */
1076 switch (w->id) {
1077 case snd_soc_dapm_pre:
1078 case snd_soc_dapm_post:
1079 case snd_soc_dapm_vmid:
1080 continue;
1081 case snd_soc_dapm_mux:
1082 case snd_soc_dapm_value_mux:
1083 case snd_soc_dapm_output:
1084 case snd_soc_dapm_input:
1085 case snd_soc_dapm_switch:
1086 case snd_soc_dapm_hp:
1087 case snd_soc_dapm_mic:
1088 case snd_soc_dapm_spk:
1089 case snd_soc_dapm_line:
1090 case snd_soc_dapm_micbias:
1091 case snd_soc_dapm_dac:
1092 case snd_soc_dapm_adc:
1093 case snd_soc_dapm_pga:
1094 case snd_soc_dapm_mixer:
1095 case snd_soc_dapm_mixer_named_ctl:
1096 case snd_soc_dapm_supply:
1097 case snd_soc_dapm_aif_in:
1098 case snd_soc_dapm_aif_out:
1099 if (w->name) {
1100 in = is_connected_input_ep(w);
1101 dapm_clear_walk(w->codec);
1102 out = is_connected_output_ep(w);
1103 dapm_clear_walk(w->codec);
1104 printk("%s: %s in %d out %d\n", w->name,
1105 w->power ? "On":"Off",in, out);
1106
1107 list_for_each_entry(p, &w->sources, list_sink) {
1108 if (p->connect)
1109 printk(" in %s %s\n", p->name ? p->name : "static",
1110 p->source->name);
1111 }
1112 list_for_each_entry(p, &w->sinks, list_source) {
1113 if (p->connect)
1114 printk(" out %s %s\n", p->name ? p->name : "static",
1115 p->sink->name);
1116 }
1117 }
1118 break;
1119 }
1120 }
1121}
1122#endif
1123
1124#ifdef CONFIG_DEBUG_FS 1082#ifdef CONFIG_DEBUG_FS
1125static int dapm_widget_power_open_file(struct inode *inode, struct file *file) 1083static int dapm_widget_power_open_file(struct inode *inode, struct file *file)
1126{ 1084{
@@ -1147,9 +1105,16 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1147 out = is_connected_output_ep(w); 1105 out = is_connected_output_ep(w);
1148 dapm_clear_walk(w->codec); 1106 dapm_clear_walk(w->codec);
1149 1107
1150 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d\n", 1108 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
1151 w->name, w->power ? "On" : "Off", in, out); 1109 w->name, w->power ? "On" : "Off", in, out);
1152 1110
1111 if (w->reg >= 0)
1112 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1113 " - R%d(0x%x) bit %d",
1114 w->reg, w->reg, w->shift);
1115
1116 ret += snprintf(buf + ret, PAGE_SIZE - ret, "\n");
1117
1153 if (w->sname) 1118 if (w->sname)
1154 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n", 1119 ret += snprintf(buf + ret, PAGE_SIZE - ret, " stream %s %s\n",
1155 w->sname, 1120 w->sname,
@@ -1245,18 +1210,15 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1245 path->connect = 0; /* old connection must be powered down */ 1210 path->connect = 0; /* old connection must be powered down */
1246 } 1211 }
1247 1212
1248 if (found) { 1213 if (found)
1249 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1214 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1250 dump_dapm(widget->codec, "mux power update");
1251 }
1252 1215
1253 return 0; 1216 return 0;
1254} 1217}
1255 1218
1256/* test and update the power status of a mixer or switch widget */ 1219/* test and update the power status of a mixer or switch widget */
1257static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, 1220static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1258 struct snd_kcontrol *kcontrol, int reg, 1221 struct snd_kcontrol *kcontrol, int connect)
1259 int val_mask, int val, int invert)
1260{ 1222{
1261 struct snd_soc_dapm_path *path; 1223 struct snd_soc_dapm_path *path;
1262 int found = 0; 1224 int found = 0;
@@ -1266,9 +1228,6 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1266 widget->id != snd_soc_dapm_switch) 1228 widget->id != snd_soc_dapm_switch)
1267 return -ENODEV; 1229 return -ENODEV;
1268 1230
1269 if (!snd_soc_test_bits(widget->codec, reg, val_mask, val))
1270 return 0;
1271
1272 /* find dapm widget path assoc with kcontrol */ 1231 /* find dapm widget path assoc with kcontrol */
1273 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1232 list_for_each_entry(path, &widget->codec->dapm_paths, list) {
1274 if (path->kcontrol != kcontrol) 1233 if (path->kcontrol != kcontrol)
@@ -1276,19 +1235,12 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1276 1235
1277 /* found, now check type */ 1236 /* found, now check type */
1278 found = 1; 1237 found = 1;
1279 if (val) 1238 path->connect = connect;
1280 /* new connection */
1281 path->connect = invert ? 0:1;
1282 else
1283 /* old connection must be powered down */
1284 path->connect = invert ? 1:0;
1285 break; 1239 break;
1286 } 1240 }
1287 1241
1288 if (found) { 1242 if (found)
1289 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1243 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
1290 dump_dapm(widget->codec, "mixer power update");
1291 }
1292 1244
1293 return 0; 1245 return 0;
1294} 1246}
@@ -1404,9 +1356,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1404 */ 1356 */
1405int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1357int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1406{ 1358{
1407 int ret = dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1359 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP);
1408 dump_dapm(codec, "sync");
1409 return ret;
1410} 1360}
1411EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1361EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1412 1362
@@ -1688,6 +1638,7 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1688 unsigned int mask = (1 << fls(max)) - 1; 1638 unsigned int mask = (1 << fls(max)) - 1;
1689 unsigned int invert = mc->invert; 1639 unsigned int invert = mc->invert;
1690 unsigned int val, val2, val_mask; 1640 unsigned int val, val2, val_mask;
1641 int connect;
1691 int ret; 1642 int ret;
1692 1643
1693 val = (ucontrol->value.integer.value[0] & mask); 1644 val = (ucontrol->value.integer.value[0] & mask);
@@ -1714,7 +1665,17 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1714 return 1; 1665 return 1;
1715 } 1666 }
1716 1667
1717 dapm_mixer_update_power(widget, kcontrol, reg, val_mask, val, invert); 1668 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
1669 if (val)
1670 /* new connection */
1671 connect = invert ? 0:1;
1672 else
1673 /* old connection must be powered down */
1674 connect = invert ? 1:0;
1675
1676 dapm_mixer_update_power(widget, kcontrol, connect);
1677 }
1678
1718 if (widget->event) { 1679 if (widget->event) {
1719 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1680 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1720 ret = widget->event(widget, kcontrol, 1681 ret = widget->event(widget, kcontrol,
@@ -2152,7 +2113,6 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2152 2113
2153 dapm_power_widgets(codec, event); 2114 dapm_power_widgets(codec, event);
2154 mutex_unlock(&codec->mutex); 2115 mutex_unlock(&codec->mutex);
2155 dump_dapm(codec, __func__);
2156 return 0; 2116 return 0;
2157} 2117}
2158EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); 2118EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index ddc584b64871..4b91d8cf00ec 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -705,7 +705,7 @@ static void print_mapped_keys(void)
705 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); 705 fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0);
706 706
707 fprintf(stdout, 707 fprintf(stdout,
708 "\t[K] hide kernel_symbols symbols. \t(%s)\n", 708 "\t[K] hide kernel_symbols symbols. \t(%s)\n",
709 hide_kernel_symbols ? "yes" : "no"); 709 hide_kernel_symbols ? "yes" : "no");
710 fprintf(stdout, 710 fprintf(stdout,
711 "\t[U] hide user symbols. \t(%s)\n", 711 "\t[U] hide user symbols. \t(%s)\n",
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index bb0fd6da2d56..8a9e6baa3099 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -295,10 +295,10 @@ void thread__find_addr_location(struct thread *self,
295 al->thread = self; 295 al->thread = self;
296 al->addr = addr; 296 al->addr = addr;
297 297
298 if (cpumode & PERF_RECORD_MISC_KERNEL) { 298 if (cpumode == PERF_RECORD_MISC_KERNEL) {
299 al->level = 'k'; 299 al->level = 'k';
300 mg = &session->kmaps; 300 mg = &session->kmaps;
301 } else if (cpumode & PERF_RECORD_MISC_USER) 301 } else if (cpumode == PERF_RECORD_MISC_USER)
302 al->level = '.'; 302 al->level = '.';
303 else { 303 else {
304 al->level = 'H'; 304 al->level = 'H';
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 29465d440043..fde17b090a47 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -272,6 +272,7 @@ int synthesize_perf_probe_point(struct probe_point *pp)
272 int ret; 272 int ret;
273 273
274 pp->probes[0] = buf = zalloc(MAX_CMDLEN); 274 pp->probes[0] = buf = zalloc(MAX_CMDLEN);
275 pp->found = 1;
275 if (!buf) 276 if (!buf)
276 die("Failed to allocate memory by zalloc."); 277 die("Failed to allocate memory by zalloc.");
277 if (pp->offset) { 278 if (pp->offset) {
@@ -294,6 +295,7 @@ int synthesize_perf_probe_point(struct probe_point *pp)
294error: 295error:
295 free(pp->probes[0]); 296 free(pp->probes[0]);
296 pp->probes[0] = NULL; 297 pp->probes[0] = NULL;
298 pp->found = 0;
297 } 299 }
298 return ret; 300 return ret;
299} 301}
@@ -455,6 +457,7 @@ void show_perf_probe_events(void)
455 struct strlist *rawlist; 457 struct strlist *rawlist;
456 struct str_node *ent; 458 struct str_node *ent;
457 459
460 memset(&pp, 0, sizeof(pp));
458 fd = open_kprobe_events(O_RDONLY, 0); 461 fd = open_kprobe_events(O_RDONLY, 0);
459 rawlist = get_trace_kprobe_event_rawlist(fd); 462 rawlist = get_trace_kprobe_event_rawlist(fd);
460 close(fd); 463 close(fd);