Merge branch 'fix/asoc' into topic/asoc
authorTakashi Iwai <tiwai@suse.de>
Fri, 19 Dec 2008 14:36:58 +0000 (15:36 +0100)
committerTakashi Iwai <tiwai@suse.de>
Fri, 19 Dec 2008 14:36:58 +0000 (15:36 +0100)
356 files changed:
Documentation/cpu-freq/user-guide.txt
Documentation/filesystems/ramfs-rootfs-initramfs.txt
Documentation/input/input-programming.txt
Documentation/sound/alsa/ALSA-Configuration.txt
Documentation/sound/alsa/soc/machine.txt
Documentation/tracers/mmiotrace.txt
MAINTAINERS
arch/Kconfig
arch/alpha/kernel/pci.c
arch/alpha/kernel/smp.c
arch/alpha/kernel/traps.c
arch/arm/configs/corgi_defconfig
arch/arm/mach-pxa/include/mach/palmasoc.h [new file with mode: 0644]
arch/arm/mach-pxa/include/mach/pxafb.h
arch/arm/mach-pxa/mioa701.c
arch/arm/mach-pxa/mioa701_bootresume.S
arch/arm/mach-pxa/palmtx.c
arch/arm/mach-pxa/pcm990-baseboard.c
arch/arm/mach-pxa/reset.c
arch/arm/mach-pxa/spitz.c
arch/arm/plat-omap/gpio.c
arch/arm/plat-omap/include/mach/pm.h
arch/ia64/include/asm/ptrace.h
arch/ia64/sn/kernel/io_init.c
arch/m32r/kernel/head.S
arch/m32r/kernel/vmlinux.lds.S
arch/mips/include/asm/bug.h
arch/mips/include/asm/ptrace.h
arch/mn10300/kernel/gdb-stub.c
arch/parisc/include/asm/parisc-device.h
arch/parisc/include/asm/posix_types.h
arch/parisc/include/asm/ptrace.h
arch/parisc/kernel/drivers.c
arch/parisc/kernel/traps.c
arch/powerpc/boot/dts/mpc832x_rdb.dts
arch/powerpc/boot/dts/mpc8572ds.dts
arch/powerpc/configs/40x/virtex_defconfig [new file with mode: 0644]
arch/powerpc/configs/44x/virtex5_defconfig
arch/powerpc/configs/52xx/cm5200_defconfig
arch/powerpc/configs/52xx/lite5200b_defconfig
arch/powerpc/configs/52xx/motionpro_defconfig
arch/powerpc/configs/52xx/pcm030_defconfig
arch/powerpc/configs/52xx/tqm5200_defconfig
arch/powerpc/configs/86xx/gef_sbc610_defconfig
arch/powerpc/configs/mpc5200_defconfig
arch/powerpc/configs/ppc40x_defconfig
arch/powerpc/configs/ppc44x_defconfig
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/kernel/cpu_setup_44x.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/prom_parse.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/mm/40x_mmu.c
arch/powerpc/mm/hugetlbpage.c
arch/powerpc/mm/numa.c
arch/powerpc/platforms/cell/axon_msi.c
arch/powerpc/platforms/cell/smp.c
arch/powerpc/platforms/cell/spufs/file.c
arch/powerpc/sysdev/bestcomm/Kconfig
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/xilinx_intc.c
arch/s390/defconfig
arch/s390/include/asm/pgtable.h
arch/s390/include/asm/ptrace.h
arch/s390/include/asm/syscall.h
arch/s390/kernel/asm-offsets.c
arch/s390/kernel/compat_signal.c
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S
arch/s390/kernel/init_task.c
arch/s390/kernel/ptrace.c
arch/s390/kernel/signal.c
arch/s390/kernel/time.c
arch/s390/kernel/vmlinux.lds.S
arch/sparc/include/asm/ptrace_64.h
arch/sparc/kernel/cpu.c
arch/sparc/kernel/head.S
arch/sparc/kernel/smp.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sun4m_smp.c
arch/sparc/kernel/trampoline.S
arch/sparc/kernel/vmlinux.lds.S
arch/sparc/mm/srmmu.c
arch/sparc64/kernel/smp.c
arch/sparc64/mm/init.c
arch/x86/boot/tty.c
arch/x86/include/asm/ds.h
arch/x86/include/asm/pci_64.h
arch/x86/include/asm/ptrace.h
arch/x86/kernel/Makefile
arch/x86/kernel/apic.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.c
arch/x86/kernel/cpu/cpufreq/powernow-k8.h
arch/x86/kernel/ds.c
arch/x86/kernel/i387.c
arch/x86/kernel/io_apic.c
arch/x86/kernel/kvmclock.c
arch/x86/kernel/pci-calgary_64.c
arch/x86/kernel/xsave.c
arch/x86/oprofile/op_model_ppro.c
arch/x86/pci/fixup.c
arch/x86/xen/mmu.c
arch/x86/xen/smp.c
arch/x86/xen/xen-ops.h
drivers/acpi/battery.c
drivers/acpi/blacklist.c
drivers/acpi/ec.c
drivers/acpi/osl.c
drivers/acpi/scan.c
drivers/acpi/sleep/main.c
drivers/acpi/toshiba_acpi.c
drivers/acpi/utils.c
drivers/block/xsysace.c
drivers/char/agp/uninorth-agp.c
drivers/char/istallion.c
drivers/char/tty_io.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/crypto/talitos.c
drivers/gpu/drm/drm_drv.c
drivers/gpu/drm/drm_irq.c
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/i915_opregion.c
drivers/gpu/drm/i915/i915_suspend.c
drivers/gpu/drm/mga/mga_dma.c
drivers/gpu/drm/mga/mga_irq.c
drivers/gpu/drm/r128/r128_drv.c
drivers/gpu/drm/r128/r128_drv.h
drivers/gpu/drm/r128/r128_irq.c
drivers/gpu/drm/radeon/radeon_cp.c
drivers/gpu/drm/radeon/radeon_irq.c
drivers/gpu/drm/via/via_irq.c
drivers/gpu/drm/via/via_map.c
drivers/hid/hid-apple.c
drivers/hid/hid-core.c
drivers/hid/hid-ids.h
drivers/hid/hid-pl.c
drivers/hid/usbhid/hid-core.c
drivers/hid/usbhid/usbhid.h
drivers/i2c/busses/i2c-parport.c
drivers/i2c/chips/isp1301_omap.c
drivers/i2c/i2c-core.c
drivers/ide/icside.c
drivers/input/ff-memless.c
drivers/input/keyboard/atkbd.c
drivers/input/misc/cm109.c
drivers/input/mouse/hgpk.c
drivers/input/serio/i8042-x86ia64io.h
drivers/input/tablet/wacom.h
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.h
drivers/input/touchscreen/elo.c
drivers/input/xen-kbdfront.c
drivers/isdn/hisax/config.c
drivers/macintosh/rack-meter.c
drivers/misc/sony-laptop.c
drivers/misc/thinkpad_acpi.c
drivers/mtd/ubi/eba.c
drivers/mtd/ubi/scan.c
drivers/mtd/ubi/wl.c
drivers/net/Kconfig
drivers/net/ixgbe/ixgbe_main.c
drivers/net/pcmcia/ibmtr_cs.c
drivers/net/smc911x.c
drivers/net/smc91x.c
drivers/net/xen-netfront.c
drivers/pci/pci.c
drivers/rapidio/rio-scan.c
drivers/rapidio/rio.c
drivers/scsi/advansys.c
drivers/scsi/gdth.c
drivers/serial/uartlite.c
drivers/usb/gadget/fsl_qe_udc.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/pxa25x_udc.c
drivers/usb/host/ehci-pci.c
drivers/usb/host/ehci.h
drivers/usb/serial/console.c
drivers/usb/serial/option.c
drivers/usb/storage/unusual_devs.h
drivers/video/omap/Makefile
drivers/video/omap/lcd_sx1.c [deleted file]
drivers/video/pxafb.c
drivers/video/xen-fbfront.c
drivers/video/xilinxfb.c
drivers/w1/masters/Kconfig
fs/buffer.c
fs/cifs/file.c
fs/udf/inode.c
include/acpi/acpredef.h
include/drm/drmP.h
include/linux/compat.h
include/linux/highmem.h
include/linux/irq.h
include/linux/memory.h
include/linux/mfd/wm8350/audio.h
include/linux/page_cgroup.h
include/sound/l3.h [new file with mode: 0644]
include/sound/s3c24xx_uda134x.h [new file with mode: 0644]
include/sound/soc-dai.h [new file with mode: 0644]
include/sound/soc-dapm.h
include/sound/soc.h
include/sound/uda134x.h [new file with mode: 0644]
kernel/cpu.c
kernel/cpuset.c
kernel/irq/internals.h
kernel/irq/manage.c
kernel/irq/migration.c
kernel/irq/proc.c
kernel/lockdep.c
kernel/profile.c
kernel/ptrace.c
kernel/sched.c
kernel/trace/ring_buffer.c
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_stack.c
mm/memory_hotplug.c
mm/page_cgroup.c
mm/sparse.c
mm/vmscan.c
sound/pci/hda/hda_codec.c
sound/pci/hda/patch_sigmatel.c
sound/soc/Kconfig
sound/soc/Makefile
sound/soc/at32/Kconfig [deleted file]
sound/soc/at32/Makefile [deleted file]
sound/soc/at32/at32-pcm.c [deleted file]
sound/soc/at32/at32-pcm.h [deleted file]
sound/soc/at32/at32-ssc.c [deleted file]
sound/soc/at32/at32-ssc.h [deleted file]
sound/soc/at91/Kconfig [deleted file]
sound/soc/at91/Makefile [deleted file]
sound/soc/at91/at91-pcm.c [deleted file]
sound/soc/at91/at91-pcm.h [deleted file]
sound/soc/at91/at91-ssc.c [deleted file]
sound/soc/at91/at91-ssc.h [deleted file]
sound/soc/atmel/Kconfig [new file with mode: 0644]
sound/soc/atmel/Makefile [new file with mode: 0644]
sound/soc/atmel/atmel-pcm.c [new file with mode: 0644]
sound/soc/atmel/atmel-pcm.h [new file with mode: 0644]
sound/soc/atmel/atmel_ssc_dai.c [new file with mode: 0644]
sound/soc/atmel/atmel_ssc_dai.h [new file with mode: 0644]
sound/soc/atmel/playpaq_wm8510.c [moved from sound/soc/at32/playpaq_wm8510.c with 98% similarity]
sound/soc/atmel/sam9g20_wm8731.c [new file with mode: 0644]
sound/soc/au1x/dbdma2.c
sound/soc/au1x/psc-ac97.c
sound/soc/au1x/psc-i2s.c
sound/soc/au1x/sample-ac97.c
sound/soc/blackfin/Kconfig
sound/soc/blackfin/bf5xx-ac97-pcm.c
sound/soc/blackfin/bf5xx-ac97.c
sound/soc/blackfin/bf5xx-ac97.h
sound/soc/blackfin/bf5xx-ad1980.c
sound/soc/blackfin/bf5xx-ad73311.c
sound/soc/blackfin/bf5xx-i2s-pcm.c
sound/soc/blackfin/bf5xx-i2s.c
sound/soc/blackfin/bf5xx-sport.h
sound/soc/blackfin/bf5xx-ssm2602.c
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/ac97.c
sound/soc/codecs/ad1980.c
sound/soc/codecs/ad73311.c
sound/soc/codecs/ak4535.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/l3.c [new file with mode: 0644]
sound/soc/codecs/pcm3008.c [new file with mode: 0644]
sound/soc/codecs/pcm3008.h [new file with mode: 0644]
sound/soc/codecs/ssm2602.c
sound/soc/codecs/tlv320aic23.c
sound/soc/codecs/tlv320aic26.c
sound/soc/codecs/tlv320aic3x.c
sound/soc/codecs/tlv320aic3x.h
sound/soc/codecs/twl4030.c [new file with mode: 0644]
sound/soc/codecs/twl4030.h [new file with mode: 0644]
sound/soc/codecs/uda134x.c [new file with mode: 0644]
sound/soc/codecs/uda134x.h [new file with mode: 0644]
sound/soc/codecs/uda1380.c
sound/soc/codecs/wm8350.c [new file with mode: 0644]
sound/soc/codecs/wm8350.h [new file with mode: 0644]
sound/soc/codecs/wm8510.c
sound/soc/codecs/wm8580.c
sound/soc/codecs/wm8580.h
sound/soc/codecs/wm8728.c [new file with mode: 0644]
sound/soc/codecs/wm8728.h [new file with mode: 0644]
sound/soc/codecs/wm8731.c
sound/soc/codecs/wm8750.c
sound/soc/codecs/wm8753.c
sound/soc/codecs/wm8900.c
sound/soc/codecs/wm8900.h
sound/soc/codecs/wm8903.c
sound/soc/codecs/wm8903.h
sound/soc/codecs/wm8971.c
sound/soc/codecs/wm8990.c
sound/soc/codecs/wm8990.h
sound/soc/codecs/wm9712.c
sound/soc/codecs/wm9713.c
sound/soc/davinci/Kconfig
sound/soc/davinci/Makefile
sound/soc/davinci/davinci-evm.c
sound/soc/davinci/davinci-i2s.c
sound/soc/davinci/davinci-pcm.c
sound/soc/davinci/davinci-sffsdr.c [new file with mode: 0644]
sound/soc/fsl/Kconfig
sound/soc/fsl/fsl_dma.c
sound/soc/fsl/fsl_ssi.c
sound/soc/fsl/mpc5200_psc_i2s.c
sound/soc/fsl/mpc8610_hpcd.c
sound/soc/fsl/soc-of-simple.c
sound/soc/omap/Kconfig
sound/soc/omap/Makefile
sound/soc/omap/n810.c
sound/soc/omap/omap-mcbsp.c
sound/soc/omap/omap-pcm.c
sound/soc/omap/omap2evm.c [new file with mode: 0644]
sound/soc/omap/omap3beagle.c [new file with mode: 0644]
sound/soc/omap/omap3pandora.c [new file with mode: 0644]
sound/soc/omap/osk5912.c
sound/soc/omap/overo.c [new file with mode: 0644]
sound/soc/omap/sdp3430.c [new file with mode: 0644]
sound/soc/pxa/Kconfig
sound/soc/pxa/Makefile
sound/soc/pxa/corgi.c
sound/soc/pxa/e800_wm9712.c
sound/soc/pxa/em-x270.c
sound/soc/pxa/palm27x.c [new file with mode: 0644]
sound/soc/pxa/poodle.c
sound/soc/pxa/pxa-ssp.c [new file with mode: 0644]
sound/soc/pxa/pxa-ssp.h [new file with mode: 0644]
sound/soc/pxa/pxa2xx-ac97.c
sound/soc/pxa/pxa2xx-i2s.c
sound/soc/pxa/pxa2xx-pcm.c
sound/soc/pxa/spitz.c
sound/soc/pxa/tosa.c
sound/soc/pxa/zylonite.c [new file with mode: 0644]
sound/soc/s3c24xx/Kconfig
sound/soc/s3c24xx/Makefile
sound/soc/s3c24xx/ln2440sbc_alc650.c
sound/soc/s3c24xx/neo1973_wm8753.c
sound/soc/s3c24xx/s3c2412-i2s.c
sound/soc/s3c24xx/s3c2443-ac97.c
sound/soc/s3c24xx/s3c24xx-i2s.c
sound/soc/s3c24xx/s3c24xx-pcm.c
sound/soc/s3c24xx/s3c24xx_uda134x.c [new file with mode: 0644]
sound/soc/s3c24xx/smdk2443_wm9710.c
sound/soc/sh/dma-sh7760.c
sound/soc/sh/hac.c
sound/soc/sh/sh7760-ac97.c
sound/soc/sh/ssi.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c
sound/sound_core.c

index 6c442d8426b5928569918ebd149f4818c5657ab1..4f3f3840320e30eaa0650e9197725b7d6e811b4e 100644 (file)
@@ -23,6 +23,7 @@ Contents:
 1.3 sparc64
 1.4 ppc
 1.5 SuperH
+1.6 Blackfin
 
 2. "Policy" / "Governor"?
 2.1 Policy
@@ -97,6 +98,17 @@ The following SuperH processors are supported by cpufreq:
 SH-3
 SH-4
 
+1.6 Blackfin
+------------
+
+The following Blackfin processors are supported by cpufreq:
+
+BF522, BF523, BF524, BF525, BF526, BF527, Rev 0.1 or higher
+BF531, BF532, BF533, Rev 0.3 or higher
+BF534, BF536, BF537, Rev 0.2 or higher
+BF561, Rev 0.3 or higher
+BF542, BF544, BF547, BF548, BF549, Rev 0.1 or higher
+
 
 2. "Policy" / "Governor" ?
 ==========================
index 62fe9b1e089031c2e30153e9dc1be6f15d30aa6c..a8273d5fad209b4ab4393c0667c03b549c83091c 100644 (file)
@@ -130,12 +130,12 @@ The 2.6 kernel build process always creates a gzipped cpio format initramfs
 archive and links it into the resulting kernel binary.  By default, this
 archive is empty (consuming 134 bytes on x86).
 
-The config option CONFIG_INITRAMFS_SOURCE (for some reason buried under
-devices->block devices in menuconfig, and living in usr/Kconfig) can be used
-to specify a source for the initramfs archive, which will automatically be
-incorporated into the resulting binary.  This option can point to an existing
-gzipped cpio archive, a directory containing files to be archived, or a text
-file specification such as the following example:
+The config option CONFIG_INITRAMFS_SOURCE (in General Setup in menuconfig,
+and living in usr/Kconfig) can be used to specify a source for the
+initramfs archive, which will automatically be incorporated into the
+resulting binary.  This option can point to an existing gzipped cpio
+archive, a directory containing files to be archived, or a text file
+specification such as the following example:
 
   dir /dev 755 0 0
   nod /dev/console 644 0 0 c 5 1
index 81905e81585e2de04f9b80a658fb087013acd147..7f8b9d97bc47d32359150822eaa16b23acfc13be 100644 (file)
@@ -20,10 +20,11 @@ pressed or released a BUTTON_IRQ happens. The driver could look like:
 
 static struct input_dev *button_dev;
 
-static void button_interrupt(int irq, void *dummy, struct pt_regs *fp)
+static irqreturn_t button_interrupt(int irq, void *dummy)
 {
        input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1);
        input_sync(button_dev);
+       return IRQ_HANDLED;
 }
 
 static int __init button_init(void)
index e0e54a27fc10905a62bd649605ad2dbe8f8bfdbf..3cd2ad958176c9e4f4969de00597ea55633d0c2c 100644 (file)
@@ -1072,10 +1072,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
          ref           Reference board
          dell-m4-1     Dell desktops
          dell-m4-2     Dell desktops
+         dell-m4-3     Dell desktops
 
        STAC92HD73*
          ref           Reference board
-         dell-m6       Dell desktops
+         dell-m6-amic  Dell desktops/laptops with analog mics
+         dell-m6-dmic  Dell desktops/laptops with digital mics
+         dell-m6       Dell desktops/laptops with both type of mics
 
        STAC9872
          vaio          Setup for VAIO FE550G/SZ110
index f370e7db86af6a970de14433523af4b1ca71d390..bab7711ce96311470a3eddb9a9500772b02a777e 100644 (file)
@@ -9,7 +9,7 @@ the audio subsystem with the kernel as a platform device and is represented by
 the following struct:-
 
 /* SoC machine */
-struct snd_soc_machine {
+struct snd_soc_card {
        char *name;
 
        int (*probe)(struct platform_device *pdev);
@@ -67,10 +67,10 @@ static struct snd_soc_dai_link corgi_dai = {
        .ops = &corgi_ops,
 };
 
-struct snd_soc_machine then sets up the machine with it's DAIs. e.g.
+struct snd_soc_card then sets up the machine with it's DAIs. e.g.
 
 /* corgi audio machine driver */
-static struct snd_soc_machine snd_soc_machine_corgi = {
+static struct snd_soc_card snd_soc_corgi = {
        .name = "Corgi",
        .dai_link = &corgi_dai,
        .num_links = 1,
@@ -90,7 +90,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
 
 /* corgi audio subsystem */
 static struct snd_soc_device corgi_snd_devdata = {
-       .machine = &snd_soc_machine_corgi,
+       .machine = &snd_soc_corgi,
        .platform = &pxa2xx_soc_platform,
        .codec_dev = &soc_codec_dev_wm8731,
        .codec_data = &corgi_wm8731_setup,
index 5bbbe2096223f69bc1f0d7007f6d07a3385e4fd4..cde23b4a12a19a9306464ec1296cb4fee19eb9c0 100644 (file)
@@ -37,7 +37,7 @@ $ echo mmiotrace > /debug/tracing/current_tracer
 $ cat /debug/tracing/trace_pipe > mydump.txt &
 Start X or whatever.
 $ echo "X is up" > /debug/tracing/trace_marker
-$ echo none > /debug/tracing/current_tracer
+$ echo nop > /debug/tracing/current_tracer
 Check for lost events.
 
 
@@ -66,7 +66,7 @@ which action. It is recommended to place descriptive markers about what you
 do.
 
 Shut down mmiotrace (requires root privileges):
-$ echo none > /debug/tracing/current_tracer
+$ echo nop > /debug/tracing/current_tracer
 The 'cat' process exits. If it does not, kill it by issuing 'fg' command and
 pressing ctrl+c.
 
@@ -81,7 +81,9 @@ are:
 $ cat /debug/tracing/trace_entries
 gives you a number. Approximately double this number and write it back, for
 instance:
+$ echo 0 > /debug/tracing/tracing_enabled
 $ echo 128000 > /debug/tracing/trace_entries
+$ echo 1 > /debug/tracing/tracing_enabled
 Then start again from the top.
 
 If you are doing a trace for a driver project, e.g. Nouveau, you should also
index 618c1ef4a397502749b2d08a49e80806e99825d1..6df20eaf041866e8f305faad6c462893522d52fd 100644 (file)
@@ -3967,7 +3967,7 @@ M:        tiwai@suse.de
 L:     alsa-devel@alsa-project.org (subscribers-only)
 S:     Maintained
 
-SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
+SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC)
 P:     Liam Girdwood
 M:     lrg@slimlogic.co.uk
 P:     Mark Brown
index 8977d99987cb31b4b7bc5a6b4ccc2fa333b267cd..471e72dbaf8b123ce235b470303b56f2852209f0 100644 (file)
@@ -79,8 +79,6 @@ config HAVE_KRETPROBES
 #      task_pt_regs()          in asm/processor.h or asm/ptrace.h
 #      arch_has_single_step()  if there is hardware single-step support
 #      arch_has_block_step()   if there is hardware block-step support
-#      arch_ptrace()           and not #define __ARCH_SYS_PTRACE
-#      compat_arch_ptrace()    and #define __ARCH_WANT_COMPAT_SYS_PTRACE
 #      asm/syscall.h           supplying asm-generic/syscall.h interface
 #      linux/regset.h          user_regset interfaces
 #      CORE_DUMP_USE_REGSET    #define'd in linux/elf.h
index 5cf45fc5134315bdc930d1a36dad08e4dc4c6dac..ff8cb638472e54cfbcb298cefb536cdfcfa0dd03 100644 (file)
@@ -338,7 +338,7 @@ common_swizzle(struct pci_dev *dev, u8 *pinp)
        return PCI_SLOT(dev->devfn);
 }
 
-void __devinit
+void
 pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
                         struct resource *res)
 {
index e657c45d91d27c5a62f7d542ab9d36f3adcb9109..cf7da10097bb29d5f8fb69aaefc9107a3419783a 100644 (file)
@@ -121,7 +121,7 @@ wait_boot_cpu_to_stop(int cpuid)
 /*
  * Where secondaries begin a life of C.
  */
-void __init
+void __cpuinit
 smp_callin(void)
 {
        int cpuid = hard_smp_processor_id();
@@ -198,7 +198,7 @@ wait_for_txrdy (unsigned long cpumask)
  * Send a message to a secondary's console.  "START" is one such
  * interesting message.  ;-)
  */
-static void __init
+static void __cpuinit
 send_secondary_console_msg(char *str, int cpuid)
 {
        struct percpu_struct *cpu;
@@ -289,7 +289,7 @@ recv_secondary_console_msg(void)
 /*
  * Convince the console to have a secondary cpu begin execution.
  */
-static int __init
+static int __cpuinit
 secondary_cpu_start(int cpuid, struct task_struct *idle)
 {
        struct percpu_struct *cpu;
index c778779007fc58339abb11bc7f42f1299d5d65c1..cefc5a355ef9645233bfec5535e71e1d96e47e54 100644 (file)
@@ -31,7 +31,7 @@
 
 static int opDEC_fix;
 
-static void __init
+static void __cpuinit
 opDEC_check(void)
 {
        __asm__ __volatile__ (
@@ -1072,7 +1072,7 @@ give_sigbus:
        return;
 }
 
-void __init
+void __cpuinit
 trap_init(void)
 {
        /* Tell PAL-code what global pointer we want in the kernel.  */
index f3af0b593eb08ab5149acca798ca53acbb8b2c47..98765438048da09d663ad18c5356e961ae3bd769 100644 (file)
@@ -179,7 +179,7 @@ CONFIG_MACH_HUSKY=y
 # CONFIG_MACH_AKITA is not set
 # CONFIG_MACH_SPITZ is not set
 # CONFIG_MACH_BORZOI is not set
-CONFIG_MACH_TOSA=y
+# CONFIG_MACH_TOSA is not set
 # CONFIG_ARCH_VIPER is not set
 # CONFIG_ARCH_PXA_ESERIES is not set
 # CONFIG_TRIZEPS_PXA is not set
diff --git a/arch/arm/mach-pxa/include/mach/palmasoc.h b/arch/arm/mach-pxa/include/mach/palmasoc.h
new file mode 100644 (file)
index 0000000..6c4b1f7
--- /dev/null
@@ -0,0 +1,13 @@
+#ifndef _INCLUDE_PALMASOC_H_
+#define _INCLUDE_PALMASOC_H_
+struct palm27x_asoc_info {
+       int     jack_gpio;
+};
+
+#ifdef CONFIG_SND_PXA2XX_SOC_PALM27X
+void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data);
+#else
+static inline void palm27x_asoc_set_pdata(struct palm27x_asoc_info *data) {}
+#endif
+
+#endif
index 8e591118371e36adaf365b52db1104e92f60154c..cbda4d35c42130d44eca008fce11cc03ac9f9ba2 100644 (file)
@@ -33,6 +33,7 @@
 #define LCD_CONN_TYPE(_x)      ((_x) & 0x0f)
 #define LCD_CONN_WIDTH(_x)     (((_x) >> 4) & 0x1f)
 
+#define LCD_TYPE_MASK          0xf
 #define LCD_TYPE_UNKNOWN       0
 #define LCD_TYPE_MONO_STN      1
 #define LCD_TYPE_MONO_DSTN     2
index 0842c531ee4df990f0e7a822e2938593cd9047de..782903fe9c6c2d5900e77efdfe2bc2e664acd4bd 100644 (file)
@@ -565,7 +565,7 @@ static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
        u32 *mem_resume_unknown = phys_to_virt(RESUME_UNKNOWN_ADDR);
 
        /* Devices prepare suspend */
-       is_bt_on = gpio_get_value(GPIO83_BT_ON);
+       is_bt_on = !!gpio_get_value(GPIO83_BT_ON);
        pxa2xx_mfp_set_lpm(GPIO83_BT_ON,
                           is_bt_on ? MFP_LPM_DRIVE_HIGH : MFP_LPM_DRIVE_LOW);
 
index a647693d98568ff6890c7e86d519ad52b4d534f6..324d25a48c85cd363f31810226d392fbb9a8f5da 100644 (file)
@@ -24,6 +24,7 @@ ENTRY(mioa701_jumpaddr)
 1:
        mov     r0,     #0xa0000000     @ Don't suppose memory access works
        orr     r0, r0, #0x00200000     @ even if it's supposed to
+       orr     r0, r0, #0x0000b000
        mov     r1, #0
        str     r1, [r0]                @ Early disable resume for next boot
        ldr     r0, mioa701_jumpaddr    @ (Murphy's Law)
index 4447711c9fc61bc09267f355a82ac0195a3e5952..a9d94f5dbec4b2adaa71345881605f153b687a05 100644 (file)
@@ -56,6 +56,9 @@ static unsigned long palmtx_pin_config[] __initdata = {
        GPIO110_MMC_DAT_2,
        GPIO111_MMC_DAT_3,
        GPIO112_MMC_CMD,
+       GPIO14_GPIO,    /* SD detect */
+       GPIO114_GPIO,   /* SD power */
+       GPIO115_GPIO,   /* SD r/o switch */
 
        /* AC97 */
        GPIO28_AC97_BITCLK,
@@ -64,6 +67,7 @@ static unsigned long palmtx_pin_config[] __initdata = {
        GPIO31_AC97_SYNC,
 
        /* IrDA */
+       GPIO40_GPIO,    /* ir disable */
        GPIO46_FICP_RXD,
        GPIO47_FICP_TXD,
 
@@ -71,7 +75,8 @@ static unsigned long palmtx_pin_config[] __initdata = {
        GPIO16_PWM0_OUT,
 
        /* USB */
-       GPIO13_GPIO,
+       GPIO13_GPIO,    /* usb detect */
+       GPIO95_GPIO,    /* usb power */
 
        /* PCMCIA */
        GPIO48_nPOE,
@@ -84,6 +89,45 @@ static unsigned long palmtx_pin_config[] __initdata = {
        GPIO55_nPREG,
        GPIO56_nPWAIT,
        GPIO57_nIOIS16,
+       GPIO94_GPIO,    /* wifi power 1 */
+       GPIO108_GPIO,   /* wifi power 2 */
+       GPIO116_GPIO,   /* wifi ready */
+
+       /* MATRIX KEYPAD */
+       GPIO100_KP_MKIN_0,
+       GPIO101_KP_MKIN_1,
+       GPIO102_KP_MKIN_2,
+       GPIO97_KP_MKIN_3,
+       GPIO103_KP_MKOUT_0,
+       GPIO104_KP_MKOUT_1,
+       GPIO105_KP_MKOUT_2,
+
+       /* LCD */
+       GPIO58_LCD_LDD_0,
+       GPIO59_LCD_LDD_1,
+       GPIO60_LCD_LDD_2,
+       GPIO61_LCD_LDD_3,
+       GPIO62_LCD_LDD_4,
+       GPIO63_LCD_LDD_5,
+       GPIO64_LCD_LDD_6,
+       GPIO65_LCD_LDD_7,
+       GPIO66_LCD_LDD_8,
+       GPIO67_LCD_LDD_9,
+       GPIO68_LCD_LDD_10,
+       GPIO69_LCD_LDD_11,
+       GPIO70_LCD_LDD_12,
+       GPIO71_LCD_LDD_13,
+       GPIO72_LCD_LDD_14,
+       GPIO73_LCD_LDD_15,
+       GPIO74_LCD_FCLK,
+       GPIO75_LCD_LCLK,
+       GPIO76_LCD_PCLK,
+       GPIO77_LCD_BIAS,
+
+       /* MISC. */
+       GPIO10_GPIO,    /* hotsync button */
+       GPIO12_GPIO,    /* power detect */
+       GPIO107_GPIO,   /* earphone detect */
 };
 
 /******************************************************************************
@@ -95,32 +139,49 @@ static int palmtx_mci_init(struct device *dev, irq_handler_t palmtx_detect_int,
        int err = 0;
 
        /* Setup an interrupt for detecting card insert/remove events */
-       err = request_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, palmtx_detect_int,
-                       IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
+       err = gpio_request(GPIO_NR_PALMTX_SD_DETECT_N, "SD IRQ");
+       if (err)
+               goto err;
+       err = gpio_direction_input(GPIO_NR_PALMTX_SD_DETECT_N);
+       if (err)
+               goto err2;
+       err = request_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N),
+                       palmtx_detect_int, IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
                        IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
                        "SD/MMC card detect", data);
        if (err) {
                printk(KERN_ERR "%s: cannot request SD/MMC card detect IRQ\n",
                                __func__);
-               return err;
+               goto err2;
        }
 
        err = gpio_request(GPIO_NR_PALMTX_SD_POWER, "SD_POWER");
        if (err)
-               goto pwr_err;
+               goto err3;
+       err = gpio_direction_output(GPIO_NR_PALMTX_SD_POWER, 0);
+       if (err)
+               goto err4;
 
        err = gpio_request(GPIO_NR_PALMTX_SD_READONLY, "SD_READONLY");
        if (err)
-               goto ro_err;
+               goto err4;
+       err = gpio_direction_input(GPIO_NR_PALMTX_SD_READONLY);
+       if (err)
+               goto err5;
 
        printk(KERN_DEBUG "%s: irq registered\n", __func__);
 
        return 0;
 
-ro_err:
+err5:
+       gpio_free(GPIO_NR_PALMTX_SD_READONLY);
+err4:
        gpio_free(GPIO_NR_PALMTX_SD_POWER);
-pwr_err:
-       free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
+err3:
+       free_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N), data);
+err2:
+       gpio_free(GPIO_NR_PALMTX_SD_DETECT_N);
+err:
        return err;
 }
 
@@ -128,7 +189,8 @@ static void palmtx_mci_exit(struct device *dev, void *data)
 {
        gpio_free(GPIO_NR_PALMTX_SD_READONLY);
        gpio_free(GPIO_NR_PALMTX_SD_POWER);
-       free_irq(IRQ_GPIO_PALMTX_SD_DETECT_N, data);
+       free_irq(gpio_to_irq(GPIO_NR_PALMTX_SD_DETECT_N), data);
+       gpio_free(GPIO_NR_PALMTX_SD_DETECT_N);
 }
 
 static void palmtx_mci_power(struct device *dev, unsigned int vdd)
@@ -167,7 +229,6 @@ static unsigned int palmtx_matrix_keys[] = {
 
        KEY(3, 0, KEY_RIGHT),
        KEY(3, 2, KEY_LEFT),
-
 };
 
 static struct pxa27x_keypad_platform_data palmtx_keypad_platform_data = {
@@ -209,11 +270,19 @@ static int palmtx_backlight_init(struct device *dev)
        ret = gpio_request(GPIO_NR_PALMTX_BL_POWER, "BL POWER");
        if (ret)
                goto err;
+       ret = gpio_direction_output(GPIO_NR_PALMTX_BL_POWER, 0);
+       if (ret)
+               goto err2;
        ret = gpio_request(GPIO_NR_PALMTX_LCD_POWER, "LCD POWER");
        if (ret)
                goto err2;
+       ret = gpio_direction_output(GPIO_NR_PALMTX_LCD_POWER, 0);
+       if (ret)
+               goto err3;
 
        return 0;
+err3:
+       gpio_free(GPIO_NR_PALMTX_LCD_POWER);
 err2:
        gpio_free(GPIO_NR_PALMTX_BL_POWER);
 err:
@@ -254,6 +323,24 @@ static struct platform_device palmtx_backlight = {
 /******************************************************************************
  * IrDA
  ******************************************************************************/
+static int palmtx_irda_startup(struct device *dev)
+{
+       int err;
+       err = gpio_request(GPIO_NR_PALMTX_IR_DISABLE, "IR DISABLE");
+       if (err)
+               goto err;
+       err = gpio_direction_output(GPIO_NR_PALMTX_IR_DISABLE, 1);
+       if (err)
+               gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
+err:
+       return err;
+}
+
+static void palmtx_irda_shutdown(struct device *dev)
+{
+       gpio_free(GPIO_NR_PALMTX_IR_DISABLE);
+}
+
 static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
 {
        gpio_set_value(GPIO_NR_PALMTX_IR_DISABLE, mode & IR_OFF);
@@ -261,6 +348,8 @@ static void palmtx_irda_transceiver_mode(struct device *dev, int mode)
 }
 
 static struct pxaficp_platform_data palmtx_ficp_platform_data = {
+       .startup                = palmtx_irda_startup,
+       .shutdown               = palmtx_irda_shutdown,
        .transceiver_cap        = IR_SIRMODE | IR_FIRMODE | IR_OFF,
        .transceiver_mode       = palmtx_irda_transceiver_mode,
 };
@@ -268,17 +357,11 @@ static struct pxaficp_platform_data palmtx_ficp_platform_data = {
 /******************************************************************************
  * UDC
  ******************************************************************************/
-static void palmtx_udc_command(int cmd)
-{
-       gpio_set_value(GPIO_NR_PALMTX_USB_POWER, !cmd);
-       udelay(50);
-       gpio_set_value(GPIO_NR_PALMTX_USB_PULLUP, !cmd);
-}
-
 static struct pxa2xx_udc_mach_info palmtx_udc_info __initdata = {
        .gpio_vbus              = GPIO_NR_PALMTX_USB_DETECT_N,
        .gpio_vbus_inverted     = 1,
-       .udc_command            = palmtx_udc_command,
+       .gpio_pullup            = GPIO_NR_PALMTX_USB_POWER,
+       .gpio_pullup_inverted   = 0,
 };
 
 /******************************************************************************
@@ -290,17 +373,16 @@ static int power_supply_init(struct device *dev)
 
        ret = gpio_request(GPIO_NR_PALMTX_POWER_DETECT, "CABLE_STATE_AC");
        if (ret)
-               goto err_cs_ac;
-
-       ret = gpio_request(GPIO_NR_PALMTX_USB_DETECT_N, "CABLE_STATE_USB");
+               goto err1;
+       ret = gpio_direction_input(GPIO_NR_PALMTX_POWER_DETECT);
        if (ret)
-               goto err_cs_usb;
+               goto err2;
 
        return 0;
 
-err_cs_usb:
+err2:
        gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
-err_cs_ac:
+err1:
        return ret;
 }
 
@@ -309,14 +391,8 @@ static int palmtx_is_ac_online(void)
        return gpio_get_value(GPIO_NR_PALMTX_POWER_DETECT);
 }
 
-static int palmtx_is_usb_online(void)
-{
-       return !gpio_get_value(GPIO_NR_PALMTX_USB_DETECT_N);
-}
-
 static void power_supply_exit(struct device *dev)
 {
-       gpio_free(GPIO_NR_PALMTX_USB_DETECT_N);
        gpio_free(GPIO_NR_PALMTX_POWER_DETECT);
 }
 
@@ -327,7 +403,6 @@ static char *palmtx_supplicants[] = {
 static struct pda_power_pdata power_supply_info = {
        .init            = power_supply_init,
        .is_ac_online    = palmtx_is_ac_online,
-       .is_usb_online   = palmtx_is_usb_online,
        .exit            = power_supply_exit,
        .supplied_to     = palmtx_supplicants,
        .num_supplicants = ARRAY_SIZE(palmtx_supplicants),
@@ -410,12 +485,23 @@ static void __init palmtx_map_io(void)
        iotable_init(palmtx_io_desc, ARRAY_SIZE(palmtx_io_desc));
 }
 
+/* setup udc GPIOs initial state */
+static void __init palmtx_udc_init(void)
+{
+       if (!gpio_request(GPIO_NR_PALMTX_USB_POWER, "UDC Vbus")) {
+               gpio_direction_output(GPIO_NR_PALMTX_USB_POWER, 1);
+               gpio_free(GPIO_NR_PALMTX_USB_POWER);
+       }
+}
+
+
 static void __init palmtx_init(void)
 {
        pxa2xx_mfp_config(ARRAY_AND_SIZE(palmtx_pin_config));
 
        set_pxa_fb_info(&palmtx_lcd_screen);
        pxa_set_mci_info(&palmtx_mci_platform_data);
+       palmtx_udc_init();
        pxa_set_udc_info(&palmtx_udc_info);
        pxa_set_ac97_info(NULL);
        pxa_set_ficp_info(&palmtx_ficp_platform_data);
index f601425f1b1eaa31b3307c4fea3e36785f920244..b36cec5c9eed528b1d595fe1b4085a5dfcd7dccc 100644 (file)
@@ -385,6 +385,7 @@ static struct soc_camera_link iclink[] = {
                .gpio   = NR_BUILTIN_GPIO + 1,
        }, {
                .bus_id = 0, /* Must match with the camera ID above */
+               .gpio   = -ENXIO,
        }
 };
 
index 1b2af575c40fdacb47cba208a450a27a99375e1f..00b2dc2a10747b5f87d04d02f82d9f74bdd1b356 100644 (file)
@@ -90,12 +90,13 @@ void arch_reset(char mode)
                /* Jump into ROM at address 0 */
                cpu_reset(0);
                break;
-       case 'h':
-               do_hw_reset();
-               break;
        case 'g':
                do_gpio_reset();
                break;
+       case 'h':
+       default:
+               do_hw_reset();
+               break;
        }
 }
 
index f0a5bbae0b45d32966d3f61f00c77ccf738bde16..3be76ee2bdbfd759b83eee07151ba7cf7917cc42 100644 (file)
@@ -67,6 +67,7 @@
 static unsigned long spitz_pin_config[] __initdata = {
        /* Chip Selects */
        GPIO78_nCS_2,   /* SCOOP #2 */
+       GPIO79_nCS_3,   /* NAND */
        GPIO80_nCS_4,   /* SCOOP #1 */
 
        /* LCD - 16bpp Active TFT */
@@ -97,10 +98,10 @@ static unsigned long spitz_pin_config[] __initdata = {
        GPIO51_nPIOW,
        GPIO85_nPCE_1,
        GPIO54_nPCE_2,
-       GPIO79_PSKTSEL,
        GPIO55_nPREG,
        GPIO56_nPWAIT,
        GPIO57_nIOIS16,
+       GPIO104_PSKTSEL,
 
        /* MMC */
        GPIO32_MMC_CLK,
@@ -686,7 +687,6 @@ static void __init akita_init(void)
        spitz_pcmcia_config.num_devs = 1;
        platform_scoop_config = &spitz_pcmcia_config;
 
-       pxa_set_i2c_info(NULL);
        i2c_register_board_info(0, ARRAY_AND_SIZE(akita_i2c_board_info));
 
        common_init();
index 8679fbca6bbec4ec3d5e5561b92c633cf1e6f298..424049d83fbeb42b63e66286642b35ecbf3bd661 100644 (file)
 #define OMAP24XX_GPIO_IRQSTATUS2       0x0028
 #define OMAP24XX_GPIO_IRQENABLE2       0x002c
 #define OMAP24XX_GPIO_IRQENABLE1       0x001c
+#define OMAP24XX_GPIO_WAKE_EN          0x0020
 #define OMAP24XX_GPIO_CTRL             0x0030
 #define OMAP24XX_GPIO_OE               0x0034
 #define OMAP24XX_GPIO_DATAIN           0x0038
@@ -1551,7 +1552,7 @@ static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
 #endif
 #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
                case METHOD_GPIO_24XX:
-                       wake_status = bank->base + OMAP24XX_GPIO_SETWKUENA;
+                       wake_status = bank->base + OMAP24XX_GPIO_WAKE_EN;
                        wake_clear = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
                        wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
                        break;
@@ -1574,7 +1575,7 @@ static int omap_gpio_resume(struct sys_device *dev)
 {
        int i;
 
-       if (!cpu_is_omap24xx() && !cpu_is_omap16xx())
+       if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
                return 0;
 
        for (i = 0; i < gpio_bank_count; i++) {
index 768eb6e7abcfb719e83a3f085e3955e4b65d07fb..2a9c27ad4c373b349ae85db6fb7f06dd6b0f0035 100644 (file)
@@ -128,7 +128,7 @@ void clk_deny_idle(struct clk *clk);
  * clk_allow_idle - Counters previous clk_deny_idle
  * @clk: clock signal handle
  */
-void clk_deny_idle(struct clk *clk);
+void clk_allow_idle(struct clk *clk);
 
 extern void omap_pm_idle(void);
 extern void omap_pm_suspend(void);
index 6417c1ecb44ec47192f70ec6a2f009a502b5022a..14055c636adf24a4f16c80e2fc123f678bbb9edd 100644 (file)
@@ -325,8 +325,6 @@ static inline unsigned long user_stack_pointer(struct pt_regs *regs)
   #define arch_has_block_step()   (1)
   extern void user_enable_block_step(struct task_struct *);
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 #endif /* !__KERNEL__ */
 
 /* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */
index c3aa851d1ca60278c9897859ba9a6740976ae6c9..4e1801bad83a7fdc171a90af0ff3c2df4277f62f 100644 (file)
@@ -292,7 +292,7 @@ EXPORT_SYMBOL(sn_io_slot_fixup);
  * sn_pci_controller_fixup() - This routine sets up a bus's resources
  *                            consistent with the Linux PCI abstraction layer.
  */
-static void
+static void __init
 sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus)
 {
        s64 status = 0;
index 40180778a5c723e069cfc96739a0600f10b6e02b..90916067b9c17d766c33cb7e8033ced06943602a 100644 (file)
@@ -23,7 +23,7 @@ __INITDATA
 /*
  * References to members of the boot_cpu_data structure.
  */
-       .text
+.section .text.head, "ax"
        .global start_kernel
        .global __bss_start
        .global _end
@@ -133,7 +133,6 @@ loop1:
 /*
  * AP startup routine
  */
-       .text
        .global eit_vector
 ENTRY(startup_AP)
 ;; setup EVB
@@ -230,6 +229,7 @@ ENTRY(startup_AP)
        nop
 #endif  /* CONFIG_SMP */
 
+       .text
 ENTRY(stack_start)
        .long   init_thread_union+8192
        .long   __KERNEL_DS
index 15a6f36c06db9c7c84db8d4698339f3f8d9ba413..9db05df20c0ef0a5bba249282604bbcc2b1763e9 100644 (file)
@@ -27,6 +27,7 @@ SECTIONS
   _text = .;                   /* Text and read-only data */
   .boot : { *(.boot) } = 0
   .text : {
+       *(.text.head)
        TEXT_TEXT
        SCHED_TEXT
        LOCK_TEXT
index 7eb63de808bc153cf3f14ed5b2f180365f0f168b..08ea46863fe5ca8ce6683fe71f527a6c4346b690 100644 (file)
@@ -7,20 +7,31 @@
 
 #include <asm/break.h>
 
-#define BUG()                                                          \
-do {                                                                   \
-       __asm__ __volatile__("break %0" : : "i" (BRK_BUG));             \
-} while (0)
+static inline void __noreturn BUG(void)
+{
+       __asm__ __volatile__("break %0" : : "i" (BRK_BUG));
+       /* Fool GCC into thinking the function doesn't return. */
+       while (1)
+               ;
+}
 
 #define HAVE_ARCH_BUG
 
 #if (_MIPS_ISA > _MIPS_ISA_MIPS1)
 
-#define BUG_ON(condition)                                              \
-do {                                                                   \
-       __asm__ __volatile__("tne $0, %0, %1"                           \
-                            : : "r" (condition), "i" (BRK_BUG));       \
-} while (0)
+static inline void  __BUG_ON(unsigned long condition)
+{
+       if (__builtin_constant_p(condition)) {
+               if (condition)
+                       BUG();
+               else
+                       return;
+       }
+       __asm__ __volatile__("tne $0, %0, %1"
+                            : : "r" (condition), "i" (BRK_BUG));
+}
+
+#define BUG_ON(C) __BUG_ON((unsigned long)(C))
 
 #define HAVE_ARCH_BUG_ON
 
index 813abd16255d13322d27130f52df281ae48b8b78..c2c8bac43307570cd444daaa321b548025844697 100644 (file)
@@ -9,10 +9,6 @@
 #ifndef _ASM_PTRACE_H
 #define _ASM_PTRACE_H
 
-#ifdef CONFIG_64BIT
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-#endif
-
 /* 0 - 31 are integer registers, 32 - 63 are fp registers.  */
 #define FPR_BASE       32
 #define PC             64
index 54be6afb5555c3ae194df237b56c9ff2a387f551..0ea7482c1522712d73af221a199f8fa7c0b78738 100644 (file)
@@ -522,17 +522,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
        } else {
                switch (cur) {
                        /* Bxx (d8,PC) */
-               case 0xc0:
-               case 0xc1:
-               case 0xc2:
-               case 0xc3:
-               case 0xc4:
-               case 0xc5:
-               case 0xc6:
-               case 0xc7:
-               case 0xc8:
-               case 0xc9:
-               case 0xca:
+               case 0xc0 ... 0xca:
                        if (gdbstub_read_byte(pc + 1, (u8 *) &x) < 0)
                                goto fault;
                        if (!__gdbstub_mark_bp(pc + 2, 0))
@@ -543,17 +533,7 @@ static int gdbstub_single_step(struct pt_regs *regs)
                        break;
 
                        /* LXX (d8,PC) */
-               case 0xd0:
-               case 0xd1:
-               case 0xd2:
-               case 0xd3:
-               case 0xd4:
-               case 0xd5:
-               case 0xd6:
-               case 0xd7:
-               case 0xd8:
-               case 0xd9:
-               case 0xda:
+               case 0xd0 ... 0xda:
                        if (!__gdbstub_mark_bp(pc + 1, 0))
                                goto fault;
                        if (regs->pc != regs->lar &&
index 7aa13f2add7a837d36653a7f4f63a0bcc521fbb0..9afdad6c2ffb81db7f8ffb68dd003bd3b5cd4980 100644 (file)
@@ -42,9 +42,9 @@ struct parisc_driver {
 #define to_parisc_driver(d)    container_of(d, struct parisc_driver, drv)
 #define parisc_parent(d)       to_parisc_device(d->dev.parent)
 
-static inline char *parisc_pathname(struct parisc_device *d)
+static inline const char *parisc_pathname(struct parisc_device *d)
 {
-       return d->dev.bus_id;
+       return dev_name(&d->dev);
 }
 
 static inline void
index bb725a6630bb97373db7e212fc18b55d7dfa67b1..00da29a340ba9ad352294a2d47a00cff8e3daaeb 100644 (file)
@@ -24,13 +24,12 @@ typedef int                 __kernel_daddr_t;
 typedef unsigned long          __kernel_size_t;
 typedef long                   __kernel_ssize_t;
 typedef long                   __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
 #else
 typedef unsigned int           __kernel_size_t;
 typedef int                    __kernel_ssize_t;
 typedef int                    __kernel_ptrdiff_t;
-typedef long                   __kernel_time_t;
 #endif
+typedef long                   __kernel_time_t;
 typedef char *                 __kernel_caddr_t;
 
 typedef unsigned short         __kernel_uid16_t;
index afa5333187b4519126d2556b008e9fdfaba0fde5..302f68dc889cb0e3c5ddc04a1a42ad19e5e58998 100644 (file)
@@ -47,8 +47,6 @@ struct pt_regs {
 
 #define task_regs(task) ((struct pt_regs *) ((char *)(task) + TASK_REGS))
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 struct task_struct;
 #define arch_has_single_step() 1
 void user_disable_single_step(struct task_struct *task);
index 2ca654bd632224373cfcc28c294fc5efe783888c..884b7ce16a3bd3cee27ba80e01e7bd3755d43cbd 100644 (file)
@@ -43,7 +43,7 @@ struct hppa_dma_ops *hppa_dma_ops __read_mostly;
 EXPORT_SYMBOL(hppa_dma_ops);
 
 static struct device root = {
-       .bus_id = "parisc",
+       .init_name = "parisc",
 };
 
 static inline int check_dev(struct device *dev)
@@ -393,7 +393,8 @@ EXPORT_SYMBOL(print_pci_hwpath);
 static void setup_bus_id(struct parisc_device *padev)
 {
        struct hardware_path path;
-       char *output = padev->dev.bus_id;
+       char name[20];
+       char *output = name;
        int i;
 
        get_node_path(padev->dev.parent, &path);
@@ -404,6 +405,7 @@ static void setup_bus_id(struct parisc_device *padev)
                output += sprintf(output, "%u:", (unsigned char) path.bc[i]);
        }
        sprintf(output, "%u", (unsigned char) padev->hw_path);
+       dev_set_name(&padev->dev, name);
 }
 
 struct parisc_device * create_tree_node(char id, struct device *parent)
index 675f1d098f05d2f6ec29ab8c5be3d55005627a03..4c771cd580ecf9abbc4e6d9238accbb0a99bd0d8 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/console.h>
-#include <linux/kallsyms.h>
 #include <linux/bug.h>
 
 #include <asm/assembly.h>
@@ -51,7 +50,7 @@
 DEFINE_SPINLOCK(pa_dbit_lock);
 #endif
 
-void parisc_show_stack(struct task_struct *t, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
        struct pt_regs *regs);
 
 static int printbinary(char *buf, unsigned long x, int nbits)
@@ -121,18 +120,19 @@ static void print_fr(char *level, struct pt_regs *regs)
 
 void show_regs(struct pt_regs *regs)
 {
-       int i;
+       int i, user;
        char *level;
        unsigned long cr30, cr31;
 
-       level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT;
+       user = user_mode(regs);
+       level = user ? KERN_DEBUG : KERN_CRIT;
 
        print_gr(level, regs);
 
        for (i = 0; i < 8; i += 4)
                PRINTREGS(level, regs->sr, "sr", RFMT, i);
 
-       if (user_mode(regs))
+       if (user)
                print_fr(level, regs);
 
        cr30 = mfctl(30);
@@ -145,14 +145,18 @@ void show_regs(struct pt_regs *regs)
        printk("%s CPU: %8d   CR30: " RFMT " CR31: " RFMT "\n",
               level, current_thread_info()->cpu, cr30, cr31);
        printk("%s ORIG_R28: " RFMT "\n", level, regs->orig_r28);
-       printk(level);
-       print_symbol(" IAOQ[0]: %s\n", regs->iaoq[0]);
-       printk(level);
-       print_symbol(" IAOQ[1]: %s\n", regs->iaoq[1]);
-       printk(level);
-       print_symbol(" RP(r2): %s\n", regs->gr[2]);
-
-       parisc_show_stack(current, NULL, regs);
+
+       if (user) {
+               printk("%s IAOQ[0]: " RFMT "\n", level, regs->iaoq[0]);
+               printk("%s IAOQ[1]: " RFMT "\n", level, regs->iaoq[1]);
+               printk("%s RP(r2): " RFMT "\n", level, regs->gr[2]);
+       } else {
+               printk("%s IAOQ[0]: %pS\n", level, (void *) regs->iaoq[0]);
+               printk("%s IAOQ[1]: %pS\n", level, (void *) regs->iaoq[1]);
+               printk("%s RP(r2): %pS\n", level, (void *) regs->gr[2]);
+
+               parisc_show_stack(current, NULL, regs);
+       }
 }
 
 
@@ -173,20 +177,15 @@ static void do_show_stack(struct unwind_frame_info *info)
                        break;
 
                if (__kernel_text_address(info->ip)) {
-                       printk("%s [<" RFMT ">] ", (i&0x3)==1 ? KERN_CRIT : "", info->ip);
-#ifdef CONFIG_KALLSYMS
-                       print_symbol("%s\n", info->ip);
-#else
-                       if ((i & 0x03) == 0)
-                               printk("\n");
-#endif
+                       printk(KERN_CRIT " [<" RFMT ">] %pS\n",
+                               info->ip, (void *) info->ip);
                        i++;
                }
        }
-       printk("\n");
+       printk(KERN_CRIT "\n");
 }
 
-void parisc_show_stack(struct task_struct *task, unsigned long *sp,
+static void parisc_show_stack(struct task_struct *task, unsigned long *sp,
        struct pt_regs *regs)
 {
        struct unwind_frame_info info;
index 226ff066652ba36e8f5e5c229b643a68c03da49d..dea30910c136800cbe1bdb37fbe3e354376cf9d3 100644 (file)
@@ -18,8 +18,8 @@
        #size-cells = <1>;
 
        aliases {
-               ethernet0 = &enet0;
-               ethernet1 = &enet1;
+               ethernet0 = &enet1;
+               ethernet1 = &enet0;
                serial0 = &serial0;
                serial1 = &serial1;
                pci0 = &pci0;
index cadd4652a69556a8eb496449b3d3f15e0d4928fb..5c69b2fafd32c588e64b0bb1ec1f257010477b18 100644 (file)
@@ -90,7 +90,7 @@
                        compatible = "fsl,mpc8572-l2-cache-controller";
                        reg = <0x20000 0x1000>;
                        cache-line-size = <32>; // 32 bytes
-                       cache-size = <0x80000>; // L2, 512K
+                       cache-size = <0x100000>; // L2, 1M
                        interrupt-parent = <&mpic>;
                        interrupts = <16 2>;
                };
diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig
new file mode 100644 (file)
index 0000000..9a9350d
--- /dev/null
@@ -0,0 +1,1176 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc4
+# Fri Nov 14 10:49:16 2008
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_6xx is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+CONFIG_40x=y
+# CONFIG_44x is not set
+# CONFIG_E200 is not set
+CONFIG_4xx=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_NOT_COHERENT_CACHE=y
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+# CONFIG_GENERIC_TBSYNC is not set
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+# CONFIG_EMBEDDED is not set
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
+# CONFIG_PPC4xx_PCI_EXPRESS is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+# CONFIG_PPC4xx_GPIO is not set
+CONFIG_XILINX_VIRTEX=y
+# CONFIG_ACADIA is not set
+# CONFIG_EP405 is not set
+# CONFIG_HCU4 is not set
+# CONFIG_KILAUEA is not set
+# CONFIG_MAKALU is not set
+# CONFIG_WALNUT is not set
+CONFIG_XILINX_VIRTEX_GENERIC_BOARD=y
+# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_XILINX_VIRTEX_II_PRO=y
+CONFIG_XILINX_VIRTEX_4_FX=y
+CONFIG_IBM405_ERR77=y
+CONFIG_IBM405_ERR51=y
+# CONFIG_IPIC is not set
+# CONFIG_MPIC is not set
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_RESOURCES_64BIT=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE=""
+CONFIG_EXTRA_TARGETS=""
+# CONFIG_PM is not set
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_PPC_INDIRECT_PCI=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_PCIEPORTBUS is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
+# CONFIG_PCI_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_CONSISTENT_START=0xff100000
+CONFIG_CONSISTENT_SIZE=0x00200000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=m
+# CONFIG_IPV6_PRIVACY is not set
+# CONFIG_IPV6_ROUTER_PREF is not set
+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
+# CONFIG_INET6_AH is not set
+# CONFIG_INET6_ESP is not set
+# CONFIG_INET6_IPCOMP is not set
+# CONFIG_IPV6_MIP6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_NDISC_NODETYPE=y
+# CONFIG_IPV6_TUNNEL is not set
+# CONFIG_IPV6_MULTIPLE_TABLES is not set
+# CONFIG_IPV6_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+CONFIG_NETFILTER=y
+# CONFIG_NETFILTER_DEBUG is not set
+CONFIG_NETFILTER_ADVANCED=y
+
+#
+# Core Netfilter Configuration
+#
+# CONFIG_NETFILTER_NETLINK_QUEUE is not set
+# CONFIG_NETFILTER_NETLINK_LOG is not set
+# CONFIG_NF_CONNTRACK is not set
+CONFIG_NETFILTER_XTABLES=m
+# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
+# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
+# CONFIG_NETFILTER_XT_TARGET_MARK is not set
+# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
+# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
+# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
+# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
+# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
+# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
+# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
+# CONFIG_NETFILTER_XT_MATCH_MAC is not set
+# CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
+# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
+# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
+# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
+# CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
+# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
+# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
+# CONFIG_NETFILTER_XT_MATCH_STRING is not set
+# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
+# CONFIG_NETFILTER_XT_MATCH_TIME is not set
+# CONFIG_NETFILTER_XT_MATCH_U32 is not set
+# CONFIG_IP_VS is not set
+
+#
+# IP: Netfilter Configuration
+#
+# CONFIG_NF_DEFRAG_IPV4 is not set
+# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_IPTABLES=m
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
+# CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_TTL is not set
+CONFIG_IP_NF_FILTER=m
+# CONFIG_IP_NF_TARGET_REJECT is not set
+# CONFIG_IP_NF_TARGET_LOG is not set
+# CONFIG_IP_NF_TARGET_ULOG is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_ECN is not set
+# CONFIG_IP_NF_TARGET_TTL is not set
+# CONFIG_IP_NF_RAW is not set
+# CONFIG_IP_NF_ARPTABLES is not set
+
+#
+# IPv6: Netfilter Configuration
+#
+# CONFIG_IP6_NF_QUEUE is not set
+# CONFIG_IP6_NF_IPTABLES is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
+# CONFIG_WIRELESS_EXT is not set
+# CONFIG_MAC80211 is not set
+# CONFIG_IEEE80211 is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+# CONFIG_MTD is not set
+CONFIG_OF_DEVICE=y
+CONFIG_OF_GPIO=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=8192
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_XILINX_SYSACE=y
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_PHANTOM is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_SGI_IOC4 is not set
+# CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_IEEE1394 is not set
+# CONFIG_I2O is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_HAPPYMEAL is not set
+# CONFIG_SUNGEM is not set
+# CONFIG_CASSINI is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_TULIP is not set
+# CONFIG_HP100 is not set
+# CONFIG_IBM_NEW_EMAC is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=y
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_LIFEBOOK=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+CONFIG_SERIO_XILINX_XPS_PS2=y
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_OF_PLATFORM is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=m
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+CONFIG_XILINX_HWICAP=y
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_XILINX=y
+
+#
+# I2C GPIO expanders:
+#
+
+#
+# PCI GPIO expanders:
+#
+# CONFIG_GPIO_BT8XX is not set
+
+#
+# SPI GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+CONFIG_FB_XILINX=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE is not set
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+CONFIG_ROMFS_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
+# CONFIG_PPC_EARLY_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index 663ec512b33bc64c9ec20d59dde0662f6ddd0f93..7513d360e0b04bf4b8f15f1fa79b81411e26bc4c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc1
-# Tue Aug  5 09:20:16 2008
+# Linux kernel version: 2.6.28-rc4
+# Fri Nov 14 10:31:16 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,14 +22,13 @@ CONFIG_PHYS_64BIT=y
 CONFIG_NOT_COHERENT_CACHE=y
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
-# CONFIG_HAVE_GET_USER_PAGES_FAST is not set
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -40,6 +39,7 @@ CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_GPIO=y
 # CONFIG_ARCH_NO_VIRT_TO_BUS is not set
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
@@ -93,8 +93,8 @@ CONFIG_INITRAMFS_SOURCE=""
 CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
@@ -109,7 +109,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -122,10 +124,6 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -158,6 +156,7 @@ CONFIG_DEFAULT_CFQ=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="cfq"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
 #
@@ -174,9 +173,13 @@ CONFIG_CLASSIC_RCU=y
 # CONFIG_KATMAI is not set
 # CONFIG_RAINIER is not set
 # CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
 # CONFIG_YOSEMITE is not set
 CONFIG_XILINX_VIRTEX440_GENERIC_BOARD=y
+# CONFIG_PPC44x_SIMPLE is not set
+# CONFIG_PPC4xx_GPIO is not set
 CONFIG_XILINX_VIRTEX=y
 CONFIG_XILINX_VIRTEX_5_FXT=y
 # CONFIG_IPIC is not set
@@ -196,7 +199,6 @@ CONFIG_XILINX_VIRTEX_5_FXT=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -211,6 +213,8 @@ CONFIG_HZ=250
 CONFIG_PREEMPT=y
 # CONFIG_PREEMPT_RCU is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 CONFIG_MATH_EMULATION=y
 # CONFIG_IOMMU_HELPER is not set
@@ -225,15 +229,15 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -256,6 +260,7 @@ CONFIG_PCI_SYSCALL=y
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
 CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -317,7 +322,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=m
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -352,8 +356,8 @@ CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
 # CONFIG_NETFILTER_XT_TARGET_DSCP is not set
 # CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
 # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
+# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
 # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
 # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
 # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
@@ -361,36 +365,38 @@ CONFIG_NETFILTER_XTABLES=m
 # CONFIG_NETFILTER_XT_MATCH_DCCP is not set
 # CONFIG_NETFILTER_XT_MATCH_DSCP is not set
 # CONFIG_NETFILTER_XT_MATCH_ESP is not set
+# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
 # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
 # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
 # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
 # CONFIG_NETFILTER_XT_MATCH_MAC is not set
 # CONFIG_NETFILTER_XT_MATCH_MARK is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
 # CONFIG_NETFILTER_XT_MATCH_OWNER is not set
 # CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
 # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
 # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
 # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
 # CONFIG_NETFILTER_XT_MATCH_REALM is not set
+# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
 # CONFIG_NETFILTER_XT_MATCH_SCTP is not set
 # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
 # CONFIG_NETFILTER_XT_MATCH_STRING is not set
 # CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
 # CONFIG_NETFILTER_XT_MATCH_TIME is not set
 # CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 # CONFIG_IP_NF_QUEUE is not set
 CONFIG_IP_NF_IPTABLES=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
+# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
 # CONFIG_IP_NF_MATCH_AH is not set
+# CONFIG_IP_NF_MATCH_ECN is not set
 # CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
 CONFIG_IP_NF_FILTER=m
 # CONFIG_IP_NF_TARGET_REJECT is not set
 # CONFIG_IP_NF_TARGET_LOG is not set
@@ -411,6 +417,7 @@ CONFIG_IP_NF_MANGLE=m
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -431,11 +438,10 @@ CONFIG_IP_NF_MANGLE=m
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
 # CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
 # CONFIG_WIRELESS_EXT is not set
 # CONFIG_MAC80211 is not set
 # CONFIG_IEEE80211 is not set
@@ -455,11 +461,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
 CONFIG_FW_LOADER=y
 CONFIG_FIRMWARE_IN_KERNEL=y
 CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
 # CONFIG_SYS_HYPERVISOR is not set
 # CONFIG_CONNECTOR is not set
 # CONFIG_MTD is not set
 CONFIG_OF_DEVICE=y
-CONFIG_OF_I2C=y
+CONFIG_OF_GPIO=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -478,7 +486,7 @@ CONFIG_BLK_DEV_RAM_SIZE=8192
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_XILINX_SYSACE is not set
+CONFIG_XILINX_SYSACE=y
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
@@ -487,6 +495,7 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -534,8 +543,12 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
@@ -556,6 +569,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
 
@@ -604,6 +618,7 @@ CONFIG_KEYBOARD_ATKBD=y
 # CONFIG_KEYBOARD_XTKBD is not set
 # CONFIG_KEYBOARD_NEWTON is not set
 # CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_GPIO is not set
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 CONFIG_MOUSE_PS2_ALPS=y
@@ -611,9 +626,11 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
 CONFIG_MOUSE_PS2_SYNAPTICS=y
 CONFIG_MOUSE_PS2_LIFEBOOK=y
 CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
 # CONFIG_MOUSE_PS2_TOUCHKIT is not set
 # CONFIG_MOUSE_SERIAL is not set
 # CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TABLET is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -624,11 +641,11 @@ CONFIG_MOUSE_PS2_TRACKPOINT=y
 #
 CONFIG_SERIO=y
 # CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_SERPORT is not set
 # CONFIG_SERIO_PCIPS2 is not set
 CONFIG_SERIO_LIBPS2=y
 # CONFIG_SERIO_RAW is not set
-# CONFIG_SERIO_XILINX_XPS_PS2 is not set
+CONFIG_SERIO_XILINX_XPS_PS2=y
 # CONFIG_GAMEPORT is not set
 
 #
@@ -656,11 +673,12 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
-CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -674,87 +692,41 @@ CONFIG_XILINX_HWICAP=y
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
 CONFIG_DEVPORT=y
-CONFIG_I2C=y
-CONFIG_I2C_BOARDINFO=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Hardware Bus support
-#
-
-#
-# PC SMBus host controller drivers
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
 
 #
-# I2C system bus drivers (mostly embedded / system-on-chip)
+# Memory mapped GPIO expanders:
 #
-# CONFIG_I2C_IBM_IIC is not set
-# CONFIG_I2C_MPC is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_SIMTEC is not set
+CONFIG_GPIO_XILINX=y
 
 #
-# External I2C/SMBus adapter drivers
+# I2C GPIO expanders:
 #
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_TAOS_EVM is not set
 
 #
-# Graphics adapter I2C/DDC channel drivers
+# PCI GPIO expanders:
 #
-# CONFIG_I2C_VOODOO3 is not set
+# CONFIG_GPIO_BT8XX is not set
 
 #
-# Other I2C/SMBus bus drivers
+# SPI GPIO expanders:
 #
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_STUB is not set
-
-#
-# Miscellaneous I2C Chip support
-#
-# CONFIG_DS1682 is not set
-# CONFIG_AT24 is not set
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_PCF8575 is not set
-# CONFIG_SENSORS_PCA9539 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-CONFIG_I2C_DEBUG_CORE=y
-CONFIG_I2C_DEBUG_ALGO=y
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-# CONFIG_SPI is not set
-CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
-# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -763,6 +735,8 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -790,6 +764,7 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_FB=y
 # CONFIG_FIRMWARE_EDID is not set
 # CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
 CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
@@ -826,6 +801,7 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_S3 is not set
 # CONFIG_FB_SAVAGE is not set
 # CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
 # CONFIG_FB_NEOMAGIC is not set
 # CONFIG_FB_KYRO is not set
 # CONFIG_FB_3DFX is not set
@@ -838,6 +814,8 @@ CONFIG_FB_CFB_IMAGEBLIT=y
 # CONFIG_FB_IBM_GXT4500 is not set
 CONFIG_FB_XILINX=y
 # CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
@@ -870,6 +848,7 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
@@ -879,6 +858,8 @@ CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -887,10 +868,11 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XATTR is not set
 # CONFIG_EXT2_FS_XIP is not set
 # CONFIG_EXT3_FS is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -899,7 +881,7 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
-CONFIG_FUSE_FS=m
+# CONFIG_FUSE_FS is not set
 
 #
 # CD-ROM/DVD Filesystems
@@ -923,6 +905,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -954,19 +937,15 @@ CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
 CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
+# CONFIG_SMB_FS is not set
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 # CONFIG_CODA_FS is not set
@@ -1023,7 +1002,6 @@ CONFIG_NLS_UTF8=m
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 CONFIG_CRC_CCITT=y
 # CONFIG_CRC16 is not set
 # CONFIG_CRC_T10DIF is not set
@@ -1041,7 +1019,7 @@ CONFIG_HAVE_LMB=y
 #
 # Kernel hacking
 #
-# CONFIG_PRINTK_TIME is not set
+CONFIG_PRINTK_TIME=y
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
@@ -1049,19 +1027,62 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
 # CONFIG_HEADERS_CHECK is not set
-# CONFIG_DEBUG_KERNEL is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
 CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_PREEMPT_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
 # CONFIG_IRQSTACKS is not set
+# CONFIG_BDI_SWITCH is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
 
 #
@@ -1069,12 +1090,14 @@ CONFIG_HAVE_ARCH_KGDB=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 # CONFIG_CRYPTO_MANAGER is not set
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1147,6 +1170,11 @@ CONFIG_CRYPTO=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 # CONFIG_PPC_CLOCK is not set
index c10f7395aa1b074e791c3ceceecd8f71706ca60b..3df627494b650844a53844dbf425bdcb77461ce3 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 07:11:37 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:12:40 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,7 +22,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -102,6 +103,7 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
@@ -110,9 +112,13 @@ CONFIG_SLUB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -123,6 +129,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -137,19 +144,16 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
@@ -159,7 +163,10 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -183,7 +190,6 @@ CONFIG_PPC_BESTCOMM_FEC=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -197,6 +203,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -211,19 +219,20 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -233,7 +242,7 @@ CONFIG_ISA_DMA_API=y
 #
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
 # CONFIG_PCI_SYSCALL is not set
@@ -254,10 +263,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -308,6 +313,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -328,14 +334,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -446,6 +446,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -487,11 +488,11 @@ CONFIG_CHR_DEV_SG=y
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
 # CONFIG_ATA is not set
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -521,6 +522,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
@@ -532,7 +536,6 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
@@ -567,6 +570,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -596,25 +600,40 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
 # CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -623,10 +642,13 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -640,24 +662,39 @@ CONFIG_WATCHDOG=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -672,10 +709,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -695,11 +728,16 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
 CONFIG_USB_OHCI_HCD_PPC_OF=y
@@ -710,12 +748,16 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -744,7 +786,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -757,7 +798,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -773,14 +814,19 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -792,12 +838,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -830,6 +877,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -860,6 +908,7 @@ CONFIG_JFFS2_RTIME=y
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -870,14 +919,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -953,9 +1002,9 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -982,9 +1031,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -998,16 +1050,37 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_INFO is not set
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
 # CONFIG_BOOTX_TEXT is not set
@@ -1018,14 +1091,19 @@ CONFIG_SCHED_DEBUG=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1063,6 +1141,10 @@ CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1093,6 +1175,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
index 1a8a250fa11b0c14753ad7a02f489320f144fc6d..5b969f9c925effbd2f5fb77e767b20d6be4919fd 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 07:12:56 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:10:16 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,7 +22,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -103,7 +104,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
@@ -111,24 +114,30 @@ CONFIG_SLUB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -143,19 +152,16 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
@@ -165,7 +171,10 @@ CONFIG_PPC_LITE5200=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -198,11 +207,13 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -217,19 +228,20 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_PM_SLEEP=y
 CONFIG_SUSPEND=y
@@ -243,7 +255,7 @@ CONFIG_ISA_DMA_API=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
@@ -269,10 +281,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -323,6 +331,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -343,14 +352,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -390,12 +393,16 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -412,7 +419,7 @@ CONFIG_SCSI_DMA=y
 #
 # SCSI support type (disk, tape, CD-ROM)
 #
-# CONFIG_BLK_DEV_SD is not set
+CONFIG_BLK_DEV_SD=y
 # CONFIG_CHR_DEV_ST is not set
 # CONFIG_CHR_DEV_OSST is not set
 # CONFIG_BLK_DEV_SR is not set
@@ -474,12 +481,12 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_FSL is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
@@ -535,18 +542,22 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -583,16 +594,19 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_ATL2 is not set
 CONFIG_NETDEV_1000=y
 # CONFIG_ACENIC is not set
 # CONFIG_DL2K is not set
 # CONFIG_E1000 is not set
 # CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
@@ -605,22 +619,27 @@ CONFIG_NETDEV_1000=y
 # CONFIG_VIA_VELOCITY is not set
 # CONFIG_TIGON3 is not set
 # CONFIG_BNX2 is not set
-# CONFIG_GIANFAR is not set
 # CONFIG_MV643XX_ETH is not set
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
 # CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
 # CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
 # CONFIG_TR is not set
 
 #
@@ -628,7 +647,6 @@ CONFIG_NETDEV_10000=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_FDDI is not set
@@ -657,6 +675,7 @@ CONFIG_NETDEV_10000=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_NOZOMI is not set
 
@@ -691,42 +710,63 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -735,29 +775,47 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -774,10 +832,6 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -787,18 +841,26 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
 
+#
+# Enable Host or Gadget support to see Inventra options
+#
+
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
 #
 # CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -810,12 +872,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -845,6 +908,7 @@ CONFIG_INOTIFY_USER=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -864,6 +928,7 @@ CONFIG_TMPFS=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -874,14 +939,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -902,9 +967,9 @@ CONFIG_MSDOS_PARTITION=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -929,9 +994,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -945,17 +1013,37 @@ CONFIG_SCHED_DEBUG=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
 # CONFIG_BOOTX_TEXT is not set
@@ -966,14 +1054,19 @@ CONFIG_DEBUG_INFO=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1012,6 +1105,10 @@ CONFIG_CRYPTO_CBC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1042,6 +1139,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
 CONFIG_PPC_CLOCK=y
index 8c7ba7c6ba49241c0484e940dccb1e98da96a97e..3c0d4e561726d98ce441f1f440b97ccc1d148c3f 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 07:12:22 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:11:02 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,7 +22,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -102,6 +103,7 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
@@ -110,9 +112,13 @@ CONFIG_SLUB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -123,6 +129,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -137,19 +144,16 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
@@ -159,7 +163,10 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -183,7 +190,6 @@ CONFIG_PPC_BESTCOMM_FEC=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -197,6 +203,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -211,19 +219,20 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -233,7 +242,7 @@ CONFIG_ISA_DMA_API=y
 #
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
 # CONFIG_PCI_SYSCALL is not set
@@ -254,10 +263,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -308,6 +313,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -328,14 +334,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -445,9 +445,12 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -490,10 +493,10 @@ CONFIG_CHR_DEV_SG=y
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
-# CONFIG_SATA_FSL is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
 CONFIG_PATA_MPC52xx=y
@@ -501,7 +504,6 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -531,6 +533,9 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
@@ -542,7 +547,6 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 # CONFIG_WAN is not set
 # CONFIG_PPP is not set
@@ -568,6 +572,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -596,24 +601,39 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -622,10 +642,13 @@ CONFIG_SENSORS_EEPROM=y
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -633,6 +656,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
@@ -675,6 +699,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -683,24 +708,39 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_SOFT_WATCHDOG is not set
 # CONFIG_MPC5200_WDT is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 CONFIG_DAB=y
 
 #
@@ -715,10 +755,6 @@ CONFIG_DAB=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 # CONFIG_USB_SUPPORT is not set
 # CONFIG_MMC is not set
@@ -729,6 +765,7 @@ CONFIG_LEDS_CLASS=y
 #
 # LED drivers
 #
+# CONFIG_LEDS_PCA955X is not set
 
 #
 # LED Triggers
@@ -736,7 +773,9 @@ CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
 # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_EDAC is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -767,6 +806,8 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
@@ -776,19 +817,25 @@ CONFIG_RTC_DRV_DS1307=y
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
+# CONFIG_RTC_DRV_PPC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -800,12 +847,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -838,6 +886,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -868,6 +917,7 @@ CONFIG_JFFS2_RTIME=y
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -878,14 +928,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -961,9 +1011,9 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -990,9 +1040,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1006,16 +1059,37 @@ CONFIG_SCHED_DEBUG=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
 # CONFIG_BOOTX_TEXT is not set
@@ -1026,14 +1100,19 @@ CONFIG_DEBUG_INFO=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1071,6 +1150,10 @@ CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1101,6 +1184,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
index 9c0caa488b2e29c1fd214b001dc66c1fe72be212..9d0207783d60ee9ef11ad1d83d2728d229caa7e0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 07:13:19 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:13:16 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,7 +22,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -104,7 +105,9 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 # CONFIG_VM_EVENT_COUNTERS is not set
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
 # CONFIG_SLOB is not set
@@ -112,24 +115,30 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -144,19 +153,16 @@ CONFIG_IOSCHED_NOOP=y
 CONFIG_DEFAULT_NOOP=y
 CONFIG_DEFAULT_IOSCHED="noop"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
@@ -166,7 +172,10 @@ CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -199,12 +208,14 @@ CONFIG_HZ_100=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=100
-# CONFIG_SCHED_HRTICK is not set
+CONFIG_SCHED_HRTICK=y
 # CONFIG_PREEMPT_NONE is not set
 # CONFIG_PREEMPT_VOLUNTARY is not set
 CONFIG_PREEMPT=y
 # CONFIG_PREEMPT_RCU is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -219,17 +230,19 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 # CONFIG_PM is not set
 # CONFIG_SECCOMP is not set
 CONFIG_ISA_DMA_API=y
@@ -240,7 +253,7 @@ CONFIG_ISA_DMA_API=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
@@ -265,10 +278,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -313,6 +322,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -333,14 +343,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -484,12 +488,12 @@ CONFIG_SCSI_WAIT_SCAN=m
 # CONFIG_SCSI_SAS_LIBSAS is not set
 # CONFIG_SCSI_SRP_ATTRS is not set
 # CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=m
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
 # CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_FSL is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
@@ -545,18 +549,22 @@ CONFIG_PATA_MPC52xx=m
 # CONFIG_PATA_VIA is not set
 # CONFIG_PATA_WINBOND is not set
 # CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -593,10 +601,14 @@ CONFIG_MII=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -606,7 +618,6 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
@@ -644,6 +655,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 # CONFIG_NOZOMI is not set
 
@@ -675,43 +687,64 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# PC SMBus host controller drivers
+#
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
 # CONFIG_I2C_ALI15X3 is not set
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 CONFIG_SENSORS_EEPROM=m
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -720,29 +753,47 @@ CONFIG_SENSORS_EEPROM=m
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -759,10 +810,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -781,12 +828,17 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=m
 # CONFIG_USB_OHCI_HCD_PPC_SOC is not set
 CONFIG_USB_OHCI_HCD_PPC_OF=y
@@ -799,12 +851,17 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -833,7 +890,6 @@ CONFIG_USB_STORAGE=m
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
 
 #
 # USB port drivers
@@ -846,7 +902,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -862,10 +918,14 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
 CONFIG_RTC_LIB=m
@@ -894,6 +954,8 @@ CONFIG_RTC_DRV_PCF8563=m
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
@@ -903,19 +965,25 @@ CONFIG_RTC_DRV_PCF8563=m
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
+# CONFIG_RTC_DRV_PPC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -927,12 +995,13 @@ CONFIG_EXT3_FS=m
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=m
 CONFIG_FS_MBCACHE=m
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 # CONFIG_DNOTIFY is not set
@@ -964,6 +1033,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 # CONFIG_PROC_KCORE is not set
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -994,6 +1064,7 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1004,13 +1075,13 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 # CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1070,9 +1141,9 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -1098,7 +1169,17 @@ CONFIG_FRAME_WARN=1024
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
@@ -1108,6 +1189,7 @@ CONFIG_FRAME_WARN=1024
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 # CONFIG_CRYPTO is not set
 CONFIG_PPC_CLOCK=y
index 7672bfba35664557630fe9aa9285ed25f529746d..bc190051e8d50d70b57463be5fee5cd0c46adb40 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 07:12:39 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:09:30 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,7 +22,7 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
@@ -32,6 +32,7 @@ CONFIG_GENERIC_HARDIRQS=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
 CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -102,6 +103,7 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
@@ -110,14 +112,19 @@ CONFIG_SLUB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 CONFIG_MODVERSIONS=y
@@ -128,6 +135,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -142,19 +150,16 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
-# CONFIG_PPC_MPC512x is not set
-# CONFIG_PPC_MPC5121 is not set
 # CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 # CONFIG_PPC_EFIKA is not set
@@ -164,7 +169,10 @@ CONFIG_PPC_MPC5200_BUGFIX=y
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -188,7 +196,6 @@ CONFIG_PPC_BESTCOMM_FEC=y
 # Kernel options
 #
 # CONFIG_HIGHMEM is not set
-# CONFIG_TICK_ONESHOT is not set
 # CONFIG_NO_HZ is not set
 # CONFIG_HIGH_RES_TIMERS is not set
 CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
@@ -202,6 +209,8 @@ CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
@@ -216,19 +225,20 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_SECCOMP=y
 CONFIG_ISA_DMA_API=y
@@ -238,7 +248,7 @@ CONFIG_ISA_DMA_API=y
 #
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 # CONFIG_PCI is not set
 # CONFIG_PCI_DOMAINS is not set
 # CONFIG_PCI_SYSCALL is not set
@@ -259,10 +269,6 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -313,6 +319,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -333,14 +340,8 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -451,6 +452,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 # CONFIG_MISC_DEVICES is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
@@ -495,10 +497,10 @@ CONFIG_SCSI_WAIT_SCAN=m
 CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_ISCSI_TCP is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
 CONFIG_SATA_PMP=y
-# CONFIG_SATA_FSL is not set
 CONFIG_ATA_SFF=y
 # CONFIG_SATA_MV is not set
 CONFIG_PATA_MPC52xx=y
@@ -507,7 +509,6 @@ CONFIG_PATA_PLATFORM=y
 # CONFIG_MD is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -537,6 +538,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
@@ -548,7 +552,6 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI is not set
 # CONFIG_IWLWIFI_LEDS is not set
 
 #
@@ -583,6 +586,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # Character devices
 #
 # CONFIG_VT is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
 
 #
@@ -611,26 +615,41 @@ CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
 
 #
 # I2C Hardware Bus support
 #
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
 # CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
 # CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
 
 #
 # Miscellaneous I2C Chip support
 #
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
@@ -639,10 +658,13 @@ CONFIG_I2C_MPC=y
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
 # CONFIG_SPI is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -650,6 +672,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
@@ -692,6 +715,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -705,24 +729,39 @@ CONFIG_WATCHDOG=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 # CONFIG_DAB is not set
 
 #
@@ -737,10 +776,6 @@ CONFIG_SSB_POSSIBLE=y
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -760,11 +795,16 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_OTG is not set
 # CONFIG_USB_OTG_WHITELIST is not set
 # CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
 CONFIG_USB_OHCI_HCD_PPC_OF=y
@@ -775,12 +815,16 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 # CONFIG_USB_OHCI_LITTLE_ENDIAN is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -809,7 +853,6 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
@@ -822,7 +865,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -838,10 +881,13 @@ CONFIG_USB_MON=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_EDAC is not set
 CONFIG_RTC_LIB=y
 CONFIG_RTC_CLASS=y
@@ -872,6 +918,8 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
 # CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
 
 #
 # SPI RTC drivers
@@ -881,19 +929,25 @@ CONFIG_RTC_DRV_DS1307=y
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
 # CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
 # CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
 # CONFIG_RTC_DRV_V3020 is not set
 
 #
 # on-CPU RTC drivers
 #
+# CONFIG_RTC_DRV_PPC is not set
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -905,12 +959,13 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_OCFS2_FS is not set
 CONFIG_DNOTIFY=y
@@ -943,6 +998,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -973,6 +1029,7 @@ CONFIG_JFFS2_RTIME=y
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
 # CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -983,14 +1040,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1066,9 +1123,9 @@ CONFIG_NLS_ISO8859_1=y
 # Library routines
 #
 CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -1095,9 +1152,12 @@ CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
 # CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
@@ -1111,17 +1171,37 @@ CONFIG_SCHED_DEBUG=y
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
 # CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
 # CONFIG_BOOTX_TEXT is not set
@@ -1132,14 +1212,19 @@ CONFIG_DEBUG_INFO=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
@@ -1178,6 +1263,10 @@ CONFIG_CRYPTO_PCBC=y
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
@@ -1208,6 +1297,11 @@ CONFIG_CRYPTO_DES=y
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
index 2da13e00a807da950ea7812d77625ddd0177783a..07ccaf89f3793bf53006c0f8e2a011671e47766f 100644 (file)
@@ -838,7 +838,7 @@ CONFIG_PHYLIB=y
 #
 # MII PHY device drivers
 #
-CONFIG_MARVELL_PHY=y
+# CONFIG_MARVELL_PHY is not set
 # CONFIG_DAVICOM_PHY is not set
 # CONFIG_QSEMI_PHY is not set
 # CONFIG_LXT_PHY is not set
index 740c9f2b7de612b1c2cfd7e27d489d18436489f2..15c5604d0b26e6f44a9d4c6827a37fac8f83d85b 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Fri Jan 18 14:19:54 2008
+# Linux kernel version: 2.6.28-rc4
+# Thu Nov 13 02:09:07 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -22,14 +22,18 @@ CONFIG_PPC_STD_MMU_32=y
 # CONFIG_SMP is not set
 CONFIG_PPC32=y
 CONFIG_WORD_SIZE=32
-CONFIG_PPC_MERGE=y
+# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set
 CONFIG_MMU=y
 CONFIG_GENERIC_CMOS_UPDATE=y
 CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
 CONFIG_GENERIC_HWEIGHT=y
@@ -47,7 +51,8 @@ CONFIG_OF=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
-# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_DEFAULT_UIMAGE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_PPC_DCR_NATIVE is not set
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
@@ -66,17 +71,15 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -88,32 +91,49 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 # CONFIG_EPOLL is not set
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_CLK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
 CONFIG_BLOCK=y
 # CONFIG_LBD is not set
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 # CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -127,29 +147,34 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
+CONFIG_FREEZER=y
 
 #
 # Platform support
 #
 CONFIG_PPC_MULTIPLATFORM=y
-# CONFIG_PPC_82xx is not set
-# CONFIG_PPC_83xx is not set
-# CONFIG_PPC_86xx is not set
 CONFIG_CLASSIC32=y
 # CONFIG_PPC_CHRP is not set
+# CONFIG_MPC5121_ADS is not set
+# CONFIG_MPC5121_GENERIC is not set
 CONFIG_PPC_MPC52xx=y
-CONFIG_PPC_MPC5200=y
-CONFIG_PPC_MPC5200_BUGFIX=y
 CONFIG_PPC_MPC5200_SIMPLE=y
 CONFIG_PPC_EFIKA=y
 CONFIG_PPC_LITE5200=y
+CONFIG_PPC_MPC5200_BUGFIX=y
+# CONFIG_PPC_MPC5200_GPIO is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_CELL is not set
 # CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PPC_82xx is not set
 # CONFIG_PQ2ADS is not set
+# CONFIG_PPC_83xx is not set
+# CONFIG_PPC_86xx is not set
 # CONFIG_EMBEDDED6xx is not set
 CONFIG_PPC_NATIVE=y
 # CONFIG_UDBG_RTAS_CONSOLE is not set
+# CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -163,7 +188,6 @@ CONFIG_RTAS_PROC=y
 # CONFIG_GENERIC_IOMAP is not set
 # CONFIG_CPU_FREQ is not set
 # CONFIG_TAU is not set
-# CONFIG_CPM2 is not set
 # CONFIG_FSL_ULI1575 is not set
 CONFIG_PPC_BESTCOMM=y
 CONFIG_PPC_BESTCOMM_ATA=y
@@ -183,12 +207,18 @@ CONFIG_HZ_250=y
 # CONFIG_HZ_300 is not set
 # CONFIG_HZ_1000 is not set
 CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
 CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 # CONFIG_BINFMT_MISC is not set
+# CONFIG_IOMMU_HELPER is not set
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 CONFIG_ARCH_FLATMEM_ENABLE=y
 CONFIG_ARCH_POPULATES_NODE_MAP=y
@@ -198,26 +228,25 @@ CONFIG_FLATMEM_MANUAL=y
 # CONFIG_SPARSEMEM_MANUAL is not set
 CONFIG_FLATMEM=y
 CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
 # CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_EXTRA_TARGETS=""
 CONFIG_PM=y
-# CONFIG_PM_LEGACY is not set
 # CONFIG_PM_DEBUG is not set
 CONFIG_PM_SLEEP=y
-CONFIG_SUSPEND_UP_POSSIBLE=y
 CONFIG_SUSPEND=y
-CONFIG_HIBERNATION_UP_POSSIBLE=y
-# CONFIG_HIBERNATION is not set
+CONFIG_SUSPEND_FREEZER=y
 CONFIG_SECCOMP=y
-CONFIG_WANT_DEVICE_TREE=y
-CONFIG_DEVICE_TREE=""
 CONFIG_ISA_DMA_API=y
 
 #
@@ -226,7 +255,7 @@ CONFIG_ISA_DMA_API=y
 CONFIG_ZONE_DMA=y
 CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
-CONFIG_FSL_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
 CONFIG_PCI_SYSCALL=y
@@ -237,6 +266,7 @@ CONFIG_PCI_LEGACY=y
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
+# CONFIG_HAS_RAPIDIO is not set
 
 #
 # Advanced setup
@@ -246,15 +276,11 @@ CONFIG_PCI_LEGACY=y
 #
 # Default settings for advanced configuration options are used
 #
-CONFIG_HIGHMEM_START=0xfe000000
 CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_BOOT_LOAD=0x00800000
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -267,6 +293,7 @@ CONFIG_XFRM=y
 CONFIG_XFRM_USER=m
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -297,8 +324,6 @@ CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
 # CONFIG_IPV6 is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETWORK_SECMARK is not set
 # CONFIG_NETFILTER is not set
 # CONFIG_IP_DCCP is not set
@@ -306,6 +331,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TIPC is not set
 # CONFIG_ATM is not set
 # CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
 # CONFIG_VLAN_8021Q is not set
 # CONFIG_DECNET is not set
 # CONFIG_LLC2 is not set
@@ -322,17 +348,12 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
-# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
-# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_PHONET is not set
+# CONFIG_WIRELESS is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 
@@ -357,6 +378,8 @@ CONFIG_MTD_CONCAT=y
 CONFIG_MTD_PARTITIONS=y
 # CONFIG_MTD_REDBOOT_PARTS is not set
 CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_OF_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # User Modules And Translation Layers
@@ -428,6 +451,7 @@ CONFIG_MTD_PHYSMAP_OF=y
 #
 # CONFIG_MTD_UBI is not set
 CONFIG_OF_DEVICE=y
+CONFIG_OF_I2C=y
 # CONFIG_PARPORT is not set
 CONFIG_BLK_DEV=y
 # CONFIG_BLK_DEV_FD is not set
@@ -444,14 +468,20 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=32768
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
+CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
 #
@@ -516,6 +546,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -528,9 +559,13 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_NSP32 is not set
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_ATA=y
 # CONFIG_ATA_NONSTANDARD is not set
+CONFIG_SATA_PMP=y
 # CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_SIL24 is not set
+CONFIG_ATA_SFF=y
 # CONFIG_SATA_SVW is not set
 # CONFIG_ATA_PIIX is not set
 # CONFIG_SATA_MV is not set
@@ -540,7 +575,6 @@ CONFIG_ATA=y
 # CONFIG_SATA_PROMISE is not set
 # CONFIG_SATA_SX4 is not set
 # CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
 # CONFIG_SATA_SIS is not set
 # CONFIG_SATA_ULI is not set
 # CONFIG_SATA_VIA is not set
@@ -570,6 +604,7 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
 # CONFIG_PATA_NS87410 is not set
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
@@ -586,25 +621,28 @@ CONFIG_PATA_MPC52xx=y
 # CONFIG_PATA_WINBOND is not set
 CONFIG_PATA_PLATFORM=y
 # CONFIG_PATA_OF_PLATFORM is not set
+# CONFIG_PATA_SCH is not set
 # CONFIG_MD is not set
 # CONFIG_FUSION is not set
 
 #
 # IEEE 1394 (FireWire) support
 #
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
 # CONFIG_FIREWIRE is not set
 # CONFIG_IEEE1394 is not set
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 CONFIG_PHYLIB=y
 
@@ -620,6 +658,7 @@ CONFIG_PHYLIB=y
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -634,10 +673,14 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 # CONFIG_NET_PCI is not set
 # CONFIG_B44 is not set
 CONFIG_FEC_MPC52xx=y
 CONFIG_FEC_MPC52xx_MDIO=y
+# CONFIG_ATL2 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_TR is not set
@@ -647,6 +690,7 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # USB Network Adapters
@@ -662,7 +706,6 @@ CONFIG_FEC_MPC52xx_MDIO=y
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -672,7 +715,30 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # Input device support
 #
-# CONFIG_INPUT is not set
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_PSAUX=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
 
 #
 # Hardware I/O ports
@@ -683,8 +749,14 @@ CONFIG_FEC_MPC52xx_MDIO=y
 #
 # Character devices
 #
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -718,16 +790,15 @@ CONFIG_DEVPORT=y
 CONFIG_I2C=y
 CONFIG_I2C_BOARDINFO=y
 CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+CONFIG_I2C_ALGOBIT=y
 
 #
-# I2C Algorithms
+# I2C Hardware Bus support
 #
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
 
 #
-# I2C Hardware Bus support
+# PC SMBus host controller drivers
 #
 # CONFIG_I2C_ALI1535 is not set
 # CONFIG_I2C_ALI1563 is not set
@@ -735,52 +806,64 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD756 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
+# CONFIG_I2C_ISCH is not set
 # CONFIG_I2C_PIIX4 is not set
-CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_I2C_SIMTEC is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TINY_USB is not set
 # CONFIG_I2C_VIA is not set
 # CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+CONFIG_I2C_MPC=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Graphics adapter I2C/DDC channel drivers
+#
 # CONFIG_I2C_VOODOO3 is not set
 
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
+# CONFIG_AT24 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# SPI support
-#
 # CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
 # CONFIG_W1 is not set
 # CONFIG_POWER_SUPPLY is not set
 CONFIG_HWMON=y
 # CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7414 is not set
 # CONFIG_SENSORS_AD7418 is not set
 # CONFIG_SENSORS_ADM1021 is not set
 # CONFIG_SENSORS_ADM1025 is not set
@@ -788,7 +871,9 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1029 is not set
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -818,6 +903,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
@@ -827,9 +913,12 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 CONFIG_WATCHDOG=y
 # CONFIG_WATCHDOG_NOWAYOUT is not set
 
@@ -837,6 +926,7 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
 # CONFIG_MPC5200_WDT is not set
 # CONFIG_WATCHDOG_RTAS is not set
 
@@ -850,23 +940,39 @@ CONFIG_WATCHDOG=y
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
 #
+
+#
+# Multimedia core support
+#
 # CONFIG_VIDEO_DEV is not set
 # CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
 CONFIG_DAB=y
 # CONFIG_USB_DABUSB is not set
 
@@ -874,11 +980,78 @@ CONFIG_DAB=y
 # Graphics support
 #
 # CONFIG_AGP is not set
-# CONFIG_DRM is not set
+CONFIG_DRM=y
+# CONFIG_DRM_TDFX is not set
+# CONFIG_DRM_R128 is not set
+# CONFIG_DRM_RADEON is not set
+# CONFIG_DRM_MGA is not set
+# CONFIG_DRM_VIA is not set
+# CONFIG_DRM_SAVAGE is not set
 # CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_VIDEO_OUTPUT_CONTROL=y
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+CONFIG_FB_DDC=y
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+CONFIG_FB_MACMODES=y
+CONFIG_FB_BACKLIGHT=y
+CONFIG_FB_MODE_HELPERS=y
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_OF is not set
+# CONFIG_FB_CT65550 is not set
+# CONFIG_FB_ASILIANT is not set
+# CONFIG_FB_IMSTT is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+CONFIG_FB_RADEON=y
+CONFIG_FB_RADEON_I2C=y
+CONFIG_FB_RADEON_BACKLIGHT=y
+# CONFIG_FB_RADEON_DEBUG is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=m
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
 
 #
 # Display device support
@@ -886,15 +1059,64 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m
 # CONFIG_DISPLAY_SUPPORT is not set
 
 #
-# Sound
-#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
 # CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_APPLE is not set
+CONFIG_HID_BELKIN=y
+CONFIG_HID_BRIGHT=y
+CONFIG_HID_CHERRY=y
+# CONFIG_HID_CHICONY is not set
+CONFIG_HID_CYPRESS=y
+CONFIG_HID_DELL=y
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_LOGITECH is not set
+# CONFIG_HID_MICROSOFT is not set
+# CONFIG_HID_MONTEREY is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_THRUSTMASTER_FF is not set
+# CONFIG_ZEROPLUS_FF is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
@@ -903,14 +1125,20 @@ CONFIG_USB_DEVICEFS=y
 # CONFIG_USB_DEVICE_CLASS is not set
 # CONFIG_USB_DYNAMIC_MINORS is not set
 # CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_PERSIST is not set
 # CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+CONFIG_USB_MON=y
+# CONFIG_USB_WUSB is not set
+# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
 #
+# CONFIG_USB_C67X00_HCD is not set
 # CONFIG_USB_EHCI_HCD is not set
 # CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
 CONFIG_USB_OHCI_HCD=y
 CONFIG_USB_OHCI_HCD_PPC_SOC=y
 CONFIG_USB_OHCI_HCD_PPC_OF=y
@@ -923,12 +1151,17 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 # CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
+# CONFIG_USB_WHCI_HCD is not set
+# CONFIG_USB_HWA_HCD is not set
+# CONFIG_USB_MUSB_HDRC is not set
 
 #
 # USB Device Class drivers
 #
 # CONFIG_USB_ACM is not set
 # CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
 
 #
 # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
@@ -948,7 +1181,9 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_SDDR55 is not set
 # CONFIG_USB_STORAGE_JUMPSHOT is not set
 # CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
 # CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
 # CONFIG_USB_LIBUSUAL is not set
 
 #
@@ -956,15 +1191,10 @@ CONFIG_USB_STORAGE=y
 #
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
-CONFIG_USB_MON=y
 
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 # CONFIG_USB_SERIAL is not set
 
 #
@@ -973,7 +1203,7 @@ CONFIG_USB_MON=y
 # CONFIG_USB_EMI62 is not set
 # CONFIG_USB_EMI26 is not set
 # CONFIG_USB_ADUTUX is not set
-# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_SEVSEG is not set
 # CONFIG_USB_RIO500 is not set
 # CONFIG_USB_LEGOTOWER is not set
 # CONFIG_USB_LCD is not set
@@ -989,18 +1219,14 @@ CONFIG_USB_MON=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_VST is not set
 # CONFIG_USB_GADGET is not set
+# CONFIG_UWB is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
 CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
+# CONFIG_LEDS_CLASS is not set
 
 #
 # LED drivers
@@ -1009,17 +1235,15 @@ CONFIG_LEDS_CLASS=y
 #
 # LED Triggers
 #
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
 # CONFIG_INFINIBAND is not set
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
-
-#
-# Userspace I/O
-#
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -1031,21 +1255,19 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
-# CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 # CONFIG_AUTOFS_FS is not set
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
@@ -1072,6 +1294,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_TMPFS_POSIX_ACL is not set
@@ -1101,8 +1324,11 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 CONFIG_CRAMFS=y
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
@@ -1110,15 +1336,14 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -1173,7 +1398,6 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
 
 #
 # Library routines
@@ -1181,6 +1405,7 @@ CONFIG_NLS_ISO8859_1=y
 CONFIG_BITREVERSE=y
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
 # CONFIG_CRC_ITU_T is not set
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
@@ -1191,7 +1416,7 @@ CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-# CONFIG_INSTRUMENTATION is not set
+CONFIG_HAVE_LMB=y
 
 #
 # Kernel hacking
@@ -1199,6 +1424,7 @@ CONFIG_HAS_DMA=y
 CONFIG_PRINTK_TIME=y
 CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
 # CONFIG_MAGIC_SYSRQ is not set
 # CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_DEBUG_FS is not set
@@ -1206,10 +1432,14 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_DEBUG_KERNEL=y
 # CONFIG_DEBUG_SHIRQ is not set
 CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1220,17 +1450,39 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
-CONFIG_FORCED_INLINING=y
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 # CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
 # CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUGGER is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
 # CONFIG_BDI_SWITCH is not set
 # CONFIG_BOOTX_TEXT is not set
 # CONFIG_PPC_EARLY_DEBUG is not set
@@ -1240,47 +1492,98 @@ CONFIG_FORCED_INLINING=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
 # CONFIG_CRYPTO_HMAC is not set
 # CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_NULL is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_MD4 is not set
 CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
 # CONFIG_CRYPTO_SHA1 is not set
 # CONFIG_CRYPTO_SHA256 is not set
 # CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_WP512 is not set
 # CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_ECB is not set
-CONFIG_CRYPTO_CBC=y
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-CONFIG_CRYPTO_DES=y
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
 # CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_CAST5 is not set
 # CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_ARC4 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
 # CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_SALSA20 is not set
 # CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
 # CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 CONFIG_PPC_CLOCK=y
 CONFIG_PPC_LIB_RHEAP=y
+# CONFIG_VIRTUALIZATION is not set
index c15c91deb2ab578758097325406f01b787124054..4256e2c4534b504c0e93e3ace230b1cdf7021e22 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
-# Tue Oct 28 08:56:44 2008
+# Linux kernel version: 2.6.28-rc4
+# Fri Nov 14 09:54:44 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -500,15 +500,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_XILINX_SYSACE is not set
+CONFIG_XILINX_SYSACE=m
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -632,7 +634,13 @@ CONFIG_NETDEV_10000=y
 #
 # Hardware I/O ports
 #
-# CONFIG_SERIO is not set
+CONFIG_SERIO=m
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+CONFIG_SERIO_XILINX_XPS_PS2=m
 # CONFIG_GAMEPORT is not set
 
 #
@@ -660,7 +668,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
@@ -756,6 +765,11 @@ CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
 # CONFIG_GPIO_SYSFS is not set
 
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_XILINX=y
+
 #
 # I2C GPIO expanders:
 #
@@ -776,11 +790,11 @@ CONFIG_GPIOLIB=y
 # CONFIG_HWMON is not set
 CONFIG_THERMAL=y
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -792,6 +806,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -816,13 +831,65 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 CONFIG_VIDEO_OUTPUT_CONTROL=m
-# CONFIG_FB is not set
+CONFIG_FB=m
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+CONFIG_FB_XILINX=m
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -851,6 +918,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -1077,10 +1145,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
index 55edbd545b6130516fd93f752c96cdd9b1667636..cfc94cfcf4cb3ec27803eac80aa669fddc686064 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.28-rc2
-# Tue Oct 28 09:28:58 2008
+# Linux kernel version: 2.6.28-rc4
+# Fri Nov 14 10:06:19 2008
 #
 # CONFIG_PPC64 is not set
 
@@ -506,15 +506,17 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_XILINX_SYSACE is not set
+CONFIG_XILINX_SYSACE=m
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -680,7 +682,13 @@ CONFIG_NETDEV_10000=y
 #
 # Hardware I/O ports
 #
-# CONFIG_SERIO is not set
+CONFIG_SERIO=m
+# CONFIG_SERIO_I8042 is not set
+# CONFIG_SERIO_SERPORT is not set
+# CONFIG_SERIO_PCIPS2 is not set
+# CONFIG_SERIO_LIBPS2 is not set
+# CONFIG_SERIO_RAW is not set
+CONFIG_SERIO_XILINX_XPS_PS2=m
 # CONFIG_GAMEPORT is not set
 
 #
@@ -708,7 +716,8 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y
 #
 # Non-8250 serial port support
 #
-# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_UARTLITE=y
+CONFIG_SERIAL_UARTLITE_CONSOLE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_JSM is not set
@@ -805,6 +814,11 @@ CONFIG_GPIOLIB=y
 # CONFIG_DEBUG_GPIO is not set
 # CONFIG_GPIO_SYSFS is not set
 
+#
+# Memory mapped GPIO expanders:
+#
+CONFIG_GPIO_XILINX=y
+
 #
 # I2C GPIO expanders:
 #
@@ -826,11 +840,11 @@ CONFIG_GPIOLIB=y
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
 # CONFIG_SSB is not set
 
 #
@@ -842,6 +856,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_MFD_TMIO is not set
 # CONFIG_MFD_WM8400 is not set
 # CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_REGULATOR is not set
 
 #
 # Multimedia devices
@@ -866,13 +881,65 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
 # CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
+CONFIG_FB=m
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=m
+CONFIG_FB_CFB_COPYAREA=m
+CONFIG_FB_CFB_IMAGEBLIT=m
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+# CONFIG_FB_CIRRUS is not set
+# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VGA16 is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_NVIDIA is not set
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_RADEON is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_S3 is not set
+# CONFIG_FB_SAVAGE is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIA is not set
+# CONFIG_FB_NEOMAGIC is not set
+# CONFIG_FB_KYRO is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VOODOO1 is not set
+# CONFIG_FB_VT8623 is not set
+# CONFIG_FB_TRIDENT is not set
+# CONFIG_FB_ARK is not set
+# CONFIG_FB_PM3 is not set
+# CONFIG_FB_CARMINE is not set
+# CONFIG_FB_IBM_GXT4500 is not set
+CONFIG_FB_XILINX=m
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_MB862XX is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 #
 # Display device support
 #
 # CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_LOGO is not set
 # CONFIG_SOUND is not set
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_ARCH_HAS_HCD=y
@@ -1002,6 +1069,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -1227,10 +1295,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_NOP_TRACER=y
-CONFIG_HAVE_FTRACE=y
-CONFIG_HAVE_DYNAMIC_FTRACE=y
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+
+#
+# Tracers
+#
+# CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
index 5a441742ffba45434038716ae368aa516eccbdfe..68b752626808b673d4a0ca2f2264fe61e1af7894 100644 (file)
@@ -280,7 +280,6 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
 extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
                             unsigned long pstart, unsigned long prot,
                             int psize, int ssize);
-extern void set_huge_psize(int psize);
 extern void add_gpage(unsigned long addr, unsigned long page_size,
                          unsigned long number_of_pages);
 extern void demote_segment_4k(struct mm_struct *mm, unsigned long addr);
index 280a90cc9894c6ed3f6a2e2611b9d53623218a2f..c9c678fb2538d9e4f1c17cb54476663d8305485b 100644 (file)
@@ -55,8 +55,6 @@ struct pt_regs {
 
 #ifdef __powerpc64__
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 #define STACK_FRAME_OVERHEAD   112     /* size of minimum stack frame */
 #define STACK_FRAME_LR_SAVE    2       /* Location of LR in stack frame */
 #define STACK_FRAME_REGS_MARKER        ASM_CONST(0x7265677368657265)
index 80cac984d85d06271a80d1d67cb02e08a057515c..31c18b52affb878031c69fda37421ff5e53c391f 100644 (file)
@@ -34,7 +34,12 @@ _GLOBAL(__setup_cpu_440grx)
        blr
 _GLOBAL(__setup_cpu_460ex)
 _GLOBAL(__setup_cpu_460gt)
-       b       __init_fpu_44x
+       mflr    r4
+       bl      __init_fpu_44x
+       bl      __fixup_440A_mcheck
+       mtlr    r4
+       blr
+
 _GLOBAL(__setup_cpu_440gx)
 _GLOBAL(__setup_cpu_440spe)
        b       __fixup_440A_mcheck
index e6d52845854f8e1ea67d60f48332ff8206c9fa7e..e0bcf93542867d79e20c1d5951397813535545a2 100644 (file)
@@ -57,12 +57,18 @@ system_call_common:
        beq-    1f
        ld      r1,PACAKSAVE(r13)
 1:     std     r10,0(r1)
-       crclr   so
        std     r11,_NIP(r1)
        std     r12,_MSR(r1)
        std     r0,GPR0(r1)
        std     r10,GPR1(r1)
        ACCOUNT_CPU_USER_ENTRY(r10, r11)
+       /*
+        * This "crclr so" clears CR0.SO, which is the error indication on
+        * return from this system call.  There must be no cmp instruction
+        * between it and the "mfcr r9" below, otherwise if XER.SO is set,
+        * CR0.SO will get set, causing all system calls to appear to fail.
+        */
+       crclr   so
        std     r2,GPR2(r1)
        std     r3,GPR3(r1)
        std     r4,GPR4(r1)
index bc1fb27368af4db2ff7627c5e1eb8ffa46a54013..a11d68976dc840fdf545120f94cda1c746a362c8 100644 (file)
@@ -250,8 +250,11 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
         * parsing
         */
        dn = pci_device_to_OF_node(pdev);
-       if (dn)
-               return of_irq_map_one(dn, 0, out_irq);
+       if (dn) {
+               rc = of_irq_map_one(dn, 0, out_irq);
+               if (!rc)
+                       return rc;
+       }
 
        /* Ok, we don't, time to have fun. Let's start by building up an
         * interrupt spec.  we assume #interrupt-cells is 1, which is standard
index 86a2ffccef2592066ece036093a4e0b73858f7da..20885a38237aa0ab5f028aa67537b365b340aad0 100644 (file)
@@ -717,9 +717,11 @@ static void unregister_cpu_online(unsigned int cpu)
 
        BUG_ON(!c->hotpluggable);
 
+#ifdef CONFIG_PPC64
        if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
                        cpu_has_feature(CPU_FTR_SMT))
                sysdev_remove_file(s, &attr_smt_snooze_delay);
+#endif
 
        /* PMC stuff */
        switch (cur_cpu_spec->pmc_type) {
index cecbbc76f62425da81edc80529e4a65164d42435..29954dc28942ff8408c940402f9cac7a72b7ebd3 100644 (file)
@@ -93,7 +93,7 @@ void __init MMU_init_hw(void)
 
 unsigned long __init mmu_mapin_ram(void)
 {
-       unsigned long v, s;
+       unsigned long v, s, mapped;
        phys_addr_t p;
 
        v = KERNELBASE;
@@ -130,5 +130,17 @@ unsigned long __init mmu_mapin_ram(void)
                s -= LARGE_PAGE_SIZE_4M;
        }
 
-       return total_lowmem - s;
+       mapped = total_lowmem - s;
+
+       /* If the size of RAM is not an exact power of two, we may not
+        * have covered RAM in its entirety with 16 and 4 MiB
+        * pages. Consequently, restrict the top end of RAM currently
+        * allocable so that calls to the LMB to allocate PTEs for "tail"
+        * coverage with normal-sized pages (or other reasons) do not
+        * attempt to allocate outside the allowed range.
+        */
+
+       __initial_memory_limit_addr = memstart_addr + mapped;
+
+       return mapped;
 }
index a117024ab8cdb68af98c8bfc13f822695dc4c2bf..7bbf4e4ed4306b3a395906b6307808df326fb7cf 100644 (file)
@@ -677,7 +677,7 @@ repeat:
        return err;
 }
 
-void set_huge_psize(int psize)
+static void __init set_huge_psize(int psize)
 {
        /* Check that it is a page size supported by the hardware and
         * that it fits within pagetable limits. */
index eb505ad34a857421b2deb85bbedd7b4c6ba99777..a8397bbad3d4d54a5cd50ae9ee201118c767d1d4 100644 (file)
@@ -865,6 +865,67 @@ static struct notifier_block __cpuinitdata ppc64_numa_nb = {
        .priority = 1 /* Must run before sched domains notifier. */
 };
 
+static void mark_reserved_regions_for_nid(int nid)
+{
+       struct pglist_data *node = NODE_DATA(nid);
+       int i;
+
+       for (i = 0; i < lmb.reserved.cnt; i++) {
+               unsigned long physbase = lmb.reserved.region[i].base;
+               unsigned long size = lmb.reserved.region[i].size;
+               unsigned long start_pfn = physbase >> PAGE_SHIFT;
+               unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
+               struct node_active_region node_ar;
+               unsigned long node_end_pfn = node->node_start_pfn +
+                                            node->node_spanned_pages;
+
+               /*
+                * Check to make sure that this lmb.reserved area is
+                * within the bounds of the node that we care about.
+                * Checking the nid of the start and end points is not
+                * sufficient because the reserved area could span the
+                * entire node.
+                */
+               if (end_pfn <= node->node_start_pfn ||
+                   start_pfn >= node_end_pfn)
+                       continue;
+
+               get_node_active_region(start_pfn, &node_ar);
+               while (start_pfn < end_pfn &&
+                       node_ar.start_pfn < node_ar.end_pfn) {
+                       unsigned long reserve_size = size;
+                       /*
+                        * if reserved region extends past active region
+                        * then trim size to active region
+                        */
+                       if (end_pfn > node_ar.end_pfn)
+                               reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
+                                       - (start_pfn << PAGE_SHIFT);
+                       dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
+                               reserve_size, node_ar.nid);
+                       reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
+                                               reserve_size, BOOTMEM_DEFAULT);
+                       /*
+                        * if reserved region is contained in the active region
+                        * then done.
+                        */
+                       if (end_pfn <= node_ar.end_pfn)
+                               break;
+
+                       /*
+                        * reserved region extends past the active region
+                        *   get next active region that contains this
+                        *   reserved region
+                        */
+                       start_pfn = node_ar.end_pfn;
+                       physbase = start_pfn << PAGE_SHIFT;
+                       size = size - reserve_size;
+                       get_node_active_region(start_pfn, &node_ar);
+               }
+       }
+}
+
+
 void __init do_init_bootmem(void)
 {
        int nid;
@@ -890,7 +951,13 @@ void __init do_init_bootmem(void)
 
                get_pfn_range_for_nid(nid, &start_pfn, &end_pfn);
 
-               /* Allocate the node structure node local if possible */
+               /*
+                * Allocate the node structure node local if possible
+                *
+                * Be careful moving this around, as it relies on all
+                * previous nodes' bootmem to be initialized and have
+                * all reserved areas marked.
+                */
                NODE_DATA(nid) = careful_allocation(nid,
                                        sizeof(struct pglist_data),
                                        SMP_CACHE_BYTES, end_pfn);
@@ -922,53 +989,14 @@ void __init do_init_bootmem(void)
                                  start_pfn, end_pfn);
 
                free_bootmem_with_active_regions(nid, end_pfn);
-       }
-
-       /* Mark reserved regions */
-       for (i = 0; i < lmb.reserved.cnt; i++) {
-               unsigned long physbase = lmb.reserved.region[i].base;
-               unsigned long size = lmb.reserved.region[i].size;
-               unsigned long start_pfn = physbase >> PAGE_SHIFT;
-               unsigned long end_pfn = ((physbase + size) >> PAGE_SHIFT);
-               struct node_active_region node_ar;
-
-               get_node_active_region(start_pfn, &node_ar);
-               while (start_pfn < end_pfn &&
-                       node_ar.start_pfn < node_ar.end_pfn) {
-                       unsigned long reserve_size = size;
-                       /*
-                        * if reserved region extends past active region
-                        * then trim size to active region
-                        */
-                       if (end_pfn > node_ar.end_pfn)
-                               reserve_size = (node_ar.end_pfn << PAGE_SHIFT)
-                                       - (start_pfn << PAGE_SHIFT);
-                       dbg("reserve_bootmem %lx %lx nid=%d\n", physbase,
-                               reserve_size, node_ar.nid);
-                       reserve_bootmem_node(NODE_DATA(node_ar.nid), physbase,
-                                               reserve_size, BOOTMEM_DEFAULT);
-                       /*
-                        * if reserved region is contained in the active region
-                        * then done.
-                        */
-                       if (end_pfn <= node_ar.end_pfn)
-                               break;
-
-                       /*
-                        * reserved region extends past the active region
-                        *   get next active region that contains this
-                        *   reserved region
-                        */
-                       start_pfn = node_ar.end_pfn;
-                       physbase = start_pfn << PAGE_SHIFT;
-                       size = size - reserve_size;
-                       get_node_active_region(start_pfn, &node_ar);
-               }
-
-       }
-
-       for_each_online_node(nid)
+               /*
+                * Be very careful about moving this around.  Future
+                * calls to careful_allocation() depend on this getting
+                * done correctly.
+                */
+               mark_reserved_regions_for_nid(nid);
                sparse_memory_present_with_active_regions(nid);
+       }
 }
 
 void __init paging_init(void)
index 896548ba1ca12f4eb07c7984a8b1f7d01d232a4f..442cf36aa172920b355710e65a68624d43293d33 100644 (file)
@@ -95,6 +95,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
        struct axon_msic *msic = get_irq_data(irq);
        u32 write_offset, msi;
        int idx;
+       int retry = 0;
 
        write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
        pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
@@ -102,7 +103,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
        /* write_offset doesn't wrap properly, so we have to mask it */
        write_offset &= MSIC_FIFO_SIZE_MASK;
 
-       while (msic->read_offset != write_offset) {
+       while (msic->read_offset != write_offset && retry < 100) {
                idx  = msic->read_offset / sizeof(__le32);
                msi  = le32_to_cpu(msic->fifo_virt[idx]);
                msi &= 0xFFFF;
@@ -110,13 +111,37 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
                pr_debug("axon_msi: woff %x roff %x msi %x\n",
                          write_offset, msic->read_offset, msi);
 
+               if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) {
+                       generic_handle_irq(msi);
+                       msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
+               } else {
+                       /*
+                        * Reading the MSIC_WRITE_OFFSET_REG does not
+                        * reliably flush the outstanding DMA to the
+                        * FIFO buffer. Here we were reading stale
+                        * data, so we need to retry.
+                        */
+                       udelay(1);
+                       retry++;
+                       pr_debug("axon_msi: invalid irq 0x%x!\n", msi);
+                       continue;
+               }
+
+               if (retry) {
+                       pr_debug("axon_msi: late irq 0x%x, retry %d\n",
+                                msi, retry);
+                       retry = 0;
+               }
+
                msic->read_offset += MSIC_FIFO_ENTRY_SIZE;
                msic->read_offset &= MSIC_FIFO_SIZE_MASK;
+       }
 
-               if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host)
-                       generic_handle_irq(msi);
-               else
-                       pr_debug("axon_msi: invalid irq 0x%x!\n", msi);
+       if (retry) {
+               printk(KERN_WARNING "axon_msi: irq timed out\n");
+
+               msic->read_offset += MSIC_FIFO_ENTRY_SIZE;
+               msic->read_offset &= MSIC_FIFO_SIZE_MASK;
        }
 
        desc->chip->eoi(irq);
@@ -364,6 +389,7 @@ static int axon_msi_probe(struct of_device *device,
                       dn->full_name);
                goto out_free_fifo;
        }
+       memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
 
        msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
                                        NR_IRQS, &msic_host_ops, 0);
index c0d86e1f56ea54d3eb6cb8ac70a3f71a19dc6df0..9046803c827670a273c5b43d13cee1367ffa16fe 100644 (file)
@@ -129,10 +129,15 @@ static int __init smp_iic_probe(void)
        return cpus_weight(cpu_possible_map);
 }
 
-static void __devinit smp_iic_setup_cpu(int cpu)
+static void __devinit smp_cell_setup_cpu(int cpu)
 {
        if (cpu != boot_cpuid)
                iic_setup_cpu();
+
+       /*
+        * change default DABRX to allow user watchpoints
+        */
+       mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
 }
 
 static DEFINE_SPINLOCK(timebase_lock);
@@ -192,7 +197,7 @@ static struct smp_ops_t bpa_iic_smp_ops = {
        .message_pass   = smp_iic_message_pass,
        .probe          = smp_iic_probe,
        .kick_cpu       = smp_cell_kick_cpu,
-       .setup_cpu      = smp_iic_setup_cpu,
+       .setup_cpu      = smp_cell_setup_cpu,
        .cpu_bootable   = smp_cell_cpu_bootable,
 };
 
index b73c369cc6f167a4fa52c9162cfed557c9c1bba0..1b26071a86ca8f17e1f2c04f22ffb9d60d13e2b8 100644 (file)
@@ -390,6 +390,9 @@ static int spufs_ps_fault(struct vm_area_struct *vma,
        if (offset >= ps_size)
                return VM_FAULT_SIGBUS;
 
+       if (fatal_signal_pending(current))
+               return VM_FAULT_SIGBUS;
+
        /*
         * Because we release the mmap_sem, the context may be destroyed while
         * we're in spu_wait. Grab an extra reference so it isn't destroyed
index 57cc56562567d6f9e092abdbfd7e93246d41c6e3..0b192a1c429d3b85a1d13292277095d02abee1e3 100644 (file)
@@ -17,23 +17,20 @@ config PPC_BESTCOMM
          answer Y or M. Otherwise say N.
 
 config PPC_BESTCOMM_ATA
-       tristate "Bestcomm ATA task support"
+       tristate
        depends on PPC_BESTCOMM
-       default n
        help
          This option enables the support for the ATA task.
 
 config PPC_BESTCOMM_FEC
-       tristate "Bestcomm FEC tasks support"
+       tristate
        depends on PPC_BESTCOMM
-       default n
        help
          This option enables the support for the FEC tasks.
 
 config PPC_BESTCOMM_GEN_BD
-       tristate "Bestcomm GenBD tasks support"
+       tristate
        depends on PPC_BESTCOMM
-       default n
        help
          This option enables the support for the GenBD tasks.
 
index f6299cca7814b8eda0434e94953db9fe6b38ba9e..b24e1d0855573df690aaf6f9022266ad98b95604 100644 (file)
@@ -1271,6 +1271,7 @@ void __init mpic_set_default_senses(struct mpic *mpic, u8 *senses, int count)
 void __init mpic_init(struct mpic *mpic)
 {
        int i;
+       int cpu;
 
        BUG_ON(mpic->num_sources == 0);
 
@@ -1313,6 +1314,11 @@ void __init mpic_init(struct mpic *mpic)
 
        mpic_pasemi_msi_init(mpic);
 
+       if (mpic->flags & MPIC_PRIMARY)
+               cpu = hard_smp_processor_id();
+       else
+               cpu = 0;
+
        for (i = 0; i < mpic->num_sources; i++) {
                /* start with vector = source number, and masked */
                u32 vecpri = MPIC_VECPRI_MASK | i |
@@ -1323,8 +1329,7 @@ void __init mpic_init(struct mpic *mpic)
                        continue;
                /* init hw */
                mpic_irq_write(i, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
-               mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION),
-                              1 << hard_smp_processor_id());
+               mpic_irq_write(i, MPIC_INFO(IRQ_DESTINATION), 1 << cpu);
        }
        
        /* Init spurious vector */
index b7aefd0d45cb20204d7e95b81240564e0cc1ba69..a22e1a2df1afd0a6c761b7df8b66f63d90a47132 100644 (file)
@@ -107,8 +107,8 @@ xilinx_intc_init(struct device_node *np)
        }
        regs = ioremap(res.start, 32);
 
-       printk(KERN_INFO "Xilinx intc at 0x%08LX mapped to 0x%p\n",
-               res.start, regs);
+       printk(KERN_INFO "Xilinx intc at 0x%08llx mapped to 0x%p\n",
+               (unsigned long long) res.start, regs);
 
        /* Setup interrupt controller */
        out_be32(regs + XINTC_IER, 0); /* disable all irqs */
index 9b0bc2c9fba05e17de7730b209ad68c2d0638549..a0e748da99094e5dd93f343f419527d6bd9d78c1 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.27-rc4
-# Thu Aug 21 19:43:29 2008
+# Linux kernel version: 2.6.28-rc6
+# Thu Nov 27 11:00:49 2008
 #
 CONFIG_SCHED_MC=y
 CONFIG_MMU=y
@@ -45,6 +45,7 @@ CONFIG_LOG_BUF_SHIFT=17
 CONFIG_CGROUPS=y
 # CONFIG_CGROUP_DEBUG is not set
 CONFIG_CGROUP_NS=y
+# CONFIG_CGROUP_FREEZER is not set
 # CONFIG_CGROUP_DEVICE is not set
 # CONFIG_CPUSETS is not set
 CONFIG_GROUP_SCHED=y
@@ -84,6 +85,7 @@ CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
+CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_SLAB=y
 # CONFIG_SLUB is not set
@@ -92,16 +94,10 @@ CONFIG_SLAB=y
 # CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 CONFIG_KPROBES=y
-# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
 CONFIG_KRETPROBES=y
-# CONFIG_HAVE_IOREMAP_PROT is not set
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HAVE_ARCH_TRACEHOOK is not set
-# CONFIG_HAVE_DMA_ATTRS is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
-# CONFIG_HAVE_CLK is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -135,6 +131,7 @@ CONFIG_DEFAULT_DEADLINE=y
 CONFIG_DEFAULT_IOSCHED="deadline"
 CONFIG_PREEMPT_NOTIFIERS=y
 CONFIG_CLASSIC_RCU=y
+# CONFIG_FREEZER is not set
 
 #
 # Base setup
@@ -189,7 +186,6 @@ CONFIG_SELECT_MEMORY_MODEL=y
 CONFIG_SPARSEMEM_MANUAL=y
 CONFIG_SPARSEMEM=y
 CONFIG_HAVE_MEMORY_PRESENT=y
-# CONFIG_SPARSEMEM_STATIC is not set
 CONFIG_SPARSEMEM_EXTREME=y
 CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y
 CONFIG_SPARSEMEM_VMEMMAP=y
@@ -200,9 +196,11 @@ CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_SPLIT_PTLOCK_CPUS=4
 CONFIG_MIGRATION=y
 CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
 CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
 
 #
 # I/O subsystem configuration
@@ -220,6 +218,8 @@ CONFIG_IPL=y
 CONFIG_IPL_VM=y
 CONFIG_BINFMT_ELF=y
 CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_FORCE_MAX_ZONEORDER=9
 # CONFIG_PROCESS_DEBUG is not set
@@ -255,7 +255,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_STATISTICS is not set
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
-CONFIG_IUCV=m
+CONFIG_IUCV=y
 CONFIG_AFIUCV=m
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
@@ -282,7 +282,6 @@ CONFIG_INET_TCP_DIAG=y
 CONFIG_TCP_CONG_CUBIC=y
 CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_TCP_MD5SIG is not set
-# CONFIG_IP_VS is not set
 CONFIG_IPV6=y
 # CONFIG_IPV6_PRIVACY is not set
 # CONFIG_IPV6_ROUTER_PREF is not set
@@ -331,10 +330,12 @@ CONFIG_NF_CONNTRACK=m
 # CONFIG_NF_CONNTRACK_TFTP is not set
 # CONFIG_NF_CT_NETLINK is not set
 # CONFIG_NETFILTER_XTABLES is not set
+# CONFIG_IP_VS is not set
 
 #
 # IP: Netfilter Configuration
 #
+# CONFIG_NF_DEFRAG_IPV4 is not set
 # CONFIG_NF_CONNTRACK_IPV4 is not set
 # CONFIG_IP_NF_QUEUE is not set
 # CONFIG_IP_NF_IPTABLES is not set
@@ -374,6 +375,7 @@ CONFIG_NET_SCH_CBQ=m
 # CONFIG_NET_SCH_HTB is not set
 # CONFIG_NET_SCH_HFSC is not set
 CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=y
 CONFIG_NET_SCH_RED=m
 CONFIG_NET_SCH_SFQ=m
 CONFIG_NET_SCH_TEQL=m
@@ -406,6 +408,7 @@ CONFIG_NET_ACT_POLICE=y
 CONFIG_NET_ACT_NAT=m
 # CONFIG_NET_ACT_PEDIT is not set
 # CONFIG_NET_ACT_SIMP is not set
+# CONFIG_NET_ACT_SKBEDIT is not set
 # CONFIG_NET_CLS_IND is not set
 CONFIG_NET_SCH_FIFO=y
 
@@ -424,6 +427,7 @@ CONFIG_CAN_BCM=m
 CONFIG_CAN_VCAN=m
 # CONFIG_CAN_DEBUG_DEVICES is not set
 # CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
 # CONFIG_RFKILL is not set
 # CONFIG_NET_9P is not set
 # CONFIG_PCMCIA is not set
@@ -473,7 +477,7 @@ CONFIG_VIRTIO_BLK=m
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_HAVE_IDE is not set
+# CONFIG_C2PORT is not set
 
 #
 # SCSI device support
@@ -525,6 +529,7 @@ CONFIG_SCSI_DH_EMC=m
 CONFIG_SCSI_DH_ALUA=m
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
 CONFIG_MD_LINEAR=m
 CONFIG_MD_RAID0=m
 CONFIG_MD_RAID1=m
@@ -555,6 +560,9 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
 CONFIG_NETDEV_1000=y
 CONFIG_NETDEV_10000=y
 # CONFIG_TR is not set
@@ -632,13 +640,12 @@ CONFIG_S390_VMUR=m
 # CONFIG_THERMAL is not set
 # CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
-
-#
-# Sonics Silicon Backplane
-#
+# CONFIG_REGULATOR is not set
 # CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 CONFIG_ACCESSIBILITY=y
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
 
 #
 # File systems
@@ -650,13 +657,14 @@ CONFIG_EXT3_FS=y
 CONFIG_EXT3_FS_XATTR=y
 # CONFIG_EXT3_FS_POSIX_ACL is not set
 # CONFIG_EXT3_FS_SECURITY is not set
-# CONFIG_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS is not set
 CONFIG_JBD=y
 # CONFIG_JBD_DEBUG is not set
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
@@ -688,6 +696,7 @@ CONFIG_GENERIC_ACL=y
 CONFIG_PROC_FS=y
 CONFIG_PROC_KCORE=y
 CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
 CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 CONFIG_TMPFS_POSIX_ACL=y
@@ -728,6 +737,7 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -800,12 +810,24 @@ CONFIG_DEBUG_MEMORY_INIT=y
 # CONFIG_DEBUG_SG is not set
 # CONFIG_FRAME_POINTER is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 # CONFIG_KPROBES_SANITY_TEST is not set
 # CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
 # CONFIG_LKDTM is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
 CONFIG_SAMPLES=y
 # CONFIG_SAMPLE_KOBJECT is not set
 # CONFIG_SAMPLE_KPROBES is not set
@@ -816,16 +838,19 @@ CONFIG_SAMPLES=y
 #
 # CONFIG_KEYS is not set
 # CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
 # CONFIG_SECURITY_FILE_CAPABILITIES is not set
 CONFIG_CRYPTO=y
 
 #
 # Crypto core or helper
 #
+CONFIG_CRYPTO_FIPS=y
 CONFIG_CRYPTO_ALGAPI=y
-CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
-CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_GF128MUL=m
 # CONFIG_CRYPTO_NULL is not set
@@ -877,7 +902,7 @@ CONFIG_CRYPTO_SHA1=m
 #
 # Ciphers
 #
-# CONFIG_CRYPTO_AES is not set
+CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_ANUBIS is not set
 # CONFIG_CRYPTO_ARC4 is not set
 # CONFIG_CRYPTO_BLOWFISH is not set
@@ -898,6 +923,11 @@ CONFIG_CRYPTO_SEED=m
 #
 # CONFIG_CRYPTO_DEFLATE is not set
 CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
 CONFIG_CRYPTO_HW=y
 CONFIG_ZCRYPT=m
 # CONFIG_ZCRYPT_MONOLITHIC is not set
@@ -912,8 +942,6 @@ CONFIG_S390_PRNG=m
 # Library routines
 #
 CONFIG_BITREVERSE=m
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
-# CONFIG_GENERIC_FIND_NEXT_BIT is not set
 # CONFIG_CRC_CCITT is not set
 # CONFIG_CRC16 is not set
 CONFIG_CRC_T10DIF=y
index 7fc76133b3e46da10eddb1ca115b7ac69a4a80c0..5caddd4f7bedd74ed7fa9078c8cf4d97bdfc2227 100644 (file)
@@ -679,8 +679,6 @@ static inline void pmd_clear(pmd_t *pmd)
 
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
-       if (mm->context.has_pgste)
-               ptep_rcp_copy(ptep);
        pte_val(*ptep) = _PAGE_TYPE_EMPTY;
        if (mm->context.noexec)
                pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY;
index a7226f8143fb9d34df06456f1759d0c2fa085e94..5396f9f122634bda4d0ce33bd78bd1747856e7d2 100644 (file)
@@ -321,8 +321,8 @@ struct pt_regs
        psw_t psw;
        unsigned long gprs[NUM_GPRS];
        unsigned long orig_gpr2;
+       unsigned short svcnr;
        unsigned short ilc;
-       unsigned short trap;
 };
 #endif
 
@@ -486,8 +486,6 @@ struct task_struct;
 extern void user_enable_single_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
 #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN)
 #define user_stack_pointer(regs)((regs)->gprs[15])
index 6e623971fbb9ae234ad80c450b6da43fa2a68fc4..2429b87eb28d92c6fc6adf5a5887f2b29e062d70 100644 (file)
@@ -17,9 +17,7 @@
 static inline long syscall_get_nr(struct task_struct *task,
                                  struct pt_regs *regs)
 {
-       if (regs->trap != __LC_SVC_OLD_PSW)
-               return -1;
-       return regs->gprs[2];
+       return regs->svcnr ? regs->svcnr : -1;
 }
 
 static inline void syscall_rollback(struct task_struct *task,
@@ -52,18 +50,20 @@ static inline void syscall_get_arguments(struct task_struct *task,
                                         unsigned int i, unsigned int n,
                                         unsigned long *args)
 {
+       unsigned long mask = -1UL;
+
        BUG_ON(i + n > 6);
 #ifdef CONFIG_COMPAT
-       if (test_tsk_thread_flag(task, TIF_31BIT)) {
-               if (i + n == 6)
-                       args[--n] = (u32) regs->args[0];
-               while (n-- > 0)
-                       args[n] = (u32) regs->gprs[2 + i + n];
-       }
+       if (test_tsk_thread_flag(task, TIF_31BIT))
+               mask = 0xffffffff;
 #endif
        if (i + n == 6)
-               args[--n] = regs->args[0];
-       memcpy(args, &regs->gprs[2 + i], n * sizeof(args[0]));
+               args[--n] = regs->args[0] & mask;
+       while (n-- > 0)
+               if (i + n > 0)
+                       args[n] = regs->gprs[2 + i + n] & mask;
+       if (i == 0)
+               args[0] = regs->orig_gpr2 & mask;
 }
 
 static inline void syscall_set_arguments(struct task_struct *task,
@@ -74,7 +74,11 @@ static inline void syscall_set_arguments(struct task_struct *task,
        BUG_ON(i + n > 6);
        if (i + n == 6)
                regs->args[0] = args[--n];
-       memcpy(&regs->gprs[2 + i], args, n * sizeof(args[0]));
+       while (n-- > 0)
+               if (i + n > 0)
+                       regs->gprs[2 + i + n] = args[n];
+       if (i == 0)
+               regs->orig_gpr2 = args[0];
 }
 
 #endif /* _ASM_SYSCALL_H */
index fa28ecae636b2237a8bfddb49f05851ef7056f9c..3d144e6020c6c5b9ce26ad82742b3d2e7b16d51c 100644 (file)
@@ -32,7 +32,7 @@ int main(void)
        DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
        DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
        DEFINE(__PT_ILC, offsetof(struct pt_regs, ilc));
-       DEFINE(__PT_TRAP, offsetof(struct pt_regs, trap));
+       DEFINE(__PT_SVCNR, offsetof(struct pt_regs, svcnr));
        DEFINE(__PT_SIZE, sizeof(struct pt_regs));
        BLANK();
        DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
index c7f02e777af2ff0202becb4787834204720e77ae..b537cb0e9b55f607652f217f802ac7c2d8358d0b 100644 (file)
@@ -340,7 +340,7 @@ static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
                return err;
 
        restore_fp_regs(&current->thread.fp_regs);
-       regs->trap = -1;        /* disable syscall checks */
+       regs->svcnr = 0;        /* disable syscall checks */
        return 0;
 }
 
index 08844fc24a2e7b8f042364e7e0bf44a0ca4bbb3c..198ea18a534d0d9c74e68f99b44649b92e852c69 100644 (file)
@@ -46,7 +46,7 @@ SP_R14             =  STACK_FRAME_OVERHEAD + __PT_GPRS + 56
 SP_R15      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 60
 SP_ORIG_R2   = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
 SP_ILC      =  STACK_FRAME_OVERHEAD + __PT_ILC
-SP_TRAP      = STACK_FRAME_OVERHEAD + __PT_TRAP
+SP_SVCNR     = STACK_FRAME_OVERHEAD + __PT_SVCNR
 SP_SIZE      = STACK_FRAME_OVERHEAD + __PT_SIZE
 
 _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
@@ -183,11 +183,10 @@ STACK_SIZE  = 1 << STACK_SHIFT
        .macro  CREATE_STACK_FRAME psworg,savearea
        s       %r15,BASED(.Lc_spsize)  # make room for registers & psw
        mvc     SP_PSW(8,%r15),0(%r12)  # move user PSW to stack
-       la      %r12,\psworg
        st      %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
-       icm     %r12,12,__LC_SVC_ILC
+       icm     %r12,3,__LC_SVC_ILC
        stm     %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
-       st      %r12,SP_ILC(%r15)
+       st      %r12,SP_SVCNR(%r15)
        mvc     SP_R12(16,%r15),\savearea # move %r12-%r15 to stack
        la      %r12,0
        st      %r12,__SF_BACKCHAIN(%r15)       # clear back chain
@@ -264,16 +263,17 @@ sysc_update:
 #endif
 sysc_do_svc:
        l       %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       sla     %r7,2                   # *4 and test for svc 0
+       ltr     %r7,%r7                 # test for svc 0
        bnz     BASED(sysc_nr_ok)       # svc number > 0
        # svc 0: system call number in %r1
        cl      %r1,BASED(.Lnr_syscalls)
        bnl     BASED(sysc_nr_ok)
        lr      %r7,%r1           # copy svc number to %r7
-       sla     %r7,2             # *4
 sysc_nr_ok:
        mvc     SP_ARGS(4,%r15),SP_R7(%r15)
 sysc_do_restart:
+       sth     %r7,SP_SVCNR(%r15)
+       sll     %r7,2             # svc number *4
        l       %r8,BASED(.Lsysc_table)
        tm      __TI_flags+3(%r9),(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT)
        l       %r8,0(%r7,%r8)    # get system call addr.
@@ -376,7 +376,6 @@ sysc_notify_resume:
 sysc_restart:
        ni      __TI_flags+3(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
        l       %r7,SP_R2(%r15)         # load new svc number
-       sla     %r7,2
        mvc     SP_R2(4,%r15),SP_ORIG_R2(%r15) # restore first argument
        lm      %r2,%r6,SP_R2(%r15)     # load svc arguments
        b       BASED(sysc_do_restart)  # restart svc
@@ -386,7 +385,8 @@ sysc_restart:
 #
 sysc_singlestep:
        ni      __TI_flags+3(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
-       mvi     SP_TRAP+1(%r15),0x28    # set trap indication to pgm check
+       mvi     SP_SVCNR(%r15),0xff     # set trap indication to pgm check
+       mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
        la      %r14,BASED(sysc_return) # load adr. of system return
@@ -407,7 +407,7 @@ sysc_tracesys:
        bnl     BASED(sysc_tracenogo)
        l       %r8,BASED(.Lsysc_table)
        lr      %r7,%r2
-       sll     %r7,2                   # *4
+       sll     %r7,2                   # svc number *4
        l       %r8,0(%r7,%r8)
 sysc_tracego:
        lm      %r3,%r6,SP_R3(%r15)
@@ -586,7 +586,8 @@ pgm_svcper:
 # per was called from kernel, must be kprobes
 #
 kernel_per:
-       mvi     SP_TRAP+1(%r15),0x28    # set trap indication to pgm check
+       mvi     SP_SVCNR(%r15),0xff     # set trap indication to pgm check
+       mvi     SP_SVCNR+1(%r15),0xff
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        l       %r1,BASED(.Lhandle_per) # load adr. of per handler
        la      %r14,BASED(sysc_restore)# load adr. of system return
index 41aca06682aa19e294ac54160500da46594cb97a..89c121ae63391ef0453367cd26efa36d10296cf3 100644 (file)
@@ -46,7 +46,7 @@ SP_R14             =  STACK_FRAME_OVERHEAD + __PT_GPRS + 112
 SP_R15      =  STACK_FRAME_OVERHEAD + __PT_GPRS + 120
 SP_ORIG_R2   = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
 SP_ILC      =  STACK_FRAME_OVERHEAD + __PT_ILC
-SP_TRAP      = STACK_FRAME_OVERHEAD + __PT_TRAP
+SP_SVCNR      =        STACK_FRAME_OVERHEAD + __PT_SVCNR
 SP_SIZE      = STACK_FRAME_OVERHEAD + __PT_SIZE
 
 STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
@@ -171,11 +171,10 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
        .macro  CREATE_STACK_FRAME psworg,savearea
        aghi    %r15,-SP_SIZE           # make room for registers & psw
        mvc     SP_PSW(16,%r15),0(%r12) # move user PSW to stack
-       la      %r12,\psworg
        stg     %r2,SP_ORIG_R2(%r15)    # store original content of gpr 2
-       icm     %r12,12,__LC_SVC_ILC
+       icm     %r12,3,__LC_SVC_ILC
        stmg    %r0,%r11,SP_R0(%r15)    # store gprs %r0-%r11 to kernel stack
-       st      %r12,SP_ILC(%r15)
+       st      %r12,SP_SVCNR(%r15)
        mvc     SP_R12(32,%r15),\savearea # move %r12-%r15 to stack
        la      %r12,0
        stg     %r12,__SF_BACKCHAIN(%r15)
@@ -250,16 +249,17 @@ sysc_update:
 #endif
 sysc_do_svc:
        lg      %r9,__LC_THREAD_INFO    # load pointer to thread_info struct
-       slag    %r7,%r7,2       # *4 and test for svc 0
+       ltgr    %r7,%r7         # test for svc 0
        jnz     sysc_nr_ok
        # svc 0: system call number in %r1
        cl      %r1,BASED(.Lnr_syscalls)
        jnl     sysc_nr_ok
        lgfr    %r7,%r1         # clear high word in r1
-       slag    %r7,%r7,2       # svc 0: system call number in %r1
 sysc_nr_ok:
        mvc     SP_ARGS(8,%r15),SP_R7(%r15)
 sysc_do_restart:
+       sth     %r7,SP_SVCNR(%r15)
+       sllg    %r7,%r7,2       # svc number * 4
        larl    %r10,sys_call_table
 #ifdef CONFIG_COMPAT
        tm      __TI_flags+5(%r9),(_TIF_31BIT>>16)  # running in 31 bit mode ?
@@ -363,7 +363,6 @@ sysc_notify_resume:
 sysc_restart:
        ni      __TI_flags+7(%r9),255-_TIF_RESTART_SVC # clear TIF_RESTART_SVC
        lg      %r7,SP_R2(%r15)         # load new svc number
-       slag    %r7,%r7,2               # *4
        mvc     SP_R2(8,%r15),SP_ORIG_R2(%r15) # restore first argument
        lmg     %r2,%r6,SP_R2(%r15)     # load svc arguments
        j       sysc_do_restart         # restart svc
@@ -372,9 +371,8 @@ sysc_restart:
 # _TIF_SINGLE_STEP is set, call do_single_step
 #
 sysc_singlestep:
-       ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP # clear TIF_SINGLE_STEP
-       lhi     %r0,__LC_PGM_OLD_PSW
-       sth     %r0,SP_TRAP(%r15)       # set trap indication to pgm check
+       ni      __TI_flags+7(%r9),255-_TIF_SINGLE_STEP  # clear TIF_SINGLE_STEP
+       xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15)         # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        larl    %r14,sysc_return        # load adr. of system return
        jg      do_single_step          # branch to do_sigtrap
@@ -392,7 +390,7 @@ sysc_tracesys:
        lghi    %r0,NR_syscalls
        clgr    %r0,%r2
        jnh     sysc_tracenogo
-       slag    %r7,%r2,2               # *4
+       sllg    %r7,%r2,2               # svc number *4
        lgf     %r8,0(%r7,%r10)
 sysc_tracego:
        lmg     %r3,%r6,SP_R3(%r15)
@@ -567,8 +565,7 @@ pgm_svcper:
 # per was called from kernel, must be kprobes
 #
 kernel_per:
-       lhi     %r0,__LC_PGM_OLD_PSW
-       sth     %r0,SP_TRAP(%r15)       # set trap indication to pgm check
+       xc      SP_SVCNR(2,%r15),SP_SVCNR(%r15) # clear svc number
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        larl    %r14,sysc_restore       # load adr. of system ret, no work
        jg      do_single_step          # branch to do_single_step
index 7ad003969251f159cb7f5d6ab0cfaac62c9eb113..e807168436194c81fe0f4892f9be5a7e4bed685b 100644 (file)
@@ -26,7 +26,7 @@ EXPORT_SYMBOL(init_mm);
 /*
  * Initial thread structure.
  *
- * We need to make sure that this is 8192-byte aligned due to the
+ * We need to make sure that this is THREAD_SIZE aligned due to the
  * way process stacks are handled. This is done by having a special
  * "init_task" linker map entry..
  */
index 1f31be1ecc4bd57bd3af99ef004f00df4f24987b..38ff2bce12032d45a16e554b6e4545ea63fae21e 100644 (file)
@@ -657,7 +657,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
                 * debugger stored an invalid system call number. Skip
                 * the system call and the system call restart handling.
                 */
-               regs->trap = -1;
+               regs->svcnr = 0;
                ret = -1;
        }
 
index 4f7fc3059a8e8a1e1e937d976d1c962febcdbd7e..8e6812a22670b24704fafec7079c2136a9fa720a 100644 (file)
@@ -160,7 +160,7 @@ static int restore_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
        current->thread.fp_regs.fpc &= FPC_VALID_MASK;
 
        restore_fp_regs(&current->thread.fp_regs);
-       regs->trap = -1;        /* disable syscall checks */
+       regs->svcnr = 0;        /* disable syscall checks */
        return 0;
 }
 
@@ -445,7 +445,7 @@ void do_signal(struct pt_regs *regs)
                oldset = &current->blocked;
 
        /* Are we from a system call? */
-       if (regs->trap == __LC_SVC_OLD_PSW) {
+       if (regs->svcnr) {
                continue_addr = regs->psw.addr;
                restart_addr = continue_addr - regs->ilc;
                retval = regs->gprs[2];
@@ -462,7 +462,7 @@ void do_signal(struct pt_regs *regs)
                case -ERESTART_RESTARTBLOCK:
                        regs->gprs[2] = -EINTR;
                }
-               regs->trap = -1;        /* Don't deal with this again. */
+               regs->svcnr = 0;        /* Don't deal with this again. */
        }
 
        /* Get signal to deliver.  When running under ptrace, at this point
index b94e9e3b694a2bd738cfc58d8fdcc9bbc5baa412..eccefbbff887dc199b04ec715d25ec9c2ec1201c 100644 (file)
@@ -59,7 +59,7 @@
 
 static ext_int_info_t ext_int_info_cc;
 static ext_int_info_t ext_int_etr_cc;
-static u64 jiffies_timer_cc;
+static u64 sched_clock_base_cc;
 
 static DEFINE_PER_CPU(struct clock_event_device, comparators);
 
@@ -68,7 +68,7 @@ static DEFINE_PER_CPU(struct clock_event_device, comparators);
  */
 unsigned long long sched_clock(void)
 {
-       return ((get_clock_xt() - jiffies_timer_cc) * 125) >> 9;
+       return ((get_clock_xt() - sched_clock_base_cc) * 125) >> 9;
 }
 
 /*
@@ -229,13 +229,10 @@ static struct clocksource clocksource_tod = {
  */
 void __init time_init(void)
 {
-       u64 init_timer_cc;
-
-       init_timer_cc = reset_tod_clock();
-       jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY;
+       sched_clock_base_cc = reset_tod_clock();
 
        /* set xtime */
-       tod_to_timeval(init_timer_cc - TOD_UNIX_EPOCH, &xtime);
+       tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &xtime);
         set_normalized_timespec(&wall_to_monotonic,
                                 -xtime.tv_sec, -xtime.tv_nsec);
 
@@ -289,7 +286,7 @@ static unsigned long long adjust_time(unsigned long long old,
                delta = -delta;
                adjust.offset = -ticks * (1000000 / HZ);
        }
-       jiffies_timer_cc += delta;
+       sched_clock_base_cc += delta;
        if (adjust.offset != 0) {
                printk(KERN_NOTICE "etr: time adjusted by %li micro-seconds\n",
                       adjust.offset);
index 607bd67a18ce782f21051e4e306f8feced721719..d796d05c9c01ac1be6779682a730485d73502bd2 100644 (file)
@@ -2,6 +2,7 @@
  * Written by Martin Schwidefsky (schwidefsky@de.ibm.com)
  */
 
+#include <asm/thread_info.h>
 #include <asm/page.h>
 #include <asm-generic/vmlinux.lds.h>
 
@@ -86,7 +87,7 @@ SECTIONS
        }
        _edata = .;             /* End of data section */
 
-       . = ALIGN(2 * PAGE_SIZE);       /* init_task */
+       . = ALIGN(THREAD_SIZE); /* init_task */
        .data.init_task : {
                *(.data.init_task)
        }
index 3d3e9c161d8bdb41623a82aa97929fbd0be3b856..84e969f06afe318d986a9890d130cbf26759b704 100644 (file)
@@ -142,8 +142,6 @@ struct global_reg_snapshot {
 };
 extern struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 #define force_successful_syscall_return()          \
 do {   current_thread_info()->syscall_noerror = 1; \
 } while (0)
index e7a0edfc1a32532823d315a78deb6f1585a35502..1fc17f59c6bffc24758d3f44d3e8c71a66f1c8f6 100644 (file)
@@ -126,7 +126,7 @@ char *sparc_fpu_type;
 
 unsigned int fsr_storage;
 
-void __init cpu_probe(void)
+void __cpuinit cpu_probe(void)
 {
        int psr_impl, psr_vers, fpu_vers;
        int i, psr;
index 2d325fd845795e32361f658736784262f56bf5c0..51b40426f9c68e1ba0cde5fd4061c19efa02e9cf 100644 (file)
@@ -72,7 +72,7 @@ sun4e_notsup:
        .align 4
 
        /* The Sparc trap table, bootloader gives us control at _start. */
-       .text
+       .section .text.head,"ax"
        .globl  start, _stext, _start, __stext
        .globl  trapbase
 _start:   /* danger danger */
index 1619ec15c099493a85ba4f21c93e3ecbbe594576..e396c1f17a922deaef7b03a0751d06f1345770fd 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "irq.h"
 
-volatile unsigned long cpu_callin_map[NR_CPUS] __initdata = {0,};
+volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
 unsigned char boot_cpu_id = 0;
 unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */
 
@@ -120,7 +120,7 @@ void cpu_panic(void)
        panic("SMP bolixed\n");
 }
 
-struct linux_prom_registers smp_penguin_ctable __initdata = { 0 };
+struct linux_prom_registers smp_penguin_ctable __cpuinitdata = { 0 };
 
 void smp_send_reschedule(int cpu)
 {
index 7a6a5e7959282e736fb5b01baa591d9d52b478d4..16ab0cb731c5084debe40de0f701e29a92435e58 100644 (file)
@@ -83,7 +83,7 @@ static inline void show_leds(int cpuid)
                              "i" (ASI_M_CTL));
 }
 
-void __init smp4d_callin(void)
+void __cpuinit smp4d_callin(void)
 {
        int cpuid = hard_smp4d_processor_id();
        extern spinlock_t sun4d_imsk_lock;
@@ -386,7 +386,7 @@ void smp4d_percpu_timer_interrupt(struct pt_regs *regs)
 
 extern unsigned int lvl14_resolution;
 
-static void __init smp_setup_percpu_timer(void)
+static void __cpuinit smp_setup_percpu_timer(void)
 {
        int cpu = hard_smp4d_processor_id();
 
index 5fc386d08c4713ae0dd968cc02df4f044f0a77b2..4f8d60586b076caa72349094d1baa5f4a98d555c 100644 (file)
@@ -343,7 +343,7 @@ void smp4m_percpu_timer_interrupt(struct pt_regs *regs)
 
 extern unsigned int lvl14_resolution;
 
-static void __init smp_setup_percpu_timer(void)
+static void __cpuinit smp_setup_percpu_timer(void)
 {
        int cpu = smp_processor_id();
 
index 356c56aebc6284190327ae34b0a84dcfeb9de906..5e235c52d667df54cb741f67a64141854883103a 100644 (file)
@@ -18,7 +18,7 @@
        .globl sun4m_cpu_startup, __smp4m_processor_id
        .globl sun4d_cpu_startup, __smp4d_processor_id
 
-       __INIT
+       __CPUINIT
        .align 4
 
 /* When we start up a cpu for the first time it enters this routine.
@@ -109,7 +109,7 @@ __smp4d_processor_id:
 /* CPUID in bootbus can be found at PA 0xff0140000 */
 #define SUN4D_BOOTBUS_CPUID    0xf0140000
 
-       __INIT
+       __CPUINIT
        .align  4
 
 sun4d_cpu_startup:
index b1002c60719615bca22b0c4161e0d60afb959d58..5b7e69a8c32f7259497fafbcd1e816242e690423 100644 (file)
@@ -13,6 +13,7 @@ SECTIONS
        .text 0xf0004000 :
        {
                _text = .;
+               *(.text.head)
                TEXT_TEXT
                SCHED_TEXT
                LOCK_TEXT
index 6a5d7cabc04450eb10dcb4f75c792aa36838d584..dd8aa36f366c909fe4ca13e3eab297f7700cb127 100644 (file)
@@ -1251,7 +1251,7 @@ static inline void map_kernel(void)
 /* Paging initialization on the Sparc Reference MMU. */
 extern void sparc_context_init(int);
 
-void (*poke_srmmu)(void) __initdata = NULL;
+void (*poke_srmmu)(void) __cpuinitdata = NULL;
 
 extern unsigned long bootmem_init(unsigned long *pages_avail);
 
@@ -1446,7 +1446,7 @@ static void __init init_vac_layout(void)
               (int)vac_cache_size, (int)vac_line_size);
 }
 
-static void __init poke_hypersparc(void)
+static void __cpuinit poke_hypersparc(void)
 {
        volatile unsigned long clear;
        unsigned long mreg = srmmu_get_mmureg();
@@ -1501,7 +1501,7 @@ static void __init init_hypersparc(void)
        hypersparc_setup_blockops();
 }
 
-static void __init poke_cypress(void)
+static void __cpuinit poke_cypress(void)
 {
        unsigned long mreg = srmmu_get_mmureg();
        unsigned long faddr, tagval;
@@ -1589,7 +1589,7 @@ static void __init init_cypress_605(unsigned long mrev)
        init_cypress_common();
 }
 
-static void __init poke_swift(void)
+static void __cpuinit poke_swift(void)
 {
        unsigned long mreg;
 
@@ -1771,7 +1771,7 @@ static void turbosparc_flush_tlb_page(struct vm_area_struct *vma, unsigned long
 }
 
 
-static void __init poke_turbosparc(void)
+static void __cpuinit poke_turbosparc(void)
 {
        unsigned long mreg = srmmu_get_mmureg();
        unsigned long ccreg;
@@ -1834,7 +1834,7 @@ static void __init init_turbosparc(void)
        poke_srmmu = poke_turbosparc;
 }
 
-static void __init poke_tsunami(void)
+static void __cpuinit poke_tsunami(void)
 {
        unsigned long mreg = srmmu_get_mmureg();
 
@@ -1876,7 +1876,7 @@ static void __init init_tsunami(void)
        tsunami_setup_blockops();
 }
 
-static void __init poke_viking(void)
+static void __cpuinit poke_viking(void)
 {
        unsigned long mreg = srmmu_get_mmureg();
        static int smp_catch;
index e5627118e6131b527468b4107f3d9f40a63387ea..f500b0618bb0d3b4badcdee2c5c8cb20225c97e9 100644 (file)
@@ -282,7 +282,7 @@ static unsigned long kimage_addr_to_ra(void *p)
        return kern_base + (val - KERNBASE);
 }
 
-static void ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
+static void __cpuinit ldom_startcpu_cpuid(unsigned int cpu, unsigned long thread_reg)
 {
        extern unsigned long sparc64_ttable_tl0;
        extern unsigned long kern_locked_tte_data;
@@ -343,7 +343,7 @@ extern unsigned long sparc64_cpu_startup;
  */
 static struct thread_info *cpu_new_thread = NULL;
 
-static int __devinit smp_boot_one_cpu(unsigned int cpu)
+static int __cpuinit smp_boot_one_cpu(unsigned int cpu)
 {
        struct trap_per_cpu *tb = &trap_block[cpu];
        unsigned long entry =
index 3c10daf8fc015799a300ffc86d3d014b8f7ae5ee..185f34679110c3e373c99c8eaa3e569e5170c338 100644 (file)
@@ -956,7 +956,7 @@ int of_node_to_nid(struct device_node *dp)
        return nid;
 }
 
-static void add_node_ranges(void)
+static void __init add_node_ranges(void)
 {
        int i;
 
index 0be77b39328afc957c8aa70b64bbe0641f477a7c..7e8e8b25f5f6c89defd0df4064a61e3e16a4ea06 100644 (file)
@@ -74,7 +74,7 @@ static int kbd_pending(void)
 {
        u8 pending;
        asm volatile("int $0x16; setnz %0"
-                    : "=rm" (pending)
+                    : "=qm" (pending)
                     : "a" (0x0100));
        return pending;
 }
index 72c5a190bf48076d8b99b9f42f8a6f7a16a0e009..a95008457ea430ffbe7fdde3fc6a5fd57778ce79 100644 (file)
 #ifndef _ASM_X86_DS_H
 #define _ASM_X86_DS_H
 
-#ifdef CONFIG_X86_DS
 
 #include <linux/types.h>
 #include <linux/init.h>
 
 
+#ifdef CONFIG_X86_DS
+
 struct task_struct;
 
 /*
@@ -232,7 +233,8 @@ extern void ds_free(struct ds_context *context);
 
 #else /* CONFIG_X86_DS */
 
-#define ds_init_intel(config) do {} while (0)
+struct cpuinfo_x86;
+static inline void __cpuinit ds_init_intel(struct cpuinfo_x86 *ignored) {}
 
 #endif /* CONFIG_X86_DS */
 #endif /* _ASM_X86_DS_H */
index 5b28995d664e9a092b4054f770751b3413f50edf..d02d936840a3ed8e3b7f94fade13929c9a3d6413 100644 (file)
@@ -34,8 +34,6 @@ extern void pci_iommu_alloc(void);
  */
 #define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
 
-#if defined(CONFIG_GART_IOMMU) || defined(CONFIG_CALGARY_IOMMU)
-
 #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)      \
        dma_addr_t ADDR_NAME;
 #define DECLARE_PCI_UNMAP_LEN(LEN_NAME)                \
@@ -49,18 +47,6 @@ extern void pci_iommu_alloc(void);
 #define pci_unmap_len_set(PTR, LEN_NAME, VAL)          \
        (((PTR)->LEN_NAME) = (VAL))
 
-#else
-/* No IOMMU */
-
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME)         (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL)        do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME)           (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL)  do { } while (0)
-
-#endif
-
 #endif /* __KERNEL__ */
 
 #endif /* _ASM_X86_PCI_64_H */
index d1531c8480b78fdb42feb018c88e122ad93191b4..eefb0594b058917c7a93893f1f89a88973d8bfbc 100644 (file)
@@ -271,8 +271,6 @@ extern int do_get_thread_area(struct task_struct *p, int idx,
 extern int do_set_thread_area(struct task_struct *p, int idx,
                              struct user_desc __user *info, int can_allocate);
 
-#define __ARCH_WANT_COMPAT_SYS_PTRACE
-
 #endif /* __KERNEL__ */
 
 #endif /* !__ASSEMBLY__ */
index e489ff9cb3e203258aa2987d264cd26e556248ce..b62a7667828eb77574128a8ca82b1f54cee28238 100644 (file)
@@ -41,7 +41,7 @@ obj-$(CONFIG_X86_TRAMPOLINE)  += trampoline.o
 obj-y                          += process.o
 obj-y                          += i387.o xsave.o
 obj-y                          += ptrace.o
-obj-y                          += ds.o
+obj-$(CONFIG_X86_DS)           += ds.o
 obj-$(CONFIG_X86_32)           += tls.o
 obj-$(CONFIG_IA32_EMULATION)   += tls.o
 obj-y                          += step.o
index 04a7f960bbc0a2408907a959af527382dae477a5..16f94879b52578aba3e689d7a8adcccf59ab8ecb 100644 (file)
@@ -1315,7 +1315,7 @@ void enable_x2apic(void)
        }
 }
 
-void enable_IR_x2apic(void)
+void __init enable_IR_x2apic(void)
 {
 #ifdef CONFIG_INTR_REMAP
        int ret;
index d3dcd58b87cd50654d7a065e5d42b05300103f09..7f05f44b97e95c72447c0538f19e06185c0a18b1 100644 (file)
@@ -115,9 +115,20 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
        u32 i = 0;
 
        if (cpu_family == CPU_HW_PSTATE) {
-               rdmsr(MSR_PSTATE_STATUS, lo, hi);
-               i = lo & HW_PSTATE_MASK;
-               data->currpstate = i;
+               if (data->currpstate == HW_PSTATE_INVALID) {
+                       /* read (initial) hw pstate if not yet set */
+                       rdmsr(MSR_PSTATE_STATUS, lo, hi);
+                       i = lo & HW_PSTATE_MASK;
+
+                       /*
+                        * a workaround for family 11h erratum 311 might cause
+                        * an "out-of-range Pstate if the core is in Pstate-0
+                        */
+                       if (i >= data->numps)
+                               data->currpstate = HW_PSTATE_0;
+                       else
+                               data->currpstate = i;
+               }
                return 0;
        }
        do {
@@ -1121,6 +1132,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
        }
 
        data->cpu = pol->cpu;
+       data->currpstate = HW_PSTATE_INVALID;
 
        if (powernow_k8_cpu_init_acpi(data)) {
                /*
index ab48cfed4d96ce5629e29f3a21ffd9c3e25d8a21..65cfb5d7f77f17b508024c52891e68e959cab386 100644 (file)
@@ -5,6 +5,19 @@
  *  http://www.gnu.org/licenses/gpl.html
  */
 
+
+enum pstate {
+       HW_PSTATE_INVALID = 0xff,
+       HW_PSTATE_0 = 0,
+       HW_PSTATE_1 = 1,
+       HW_PSTATE_2 = 2,
+       HW_PSTATE_3 = 3,
+       HW_PSTATE_4 = 4,
+       HW_PSTATE_5 = 5,
+       HW_PSTATE_6 = 6,
+       HW_PSTATE_7 = 7,
+};
+
 struct powernow_k8_data {
        unsigned int cpu;
 
@@ -23,7 +36,9 @@ struct powernow_k8_data {
         u32 exttype; /* extended interface = 1 */
 
        /* keep track of the current fid / vid or pstate */
-       u32 currvid, currfid, currpstate;
+       u32 currvid;
+       u32 currfid;
+       enum pstate currpstate;
 
        /* the powernow_table includes all frequency and vid/fid pairings:
         * fid are the lower 8 bits of the index, vid are the upper 8 bits.
index d1a121443bde5b571c2e853734b006cbb100fbcb..a2d1176c38ee0d59b3e47925a79d8aebdff73d20 100644 (file)
@@ -21,8 +21,6 @@
  */
 
 
-#ifdef CONFIG_X86_DS
-
 #include <asm/ds.h>
 
 #include <linux/errno.h>
@@ -211,14 +209,15 @@ static DEFINE_PER_CPU(struct ds_context *, system_context);
 static inline struct ds_context *ds_get_context(struct task_struct *task)
 {
        struct ds_context *context;
+       unsigned long irq;
 
-       spin_lock(&ds_lock);
+       spin_lock_irqsave(&ds_lock, irq);
 
        context = (task ? task->thread.ds_ctx : this_system_context);
        if (context)
                context->count++;
 
-       spin_unlock(&ds_lock);
+       spin_unlock_irqrestore(&ds_lock, irq);
 
        return context;
 }
@@ -226,55 +225,46 @@ static inline struct ds_context *ds_get_context(struct task_struct *task)
 /*
  * Same as ds_get_context, but allocates the context and it's DS
  * structure, if necessary; returns NULL; if out of memory.
- *
- * pre: requires ds_lock to be held
  */
 static inline struct ds_context *ds_alloc_context(struct task_struct *task)
 {
        struct ds_context **p_context =
                (task ? &task->thread.ds_ctx : &this_system_context);
        struct ds_context *context = *p_context;
+       unsigned long irq;
 
        if (!context) {
-               spin_unlock(&ds_lock);
-
                context = kzalloc(sizeof(*context), GFP_KERNEL);
-
-               if (!context) {
-                       spin_lock(&ds_lock);
+               if (!context)
                        return NULL;
-               }
 
                context->ds = kzalloc(ds_cfg.sizeof_ds, GFP_KERNEL);
                if (!context->ds) {
                        kfree(context);
-                       spin_lock(&ds_lock);
                        return NULL;
                }
 
-               spin_lock(&ds_lock);
-               /*
-                * Check for race - another CPU could have allocated
-                * it meanwhile:
-                */
+               spin_lock_irqsave(&ds_lock, irq);
+
                if (*p_context) {
                        kfree(context->ds);
                        kfree(context);
-                       return *p_context;
-               }
 
-               *p_context = context;
+                       context = *p_context;
+               } else {
+                       *p_context = context;
 
-               context->this = p_context;
-               context->task = task;
+                       context->this = p_context;
+                       context->task = task;
 
-               if (task)
-                       set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
+                       if (task)
+                               set_tsk_thread_flag(task, TIF_DS_AREA_MSR);
 
-               if (!task || (task == current))
-                       wrmsr(MSR_IA32_DS_AREA, (unsigned long)context->ds, 0);
-
-               get_tracer(task);
+                       if (!task || (task == current))
+                               wrmsrl(MSR_IA32_DS_AREA,
+                                      (unsigned long)context->ds);
+               }
+               spin_unlock_irqrestore(&ds_lock, irq);
        }
 
        context->count++;
@@ -288,10 +278,12 @@ static inline struct ds_context *ds_alloc_context(struct task_struct *task)
  */
 static inline void ds_put_context(struct ds_context *context)
 {
+       unsigned long irq;
+
        if (!context)
                return;
 
-       spin_lock(&ds_lock);
+       spin_lock_irqsave(&ds_lock, irq);
 
        if (--context->count)
                goto out;
@@ -313,7 +305,7 @@ static inline void ds_put_context(struct ds_context *context)
        kfree(context->ds);
        kfree(context);
  out:
-       spin_unlock(&ds_lock);
+       spin_unlock_irqrestore(&ds_lock, irq);
 }
 
 
@@ -384,6 +376,7 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
        struct ds_context *context;
        unsigned long buffer, adj;
        const unsigned long alignment = (1 << 3);
+       unsigned long irq;
        int error = 0;
 
        if (!ds_cfg.sizeof_ds)
@@ -398,26 +391,27 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
                return -EOPNOTSUPP;
 
 
-       spin_lock(&ds_lock);
-
-       error = -ENOMEM;
        context = ds_alloc_context(task);
        if (!context)
-               goto out_unlock;
+               return -ENOMEM;
+
+       spin_lock_irqsave(&ds_lock, irq);
 
        error = -EPERM;
        if (!check_tracer(task))
                goto out_unlock;
 
+       get_tracer(task);
+
        error = -EALREADY;
        if (context->owner[qual] == current)
-               goto out_unlock;
+               goto out_put_tracer;
        error = -EPERM;
        if (context->owner[qual] != NULL)
-               goto out_unlock;
+               goto out_put_tracer;
        context->owner[qual] = current;
 
-       spin_unlock(&ds_lock);
+       spin_unlock_irqrestore(&ds_lock, irq);
 
 
        error = -ENOMEM;
@@ -465,10 +459,17 @@ static int ds_request(struct task_struct *task, void *base, size_t size,
  out_release:
        context->owner[qual] = NULL;
        ds_put_context(context);
+       put_tracer(task);
+       return error;
+
+ out_put_tracer:
+       spin_unlock_irqrestore(&ds_lock, irq);
+       ds_put_context(context);
+       put_tracer(task);
        return error;
 
  out_unlock:
-       spin_unlock(&ds_lock);
+       spin_unlock_irqrestore(&ds_lock, irq);
        ds_put_context(context);
        return error;
 }
@@ -818,13 +819,21 @@ static const struct ds_configuration ds_cfg_var = {
        .sizeof_ds    = sizeof(long) * 12,
        .sizeof_field = sizeof(long),
        .sizeof_rec[ds_bts]   = sizeof(long) * 3,
+#ifdef __i386__
        .sizeof_rec[ds_pebs]  = sizeof(long) * 10
+#else
+       .sizeof_rec[ds_pebs]  = sizeof(long) * 18
+#endif
 };
 static const struct ds_configuration ds_cfg_64 = {
        .sizeof_ds    = 8 * 12,
        .sizeof_field = 8,
        .sizeof_rec[ds_bts]   = 8 * 3,
+#ifdef __i386__
        .sizeof_rec[ds_pebs]  = 8 * 10
+#else
+       .sizeof_rec[ds_pebs]  = 8 * 18
+#endif
 };
 
 static inline void
@@ -878,4 +887,3 @@ void ds_free(struct ds_context *context)
        while (leftovers--)
                ds_put_context(context);
 }
-#endif /* CONFIG_X86_DS */
index 1f20608d4ca8b6e274518715ef487933e8489c59..b0f61f0dcd0a925d13a41a0500ae0f11821d51f3 100644 (file)
@@ -58,7 +58,7 @@ void __cpuinit mxcsr_feature_mask_init(void)
        stts();
 }
 
-void __init init_thread_xstate(void)
+void __cpuinit init_thread_xstate(void)
 {
        if (!HAVE_HWFP) {
                xstate_size = sizeof(struct i387_soft_struct);
index c9513e1ff28d3b79fd5fd5806cd41a0eb33a29c0..9043251210fba4dc32ea7db009a1db6196216453 100644 (file)
@@ -3608,27 +3608,7 @@ int __init io_apic_get_redir_entries (int ioapic)
 
 int __init probe_nr_irqs(void)
 {
-       int idx;
-       int nr = 0;
-#ifndef CONFIG_XEN
-       int nr_min = 32;
-#else
-       int nr_min = NR_IRQS;
-#endif
-
-       for (idx = 0; idx < nr_ioapics; idx++)
-               nr += io_apic_get_redir_entries(idx) + 1;
-
-       /* double it for hotplug and msi and nmi */
-       nr <<= 1;
-
-       /* something wrong ? */
-       if (nr < nr_min)
-               nr = nr_min;
-       if (WARN_ON(nr > NR_IRQS))
-               nr = NR_IRQS;
-
-       return nr;
+       return NR_IRQS;
 }
 
 /* --------------------------------------------------------------------------
@@ -3775,7 +3755,9 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
 void __init setup_ioapic_dest(void)
 {
        int pin, ioapic, irq, irq_entry;
+       struct irq_desc *desc;
        struct irq_cfg *cfg;
+       cpumask_t mask;
 
        if (skip_ioapic_setup == 1)
                return;
@@ -3792,16 +3774,30 @@ void __init setup_ioapic_dest(void)
                         * cpu is online.
                         */
                        cfg = irq_cfg(irq);
-                       if (!cfg->vector)
+                       if (!cfg->vector) {
                                setup_IO_APIC_irq(ioapic, pin, irq,
                                                  irq_trigger(irq_entry),
                                                  irq_polarity(irq_entry));
+                               continue;
+
+                       }
+
+                       /*
+                        * Honour affinities which have been set in early boot
+                        */
+                       desc = irq_to_desc(irq);
+                       if (desc->status &
+                           (IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
+                               mask = desc->affinity;
+                       else
+                               mask = TARGET_CPUS;
+
 #ifdef CONFIG_INTR_REMAP
-                       else if (intr_remapping_enabled)
-                               set_ir_ioapic_affinity_irq(irq, TARGET_CPUS);
-#endif
+                       if (intr_remapping_enabled)
+                               set_ir_ioapic_affinity_irq(irq, mask);
                        else
-                               set_ioapic_affinity_irq(irq, TARGET_CPUS);
+#endif
+                               set_ioapic_affinity_irq(irq, mask);
                }
 
        }
index 1c9cc431ea4f8679b0b4b6bbbe0552ad104ab379..e169ae9b6a62e9f3d2b4d914de87ce4157c26569 100644 (file)
@@ -128,7 +128,7 @@ static int kvm_register_clock(char *txt)
 }
 
 #ifdef CONFIG_X86_LOCAL_APIC
-static void __devinit kvm_setup_secondary_clock(void)
+static void __cpuinit kvm_setup_secondary_clock(void)
 {
        /*
         * Now that the first cpu already had this clocksource initialized,
index e1e731d78f3821bb6f27950eca4033e52a77c606..d28bbdc35e4e5dec064bd1f9e5e7fbc548deaf4e 100644 (file)
@@ -1567,7 +1567,7 @@ static int __init calgary_parse_options(char *p)
                                ++p;
                        if (*p == '\0')
                                break;
-                       bridge = simple_strtol(p, &endp, 0);
+                       bridge = simple_strtoul(p, &endp, 0);
                        if (p == endp)
                                break;
 
index b13acb75e822e337aec4f8e8d6a094c24e30feb0..15c3e699918221487429508113173f692794a943 100644 (file)
@@ -310,7 +310,7 @@ static void __init setup_xstate_init(void)
 /*
  * Enable and initialize the xsave feature.
  */
-void __init xsave_cntxt_init(void)
+void __ref xsave_cntxt_init(void)
 {
        unsigned int eax, ebx, ecx, edx;
 
index 3f1b81a83e2e5be2ebd1cabde2a66b71ccd20306..716d26f0e5d47b74ae43abb862d7d296c17ef609 100644 (file)
@@ -69,7 +69,7 @@ static void ppro_setup_ctrs(struct op_msrs const * const msrs)
        int i;
 
        if (!reset_value) {
-               reset_value = kmalloc(sizeof(unsigned) * num_counters,
+               reset_value = kmalloc(sizeof(reset_value[0]) * num_counters,
                                        GFP_ATOMIC);
                if (!reset_value)
                        return;
index 3c27a809393b59051aaa794ad33b2310fd70402c..2051dc96b8e94aee2b63af14d3d2a8a9486cfdcd 100644 (file)
@@ -496,21 +496,24 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SIEMENS, 0x0015,
                          pci_siemens_interrupt_controller);
 
 /*
- * Regular PCI devices have 256 bytes, but AMD Family 10h Opteron ext config
- * have 4096 bytes.  Even if the device is capable, that doesn't mean we can
- * access it.  Maybe we don't have a way to generate extended config space
- * accesses.   So check it
+ * Regular PCI devices have 256 bytes, but AMD Family 10h/11h CPUs have
+ * 4096 bytes configuration space for each function of their processor
+ * configuration space.
  */
-static void fam10h_pci_cfg_space_size(struct pci_dev *dev)
+static void amd_cpu_pci_cfg_space_size(struct pci_dev *dev)
 {
        dev->cfg_size = pci_cfg_space_size_ext(dev);
 }
-
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, fam10h_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, fam10h_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, fam10h_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, fam10h_pci_cfg_space_size);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, fam10h_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1200, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1201, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1202, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1203, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1204, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1300, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1301, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1302, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1303, amd_cpu_pci_cfg_space_size);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AMD, 0x1304, amd_cpu_pci_cfg_space_size);
 
 /*
  * SB600: Disable BAR1 on device 14.0 to avoid HPET resources from
index 688936044dc95cdac8d6ce79e3ee10f39e898178..636ef4caa52d3dee2a24fc3b1913fe23b8ab34db 100644 (file)
@@ -661,12 +661,11 @@ void xen_set_pgd(pgd_t *ptr, pgd_t val)
  * For 64-bit, we must skip the Xen hole in the middle of the address
  * space, just after the big x86-64 virtual hole.
  */
-static int xen_pgd_walk(struct mm_struct *mm,
-                       int (*func)(struct mm_struct *mm, struct page *,
-                                   enum pt_level),
-                       unsigned long limit)
+static int __xen_pgd_walk(struct mm_struct *mm, pgd_t *pgd,
+                         int (*func)(struct mm_struct *mm, struct page *,
+                                     enum pt_level),
+                         unsigned long limit)
 {
-       pgd_t *pgd = mm->pgd;
        int flush = 0;
        unsigned hole_low, hole_high;
        unsigned pgdidx_limit, pudidx_limit, pmdidx_limit;
@@ -753,6 +752,14 @@ out:
        return flush;
 }
 
+static int xen_pgd_walk(struct mm_struct *mm,
+                       int (*func)(struct mm_struct *mm, struct page *,
+                                   enum pt_level),
+                       unsigned long limit)
+{
+       return __xen_pgd_walk(mm, mm->pgd, func, limit);
+}
+
 /* If we're using split pte locks, then take the page's lock and
    return a pointer to it.  Otherwise return NULL. */
 static spinlock_t *xen_pte_lock(struct page *page, struct mm_struct *mm)
@@ -854,7 +861,7 @@ static void __xen_pgd_pin(struct mm_struct *mm, pgd_t *pgd)
 
        xen_mc_batch();
 
-        if (xen_pgd_walk(mm, xen_pin_page, USER_LIMIT)) {
+       if (__xen_pgd_walk(mm, pgd, xen_pin_page, USER_LIMIT)) {
                /* re-enable interrupts for flushing */
                xen_mc_issue(0);
 
@@ -998,7 +1005,7 @@ static void __xen_pgd_unpin(struct mm_struct *mm, pgd_t *pgd)
                       PT_PMD);
 #endif
 
-       xen_pgd_walk(mm, xen_unpin_page, USER_LIMIT);
+       __xen_pgd_walk(mm, pgd, xen_unpin_page, USER_LIMIT);
 
        xen_mc_issue(0);
 }
index d77da613b1d2e49e626e601a6cdb9027d807fb18..acd9b6705e024f0833614f209caf2ab0da62807a 100644 (file)
@@ -362,7 +362,7 @@ static void xen_cpu_die(unsigned int cpu)
                alternatives_smp_switch(0);
 }
 
-static void xen_play_dead(void)
+static void __cpuinit xen_play_dead(void) /* used only with CPU_HOTPLUG */
 {
        play_dead_common();
        HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
index d7422dc2a55c33fd1a77cee38fc877110ff3a24e..9e1afae8461f1eabc04e625c06d9ef329a73b8f2 100644 (file)
@@ -49,7 +49,7 @@ bool xen_vcpu_stolen(int vcpu);
 
 void xen_mark_init_mm_pinned(void);
 
-void __init xen_setup_vcpu_info_placement(void);
+void xen_setup_vcpu_info_placement(void);
 
 #ifdef CONFIG_SMP
 void xen_smp_init(void);
index 1423b0c0cd2eecc6e3c7b2f5c78746cee5fac4eb..a0a178dd189c3259fcc82f323b6c4011fe1442a4 100644 (file)
@@ -174,6 +174,15 @@ static int acpi_battery_get_property(struct power_supply *psy,
                break;
        case POWER_SUPPLY_PROP_CURRENT_NOW:
                val->intval = battery->current_now * 1000;
+               /* if power units are mW, convert to mA by
+                  dividing by current voltage (mV/1000) */
+               if (!battery->power_unit) {
+                       if (battery->voltage_now) {
+                               val->intval /= battery->voltage_now;
+                               val->intval *= 1000;
+                       } else
+                               val->intval = -1;
+               }
                break;
        case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
        case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
index ea92bac42c53dd438fae0c82b2e310b8098f7dff..09c69806c1fc7693f91268ce86d0a8030dc2df59 100644 (file)
@@ -176,16 +176,6 @@ static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
        acpi_dmi_osi_linux(1, d);       /* enable */
        return 0;
 }
-static int __init dmi_disable_osi_linux(const struct dmi_system_id *d)
-{
-       acpi_dmi_osi_linux(0, d);       /* disable */
-       return 0;
-}
-static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d)
-{
-       acpi_dmi_osi_linux(-1, d);      /* unknown */
-       return 0;
-}
 static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
 {
        printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
@@ -193,295 +183,21 @@ static int __init dmi_disable_osi_vista(const struct dmi_system_id *d)
        return 0;
 }
 
-/*
- * Most BIOS that invoke OSI(Linux) do nothing with it.
- * But some cause Linux to break.
- * Only a couple use it to make Linux run better.
- *
- * Thus, Linux should continue to disable OSI(Linux) by default,
- * should continue to discourage BIOS writers from using it, and
- * should whitelist the few existing systems that require it.
- *
- * If it appears clear a vendor isn't using OSI(Linux)
- * for anything constructive, blacklist them by name to disable
- * unnecessary dmesg warnings on all of their products.
- */
-
 static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
-       /*
-        * Disable OSI(Linux) warnings on all "Acer, inc."
-        *
-        * _OSI(Linux) disables the latest Windows BIOS code:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3100"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
-        * _OSI(Linux) effect unknown:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
-        */
-       /*
-        * note that dmi_check_system() uses strstr()
-        * to match sub-strings rather than !strcmp(),
-        * so "Acer" below matches "Acer, inc." above.
-        */
-       /*
-        * Disable OSI(Linux) warnings on all "Acer"
-        *
-        * _OSI(Linux) effect unknown:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"),
-        *
-        * _OSI(Linux) is a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Acer",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "Apple Computer, Inc."
-        * Disable OSI(Linux) warnings on all "Apple Inc."
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
-        * _OSI(Linux) effect unknown:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Apple",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Apple"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "BenQ"
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "BenQ",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "BenQ"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "Clevo Co."
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Clevo",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "COMPAL"
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"),
-        * _OSI(Linux) unknown effect:
-        * DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Compal",
-       .matches = {
-                    DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
-               },
-       },
-       { /* OSI(Linux) touches USB, unknown side-effect */
-       .callback = dmi_disable_osi_linux,
-       .ident = "Dell Dimension 5150",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"),
-               },
-       },
-       { /* OSI(Linux) is a NOP */
-       .callback = dmi_disable_osi_linux,
-       .ident = "Dell i1501",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"),
-               },
-       },
-       { /* OSI(Linux) effect unknown */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell Latitude D830",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"),
-               },
-       },
-       { /* OSI(Linux) effect unknown */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell OptiPlex GX620",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"),
-               },
-       },
-       { /* OSI(Linux) causes some USB initialization to not run */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell OptiPlex 755",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 755"),
-               },
-       },
-       { /* OSI(Linux) effect unknown */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell PE 1900",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"),
-               },
-       },
-       { /* OSI(Linux) is a NOP */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell PE 1950",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"),
-               },
-       },
-       { /* OSI(Linux) is a NOP */
-       .callback = dmi_disable_osi_linux,
-       .ident = "Dell PE R200",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R200"),
-               },
-       },
-       { /* OSI(Linux) touches USB */
-       .callback = dmi_disable_osi_linux,
-       .ident = "Dell PR 390",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"),
-               },
-       },
-       { /* OSI(Linux) touches USB */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell PR 390",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 690"),
-               },
-       },
-       { /* OSI(Linux) unknown - ASL looks benign, but may effect dock/SMM */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell PR M4300",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Precision M4300"),
-               },
-       },
-       { /* OSI(Linux) is a NOP */
-       .callback = dmi_disable_osi_linux,
-       .ident = "Dell Vostro 1000",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Vostro   1000"),
-               },
-       },
-       { /* OSI(Linux) effect unknown */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dell PE SC440",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"),
-               },
-       },
-       { /* OSI(Linux) effect unknown */
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Dialogue Flybook V5",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS"
-        *
-        * _OSI(Linux) disables latest Windows BIOS code:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"),
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
-        * _OSI(Linux) unknown effect:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Fujitsu Siemens",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-               },
-       },
        {
        .callback = dmi_disable_osi_vista,
        .ident = "Fujitsu Siemens",
        .matches = {
                     DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
+                    DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
                },
        },
+
        /*
-        * Disable OSI(Linux) warnings on all "Hewlett-Packard"
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * .ident = "HP Pavilion tx 1000"
-        * DMI_MATCH(DMI_BOARD_NAME, "30BF"),
-        * .ident = "HP Pavilion dv2000"
-        * DMI_MATCH(DMI_BOARD_NAME, "30B5"),
-        * .ident = "HP Pavilion dv5000",
-        * DMI_MATCH(DMI_BOARD_NAME, "30A7"),
-        * .ident = "HP Pavilion dv6300 30BC",
-        * DMI_MATCH(DMI_BOARD_NAME, "30BC"),
-        * .ident = "HP Pavilion dv6000",
-        * DMI_MATCH(DMI_BOARD_NAME, "30B7"),
-        * DMI_MATCH(DMI_BOARD_NAME, "30B8"),
-        * .ident = "HP Pavilion dv9000",
-        * DMI_MATCH(DMI_BOARD_NAME, "30B9"),
-        * .ident = "HP Pavilion dv9500",
-        * DMI_MATCH(DMI_BOARD_NAME, "30CB"),
-        * .ident = "HP/Compaq Presario C500",
-        * DMI_MATCH(DMI_BOARD_NAME, "30C6"),
-        * .ident = "HP/Compaq Presario F500",
-        * DMI_MATCH(DMI_BOARD_NAME, "30D3"),
-        * _OSI(Linux) unknown effect:
-        * .ident = "HP Pavilion dv6500",
-        * DMI_MATCH(DMI_BOARD_NAME, "30D0"),
+        * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
+        * Linux ignores it, except for the machines enumerated below.
         */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Hewlett-Packard",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
-               },
-       },
+
        /*
         * Lenovo has a mix of systems OSI(Linux) situations
         * and thus we can not wildcard the vendor.
@@ -519,113 +235,6 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
                     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"),
                },
        },
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Lenovo 3000 V100",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"),
-               },
-       },
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Lenovo 3000 N100",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
-                    DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "LG Electronics"
-        *
-        * _OSI(Linux) confirmed to be a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
-        * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
-        *
-        * unknown:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "S1-MDGDG"),
-        * with DMI_MATCH(DMI_BOARD_NAME, "ROCKY"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "LG",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
-               },
-       },
-       /* NEC - OSI(Linux) effect unknown */
-       {
-       .callback = dmi_unknown_osi_linux,
-       .ident = "NEC VERSA M360",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"),
-                    DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"),
-               },
-       },
-       /* Panasonic */
-       {
-       .callback = dmi_unknown_osi_linux,
-       .ident = "Panasonic",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"),
-                       /* Toughbook CF-52 */
-                    DMI_MATCH(DMI_PRODUCT_NAME, "CF-52CCABVBG"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "Samsung Electronics"
-        *
-        * OSI(Linux) disables PNP0C32 and other BIOS code for Windows:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Samsung",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "Sony Corporation"
-        *
-        * _OSI(Linux) is a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NR11S_S"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"),
-        * _OSI(Linux) unknown effect:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Sony",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
-               },
-       },
-       /*
-        * Disable OSI(Linux) warnings on all "TOSHIBA"
-        *
-        * _OSI(Linux) breaks sound (bugzilla 7787):
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"),
-        * _OSI(Linux) is a NOP:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"),
-        * _OSI(Linux) unknown effect:
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"),
-        * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"),
-        */
-       {
-       .callback = dmi_disable_osi_linux,
-       .ident = "Toshiba",
-       .matches = {
-                    DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-               },
-       },
        {}
 };
 
index cf41f9fc24a73fed7d7bd0799f654050609ef128..30f3ef236ecb1b354548c5bb2570866eaa8ec6be 100644 (file)
@@ -219,7 +219,8 @@ static void gpe_transaction(struct acpi_ec *ec, u8 status)
        goto unlock;
 err:
        /* false interrupt, state didn't change */
-       ++ec->curr->irq_count;
+       if (in_interrupt())
+               ++ec->curr->irq_count;
 unlock:
        spin_unlock_irqrestore(&ec->curr_lock, flags);
 }
index 4be252145cb45320cf82b14c4e579c525bf2776e..c8111424dcb88b8a8cdc0e401f025a79149dfaa1 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/interrupt.h>
 #include <linux/kmod.h>
 #include <linux/delay.h>
-#include <linux/dmi.h>
 #include <linux/workqueue.h>
 #include <linux/nmi.h>
 #include <linux/acpi.h>
@@ -97,54 +96,44 @@ static DEFINE_SPINLOCK(acpi_res_lock);
 static char osi_additional_string[OSI_STRING_LENGTH_MAX];
 
 /*
- * "Ode to _OSI(Linux)"
+ * The story of _OSI(Linux)
  *
- * osi_linux -- Control response to BIOS _OSI(Linux) query.
+ * From pre-history through Linux-2.6.22,
+ * Linux responded TRUE upon a BIOS OSI(Linux) query.
  *
- * As Linux evolves, the features that it supports change.
- * So an OSI string such as "Linux" is not specific enough
- * to be useful across multiple versions of Linux.  It
- * doesn't identify any particular feature, interface,
- * or even any particular version of Linux...
+ * Unfortunately, reference BIOS writers got wind of this
+ * and put OSI(Linux) in their example code, quickly exposing
+ * this string as ill-conceived and opening the door to
+ * an un-bounded number of BIOS incompatibilities.
  *
- * Unfortunately, Linux-2.6.22 and earlier responded "yes"
- * to a BIOS _OSI(Linux) query.  When
- * a reference mobile BIOS started using it, its use
- * started to spread to many vendor platforms.
- * As it is not supportable, we need to halt that spread.
+ * For example, OSI(Linux) was used on resume to re-POST a
+ * video card on one system, because Linux at that time
+ * could not do a speedy restore in its native driver.
+ * But then upon gaining quick native restore capability,
+ * Linux has no way to tell the BIOS to skip the time-consuming
+ * POST -- putting Linux at a permanent performance disadvantage.
+ * On another system, the BIOS writer used OSI(Linux)
+ * to infer native OS support for IPMI!  On other systems,
+ * OSI(Linux) simply got in the way of Linux claiming to
+ * be compatible with other operating systems, exposing
+ * BIOS issues such as skipped device initialization.
  *
- * Today, most BIOS references to _OSI(Linux) are noise --
- * they have no functional effect and are just dead code
- * carried over from the reference BIOS.
- *
- * The next most common case is that _OSI(Linux) harms Linux,
- * usually by causing the BIOS to follow paths that are
- * not tested during Windows validation.
- *
- * Finally, there is a short list of platforms
- * where OSI(Linux) benefits Linux.
- *
- * In Linux-2.6.23, OSI(Linux) is first disabled by default.
- * DMI is used to disable the dmesg warning about OSI(Linux)
- * on platforms where it is known to have no effect.
- * But a dmesg warning remains for systems where
- * we do not know if OSI(Linux) is good or bad for the system.
- * DMI is also used to enable OSI(Linux) for the machines
- * that are known to need it.
+ * So "Linux" turned out to be a really poor chose of
+ * OSI string, and from Linux-2.6.23 onward we respond FALSE.
  *
  * BIOS writers should NOT query _OSI(Linux) on future systems.
- * It will be ignored by default, and to get Linux to
- * not ignore it will require a kernel source update to
- * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation.
+ * Linux will complain on the console when it sees it, and return FALSE.
+ * To get Linux to return TRUE for your system  will require
+ * a kernel source update to add a DMI entry,
+ * or boot with "acpi_osi=Linux"
  */
-#define OSI_LINUX_ENABLE 0
 
 static struct osi_linux {
        unsigned int    enable:1;
        unsigned int    dmi:1;
        unsigned int    cmdline:1;
        unsigned int    known:1;
-} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0};
+} osi_linux = { 0, 0, 0, 0};
 
 static void __init acpi_request_region (struct acpi_generic_address *addr,
        unsigned int length, char *desc)
@@ -1296,34 +1285,6 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
        return (AE_OK);
 }
 
-/**
- *     acpi_dmi_dump - dump DMI slots needed for blacklist entry
- *
- *     Returns 0 on success
- */
-static int acpi_dmi_dump(void)
-{
-
-       if (!dmi_available)
-               return -1;
-
-       printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
-               dmi_get_system_info(DMI_SYS_VENDOR));
-       printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
-               dmi_get_system_info(DMI_PRODUCT_NAME));
-       printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
-               dmi_get_system_info(DMI_PRODUCT_VERSION));
-       printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
-               dmi_get_system_info(DMI_BOARD_NAME));
-       printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
-               dmi_get_system_info(DMI_BIOS_VENDOR));
-       printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
-               dmi_get_system_info(DMI_BIOS_DATE));
-
-       return 0;
-}
-
-
 /******************************************************************************
  *
  * FUNCTION:    acpi_os_validate_interface
@@ -1350,21 +1311,6 @@ acpi_os_validate_interface (char *interface)
                        osi_linux.cmdline ? " via cmdline" :
                        osi_linux.dmi ? " via DMI" : "");
 
-               if (!osi_linux.dmi) {
-                       if (acpi_dmi_dump())
-                               printk(KERN_NOTICE PREFIX
-                                       "[please extract dmidecode output]\n");
-                       printk(KERN_NOTICE PREFIX
-                               "Please send DMI info above to "
-                               "linux-acpi@vger.kernel.org\n");
-               }
-               if (!osi_linux.known && !osi_linux.cmdline) {
-                       printk(KERN_NOTICE PREFIX
-                               "If \"acpi_osi=%sLinux\" works better, "
-                               "please notify linux-acpi@vger.kernel.org\n",
-                               osi_linux.enable ? "!" : "");
-               }
-
                if (osi_linux.enable)
                        return AE_OK;
        }
index bd5253ee5c858de0af62f409590fee76e80429c7..39b7233c348592670ef86b1df5747f3d90151dc9 100644 (file)
@@ -751,16 +751,6 @@ static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
        if (!acpi_match_device_ids(device, button_device_ids))
                device->wakeup.flags.run_wake = 1;
 
-       /*
-        * Don't set Power button GPE as run_wake
-        * if Fixed Power button is used
-        */
-       if (!strcmp(device->pnp.hardware_id, "PNP0C0C") &&
-               !(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) {
-               device->wakeup.flags.run_wake = 0;
-               device->wakeup.flags.valid = 0;
-       }
-
       end:
        if (ACPI_FAILURE(status))
                device->flags.wake_capable = 0;
index 80c0868d0480e76a0eced99a00a163f98114353c..28a691cc625ebec8827454e98cfaa94b5260b9ce 100644 (file)
@@ -90,6 +90,18 @@ void __init acpi_old_suspend_ordering(void)
        old_suspend_ordering = true;
 }
 
+/*
+ * According to the ACPI specification the BIOS should make sure that ACPI is
+ * enabled and SCI_EN bit is set on wake-up from S1 - S3 sleep states.  Still,
+ * some BIOSes don't do that and therefore we use acpi_enable() to enable ACPI
+ * on such systems during resume.  Unfortunately that doesn't help in
+ * particularly pathological cases in which SCI_EN has to be set directly on
+ * resume, although the specification states very clearly that this flag is
+ * owned by the hardware.  The set_sci_en_on_resume variable will be set in such
+ * cases.
+ */
+static bool set_sci_en_on_resume;
+
 /**
  *     acpi_pm_disable_gpes - Disable the GPEs.
  */
@@ -235,7 +247,11 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
        }
 
        /* If ACPI is not enabled by the BIOS, we need to enable it here. */
-       acpi_enable();
+       if (set_sci_en_on_resume)
+               acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+       else
+               acpi_enable();
+
        /* Reprogram control registers and execute _BFS */
        acpi_leave_sleep_state_prep(acpi_state);
 
@@ -323,6 +339,12 @@ static int __init init_old_suspend_ordering(const struct dmi_system_id *d)
        return 0;
 }
 
+static int __init init_set_sci_en_on_resume(const struct dmi_system_id *d)
+{
+       set_sci_en_on_resume = true;
+       return 0;
+}
+
 static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
        {
        .callback = init_old_suspend_ordering,
@@ -340,6 +362,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "HP xw4600 Workstation"),
                },
        },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Apple MacBook 1,1",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
+               },
+       },
+       {
+       .callback = init_set_sci_en_on_resume,
+       .ident = "Apple MacMini 1,1",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
+               },
+       },
        {},
 };
 #endif /* CONFIG_SUSPEND */
index 66aac06f2ac5abd47ec7e5ecf7267f2b3c6e30aa..25f531d892deacbb5082b0696f0ba460c48a5494 100644 (file)
@@ -848,8 +848,6 @@ static int __init toshiba_acpi_init(void)
        ret = input_register_polled_device(toshiba_acpi.poll_dev);
        if (ret) {
                printk(MY_ERR "unable to register kill-switch input device\n");
-               rfkill_free(toshiba_acpi.rfk_dev);
-               toshiba_acpi.rfk_dev = NULL;
                toshiba_acpi_exit();
                return ret;
        }
index e827be36ee8db99b4b8d648389cb7cc40df4064a..f844941089bb30786b143bee118e9e1e9b1cac54 100644 (file)
@@ -259,34 +259,26 @@ acpi_evaluate_integer(acpi_handle handle,
                      struct acpi_object_list *arguments, unsigned long long *data)
 {
        acpi_status status = AE_OK;
-       union acpi_object *element;
+       union acpi_object element;
        struct acpi_buffer buffer = { 0, NULL };
 
-
        if (!data)
                return AE_BAD_PARAMETER;
 
-       element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
-       if (!element)
-               return AE_NO_MEMORY;
-
        buffer.length = sizeof(union acpi_object);
-       buffer.pointer = element;
+       buffer.pointer = &element;
        status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
        if (ACPI_FAILURE(status)) {
                acpi_util_eval_error(handle, pathname, status);
-               kfree(element);
                return status;
        }
 
-       if (element->type != ACPI_TYPE_INTEGER) {
+       if (element.type != ACPI_TYPE_INTEGER) {
                acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
-               kfree(element);
                return AE_BAD_DATA;
        }
 
-       *data = element->integer.value;
-       kfree(element);
+       *data = element.integer.value;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%llu]\n", *data));
 
index ecab9e67d47a3985b2cfb67d1c2a16e04981eb1f..29e1dfafb7c6bd813844b82f1e903f88e5d34d99 100644 (file)
@@ -194,7 +194,7 @@ struct ace_device {
        int in_irq;
 
        /* Details of hardware device */
-       unsigned long physaddr;
+       resource_size_t physaddr;
        void __iomem *baseaddr;
        int irq;
        int bus_width;          /* 0 := 8 bit; 1 := 16 bit */
@@ -628,8 +628,8 @@ static void ace_fsm_dostate(struct ace_device *ace)
 
                /* Okay, it's a data request, set it up for transfer */
                dev_dbg(ace->dev,
-                       "request: sec=%lx hcnt=%lx, ccnt=%x, dir=%i\n",
-                       req->sector, req->hard_nr_sectors,
+                       "request: sec=%llx hcnt=%lx, ccnt=%x, dir=%i\n",
+                       (unsigned long long) req->sector, req->hard_nr_sectors,
                        req->current_nr_sectors, rq_data_dir(req));
 
                ace->req = req;
@@ -935,7 +935,8 @@ static int __devinit ace_setup(struct ace_device *ace)
        int rc;
 
        dev_dbg(ace->dev, "ace_setup(ace=0x%p)\n", ace);
-       dev_dbg(ace->dev, "physaddr=0x%lx irq=%i\n", ace->physaddr, ace->irq);
+       dev_dbg(ace->dev, "physaddr=0x%llx irq=%i\n",
+               (unsigned long long)ace->physaddr, ace->irq);
 
        spin_lock_init(&ace->lock);
        init_completion(&ace->id_completion);
@@ -1017,8 +1018,8 @@ static int __devinit ace_setup(struct ace_device *ace)
        /* Print the identification */
        dev_info(ace->dev, "Xilinx SystemACE revision %i.%i.%i\n",
                 (version >> 12) & 0xf, (version >> 8) & 0x0f, version & 0xff);
-       dev_dbg(ace->dev, "physaddr 0x%lx, mapped to 0x%p, irq=%i\n",
-               ace->physaddr, ace->baseaddr, ace->irq);
+       dev_dbg(ace->dev, "physaddr 0x%llx, mapped to 0x%p, irq=%i\n",
+               (unsigned long long) ace->physaddr, ace->baseaddr, ace->irq);
 
        ace->media_change = 1;
        ace_revalidate_disk(ace->gd);
@@ -1035,8 +1036,8 @@ err_alloc_disk:
 err_blk_initq:
        iounmap(ace->baseaddr);
 err_ioremap:
-       dev_info(ace->dev, "xsysace: error initializing device at 0x%lx\n",
-              ace->physaddr);
+       dev_info(ace->dev, "xsysace: error initializing device at 0x%llx\n",
+                (unsigned long long) ace->physaddr);
        return -ENOMEM;
 }
 
@@ -1059,7 +1060,7 @@ static void __devexit ace_teardown(struct ace_device *ace)
 }
 
 static int __devinit
-ace_alloc(struct device *dev, int id, unsigned long physaddr,
+ace_alloc(struct device *dev, int id, resource_size_t physaddr,
          int irq, int bus_width)
 {
        struct ace_device *ace;
@@ -1119,7 +1120,7 @@ static void __devexit ace_free(struct device *dev)
 
 static int __devinit ace_probe(struct platform_device *dev)
 {
-       unsigned long physaddr = 0;
+       resource_size_t physaddr = 0;
        int bus_width = ACE_BUS_WIDTH_16; /* FIXME: should not be hard coded */
        int id = dev->id;
        int irq = NO_IRQ;
@@ -1165,7 +1166,7 @@ static int __devinit
 ace_of_probe(struct of_device *op, const struct of_device_id *match)
 {
        struct resource res;
-       unsigned long physaddr;
+       resource_size_t physaddr;
        const u32 *id;
        int irq, bus_width, rc;
 
index 0f004b65ec0384e383cf12eced1320e311560031..03f95ec08f59bea10ea5aaaeb94a4dda563c5eef 100644 (file)
@@ -27,7 +27,7 @@
 static int uninorth_rev;
 static int is_u3;
 
-static char __devinitdata *aperture = NULL;
+static char *aperture = NULL;
 
 static int uninorth_fetch_size(void)
 {
index 44e5d60f517ebd504c0161d516442c76a42f5e57..4b10770fa9377e2ed316abaf0bfdada41adb5044 100644 (file)
@@ -3739,7 +3739,7 @@ static int stli_getbrdnr(void)
  *     do is go probing around in the usual places hoping we can find it.
  */
 
-static int stli_findeisabrds(void)
+static int __init stli_findeisabrds(void)
 {
        struct stlibrd *brdp;
        unsigned int iobase, eid, i;
@@ -3935,7 +3935,7 @@ static struct stlibrd *stli_allocbrd(void)
  *     can find.
  */
 
-static int stli_initbrds(void)
+static int __init stli_initbrds(void)
 {
        struct stlibrd *brdp, *nxtbrdp;
        struct stlconf conf;
index 59f472143f087d9486d62bd9f3842c2a9aee7eb6..1412a8d1e58de75059b5687b533e77e4667f44a3 100644 (file)
@@ -1795,12 +1795,15 @@ retry_open:
        }
 #endif
        if (device == MKDEV(TTYAUX_MAJOR, 1)) {
-               driver = tty_driver_kref_get(console_device(&index));
-               if (driver) {
-                       /* Don't let /dev/console block */
-                       filp->f_flags |= O_NONBLOCK;
-                       noctty = 1;
-                       goto got_driver;
+               struct tty_driver *console_driver = console_device(&index);
+               if (console_driver) {
+                       driver = tty_driver_kref_get(console_driver);
+                       if (driver) {
+                               /* Don't let /dev/console block */
+                               filp->f_flags |= O_NONBLOCK;
+                               noctty = 1;
+                               goto got_driver;
+                       }
                }
                mutex_unlock(&tty_mutex);
                return -ENODEV;
index ed132fe55d3d35aad97339593d5a131fc601b8ba..d16131949097696cc8a72d2d07ae6a393094ebb7 100644 (file)
@@ -626,7 +626,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
        if (!request_mem_region(drvdata->mem_start,
                                        drvdata->mem_size, DRIVER_NAME)) {
                dev_err(dev, "Couldn't lock memory region at %Lx\n",
-                       regs_res->start);
+                       (unsigned long long) regs_res->start);
                retval = -EBUSY;
                goto failed1;
        }
@@ -645,9 +645,10 @@ static int __devinit hwicap_setup(struct device *dev, int id,
        mutex_init(&drvdata->sem);
        drvdata->is_open = 0;
 
-       dev_info(dev, "ioremap %lx to %p with size %Lx\n",
-                (unsigned long int)drvdata->mem_start,
-                       drvdata->base_address, drvdata->mem_size);
+       dev_info(dev, "ioremap %llx to %p with size %llx\n",
+                (unsigned long long) drvdata->mem_start,
+                drvdata->base_address,
+                (unsigned long long) drvdata->mem_size);
 
        cdev_init(&drvdata->cdev, &hwicap_fops);
        drvdata->cdev.owner = THIS_MODULE;
index b6ad3ac5916e0311d989fb3241b04f6327b62912..24607669a52b1a0d41d6f51319c279284e1927f5 100644 (file)
@@ -1357,7 +1357,7 @@ static int hw_supports(struct device *dev, __be32 desc_hdr_template)
        return ret;
 }
 
-static int __devexit talitos_remove(struct of_device *ofdev)
+static int talitos_remove(struct of_device *ofdev)
 {
        struct device *dev = &ofdev->dev;
        struct talitos_private *priv = dev_get_drvdata(dev);
@@ -1622,7 +1622,7 @@ static struct of_platform_driver talitos_driver = {
        .name = "talitos",
        .match_table = talitos_match,
        .probe = talitos_probe,
-       .remove = __devexit_p(talitos_remove),
+       .remove = talitos_remove,
 };
 
 static int __init talitos_init(void)
index 3ab1e9cc4692fce873b925a7fb7816acc0173710..996097acb5e76b3c3d7698c0885f563ad9248522 100644 (file)
@@ -305,6 +305,8 @@ static void drm_cleanup(struct drm_device * dev)
                return;
        }
 
+       drm_vblank_cleanup(dev);
+
        drm_lastclose(dev);
 
        if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
index 15c8dabc3e97af6601448b32442df7fa803d71e5..1e787f894b3cf38f6c46eeda39c73cb8a49ad1c5 100644 (file)
@@ -94,7 +94,7 @@ static void vblank_disable_fn(unsigned long arg)
        }
 }
 
-static void drm_vblank_cleanup(struct drm_device *dev)
+void drm_vblank_cleanup(struct drm_device *dev)
 {
        /* Bail if the driver didn't call drm_vblank_init() */
        if (dev->num_crtcs == 0)
@@ -278,8 +278,6 @@ int drm_irq_uninstall(struct drm_device * dev)
 
        free_irq(dev->pdev->irq, dev);
 
-       drm_vblank_cleanup(dev);
-
        return 0;
 }
 EXPORT_SYMBOL(drm_irq_uninstall);
index 0d215e38606a32a053a620da3026139860e7fa5a..ba89b42f790abb693a0b355e9ee918f0f1339c81 100644 (file)
@@ -856,6 +856,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
 
        spin_lock_init(&dev_priv->user_irq_lock);
 
+       ret = drm_vblank_init(dev, I915_NUM_PIPE);
+
+       if (ret) {
+               (void) i915_driver_unload(dev);
+               return ret;
+       }
+
        return ret;
 }
 
index ef1c0b8f8d07858422526f10e6f4fb63e428cf3d..0a4f39b9a0ec1623b79fa4073b8580efb203caa0 100644 (file)
@@ -47,6 +47,8 @@ enum pipe {
        PIPE_B,
 };
 
+#define I915_NUM_PIPE  2
+
 /* Interface history:
  *
  * 1.1: Original.
@@ -132,6 +134,7 @@ typedef struct drm_i915_private {
        int user_irq_refcount;
        /** Cached value of IMR to avoid reads in updating the bitfield */
        u32 irq_mask_reg;
+       u32 pipestat[2];
 
        int tex_lru_log_granularity;
        int allow_batchbuffer;
@@ -147,6 +150,7 @@ typedef struct drm_i915_private {
        u32 saveDSPBCNTR;
        u32 saveDSPARB;
        u32 saveRENDERSTANDBY;
+       u32 saveHWS;
        u32 savePIPEACONF;
        u32 savePIPEBCONF;
        u32 savePIPEASRC;
@@ -446,6 +450,13 @@ extern int i915_vblank_swap(struct drm_device *dev, void *data,
                            struct drm_file *file_priv);
 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
 
+void
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
+
+void
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
+
+
 /* i915_mem.c */
 extern int i915_mem_alloc(struct drm_device *dev, void *data,
                          struct drm_file *file_priv);
index 6b4a2bd20640598f1e5407dc095ef3a9bed0d6b7..d58ddef468f8124c29f6af32412ee2ba31f9873e 100644 (file)
@@ -31,6 +31,8 @@
 #include "i915_drv.h"
 #include <linux/swap.h>
 
+#define I915_GEM_GPU_DOMAINS   (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
+
 static int
 i915_gem_object_set_domain(struct drm_gem_object *obj,
                            uint32_t read_domains,
@@ -83,20 +85,14 @@ int
 i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data,
                            struct drm_file *file_priv)
 {
-       drm_i915_private_t *dev_priv = dev->dev_private;
        struct drm_i915_gem_get_aperture *args = data;
-       struct drm_i915_gem_object *obj_priv;
 
        if (!(dev->driver->driver_features & DRIVER_GEM))
                return -ENODEV;
 
        args->aper_size = dev->gtt_total;
-       args->aper_available_size = args->aper_size;
-
-       list_for_each_entry(obj_priv, &dev_priv->mm.active_list, list) {
-               if (obj_priv->pin_count > 0)
-                       args->aper_available_size -= obj_priv->obj->size;
-       }
+       args->aper_available_size = (args->aper_size -
+                                    atomic_read(&dev->pin_memory));
 
        return 0;
 }
@@ -1870,17 +1866,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
 
        for (i = 0; i < args->buffer_count; i++) {
                struct drm_gem_object *obj = object_list[i];
-               struct drm_i915_gem_object *obj_priv = obj->driver_private;
-
-               if (obj_priv->gtt_space == NULL) {
-                       /* We evicted the buffer in the process of validating
-                        * our set of buffers in.  We could try to recover by
-                        * kicking them everything out and trying again from
-                        * the start.
-                        */
-                       ret = -ENOMEM;
-                       goto err;
-               }
 
                /* make sure all previous memory operations have passed */
                ret = i915_gem_object_set_domain(obj,
@@ -2299,29 +2284,52 @@ i915_gem_idle(struct drm_device *dev)
 
        i915_gem_retire_requests(dev);
 
-       /* Active and flushing should now be empty as we've
-        * waited for a sequence higher than any pending execbuffer
-        */
-       BUG_ON(!list_empty(&dev_priv->mm.active_list));
-       BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
+       if (!dev_priv->mm.wedged) {
+               /* Active and flushing should now be empty as we've
+                * waited for a sequence higher than any pending execbuffer
+                */
+               WARN_ON(!list_empty(&dev_priv->mm.active_list));
+               WARN_ON(!list_empty(&dev_priv->mm.flushing_list));
+               /* Request should now be empty as we've also waited
+                * for the last request in the list
+                */
+               WARN_ON(!list_empty(&dev_priv->mm.request_list));
+       }
 
-       /* Request should now be empty as we've also waited
-        * for the last request in the list
+       /* Empty the active and flushing lists to inactive.  If there's
+        * anything left at this point, it means that we're wedged and
+        * nothing good's going to happen by leaving them there.  So strip
+        * the GPU domains and just stuff them onto inactive.
         */
-       BUG_ON(!list_empty(&dev_priv->mm.request_list));
+       while (!list_empty(&dev_priv->mm.active_list)) {
+               struct drm_i915_gem_object *obj_priv;
+
+               obj_priv = list_first_entry(&dev_priv->mm.active_list,
+                                           struct drm_i915_gem_object,
+                                           list);
+               obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
+               i915_gem_object_move_to_inactive(obj_priv->obj);
+       }
+
+       while (!list_empty(&dev_priv->mm.flushing_list)) {
+               struct drm_i915_gem_object *obj_priv;
+
+               obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
+                                           struct drm_i915_gem_object,
+                                           list);
+               obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
+               i915_gem_object_move_to_inactive(obj_priv->obj);
+       }
 
-       /* Move all buffers out of the GTT. */
+
+       /* Move all inactive buffers out of the GTT. */
        ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
+       WARN_ON(!list_empty(&dev_priv->mm.inactive_list));
        if (ret) {
                mutex_unlock(&dev->struct_mutex);
                return ret;
        }
 
-       BUG_ON(!list_empty(&dev_priv->mm.active_list));
-       BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
-       BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
-       BUG_ON(!list_empty(&dev_priv->mm.request_list));
-
        i915_gem_cleanup_ringbuffer(dev);
        mutex_unlock(&dev->struct_mutex);
 
index 82752d6177a4949d406ec383b53cc31e6bcf9474..fe3d9cc72bf510403c797398c2cafa00eeecf8c2 100644 (file)
 
 #define MAX_NOPID ((u32)~0)
 
-/** These are the interrupts used by the driver */
-#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT |              \
-                                   I915_ASLE_INTERRUPT |               \
-                                   I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
-                                   I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+/**
+ * Interrupts that are always left unmasked.
+ *
+ * Since pipe events are edge-triggered from the PIPESTAT register to IIR,
+ * we leave them always unmasked in IMR and then control enabling them through
+ * PIPESTAT alone.
+ */
+#define I915_INTERRUPT_ENABLE_FIX (I915_ASLE_INTERRUPT | \
+                                  I915_DISPLAY_PIPE_A_EVENT_INTERRUPT |  \
+                                  I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
+
+/** Interrupts that we mask and unmask at runtime. */
+#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
+
+/** These are all of the interrupts used by the driver */
+#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
+                                   I915_INTERRUPT_ENABLE_VAR)
 
 void
 i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
@@ -59,6 +71,41 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
        }
 }
 
+static inline u32
+i915_pipestat(int pipe)
+{
+       if (pipe == 0)
+               return PIPEASTAT;
+       if (pipe == 1)
+               return PIPEBSTAT;
+       BUG_ON(1);
+}
+
+void
+i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
+{
+       if ((dev_priv->pipestat[pipe] & mask) != mask) {
+               u32 reg = i915_pipestat(pipe);
+
+               dev_priv->pipestat[pipe] |= mask;
+               /* Enable the interrupt, clear any pending status */
+               I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16));
+               (void) I915_READ(reg);
+       }
+}
+
+void
+i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
+{
+       if ((dev_priv->pipestat[pipe] & mask) != 0) {
+               u32 reg = i915_pipestat(pipe);
+
+               dev_priv->pipestat[pipe] &= ~mask;
+               I915_WRITE(reg, dev_priv->pipestat[pipe]);
+               (void) I915_READ(reg);
+       }
+}
+
 /**
  * i915_pipe_enabled - check if a pipe is enabled
  * @dev: DRM device
@@ -121,80 +168,102 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
        struct drm_device *dev = (struct drm_device *) arg;
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 iir;
+       u32 iir, new_iir;
        u32 pipea_stats, pipeb_stats;
+       u32 vblank_status;
+       u32 vblank_enable;
        int vblank = 0;
+       unsigned long irqflags;
+       int irq_received;
+       int ret = IRQ_NONE;
 
        atomic_inc(&dev_priv->irq_received);
 
-       if (dev->pdev->msi_enabled)
-               I915_WRITE(IMR, ~0);
        iir = I915_READ(IIR);
 
-       if (iir == 0) {
-               if (dev->pdev->msi_enabled) {
-                       I915_WRITE(IMR, dev_priv->irq_mask_reg);
-                       (void) I915_READ(IMR);
-               }
-               return IRQ_NONE;
+       if (IS_I965G(dev)) {
+               vblank_status = I915_START_VBLANK_INTERRUPT_STATUS;
+               vblank_enable = PIPE_START_VBLANK_INTERRUPT_ENABLE;
+       } else {
+               vblank_status = I915_VBLANK_INTERRUPT_STATUS;
+               vblank_enable = I915_VBLANK_INTERRUPT_ENABLE;
        }
 
-       /*
-        * Clear the PIPE(A|B)STAT regs before the IIR otherwise
-        * we may get extra interrupts.
-        */
-       if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
+       for (;;) {
+               irq_received = iir != 0;
+
+               /* Can't rely on pipestat interrupt bit in iir as it might
+                * have been cleared after the pipestat interrupt was received.
+                * It doesn't set the bit in iir again, but it still produces
+                * interrupts (for non-MSI).
+                */
+               spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
                pipea_stats = I915_READ(PIPEASTAT);
-               if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
-                       pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                        PIPE_VBLANK_INTERRUPT_ENABLE);
-               else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
-                                       PIPE_VBLANK_INTERRUPT_STATUS)) {
+               pipeb_stats = I915_READ(PIPEBSTAT);
+               /*
+                * Clear the PIPE(A|B)STAT regs before the IIR
+                */
+               if (pipea_stats & 0x8000ffff) {
+                       I915_WRITE(PIPEASTAT, pipea_stats);
+                       irq_received = 1;
+               }
+
+               if (pipeb_stats & 0x8000ffff) {
+                       I915_WRITE(PIPEBSTAT, pipeb_stats);
+                       irq_received = 1;
+               }
+               spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
+
+               if (!irq_received)
+                       break;
+
+               ret = IRQ_HANDLED;
+
+               I915_WRITE(IIR, iir);
+               new_iir = I915_READ(IIR); /* Flush posted writes */
+
+               if (dev_priv->sarea_priv)
+                       dev_priv->sarea_priv->last_dispatch =
+                               READ_BREADCRUMB(dev_priv);
+
+               if (iir & I915_USER_INTERRUPT) {
+                       dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
+                       DRM_WAKEUP(&dev_priv->irq_queue);
+               }
+
+               if (pipea_stats & vblank_status) {
                        vblank++;
                        drm_handle_vblank(dev, 0);
                }
 
-               I915_WRITE(PIPEASTAT, pipea_stats);
-       }
-       if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
-               pipeb_stats = I915_READ(PIPEBSTAT);
-               /* Ack the event */
-               I915_WRITE(PIPEBSTAT, pipeb_stats);
-
-               /* The vblank interrupt gets enabled even if we didn't ask for
-                  it, so make sure it's shut down again */
-               if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
-                       pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                                        PIPE_VBLANK_INTERRUPT_ENABLE);
-               else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
-                                       PIPE_VBLANK_INTERRUPT_STATUS)) {
+               if (pipeb_stats & vblank_status) {
                        vblank++;
                        drm_handle_vblank(dev, 1);
                }
 
-               if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
+               if ((pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS) ||
+                   (iir & I915_ASLE_INTERRUPT))
                        opregion_asle_intr(dev);
-               I915_WRITE(PIPEBSTAT, pipeb_stats);
-       }
-
-       I915_WRITE(IIR, iir);
-       if (dev->pdev->msi_enabled)
-               I915_WRITE(IMR, dev_priv->irq_mask_reg);
-       (void) I915_READ(IIR); /* Flush posted writes */
-
-       if (dev_priv->sarea_priv)
-               dev_priv->sarea_priv->last_dispatch =
-                       READ_BREADCRUMB(dev_priv);
 
-       if (iir & I915_USER_INTERRUPT) {
-               dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
-               DRM_WAKEUP(&dev_priv->irq_queue);
+               /* With MSI, interrupts are only generated when iir
+                * transitions from zero to nonzero.  If another bit got
+                * set while we were handling the existing iir bits, then
+                * we would never get another interrupt.
+                *
+                * This is fine on non-MSI as well, as if we hit this path
+                * we avoid exiting the interrupt handler only to generate
+                * another one.
+                *
+                * Note that for MSI this could cause a stray interrupt report
+                * if an interrupt landed in the time between writing IIR and
+                * the posting read.  This should be rare enough to never
+                * trigger the 99% of 100,000 interrupts test for disabling
+                * stray interrupts.
+                */
+               iir = new_iir;
        }
 
-       if (iir & I915_ASLE_INTERRUPT)
-               opregion_asle_intr(dev);
-
-       return IRQ_HANDLED;
+       return ret;
 }
 
 static int i915_emit_irq(struct drm_device * dev)
@@ -330,48 +399,16 @@ int i915_irq_wait(struct drm_device *dev, void *data,
 int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32     pipestat_reg = 0;
-       u32     pipestat;
-       u32     interrupt = 0;
        unsigned long irqflags;
 
-       switch (pipe) {
-       case 0:
-               pipestat_reg = PIPEASTAT;
-               interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
-               break;
-       case 1:
-               pipestat_reg = PIPEBSTAT;
-               interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
-               break;
-       default:
-               DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
-                         pipe);
-               return 0;
-       }
-
        spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-       /* Enabling vblank events in IMR comes before PIPESTAT write, or
-        * there's a race where the PIPESTAT vblank bit gets set to 1, so
-        * the OR of enabled PIPESTAT bits goes to 1, so the PIPExEVENT in
-        * ISR flashes to 1, but the IIR bit doesn't get set to 1 because
-        * IMR masks it.  It doesn't ever get set after we clear the masking
-        * in IMR because the ISR bit is edge, not level-triggered, on the
-        * OR of PIPESTAT bits.
-        */
-       i915_enable_irq(dev_priv, interrupt);
-       pipestat = I915_READ(pipestat_reg);
        if (IS_I965G(dev))
-               pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
+               i915_enable_pipestat(dev_priv, pipe,
+                                    PIPE_START_VBLANK_INTERRUPT_ENABLE);
        else
-               pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
-       /* Clear any stale interrupt status */
-       pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                    PIPE_VBLANK_INTERRUPT_STATUS);
-       I915_WRITE(pipestat_reg, pipestat);
-       (void) I915_READ(pipestat_reg); /* Posting read */
+               i915_enable_pipestat(dev_priv, pipe,
+                                    PIPE_VBLANK_INTERRUPT_ENABLE);
        spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
-
        return 0;
 }
 
@@ -381,37 +418,12 @@ int i915_enable_vblank(struct drm_device *dev, int pipe)
 void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32     pipestat_reg = 0;
-       u32     pipestat;
-       u32     interrupt = 0;
        unsigned long irqflags;
 
-       switch (pipe) {
-       case 0:
-               pipestat_reg = PIPEASTAT;
-               interrupt = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
-               break;
-       case 1:
-               pipestat_reg = PIPEBSTAT;
-               interrupt = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
-               break;
-       default:
-               DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
-                         pipe);
-               return;
-               break;
-       }
-
        spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
-       i915_disable_irq(dev_priv, interrupt);
-       pipestat = I915_READ(pipestat_reg);
-       pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
-                     PIPE_VBLANK_INTERRUPT_ENABLE);
-       /* Clear any stale interrupt status */
-       pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
-                    PIPE_VBLANK_INTERRUPT_STATUS);
-       I915_WRITE(pipestat_reg, pipestat);
-       (void) I915_READ(pipestat_reg); /* Posting read */
+       i915_disable_pipestat(dev_priv, pipe,
+                             PIPE_VBLANK_INTERRUPT_ENABLE |
+                             PIPE_START_VBLANK_INTERRUPT_ENABLE);
        spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags);
 }
 
@@ -476,32 +488,35 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
        I915_WRITE(HWSTAM, 0xeffe);
+       I915_WRITE(PIPEASTAT, 0);
+       I915_WRITE(PIPEBSTAT, 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
+       (void) I915_READ(IER);
 }
 
 int i915_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       int ret, num_pipes = 2;
-
-       /* Set initial unmasked IRQs to just the selected vblank pipes. */
-       dev_priv->irq_mask_reg = ~0;
-
-       ret = drm_vblank_init(dev, num_pipes);
-       if (ret)
-               return ret;
 
        dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
-       dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
-       dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
 
        dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
 
-       dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
+       /* Unmask the interrupts that we always want on. */
+       dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX;
+
+       dev_priv->pipestat[0] = 0;
+       dev_priv->pipestat[1] = 0;
+
+       /* Disable pipe interrupt enables, clear pending pipe status */
+       I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
+       I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
+       /* Clear pending interrupt status */
+       I915_WRITE(IIR, I915_READ(IIR));
 
-       I915_WRITE(IMR, dev_priv->irq_mask_reg);
        I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+       I915_WRITE(IMR, dev_priv->irq_mask_reg);
        (void) I915_READ(IER);
 
        opregion_enable_asle(dev);
@@ -513,7 +528,6 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
 void i915_driver_irq_uninstall(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
-       u32 temp;
 
        if (!dev_priv)
                return;
@@ -521,13 +535,12 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
        dev_priv->vblank_pipe = 0;
 
        I915_WRITE(HWSTAM, 0xffffffff);
+       I915_WRITE(PIPEASTAT, 0);
+       I915_WRITE(PIPEBSTAT, 0);
        I915_WRITE(IMR, 0xffffffff);
        I915_WRITE(IER, 0x0);
 
-       temp = I915_READ(PIPEASTAT);
-       I915_WRITE(PIPEASTAT, temp);
-       temp = I915_READ(PIPEBSTAT);
-       I915_WRITE(PIPEBSTAT, temp);
-       temp = I915_READ(IIR);
-       I915_WRITE(IIR, temp);
+       I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
+       I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
+       I915_WRITE(IIR, I915_READ(IIR));
 }
index 1787a0c7e3abf09acc363b87495190ce362db6ce..13ae731a33dba577b9a7326a9fe22daf8c1baf1c 100644 (file)
@@ -235,17 +235,15 @@ void opregion_enable_asle(struct drm_device *dev)
        struct opregion_asle *asle = dev_priv->opregion.asle;
 
        if (asle) {
-               u32 pipeb_stats = I915_READ(PIPEBSTAT);
                if (IS_MOBILE(dev)) {
-                       /* Many devices trigger events with a write to the
-                          legacy backlight controller, so we need to ensure
-                          that it's able to generate interrupts */
-                       I915_WRITE(PIPEBSTAT, pipeb_stats |=
-                                  I915_LEGACY_BLC_EVENT_ENABLE);
-                       i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT |
-                                       I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
-               } else
-                       i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
+                       unsigned long irqflags;
+
+                       spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags);
+                       i915_enable_pipestat(dev_priv, 1,
+                                            I915_LEGACY_BLC_EVENT_ENABLE);
+                       spin_unlock_irqrestore(&dev_priv->user_irq_lock,
+                                              irqflags);
+               }
 
                asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
                        ASLE_PFMB_EN;
index 5ddc6e595c0cef6b12ca729570505fd136f5d07d..5d84027ee8f39608076220513c71ed097cb751e4 100644 (file)
@@ -244,6 +244,9 @@ int i915_save_state(struct drm_device *dev)
        if (IS_I965G(dev) && IS_MOBILE(dev))
                dev_priv->saveRENDERSTANDBY = I915_READ(MCHBAR_RENDER_STANDBY);
 
+       /* Hardware status page */
+       dev_priv->saveHWS = I915_READ(HWS_PGA);
+
        /* Display arbitration control */
        dev_priv->saveDSPARB = I915_READ(DSPARB);
 
@@ -373,6 +376,9 @@ int i915_restore_state(struct drm_device *dev)
        if (IS_I965G(dev) && IS_MOBILE(dev))
                I915_WRITE(MCHBAR_RENDER_STANDBY, dev_priv->saveRENDERSTANDBY);
 
+       /* Hardware status page */
+       I915_WRITE(HWS_PGA, dev_priv->saveHWS);
+
        /* Display arbitration */
        I915_WRITE(DSPARB, dev_priv->saveDSPARB);
 
index c1d12dbfa8d8dec82e47c7821561e06da9744417..b49c5ff29585d3533b9b915b6c65cc5f9904c68f 100644 (file)
@@ -396,6 +396,7 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
 int mga_driver_load(struct drm_device * dev, unsigned long flags)
 {
        drm_mga_private_t *dev_priv;
+       int ret;
 
        dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
        if (!dev_priv)
@@ -415,6 +416,13 @@ int mga_driver_load(struct drm_device * dev, unsigned long flags)
        dev->types[7] = _DRM_STAT_PRIMARY;
        dev->types[8] = _DRM_STAT_SECONDARY;
 
+       ret = drm_vblank_init(dev, 1);
+
+       if (ret) {
+               (void) mga_driver_unload(dev);
+               return ret;
+       }
+
        return 0;
 }
 
index bab42f41188b0238356b4ef1ce80caeb87e6a6db..daa6041a483ad8be9f608b72f4c3f79db7f63e01 100644 (file)
@@ -152,11 +152,6 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
 int mga_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
-       int ret;
-
-       ret = drm_vblank_init(dev, 1);
-       if (ret)
-               return ret;
 
        DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
 
index 3265d53ba91f0d966fb4aadbe0645cab227cd0ef..601f4c0e5da57accd3e81ea1938f72bcf1c61c2e 100644 (file)
@@ -45,6 +45,7 @@ static struct drm_driver driver = {
            DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
            DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
        .dev_priv_size = sizeof(drm_r128_buf_priv_t),
+       .load = r128_driver_load,
        .preclose = r128_driver_preclose,
        .lastclose = r128_driver_lastclose,
        .get_vblank_counter = r128_get_vblank_counter,
@@ -84,6 +85,11 @@ static struct drm_driver driver = {
        .patchlevel = DRIVER_PATCHLEVEL,
 };
 
+int r128_driver_load(struct drm_device * dev, unsigned long flags)
+{
+       return drm_vblank_init(dev, 1);
+}
+
 static int __init r128_init(void)
 {
        driver.num_ioctls = r128_max_ioctl;
index 5898b274279d216cf0630fed63af2480a7a0ebb4..797a26c42dababf8c12193271aaf336849271424 100644 (file)
@@ -159,6 +159,7 @@ extern void r128_driver_irq_preinstall(struct drm_device * dev);
 extern int r128_driver_irq_postinstall(struct drm_device *dev);
 extern void r128_driver_irq_uninstall(struct drm_device * dev);
 extern void r128_driver_lastclose(struct drm_device * dev);
+extern int r128_driver_load(struct drm_device * dev, unsigned long flags);
 extern void r128_driver_preclose(struct drm_device * dev,
                                 struct drm_file *file_priv);
 
index d7349012a680b35a0b50091e2e6e5f3bf70d6004..69810fb8ac49101a36645061adc93ca265e19cd8 100644 (file)
@@ -102,7 +102,7 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
 
 int r128_driver_irq_postinstall(struct drm_device *dev)
 {
-       return drm_vblank_init(dev, 1);
+       return 0;
 }
 
 void r128_driver_irq_uninstall(struct drm_device * dev)
index abdc1ae384674def8810a122ecc1ae3c11a47ae2..dcebb4bee7aaf9e0e845db50296798f76686d1a6 100644 (file)
@@ -1757,6 +1757,12 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
        if (ret != 0)
                return ret;
 
+       ret = drm_vblank_init(dev, 2);
+       if (ret) {
+               radeon_driver_unload(dev);
+               return ret;
+       }
+
        DRM_DEBUG("%s card detected\n",
                  ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
        return ret;
index 5079f7054a2f67aa712bcf6c89fa4e98cb1835b9..97c0599fdb1e2c49898c14c0ba097101978f8dc2 100644 (file)
@@ -337,15 +337,10 @@ int radeon_driver_irq_postinstall(struct drm_device *dev)
 {
        drm_radeon_private_t *dev_priv =
            (drm_radeon_private_t *) dev->dev_private;
-       int ret;
 
        atomic_set(&dev_priv->swi_emitted, 0);
        DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
 
-       ret = drm_vblank_init(dev, 2);
-       if (ret)
-               return ret;
-
        dev->max_vblank_count = 0x001fffff;
 
        radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
index 665d319b927b2d3a07cc25a65ebccbc33b1160aa..c248c1d37268ac64cfed64e8b6bfba43b3d80332 100644 (file)
@@ -314,7 +314,6 @@ int via_driver_irq_postinstall(struct drm_device *dev)
        if (!dev_priv)
                return -EINVAL;
 
-       drm_vblank_init(dev, 1);
        status = VIA_READ(VIA_REG_INTERRUPT);
        VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
                  | dev_priv->irq_enable_mask);
index a967556be014612f731125e8b9f77437a334921b..2c4f0b48579207dd74ead54b1833c03e86e92cea 100644 (file)
@@ -107,8 +107,17 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
        ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
        if (ret) {
                drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
+               return ret;
        }
-       return ret;
+
+       ret = drm_vblank_init(dev, 1);
+       if (ret) {
+               drm_sman_takedown(&dev_priv->sman);
+               drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
+               return ret;
+       }
+
+       return 0;
 }
 
 int via_driver_unload(struct drm_device *dev)
index 9b97795e45ad71dd604d55fe8ddd7f5ca460b3ee..aa28aed0e46cb4d400cdd8f419cfbb8cedefa877 100644 (file)
@@ -400,12 +400,12 @@ static const struct hid_device_id apple_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
                        APPLE_RDESC_JIS },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
                        APPLE_ISO_KEYBOARD },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS),
                .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
                .driver_data = APPLE_HAS_FN },
index 147ec591a8061df0b57e0741428cc46c046cfaeb..40df3e1b4bd11ef54f838d6a07645e8b03b8df26 100644 (file)
@@ -1241,9 +1241,9 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_HF_JIS) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ANSI) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_ISO) },
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_JIS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_JIS) },
@@ -1266,6 +1266,9 @@ static const struct hid_device_id hid_blacklist[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_DELL, USB_DEVICE_ID_DELL_SK8115) },
        { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERIC_13BA, USB_DEVICE_ID_GENERIC_13BA_KBD_MOUSE) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
@@ -1420,7 +1423,6 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0001) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0002) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, 0x0003) },
@@ -1436,7 +1438,6 @@ static const struct hid_device_id hid_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_SUPER_Q2) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_GOGOPEN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GOTOP, USB_DEVICE_ID_PENPOWER) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GRETAGMACBETH, USB_DEVICE_ID_GRETAGMACBETH_HUEY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE) },
        { HID_USB_DEVICE(USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB) },
@@ -1576,9 +1577,6 @@ static const struct hid_device_id hid_mouse_ignore_list[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_ISO) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING2_JIS) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) },
-       { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) },
        { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) },
        { }
index d70075dd3d81579e21e704acc1556b33cf874310..39289699c32fbd5b640e5bd9c440990bf5f2a97c 100644 (file)
 
 #define USB_VENDOR_ID_GAMERON          0x0810
 #define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
+#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
 
 #define USB_VENDOR_ID_GENERAL_TOUCH    0x0dfc
 
index acd81558618285ffd25f0ec1c5b01c9ec1de5d01..46941f979b9d058202f9ce71f8b70e341457c62a 100644 (file)
@@ -178,6 +178,8 @@ err:
 static const struct hid_device_id pl_devices[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR),
                .driver_data = 1 }, /* Twin USB Joystick */
+       { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
+               .driver_data = 1 }, /* Twin USB Joystick */
        { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
        { }
 };
index d746bf8284dd31994999916a72cab2f2c753b8a0..606369ea24ca038e36704f6b9c14d415e5fd5d36 100644 (file)
@@ -796,7 +796,6 @@ static int usbhid_start(struct hid_device *hid)
        if (insize > HID_MAX_BUFFER_SIZE)
                insize = HID_MAX_BUFFER_SIZE;
 
-       mutex_lock(&usbhid->setup);
        if (hid_alloc_buffers(dev, hid)) {
                ret = -ENOMEM;
                goto fail;
@@ -876,7 +875,6 @@ static int usbhid_start(struct hid_device *hid)
        hid_dump_device(hid);
 
        set_bit(HID_STARTED, &usbhid->iofl);
-       mutex_unlock(&usbhid->setup);
 
        return 0;
 
@@ -888,7 +886,6 @@ fail:
        usbhid->urbout = NULL;
        usbhid->urbctrl = NULL;
        hid_free_buffers(dev, hid);
-       mutex_unlock(&usbhid->setup);
        return ret;
 }
 
@@ -899,7 +896,6 @@ static void usbhid_stop(struct hid_device *hid)
        if (WARN_ON(!usbhid))
                return;
 
-       mutex_lock(&usbhid->setup);
        clear_bit(HID_STARTED, &usbhid->iofl);
        spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
        set_bit(HID_DISCONNECTED, &usbhid->iofl);
@@ -928,7 +924,6 @@ static void usbhid_stop(struct hid_device *hid)
        usbhid->urbout = NULL;
 
        hid_free_buffers(hid_to_usb_dev(hid), hid);
-       mutex_unlock(&usbhid->setup);
 }
 
 static struct hid_ll_driver usb_hid_driver = {
@@ -1016,7 +1011,6 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id)
 
        hid->driver_data = usbhid;
        usbhid->hid = hid;
-       mutex_init(&usbhid->setup); /* needed on suspend/resume */
 
        ret = hid_add_device(hid);
        if (ret) {
@@ -1051,18 +1045,14 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message)
        struct hid_device *hid = usb_get_intfdata (intf);
        struct usbhid_device *usbhid = hid->driver_data;
 
-       mutex_lock(&usbhid->setup);
-       if (!test_bit(HID_STARTED, &usbhid->iofl)) {
-               mutex_unlock(&usbhid->setup);
+       if (!test_bit(HID_STARTED, &usbhid->iofl))
                return 0;
-       }
 
        spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
        set_bit(HID_SUSPENDED, &usbhid->iofl);
        spin_unlock_irq(&usbhid->inlock);
        del_timer_sync(&usbhid->io_retry);
        usb_kill_urb(usbhid->urbin);
-       mutex_unlock(&usbhid->setup);
        dev_dbg(&intf->dev, "suspend\n");
        return 0;
 }
@@ -1073,16 +1063,12 @@ static int hid_resume(struct usb_interface *intf)
        struct usbhid_device *usbhid = hid->driver_data;
        int status;
 
-       mutex_lock(&usbhid->setup);
-       if (!test_bit(HID_STARTED, &usbhid->iofl)) {
-               mutex_unlock(&usbhid->setup);
+       if (!test_bit(HID_STARTED, &usbhid->iofl))
                return 0;
-       }
 
        clear_bit(HID_SUSPENDED, &usbhid->iofl);
        usbhid->retry_delay = 0;
        status = hid_start_in(hid);
-       mutex_unlock(&usbhid->setup);
        dev_dbg(&intf->dev, "resume status %d\n", status);
        return status;
 }
index 55973ff54008f36e6c2381275a1c26e08db25f47..332abcdf9956468ebf9b3aec792a716125b62f6c 100644 (file)
@@ -74,7 +74,6 @@ struct usbhid_device {
        dma_addr_t outbuf_dma;                                          /* Output buffer dma */
        spinlock_t outlock;                                             /* Output fifo spinlock */
 
-       struct mutex setup;
        unsigned long iofl;                                             /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
        struct timer_list io_retry;                                     /* Retry timer */
        unsigned long stop_retry;                                       /* Time to give up, in jiffies */
index 59ba2086d2f92ffd5aa9c3c866b362ff6232ed3f..a257cd5cd134937f9ef8aaf1f37bebcea46e9bee 100644 (file)
@@ -189,8 +189,6 @@ static void i2c_parport_attach (struct parport *port)
        if (adapter_parm[type].init.val)
                line_set(port, 1, &adapter_parm[type].init);
 
-       parport_release(adapter->pdev);
-
        if (i2c_bit_add_bus(&adapter->adapter) < 0) {
                printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
                goto ERROR1;
@@ -202,6 +200,7 @@ static void i2c_parport_attach (struct parport *port)
         return;
 
 ERROR1:
+       parport_release(adapter->pdev);
        parport_unregister_device(adapter->pdev);
 ERROR0:
        kfree(adapter);
@@ -221,6 +220,7 @@ static void i2c_parport_detach (struct parport *port)
                        if (adapter_parm[type].init.val)
                                line_set(port, 0, &adapter_parm[type].init);
                                
+                       parport_release(adapter->pdev);
                        parport_unregister_device(adapter->pdev);
                        if (prev)
                                prev->next = adapter->next;
index 28902ebd553905aedd2507d32870d97ea7023ade..e0d56ef2bcb08dd522958e8456369563436e107e 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <linux/usb.h>
 #include <linux/workqueue.h>
 
 #include <asm/irq.h>
+#include <asm/mach-types.h>
+
 #include <mach/usb.h>
+#include <mach/mux.h>
 
 
 #ifndef        DEBUG
@@ -88,14 +92,9 @@ struct isp1301 {
 
 /*-------------------------------------------------------------------------*/
 
-#ifdef CONFIG_MACH_OMAP_H2
-
 /* board-specific PM hooks */
 
-#include <asm/gpio.h>
-#include <mach/mux.h>
-#include <asm/mach-types.h>
-
+#if defined(CONFIG_MACH_OMAP_H2) || defined(CONFIG_MACH_OMAP_H3)
 
 #if    defined(CONFIG_TPS65010) || defined(CONFIG_TPS65010_MODULE)
 
@@ -133,6 +132,33 @@ static inline void notresponding(struct isp1301 *isp)
 }
 
 
+#endif
+
+#if defined(CONFIG_MACH_OMAP_H4)
+
+static void enable_vbus_draw(struct isp1301 *isp, unsigned mA)
+{
+       /* H4 controls this by DIP switch S2.4; no soft control.
+        * ON means the charger is always enabled.  Leave it OFF
+        * unless the OTG port is used only in B-peripheral mode.
+        */
+}
+
+static void enable_vbus_source(struct isp1301 *isp)
+{
+       /* this board won't supply more than 8mA vbus power.
+        * some boards can switch a 100ma "unit load" (or more).
+        */
+}
+
+
+/* products will deliver OTG messages with LEDs, GUI, etc */
+static inline void notresponding(struct isp1301 *isp)
+{
+       printk(KERN_NOTICE "OTG device not responding.\n");
+}
+
+
 #endif
 
 /*-------------------------------------------------------------------------*/
@@ -334,8 +360,7 @@ static int gadget_suspend(struct isp1301 *isp)
  * NOTE: guaranteeing certain response times might mean we shouldn't
  * share keventd's work queue; a realtime task might be safest.
  */
-void
-isp1301_defer_work(struct isp1301 *isp, int work)
+static void isp1301_defer_work(struct isp1301 *isp, int work)
 {
        int status;
 
@@ -512,7 +537,6 @@ static void update_otg1(struct isp1301 *isp, u8 int_src)
        otg_ctrl &= ~OTG_XCEIV_INPUTS;
        otg_ctrl &= ~(OTG_ID|OTG_ASESSVLD|OTG_VBUSVLD);
 
-
        if (int_src & INTR_SESS_VLD)
                otg_ctrl |= OTG_ASESSVLD;
        else if (isp->otg.state == OTG_STATE_A_WAIT_VFALL) {
@@ -886,11 +910,11 @@ static int otg_probe(struct platform_device *dev)
 
 static int otg_remove(struct platform_device *dev)
 {
-       otg_dev = 0;
+       otg_dev = NULL;
        return 0;
 }
 
-struct platform_driver omap_otg_driver = {
+static struct platform_driver omap_otg_driver = {
        .probe          = otg_probe,
        .remove         = otg_remove,
        .driver         = {
@@ -1212,6 +1236,8 @@ static void isp1301_release(struct device *dev)
 
        isp = dev_get_drvdata(dev);
 
+       /* FIXME -- not with a "new style" driver, it doesn't!! */
+
        /* ugly -- i2c hijacks our memory hook to wait_for_completion() */
        if (isp->i2c_release)
                isp->i2c_release(dev);
@@ -1233,7 +1259,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c)
        otg_unbind(isp);
 #endif
        if (machine_is_omap_h2())
-               omap_free_gpio(2);
+               gpio_free(2);
 
        isp->timer.data = 0;
        set_bit(WORK_STOP, &isp->todo);
@@ -1241,7 +1267,7 @@ static int __exit isp1301_remove(struct i2c_client *i2c)
        flush_scheduled_work();
 
        put_device(&i2c->dev);
-       the_transceiver = 0;
+       the_transceiver = NULL;
 
        return 0;
 }
@@ -1295,7 +1321,7 @@ isp1301_set_host(struct otg_transceiver *otg, struct usb_bus *host)
        if (!host) {
                omap_writew(0, OTG_IRQ_EN);
                power_down(isp);
-               isp->otg.host = 0;
+               isp->otg.host = NULL;
                return 0;
        }
 
@@ -1344,7 +1370,9 @@ static int
 isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
 {
        struct isp1301  *isp = container_of(otg, struct isp1301, otg);
+#ifndef        CONFIG_USB_OTG
        u32 l;
+#endif
 
        if (!otg || isp != the_transceiver)
                return -ENODEV;
@@ -1354,7 +1382,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
                if (!isp->otg.default_a)
                        enable_vbus_draw(isp, 0);
                usb_gadget_vbus_disconnect(isp->otg.gadget);
-               isp->otg.gadget = 0;
+               isp->otg.gadget = NULL;
                power_down(isp);
                return 0;
        }
@@ -1379,7 +1407,7 @@ isp1301_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *gadget)
        power_up(isp);
        isp->otg.state = OTG_STATE_B_IDLE;
 
-       if (machine_is_omap_h2())
+       if (machine_is_omap_h2() || machine_is_omap_h3())
                isp1301_set_bits(isp, ISP1301_MODE_CONTROL_1, MC1_DAT_SE0);
 
        isp1301_set_bits(isp, ISP1301_INTERRUPT_RISING,
@@ -1499,7 +1527,8 @@ isp1301_start_hnp(struct otg_transceiver *dev)
 
 /*-------------------------------------------------------------------------*/
 
-static int __init isp1301_probe(struct i2c_client *i2c)
+static int __init
+isp1301_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
 {
        int                     status;
        struct isp1301          *isp;
@@ -1647,7 +1676,7 @@ module_init(isp_init);
 static void __exit isp_exit(void)
 {
        if (the_transceiver)
-               otg_set_transceiver(0);
+               otg_set_transceiver(NULL);
        i2c_del_driver(&isp1301_driver);
 }
 module_exit(isp_exit);
index 5a485c22660a9cc97d5d72d1e6ccad38e5b0658e..c6a63f46bc152796dbea5c5a930c44eed595f476 100644 (file)
@@ -631,7 +631,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
 
        /* detach any active clients. This must be done first, because
         * it can fail; in which case we give up. */
-       list_for_each_entry_safe(client, _n, &adap->clients, list) {
+       list_for_each_entry_safe_reverse(client, _n, &adap->clients, list) {
                struct i2c_driver       *driver;
 
                driver = client->driver;
index 2d848010499dfed1997e0f0eed459cb0cff847ec..81f70caeb40f1a1394f1ec25023635e26b8a70f3 100644 (file)
@@ -419,7 +419,7 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
        hw->chipset = ide_acorn;
 }
 
-static int __init
+static int __devinit
 icside_register_v5(struct icside_state *state, struct expansion_card *ec)
 {
        void __iomem *base;
@@ -473,7 +473,7 @@ static const struct ide_port_info icside_v6_port_info __initdata = {
        .swdma_mask             = ATA_SWDMA2,
 };
 
-static int __init
+static int __devinit
 icside_register_v6(struct icside_state *state, struct expansion_card *ec)
 {
        void __iomem *ioc_base, *easi_base;
index 6790e975a98c327fd038198f535be9fc9059ab5b..bc4e40f3ede7303d97816a6cbf8588c8f22118d2 100644 (file)
@@ -397,8 +397,9 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
 {
        struct ml_device *ml = dev->ff->private;
        struct ml_effect_state *state = &ml->states[effect_id];
+       unsigned long flags;
 
-       spin_lock_bh(&ml->timer_lock);
+       spin_lock_irqsave(&ml->timer_lock, flags);
 
        if (value > 0) {
                debug("initiated play");
@@ -424,7 +425,7 @@ static int ml_ff_playback(struct input_dev *dev, int effect_id, int value)
                ml_play_effects(ml);
        }
 
-       spin_unlock_bh(&ml->timer_lock);
+       spin_unlock_irqrestore(&ml->timer_lock, flags);
 
        return 0;
 }
index 22016ca153518b8c9535b11f215c59e1d0008880..379b7ff354ec7ba0036d3e1d1072b51eac61f1c3 100644 (file)
@@ -824,7 +824,7 @@ static void atkbd_disconnect(struct serio *serio)
        atkbd_disable(atkbd);
 
        /* make sure we don't have a command in flight */
-       flush_scheduled_work();
+       cancel_delayed_work_sync(&atkbd->event_work);
 
        sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
        input_unregister_device(atkbd->dev);
@@ -867,6 +867,22 @@ static void atkbd_hp_keymap_fixup(struct atkbd *atkbd)
                                        atkbd->force_release_mask);
 }
 
+/*
+ * Inventec system with broken key release on volume keys
+ */
+static void atkbd_inventec_keymap_fixup(struct atkbd *atkbd)
+{
+       const unsigned int forced_release_keys[] = {
+               0xae, 0xb0,
+       };
+       int i;
+
+       if (atkbd->set == 2)
+               for (i = 0; i < ARRAY_SIZE(forced_release_keys); i++)
+                       __set_bit(forced_release_keys[i],
+                                 atkbd->force_release_mask);
+}
+
 /*
  * atkbd_set_keycode_table() initializes keyboard's keycode table
  * according to the selected scancode set
@@ -1468,6 +1484,15 @@ static struct dmi_system_id atkbd_dmi_quirk_table[] __initdata = {
                .callback = atkbd_setup_fixup,
                .driver_data = atkbd_hp_keymap_fixup,
        },
+       {
+               .ident = "Inventec Symphony",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"),
+               },
+               .callback = atkbd_setup_fixup,
+               .driver_data = atkbd_inventec_keymap_fixup,
+       },
        { }
 };
 
index bce160f4349bb657947acf5a696e292a28fd8e21..86457feccfc4f2fdbf3834adea42b1a32ed9e0d6 100644 (file)
@@ -42,7 +42,7 @@
 
 static char *phone = "kip1000";
 module_param(phone, charp, S_IRUSR);
-MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01}");
+MODULE_PARM_DESC(phone, "Phone name {kip1000, gtalk, usbph01, atcom}");
 
 enum {
        /* HID Registers */
@@ -258,6 +258,37 @@ static unsigned short keymap_usbph01(int scancode)
        }
 }
 
+/*
+ * Keymap for ATCom AU-100
+ * http://www.atcom.cn/En_products_AU100.html
+ * http://www.packetizer.com/products/au100/
+ * http://www.voip-info.org/wiki/view/AU-100
+ *
+ * Contributed by daniel@gimpelevich.san-francisco.ca.us
+ */
+static unsigned short keymap_atcom(int scancode)
+{
+       switch (scancode) {                             /* phone key:   */
+       case 0x82: return KEY_NUMERIC_0;                /*   0          */
+       case 0x11: return KEY_NUMERIC_1;                /*   1          */
+       case 0x12: return KEY_NUMERIC_2;                /*   2          */
+       case 0x14: return KEY_NUMERIC_3;                /*   3          */
+       case 0x21: return KEY_NUMERIC_4;                /*   4          */
+       case 0x22: return KEY_NUMERIC_5;                /*   5          */
+       case 0x24: return KEY_NUMERIC_6;                /*   6          */
+       case 0x41: return KEY_NUMERIC_7;                /*   7          */
+       case 0x42: return KEY_NUMERIC_8;                /*   8          */
+       case 0x44: return KEY_NUMERIC_9;                /*   9          */
+       case 0x84: return KEY_NUMERIC_POUND;            /*   #          */
+       case 0x81: return KEY_NUMERIC_STAR;             /*   *          */
+       case 0x18: return KEY_ENTER;                    /*   pickup     */
+       case 0x28: return KEY_ESC;                      /*   hangup     */
+       case 0x48: return KEY_LEFT;                     /* left arrow   */
+       case 0x88: return KEY_RIGHT;                    /* right arrow  */
+       default:   return special_keymap(scancode);
+       }
+}
+
 static unsigned short (*keymap)(int) = keymap_kip1000;
 
 /*
@@ -840,6 +871,10 @@ static int __init cm109_select_keymap(void)
                keymap = keymap_usbph01;
                printk(KERN_INFO KBUILD_MODNAME ": "
                        "Keymap for Allied-Telesis Corega USBPH01 phone loaded\n");
+       } else if (!strcasecmp(phone, "atcom")) {
+               keymap = keymap_atcom;
+               printk(KERN_INFO KBUILD_MODNAME ": "
+                       "Keymap for ATCom AU-100 phone loaded\n");
        } else {
                printk(KERN_ERR KBUILD_MODNAME ": "
                        "Unsupported phone: %s\n", phone);
index e82d34201e97e3c26daeb8fc85f9dcf69be0177c..88f04bf2ad6cfe677d13e9f3d73da6d5379d2186 100644 (file)
@@ -125,7 +125,7 @@ static void hgpk_spewing_hack(struct psmouse *psmouse,
  */
 static int hgpk_validate_byte(unsigned char *packet)
 {
-       return (packet[0] & 0x0C) == 0x08;
+       return (packet[0] & 0x0C) != 0x08;
 }
 
 static void hgpk_process_packet(struct psmouse *psmouse)
index eec375cd10e6ef89546e8a51314bf647411a47ea..29e686388a2c9a85732a028ede45d16e188087c8 100644 (file)
@@ -337,6 +337,20 @@ static struct dmi_system_id __initdata i8042_dmi_nomux_table[] = {
                        DMI_MATCH(DMI_PRODUCT_NAME, "2656"),
                },
        },
+       {
+               .ident = "Dell XPS M1530",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "XPS M1530"),
+               },
+       },
+       {
+               .ident = "Compal HEL80I",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "COMPAL"),
+                       DMI_MATCH(DMI_PRODUCT_NAME, "HEL80I"),
+               },
+       },
        { }
 };
 
index ca62ec639f8f8bee57783030f51c508fe8a4b96a..677680e9f54f7498c60632b5f22b070bd65c5ba4 100644 (file)
@@ -66,6 +66,7 @@
  *                - Support Intuos3 4x6
  *      v1.47 (pc) - Added support for Bamboo
  *      v1.48 (pc) - Added support for Bamboo1, BambooFun, and Cintiq 12WX
+ *      v1.49 (pc) - Added support for USB Tablet PC (0x90, 0x93, and 0x9A)
  */
 
 /*
@@ -86,7 +87,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.48"
+#define DRIVER_VERSION "v1.49"
 #define DRIVER_AUTHOR "Vojtech Pavlik <vojtech@ucw.cz>"
 #define DRIVER_DESC "USB Wacom Graphire and Wacom Intuos tablet driver"
 #define DRIVER_LICENSE "GPL"
@@ -103,15 +104,15 @@ struct wacom {
        struct usb_device *usbdev;
        struct usb_interface *intf;
        struct urb *irq;
-       struct wacom_wac * wacom_wac;
+       struct wacom_wac *wacom_wac;
        struct mutex lock;
        unsigned int open:1;
        char phys[32];
 };
 
 struct wacom_combo {
-       struct wacom * wacom;
-       struct urb * urb;
+       struct wacom *wacom;
+       struct urb *urb;
 };
 
 extern int wacom_wac_irq(struct wacom_wac * wacom_wac, void * wcombo);
@@ -132,7 +133,7 @@ extern void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wa
 extern void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac);
 extern __u16 wacom_le16_to_cpu(unsigned char *data);
 extern __u16 wacom_be16_to_cpu(unsigned char *data);
-extern struct wacom_features * get_wacom_feature(const struct usb_device_id *id);
-extern const struct usb_device_id * get_device_table(void);
+extern struct wacom_features *get_wacom_feature(const struct usb_device_id *id);
+extern const struct usb_device_id *get_device_table(void);
 
 #endif
index 09e227aa0d49d9f5bfea9efb3be7079116a82f79..484496daa0f3fbdb0cb8714ecb58d6086b2d99ad 100644 (file)
 #include "wacom.h"
 #include "wacom_wac.h"
 
+/* defines to get HID report descriptor */
+#define HID_DEVICET_HID                (USB_TYPE_CLASS | 0x01)
+#define HID_DEVICET_REPORT     (USB_TYPE_CLASS | 0x02)
+#define HID_USAGE_UNDEFINED            0x00
+#define HID_USAGE_PAGE                 0x05
+#define HID_USAGE_PAGE_DIGITIZER       0x0d
+#define HID_USAGE_PAGE_DESKTOP         0x01
+#define HID_USAGE                      0x09
+#define HID_USAGE_X                    0x30
+#define HID_USAGE_Y                    0x31
+#define HID_USAGE_X_TILT               0x3d
+#define HID_USAGE_Y_TILT               0x3e
+#define HID_USAGE_FINGER               0x22
+#define HID_USAGE_STYLUS               0x20
+#define HID_COLLECTION                 0xc0
+
+enum {
+       WCM_UNDEFINED = 0,
+       WCM_DESKTOP,
+       WCM_DIGITIZER,
+};
+
+struct hid_descriptor {
+       struct usb_descriptor_header header;
+       __le16   bcdHID;
+       u8       bCountryCode;
+       u8       bNumDescriptors;
+       u8       bDescriptorType;
+       __le16   wDescriptorLength;
+} __attribute__ ((packed));
+
+/* defines to get/set USB message */
 #define USB_REQ_GET_REPORT     0x01
 #define USB_REQ_SET_REPORT     0x09
+#define WAC_HID_FEATURE_REPORT 0x03
 
 static int usb_get_report(struct usb_interface *intf, unsigned char type,
                                unsigned char id, void *buf, int size)
@@ -80,25 +113,21 @@ static void wacom_sys_irq(struct urb *urb)
 void wacom_report_key(void *wcombo, unsigned int key_type, int key_data)
 {
        input_report_key(get_input_dev((struct wacom_combo *)wcombo), key_type, key_data);
-       return;
 }
 
 void wacom_report_abs(void *wcombo, unsigned int abs_type, int abs_data)
 {
        input_report_abs(get_input_dev((struct wacom_combo *)wcombo), abs_type, abs_data);
-       return;
 }
 
 void wacom_report_rel(void *wcombo, unsigned int rel_type, int rel_data)
 {
        input_report_rel(get_input_dev((struct wacom_combo *)wcombo), rel_type, rel_data);
-       return;
 }
 
 void wacom_input_event(void *wcombo, unsigned int type, unsigned int code, int value)
 {
        input_event(get_input_dev((struct wacom_combo *)wcombo), type, code, value);
-       return;
 }
 
 __u16 wacom_be16_to_cpu(unsigned char *data)
@@ -118,7 +147,6 @@ __u16 wacom_le16_to_cpu(unsigned char *data)
 void wacom_input_sync(void *wcombo)
 {
        input_sync(get_input_dev((struct wacom_combo *)wcombo));
-       return;
 }
 
 static int wacom_open(struct input_dev *dev)
@@ -160,7 +188,7 @@ static void wacom_close(struct input_dev *dev)
 
 void input_dev_mo(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_1) |
+       input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_1) |
                BIT_MASK(BTN_5);
        input_set_abs_params(input_dev, ABS_WHEEL, 0, 71, 0, 0);
 }
@@ -170,7 +198,7 @@ void input_dev_g4(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
        input_dev->evbit[0] |= BIT_MASK(EV_MSC);
        input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+       input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
                BIT_MASK(BTN_4);
 }
 
@@ -178,7 +206,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
        input_dev->evbit[0] |= BIT_MASK(EV_REL);
        input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
                BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE);
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
                BIT_MASK(BTN_TOOL_MOUSE) | BIT_MASK(BTN_STYLUS2);
@@ -188,7 +216,7 @@ void input_dev_g(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_FINGER);
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_0) |
+       input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_0) |
                BIT_MASK(BTN_1) | BIT_MASK(BTN_2) | BIT_MASK(BTN_3);
        input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0);
        input_set_abs_params(input_dev, ABS_Z, -900, 899, 0, 0);
@@ -196,14 +224,14 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 
 void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_4) |
+       input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_4) |
                BIT_MASK(BTN_5) | BIT_MASK(BTN_6) | BIT_MASK(BTN_7);
        input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0);
 }
 
 void input_dev_bee(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9);
+       input_dev->keybit[BIT_WORD(BTN_MISC)] |= BIT_MASK(BTN_8) | BIT_MASK(BTN_9);
 }
 
 void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -211,7 +239,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
        input_dev->evbit[0] |= BIT_MASK(EV_MSC) | BIT_MASK(EV_REL);
        input_dev->mscbit[0] |= BIT_MASK(MSC_SERIAL);
        input_dev->relbit[0] |= BIT_MASK(REL_WHEEL);
-       input_dev->keybit[BIT_WORD(BTN_LEFT)] |= BIT_MASK(BTN_LEFT) |
+       input_dev->keybit[BIT_WORD(BTN_MOUSE)] |= BIT_MASK(BTN_LEFT) |
                BIT_MASK(BTN_RIGHT) | BIT_MASK(BTN_MIDDLE) |
                BIT_MASK(BTN_SIDE) | BIT_MASK(BTN_EXTRA);
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER) |
@@ -228,8 +256,7 @@ void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 
 void input_dev_pl(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
 {
-       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2) |
-               BIT_MASK(BTN_TOOL_RUBBER);
+       input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_STYLUS2);
 }
 
 void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
@@ -237,15 +264,129 @@ void input_dev_pt(struct input_dev *input_dev, struct wacom_wac *wacom_wac)
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_RUBBER);
 }
 
+static int wacom_parse_hid(struct usb_interface *intf, struct hid_descriptor *hid_desc,
+                          struct wacom_wac *wacom_wac)
+{
+       struct usb_device *dev = interface_to_usbdev(intf);
+       struct wacom_features *features = wacom_wac->features;
+       char limit = 0, result = 0;
+       int i = 0, usage = WCM_UNDEFINED, finger = 0, pen = 0;
+       unsigned char *report;
+
+       report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL);
+       if (!report)
+               return -ENOMEM;
+
+       /* retrive report descriptors */
+       do {
+               result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+                       USB_REQ_GET_DESCRIPTOR,
+                       USB_RECIP_INTERFACE | USB_DIR_IN,
+                       HID_DEVICET_REPORT << 8,
+                       intf->altsetting[0].desc.bInterfaceNumber, /* interface */
+                       report,
+                       hid_desc->wDescriptorLength,
+                       5000); /* 5 secs */
+       } while (result < 0 && limit++ < 5);
+
+       if (result < 0)
+               goto out;
+
+       for (i = 0; i < hid_desc->wDescriptorLength; i++) {
+
+               switch (report[i]) {
+               case HID_USAGE_PAGE:
+                       switch (report[i + 1]) {
+                       case HID_USAGE_PAGE_DIGITIZER:
+                               usage = WCM_DIGITIZER;
+                               i++;
+                               break;
+
+                       case HID_USAGE_PAGE_DESKTOP:
+                               usage = WCM_DESKTOP;
+                               i++;
+                               break;
+                       }
+                       break;
+
+               case HID_USAGE:
+                       switch (report[i + 1]) {
+                       case HID_USAGE_X:
+                               if (usage == WCM_DESKTOP) {
+                                       if (finger) {
+                                               features->touch_x_max =
+                                                       features->touch_y_max =
+                                                       wacom_le16_to_cpu(&report[i + 3]);
+                                               features->x_max =
+                                                       wacom_le16_to_cpu(&report[i + 6]);
+                                               i += 7;
+                                       } else if (pen) {
+                                               features->x_max =
+                                                       wacom_le16_to_cpu(&report[i + 3]);
+                                               i += 4;
+                                       }
+                               } else if (usage == WCM_DIGITIZER) {
+                                       /* max pressure isn't reported
+                                       features->pressure_max = (unsigned short)
+                                                       (report[i+4] << 8  | report[i + 3]);
+                                       */
+                                       features->pressure_max = 255;
+                                       i += 4;
+                               }
+                               break;
+
+                       case HID_USAGE_Y:
+                               if (usage == WCM_DESKTOP)
+                                       features->y_max =
+                                               wacom_le16_to_cpu(&report[i + 3]);
+                               i += 4;
+                               break;
+
+                       case HID_USAGE_FINGER:
+                               finger = 1;
+                               i++;
+                               break;
+
+                       case HID_USAGE_STYLUS:
+                               pen = 1;
+                               i++;
+                               break;
+
+                       case HID_USAGE_UNDEFINED:
+                               if (usage == WCM_DESKTOP && finger) /* capacity */
+                                       features->pressure_max =
+                                               wacom_le16_to_cpu(&report[i + 3]);
+                               i += 4;
+                               break;
+                       }
+                       break;
+
+               case HID_COLLECTION:
+                       /* reset UsagePage ans Finger */
+                       finger = usage = 0;
+                       break;
+               }
+       }
+
+       result = 0;
+
+ out:
+       kfree(report);
+       return result;
+}
+
 static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
        struct usb_device *dev = interface_to_usbdev(intf);
+       struct usb_host_interface *interface = intf->cur_altsetting;
        struct usb_endpoint_descriptor *endpoint;
        struct wacom *wacom;
        struct wacom_wac *wacom_wac;
+       struct wacom_features *features;
        struct input_dev *input_dev;
        int error = -ENOMEM;
        char rep_data[2], limit = 0;
+       struct hid_descriptor *hid_desc;
 
        wacom = kzalloc(sizeof(struct wacom), GFP_KERNEL);
        wacom_wac = kzalloc(sizeof(struct wacom_wac), GFP_KERNEL);
@@ -268,8 +409,8 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        usb_make_path(dev, wacom->phys, sizeof(wacom->phys));
        strlcat(wacom->phys, "/input0", sizeof(wacom->phys));
 
-       wacom_wac->features = get_wacom_feature(id);
-       BUG_ON(wacom_wac->features->pktlen > 10);
+       wacom_wac->features = features = get_wacom_feature(id);
+       BUG_ON(features->pktlen > 10);
 
        input_dev->name = wacom_wac->features->name;
        wacom->wacom_wac = wacom_wac;
@@ -282,18 +423,37 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        input_dev->open = wacom_open;
        input_dev->close = wacom_close;
 
+       endpoint = &intf->cur_altsetting->endpoint[0].desc;
+
+       /* TabletPC need to retrieve the physical and logical maximum from report descriptor */
+       if (wacom_wac->features->type == TABLETPC) {
+               if (usb_get_extra_descriptor(interface, HID_DEVICET_HID, &hid_desc)) {
+                       if (usb_get_extra_descriptor(&interface->endpoint[0],
+                                                    HID_DEVICET_REPORT, &hid_desc)) {
+                               printk("wacom: can not retrive extra class descriptor\n");
+                               goto fail2;
+                       }
+               }
+               error = wacom_parse_hid(intf, hid_desc, wacom_wac);
+               if (error)
+                       goto fail2;
+       }
+
        input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
        input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_PEN) |
                BIT_MASK(BTN_TOUCH) | BIT_MASK(BTN_STYLUS);
-       input_set_abs_params(input_dev, ABS_X, 0, wacom_wac->features->x_max, 4, 0);
-       input_set_abs_params(input_dev, ABS_Y, 0, wacom_wac->features->y_max, 4, 0);
-       input_set_abs_params(input_dev, ABS_PRESSURE, 0, wacom_wac->features->pressure_max, 0, 0);
+       input_set_abs_params(input_dev, ABS_X, 0, features->x_max, 4, 0);
+       input_set_abs_params(input_dev, ABS_Y, 0, features->y_max, 4, 0);
+       input_set_abs_params(input_dev, ABS_PRESSURE, 0, features->pressure_max, 0, 0);
+       if (features->type == TABLETPC) {
+               input_dev->keybit[BIT_WORD(BTN_DIGI)] |= BIT_MASK(BTN_TOOL_DOUBLETAP);
+               input_set_abs_params(input_dev, ABS_RX, 0, features->touch_x_max, 4, 0);
+               input_set_abs_params(input_dev, ABS_RY, 0, features->touch_y_max, 4, 0);
+       }
        input_dev->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
 
        wacom_init_input_dev(input_dev, wacom_wac);
 
-       endpoint = &intf->cur_altsetting->endpoint[0].desc;
-
        usb_fill_int_urb(wacom->irq, dev,
                         usb_rcvintpipe(dev, endpoint->bEndpointAddress),
                         wacom_wac->data, wacom_wac->features->pktlen,
@@ -305,13 +465,22 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
        if (error)
                goto fail3;
 
-       /* Ask the tablet to report tablet data. Repeat until it succeeds */
-       do {
-               rep_data[0] = 2;
-               rep_data[1] = 2;
-               usb_set_report(intf, 3, 2, rep_data, 2);
-               usb_get_report(intf, 3, 2, rep_data, 2);
-       } while (rep_data[1] != 2 && limit++ < 5);
+       /*
+        * Ask the tablet to report tablet data if it is not a Tablet PC.
+        * Repeat until it succeeds
+        */
+       if (wacom_wac->features->type != TABLETPC) {
+               do {
+                       rep_data[0] = 2;
+                       rep_data[1] = 2;
+                       error = usb_set_report(intf, WAC_HID_FEATURE_REPORT,
+                                               2, rep_data, 2);
+                       if (error >= 0)
+                               error = usb_get_report(intf,
+                                               WAC_HID_FEATURE_REPORT, 2,
+                                               rep_data, 2);
+               } while ((error < 0 || rep_data[1] != 2) && limit++ < 5);
+       }
 
        usb_set_intfdata(intf, wacom);
        return 0;
@@ -333,7 +502,8 @@ static void wacom_disconnect(struct usb_interface *intf)
        usb_kill_urb(wacom->irq);
        input_unregister_device(wacom->dev);
        usb_free_urb(wacom->irq);
-       usb_buffer_free(interface_to_usbdev(intf), 10, wacom->wacom_wac->data, wacom->data_dma);
+       usb_buffer_free(interface_to_usbdev(intf), 10,
+                       wacom->wacom_wac->data, wacom->data_dma);
        kfree(wacom->wacom_wac);
        kfree(wacom);
 }
index bf3d9a8b2c1be6bc6777ab681947cb280cf60149..8dc8d1e59beaeeb1a1f154ba122e929d7f45e492 100644 (file)
@@ -535,31 +535,147 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo)
        return 1;
 }
 
+int wacom_tpc_irq(struct wacom_wac *wacom, void *wcombo)
+{
+       char *data = wacom->data;
+       int prox = 0, pressure;
+       static int stylusInProx, touchInProx = 1, touchOut;
+       struct urb *urb = ((struct wacom_combo *)wcombo)->urb;
+
+       dbg("wacom_tpc_irq: received report #%d", data[0]);
+
+       if (urb->actual_length == 5 || data[0] == 6) { /* Touch data */
+               if (urb->actual_length == 5) {  /* with touch */
+                       prox = data[0] & 0x03;
+               } else {  /* with capacity */
+                       prox = data[1] & 0x03;
+               }
+
+               if (!stylusInProx) { /* stylus not in prox */
+                       if (prox) {
+                               if (touchInProx) {
+                                       wacom->tool[1] = BTN_TOOL_DOUBLETAP;
+                                       wacom->id[0] = TOUCH_DEVICE_ID;
+                                       if (urb->actual_length != 5) {
+                                               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+                                               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+                                               wacom_report_abs(wcombo, ABS_PRESSURE, wacom_le16_to_cpu(&data[6]));
+                                               wacom_report_key(wcombo, BTN_TOUCH, wacom_le16_to_cpu(&data[6]));
+                                       } else {
+                                               wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[1]));
+                                               wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[3]));
+                                               wacom_report_key(wcombo, BTN_TOUCH, 1);
+                                       }
+                                       wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+                                       wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
+                                       touchOut = 1;
+                                       return 1;
+                               }
+                       } else {
+                               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+                               wacom_report_key(wcombo, wacom->tool[1], prox & 0x01);
+                               wacom_report_key(wcombo, BTN_TOUCH, 0);
+                               touchOut = 0;
+                               touchInProx = 1;
+                               return 1;
+                       }
+               } else if (touchOut || !prox) { /* force touch out-prox */
+                       wacom_report_abs(wcombo, ABS_MISC, TOUCH_DEVICE_ID);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+                       touchOut = 0;
+                       touchInProx = 1;
+                       return 1;
+               }
+       } else if (data[0] == 2) { /* Penabled */
+               prox = data[1] & 0x20;
+
+               touchInProx = 0;
+
+               wacom->id[0] = ERASER_DEVICE_ID;
+
+               /*
+                * if going from out of proximity into proximity select between the eraser
+                * and the pen based on the state of the stylus2 button, choose eraser if
+                * pressed else choose pen. if not a proximity change from out to in, send
+                * an out of proximity for previous tool then a in for new tool.
+                */
+               if (prox) { /* in prox */
+                       if (!wacom->tool[0]) {
+                               /* Going into proximity select tool */
+                               wacom->tool[1] = (data[1] & 0x08) ? BTN_TOOL_RUBBER : BTN_TOOL_PEN;
+                               if (wacom->tool[1] == BTN_TOOL_PEN)
+                                       wacom->id[0] = STYLUS_DEVICE_ID;
+                       } else if (wacom->tool[1] == BTN_TOOL_RUBBER && !(data[1] & 0x08)) {
+                               /*
+                                * was entered with stylus2 pressed
+                                * report out proximity for previous tool
+                               */
+                               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+                               wacom_report_key(wcombo, wacom->tool[1], 0);
+                               wacom_input_sync(wcombo);
+
+                               /* set new tool */
+                               wacom->tool[1] = BTN_TOOL_PEN;
+                               wacom->id[0] = STYLUS_DEVICE_ID;
+                               return 0;
+                       }
+                       if (wacom->tool[1] != BTN_TOOL_RUBBER) {
+                               /* Unknown tool selected default to pen tool */
+                               wacom->tool[1] = BTN_TOOL_PEN;
+                               wacom->id[0] = STYLUS_DEVICE_ID;
+                       }
+                       wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02);
+                       wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x10);
+                       wacom_report_abs(wcombo, ABS_X, wacom_le16_to_cpu(&data[2]));
+                       wacom_report_abs(wcombo, ABS_Y, wacom_le16_to_cpu(&data[4]));
+                       pressure = ((data[7] & 0x01) << 8) | data[6];
+                       if (pressure < 0)
+                               pressure = wacom->features->pressure_max + pressure + 1;
+                       wacom_report_abs(wcombo, ABS_PRESSURE, pressure);
+                       wacom_report_key(wcombo, BTN_TOUCH, pressure);
+               } else {
+                       wacom_report_abs(wcombo, ABS_PRESSURE, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS, 0);
+                       wacom_report_key(wcombo, BTN_STYLUS2, 0);
+                       wacom_report_key(wcombo, BTN_TOUCH, 0);
+               }
+               wacom_report_key(wcombo, wacom->tool[1], prox);
+               wacom_report_abs(wcombo, ABS_MISC, wacom->id[0]);
+               stylusInProx = prox;
+               wacom->tool[0] = prox;
+               return 1;
+       }
+       return 0;
+}
+
 int wacom_wac_irq(struct wacom_wac *wacom_wac, void *wcombo)
 {
        switch (wacom_wac->features->type) {
                case PENPARTNER:
-                       return (wacom_penpartner_irq(wacom_wac, wcombo));
-                       break;
+                       return wacom_penpartner_irq(wacom_wac, wcombo);
+
                case PL:
-                       return (wacom_pl_irq(wacom_wac, wcombo));
-                       break;
+                       return wacom_pl_irq(wacom_wac, wcombo);
+
                case WACOM_G4:
                case GRAPHIRE:
                case WACOM_MO:
-                       return (wacom_graphire_irq(wacom_wac, wcombo));
-                       break;
+                       return wacom_graphire_irq(wacom_wac, wcombo);
+
                case PTU:
-                       return (wacom_ptu_irq(wacom_wac, wcombo));
-                       break;
+                       return wacom_ptu_irq(wacom_wac, wcombo);
+
                case INTUOS:
                case INTUOS3S:
                case INTUOS3:
                case INTUOS3L:
                case CINTIQ:
                case WACOM_BEE:
-                       return (wacom_intuos_irq(wacom_wac, wcombo));
-                       break;
+                       return wacom_intuos_irq(wacom_wac, wcombo);
+
+               case TABLETPC:
+                       return wacom_tpc_irq(wacom_wac, wcombo);
+
                default:
                        return 0;
        }
@@ -586,13 +702,15 @@ void wacom_init_input_dev(struct input_dev *input_dev, struct wacom_wac *wacom_w
                        /* fall through */
                case INTUOS3S:
                        input_dev_i3s(input_dev, wacom_wac);
+                       /* fall through */
                case INTUOS:
                        input_dev_i(input_dev, wacom_wac);
                        break;
                case PL:
                case PTU:
+               case TABLETPC:
                        input_dev_pl(input_dev, wacom_wac);
-                       break;
+                       /* fall through */
                case PENPARTNER:
                        input_dev_pt(input_dev, wacom_wac);
                        break;
@@ -611,6 +729,7 @@ static struct wacom_features wacom_features[] = {
        { "Wacom Graphire4 6x8", 8,  16704, 12064,  511, 63, WACOM_G4 },
        { "Wacom BambooFun 4x5", 9,  14760,  9225,  511, 63, WACOM_MO },
        { "Wacom BambooFun 6x8", 9,  21648, 13530,  511, 63, WACOM_MO },
+       { "Wacom Bamboo1 Medium",8,  16704, 12064,  511, 63, GRAPHIRE },
        { "Wacom Volito",        8,   5104,  3712,  511, 63, GRAPHIRE },
        { "Wacom PenStation2",   8,   3250,  2320,  255, 63, GRAPHIRE },
        { "Wacom Volito2 4x5",   8,   5104,  3712,  511, 63, GRAPHIRE },
@@ -650,6 +769,10 @@ static struct wacom_features wacom_features[] = {
        { "Wacom Cintiq 21UX",   10, 87200, 65600, 1023, 63, CINTIQ },
        { "Wacom Cintiq 20WSX",  10, 86680, 54180, 1023, 63, WACOM_BEE },
        { "Wacom Cintiq 12WX",   10, 53020, 33440, 1023, 63, WACOM_BEE },
+       { "Wacom DTU1931",        8, 37832, 30305,  511,  0, PL },
+       { "Wacom ISDv4 90",       8, 26202, 16325,  255,  0, TABLETPC },
+       { "Wacom ISDv4 93",       8, 26202, 16325,  255,  0, TABLETPC },
+       { "Wacom ISDv4 9A",       8, 26202, 16325,  255,  0, TABLETPC },
        { "Wacom Intuos2 6x8",   10, 20320, 16240, 1023, 31, INTUOS },
        { }
 };
@@ -665,6 +788,7 @@ static struct usb_device_id wacom_ids[] = {
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x16) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x17) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x18) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x19) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x60) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x61) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x62) },
@@ -704,18 +828,26 @@ static struct usb_device_id wacom_ids[] = {
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x3F) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC5) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC6) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0xC7) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x90) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x93) },
+       { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x9A) },
        { USB_DEVICE(USB_VENDOR_ID_WACOM, 0x47) },
        { }
 };
 
-const struct usb_device_id * get_device_table(void) {
-        const struct usb_device_id * id_table = wacom_ids;
+const struct usb_device_id *get_device_table(void)
+{
+        const struct usb_device_id *id_table = wacom_ids;
+
         return id_table;
 }
 
-struct wacom_features * get_wacom_feature(const struct usb_device_id * id) {
+struct wacom_features * get_wacom_feature(const struct usb_device_id *id)
+{
         int index = id - wacom_ids;
         struct wacom_features *wf = &wacom_features[index];
+
         return wf;
 }
 
index 3342bc05847d68e60f5d610dcb69e06a3c4aa5d1..f9c8b69673b7bf2d637b6c14d9e5e51a90bb42dc 100644 (file)
@@ -10,6 +10,7 @@
 #define WACOM_WAC_H
 
 #define STYLUS_DEVICE_ID       0x02
+#define TOUCH_DEVICE_ID                0x03
 #define CURSOR_DEVICE_ID       0x06
 #define ERASER_DEVICE_ID       0x0A
 #define PAD_DEVICE_ID          0x0F
@@ -27,6 +28,7 @@ enum {
        CINTIQ,
        WACOM_BEE,
        WACOM_MO,
+       TABLETPC,
        MAX_TYPE
 };
 
@@ -38,6 +40,8 @@ struct wacom_features {
        int pressure_max;
        int distance_max;
        int type;
+       int touch_x_max;
+       int touch_y_max;
 };
 
 struct wacom_wac {
index d20689cdbd5d63665601e9e00baca7ffd08eb42d..8f38c5e55ce6136782086534bdbf08e993f67702 100644 (file)
@@ -262,7 +262,7 @@ static int elo_setup_10(struct elo *elo)
                input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0);
 
        printk(KERN_INFO "elo: %sTouch touchscreen, fw: %02x.%02x, "
-               "features: %x02x, controller: 0x%02x\n",
+               "features: 0x%02x, controller: 0x%02x\n",
                elo_types[(packet[1] -'0') & 0x03],
                packet[5], packet[4], packet[3], packet[7]);
 
index 3ab6362f043c0e9db3d08f00b5f60db92da1f795..928d2ed8865f6b296b2fe9550d599b016d06f606 100644 (file)
@@ -323,7 +323,7 @@ static struct xenbus_device_id xenkbd_ids[] = {
        { "" }
 };
 
-static struct xenbus_driver xenkbd = {
+static struct xenbus_driver xenkbd_driver = {
        .name = "vkbd",
        .owner = THIS_MODULE,
        .ids = xenkbd_ids,
@@ -342,12 +342,12 @@ static int __init xenkbd_init(void)
        if (xen_initial_domain())
                return -ENODEV;
 
-       return xenbus_register_frontend(&xenkbd);
+       return xenbus_register_frontend(&xenkbd_driver);
 }
 
 static void __exit xenkbd_cleanup(void)
 {
-       xenbus_unregister_driver(&xenkbd);
+       xenbus_unregister_driver(&xenkbd_driver);
 }
 
 module_init(xenkbd_init);
index 84d75a3f5d17f20dfe9017baf455ba92edb28b25..ded9d0baf607b0daa8450c1b0e7bad775285e048 100644 (file)
@@ -1213,7 +1213,7 @@ static void HiSax_shiftcards(int idx)
                memcpy(&cards[i], &cards[i + 1], sizeof(cards[i]));
 }
 
-static int HiSax_inithardware(int *busy_flag)
+static int __init HiSax_inithardware(int *busy_flag)
 {
        int foundcards = 0;
        int i = 0;
@@ -1542,7 +1542,9 @@ static void __exit HiSax_exit(void)
        printk(KERN_INFO "HiSax module removed\n");
 }
 
-int hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
+#ifdef CONFIG_HOTPLUG
+
+int __devinit hisax_init_pcmcia(void *pcm_iob, int *busy_flag, struct IsdnCard *card)
 {
        u_char ids[16];
        int ret = -1;
@@ -1563,6 +1565,8 @@ error:
 }
 
 EXPORT_SYMBOL(hisax_init_pcmcia);
+#endif
+
 EXPORT_SYMBOL(HiSax_closecard);
 
 #include "hisax_if.h"
@@ -1580,6 +1584,11 @@ static void hisax_bc_close(struct BCState *bcs);
 static void hisax_bh(struct work_struct *work);
 static void EChannel_proc_rcv(struct hisax_d_if *d_if);
 
+static int hisax_setup_card_dynamic(struct IsdnCard *card)
+{
+       return 2;
+}
+
 int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
                   char *name, int protocol)
 {
@@ -1599,7 +1608,8 @@ int hisax_register(struct hisax_d_if *hisax_d_if, struct hisax_b_if *b_if[],
        cards[i].protocol = protocol;
        sprintf(id, "%s%d", name, i);
        nrcards++;
-       retval = checkcard(i, id, NULL, hisax_d_if->owner, hisax_cs_setup_card);
+       retval = checkcard(i, id, NULL, hisax_d_if->owner,
+                               hisax_setup_card_dynamic);
        if (retval == 0) { // yuck
                cards[i].typ = 0;
                nrcards--;
index 2c21d4f25cc82e85ab138aca5e4490f4166865f3..a98ab72adf9528f95e5c23d06b27c0d11a83c4a2 100644 (file)
@@ -288,7 +288,7 @@ static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
        cancel_rearming_delayed_work(&rm->cpu[1].sniffer);
 }
 
-static int rackmeter_setup(struct rackmeter *rm)
+static int __devinit rackmeter_setup(struct rackmeter *rm)
 {
        pr_debug("rackmeter: setting up i2s..\n");
        rackmeter_setup_i2s(rm);
@@ -582,12 +582,12 @@ static struct of_device_id rackmeter_match[] = {
        { }
 };
 
-static struct macio_driver rackmeter_drv = {
+static struct macio_driver rackmeter_driver = {
        .name = "rackmeter",
        .owner = THIS_MODULE,
        .match_table = rackmeter_match,
        .probe = rackmeter_probe,
-       .remove = rackmeter_remove,
+       .remove = __devexit_p(rackmeter_remove),
        .shutdown = rackmeter_shutdown,
 };
 
@@ -596,14 +596,14 @@ static int __init rackmeter_init(void)
 {
        pr_debug("rackmeter_init()\n");
 
-       return macio_register_driver(&rackmeter_drv);
+       return macio_register_driver(&rackmeter_driver);
 }
 
 static void __exit rackmeter_exit(void)
 {
        pr_debug("rackmeter_exit()\n");
 
-       macio_unregister_driver(&rackmeter_drv);
+       macio_unregister_driver(&rackmeter_driver);
 }
 
 module_init(rackmeter_init);
index 7bcb81002dcfe32dac89391d975ecc03b5d1a8e9..571b211608d1a7224575d99fe3ca5e27cccd03a2 100644 (file)
@@ -1038,8 +1038,8 @@ static int sony_nc_add(struct acpi_device *device)
                goto outinput;
        }
 
-       if (!acpi_video_backlight_support()) {
-               printk(KERN_INFO DRV_PFX "Sony: Brightness ignored, must be "
+       if (acpi_video_backlight_support()) {
+               printk(KERN_INFO DRV_PFX "brightness ignored, must be "
                       "controlled by ACPI video driver\n");
        } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
                                                &handle))) {
index 7a4a26b0edd2219dd28c3f4fb3475cd074ab81bd..899766e16fa822cdfd7abc240e2ce0ee7ea329e4 100644 (file)
@@ -5318,6 +5318,7 @@ static enum fan_control_commands fan_control_commands;
 
 static u8 fan_control_initial_status;
 static u8 fan_control_desired_level;
+static u8 fan_control_resume_level;
 static int fan_watchdog_maxinterval;
 
 static struct mutex fan_mutex;
@@ -5440,8 +5441,8 @@ static int fan_set_level(int level)
 
        case TPACPI_FAN_WR_ACPI_FANS:
        case TPACPI_FAN_WR_TPEC:
-               if ((level != TP_EC_FAN_AUTO) &&
-                   (level != TP_EC_FAN_FULLSPEED) &&
+               if (!(level & TP_EC_FAN_AUTO) &&
+                   !(level & TP_EC_FAN_FULLSPEED) &&
                    ((level < 0) || (level > 7)))
                        return -EINVAL;
 
@@ -6005,38 +6006,67 @@ static void fan_exit(void)
 
 static void fan_suspend(pm_message_t state)
 {
+       int rc;
+
        if (!fan_control_allowed)
                return;
 
        /* Store fan status in cache */
-       fan_get_status_safe(NULL);
+       fan_control_resume_level = 0;
+       rc = fan_get_status_safe(&fan_control_resume_level);
+       if (rc < 0)
+               printk(TPACPI_NOTICE
+                       "failed to read fan level for later "
+                       "restore during resume: %d\n", rc);
+
+       /* if it is undefined, don't attempt to restore it.
+        * KEEP THIS LAST */
        if (tp_features.fan_ctrl_status_undef)
-               fan_control_desired_level = TP_EC_FAN_AUTO;
+               fan_control_resume_level = 0;
 }
 
 static void fan_resume(void)
 {
-       u8 saved_fan_level;
        u8 current_level = 7;
        bool do_set = false;
+       int rc;
 
        /* DSDT *always* updates status on resume */
        tp_features.fan_ctrl_status_undef = 0;
 
-       saved_fan_level = fan_control_desired_level;
        if (!fan_control_allowed ||
+           !fan_control_resume_level ||
            (fan_get_status_safe(&current_level) < 0))
                return;
 
        switch (fan_control_access_mode) {
        case TPACPI_FAN_WR_ACPI_SFAN:
-               do_set = (saved_fan_level > current_level);
+               /* never decrease fan level */
+               do_set = (fan_control_resume_level > current_level);
                break;
        case TPACPI_FAN_WR_ACPI_FANS:
        case TPACPI_FAN_WR_TPEC:
-               do_set = ((saved_fan_level & TP_EC_FAN_FULLSPEED) ||
-                         (saved_fan_level == 7 &&
-                          !(current_level & TP_EC_FAN_FULLSPEED)));
+               /* never decrease fan level, scale is:
+                * TP_EC_FAN_FULLSPEED > 7 >= TP_EC_FAN_AUTO
+                *
+                * We expect the firmware to set either 7 or AUTO, but we
+                * handle FULLSPEED out of paranoia.
+                *
+                * So, we can safely only restore FULLSPEED or 7, anything
+                * else could slow the fan.  Restoring AUTO is useless, at
+                * best that's exactly what the DSDT already set (it is the
+                * slower it uses).
+                *
+                * Always keep in mind that the DSDT *will* have set the
+                * fans to what the vendor supposes is the best level.  We
+                * muck with it only to speed the fan up.
+                */
+               if (fan_control_resume_level != 7 &&
+                   !(fan_control_resume_level & TP_EC_FAN_FULLSPEED))
+                       return;
+               else
+                       do_set = !(current_level & TP_EC_FAN_FULLSPEED) &&
+                                (current_level != fan_control_resume_level);
                break;
        default:
                return;
@@ -6044,8 +6074,11 @@ static void fan_resume(void)
        if (do_set) {
                printk(TPACPI_NOTICE
                        "restoring fan level to 0x%02x\n",
-                       saved_fan_level);
-               fan_set_level_safe(saved_fan_level);
+                       fan_control_resume_level);
+               rc = fan_set_level_safe(fan_control_resume_level);
+               if (rc < 0)
+                       printk(TPACPI_NOTICE
+                               "failed to restore fan level: %d\n", rc);
        }
 }
 
index e04bcf1dff87c1b2dfdd75ef2428a0bb76781ef7..d8966bae0e0b85ea2810dd094828ddedf1e7cf6a 100644 (file)
@@ -1022,7 +1022,7 @@ int ubi_eba_copy_leb(struct ubi_device *ubi, int from, int to,
        }
 
        /*
-        * OK, now the LEB is locked and we can safely start moving iy. Since
+        * OK, now the LEB is locked and we can safely start moving it. Since
         * this function utilizes thie @ubi->peb1_buf buffer which is shared
         * with some other functions, so lock the buffer by taking the
         * @ubi->buf_mutex.
index 4f2daa5bbecfbafe646da17a586cacd3328b5d07..41d47e1cf15c23f8c36423ae3caa4a0e2091e245 100644 (file)
@@ -320,7 +320,7 @@ static int compare_lebs(struct ubi_device *ubi, const struct ubi_scan_leb *seb,
        }
 
        err = ubi_io_read_data(ubi, buf, pnum, 0, len);
-       if (err && err != UBI_IO_BITFLIPS)
+       if (err && err != UBI_IO_BITFLIPS && err != -EBADMSG)
                goto out_free_buf;
 
        data_crc = be32_to_cpu(vid_hdr->data_crc);
index 05d70937b54322d8ecd878d05cc69e084ef4a5ed..dcb6dac1dc5446b4966d85ef8e6d8e1db5ed9dcb 100644 (file)
@@ -1396,7 +1396,8 @@ int ubi_thread(void *u)
                                ubi_msg("%s: %d consecutive failures",
                                        ubi->bgt_name, WL_MAX_FAILURES);
                                ubi_ro_mode(ubi);
-                               break;
+                               ubi->thread_enabled = 0;
+                               continue;
                        }
                } else
                        failures = 0;
index 11f143f4adf6d379682833679bb9ffa7cb99346c..231eeaf1d5522513e44941871d76b67b38b0f38b 100644 (file)
@@ -1825,9 +1825,10 @@ config FEC2
 
 config FEC_MPC52xx
        tristate "MPC52xx FEC driver"
-       depends on PPC_MPC52xx && PPC_BESTCOMM_FEC
+       depends on PPC_MPC52xx && PPC_BESTCOMM
        select CRC32
        select PHYLIB
+       select PPC_BESTCOMM_FEC
        ---help---
          This option enables support for the MPC5200's on-chip
          Fast Ethernet Controller
index 36f2bb666bf7e4a8d471f932cddd2ae67b66485a..8ed823ae639e6a2a1bcbc1eeabbc8fb1177d2c66 100644 (file)
@@ -2330,7 +2330,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
  * Once we know the feature-set enabled for the device, we'll cache
  * the register offset the descriptor ring is assigned to.
  **/
-static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
+static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
 {
        int feature_mask = 0, rss_i;
        int i, txr_idx, rxr_idx;
@@ -2367,7 +2367,7 @@ static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
  * number of queues at compile-time.  The polling_netdev array is
  * intended for Multiqueue, but should work fine with a single queue.
  **/
-static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
+static int ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
 {
        int i;
 
@@ -2408,8 +2408,7 @@ err_tx_ring_allocation:
  * Attempt to configure the interrupts using the best available
  * capabilities of the hardware and the kernel.
  **/
-static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
-                                                    *adapter)
+static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
 {
        int err = 0;
        int vector, v_budget;
@@ -2501,7 +2500,7 @@ static void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
  * - Hardware queue count (num_*_queues)
  *   - defined by miscellaneous hardware support/features (RSS, etc.)
  **/
-static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
+static int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
 {
        int err;
 
index cf3cca4642f225320d9b076a9d82510c23aae493..f51944b28cfa7008bd05f282844013e5459c6fc2 100644 (file)
@@ -349,7 +349,7 @@ static int ibmtr_suspend(struct pcmcia_device *link)
        return 0;
 }
 
-static int ibmtr_resume(struct pcmcia_device *link)
+static int __devinit ibmtr_resume(struct pcmcia_device *link)
 {
        ibmtr_dev_t *info = link->priv;
        struct net_device *dev = info->dev;
index b185cd12269c1d9a1a8ff102cedd226d7695d48a..9a16a79b67d0d432f1bcf629dfba358e2a7cf918 100644 (file)
@@ -1735,7 +1735,7 @@ static const struct ethtool_ops smc911x_ethtool_ops = {
  * This routine has a simple purpose -- make the SMC chip generate an
  * interrupt, so an auto-detect routine can detect it, and find the IRQ,
  */
-static int __init smc911x_findirq(struct net_device *dev)
+static int __devinit smc911x_findirq(struct net_device *dev)
 {
        struct smc911x_local *lp = netdev_priv(dev);
        int timeout = 20;
@@ -1799,7 +1799,7 @@ static int __init smc911x_findirq(struct net_device *dev)
  * o  actually GRAB the irq.
  * o  GRAB the region
  */
-static int __init smc911x_probe(struct net_device *dev)
+static int __devinit smc911x_probe(struct net_device *dev)
 {
        struct smc911x_local *lp = netdev_priv(dev);
        int i, retval;
@@ -2048,7 +2048,7 @@ err_out:
  *      0 --> there is a device
  *      anything else, error
  */
-static int smc911x_drv_probe(struct platform_device *pdev)
+static int __devinit smc911x_drv_probe(struct platform_device *pdev)
 {
 #ifdef SMC_DYNAMIC_BUS_CONFIG
        struct smc911x_platdata *pd = pdev->dev.platform_data;
@@ -2124,7 +2124,7 @@ out:
        return ret;
 }
 
-static int smc911x_drv_remove(struct platform_device *pdev)
+static int __devexit smc911x_drv_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct smc911x_local *lp = netdev_priv(ndev);
@@ -2195,7 +2195,7 @@ static int smc911x_drv_resume(struct platform_device *dev)
 
 static struct platform_driver smc911x_driver = {
        .probe           = smc911x_drv_probe,
-       .remove  = smc911x_drv_remove,
+       .remove  = __devexit_p(smc911x_drv_remove),
        .suspend         = smc911x_drv_suspend,
        .resume  = smc911x_drv_resume,
        .driver  = {
index fc80f250da31e8940bcc2d89d781de5eca66d7f2..35c56abf4113193490c3ca4a91f1f12077e9eb13 100644 (file)
@@ -1696,7 +1696,7 @@ static const struct ethtool_ops smc_ethtool_ops = {
  * I just deleted auto_irq.c, since it was never built...
  *   --jgarzik
  */
-static int __init smc_findirq(struct smc_local *lp)
+static int __devinit smc_findirq(struct smc_local *lp)
 {
        void __iomem *ioaddr = lp->base;
        int timeout = 20;
@@ -1770,7 +1770,7 @@ static int __init smc_findirq(struct smc_local *lp)
  * o  actually GRAB the irq.
  * o  GRAB the region
  */
-static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
+static int __devinit smc_probe(struct net_device *dev, void __iomem *ioaddr,
                            unsigned long irq_flags)
 {
        struct smc_local *lp = netdev_priv(dev);
@@ -2126,7 +2126,7 @@ static void smc_release_datacs(struct platform_device *pdev, struct net_device *
  *     0 --> there is a device
  *     anything else, error
  */
-static int smc_drv_probe(struct platform_device *pdev)
+static int __devinit smc_drv_probe(struct platform_device *pdev)
 {
        struct smc91x_platdata *pd = pdev->dev.platform_data;
        struct smc_local *lp;
@@ -2240,7 +2240,7 @@ static int smc_drv_probe(struct platform_device *pdev)
        return ret;
 }
 
-static int smc_drv_remove(struct platform_device *pdev)
+static int __devexit smc_drv_remove(struct platform_device *pdev)
 {
        struct net_device *ndev = platform_get_drvdata(pdev);
        struct smc_local *lp = netdev_priv(ndev);
@@ -2305,7 +2305,7 @@ static int smc_drv_resume(struct platform_device *dev)
 
 static struct platform_driver smc_driver = {
        .probe          = smc_drv_probe,
-       .remove         = smc_drv_remove,
+       .remove         = __devexit_p(smc_drv_remove),
        .suspend        = smc_drv_suspend,
        .resume         = smc_drv_resume,
        .driver         = {
index c6948d8f53f62fbf4f6b06cf3292ebe80828132a..6d017adc914ac18c5389fb550b53ed5aa09b3246 100644 (file)
@@ -1785,7 +1785,7 @@ static int __devexit xennet_remove(struct xenbus_device *dev)
        return 0;
 }
 
-static struct xenbus_driver netfront = {
+static struct xenbus_driver netfront_driver = {
        .name = "vif",
        .owner = THIS_MODULE,
        .ids = netfront_ids,
@@ -1805,7 +1805,7 @@ static int __init netif_init(void)
 
        printk(KERN_INFO "Initialising Xen virtual ethernet driver.\n");
 
-       return xenbus_register_frontend(&netfront);
+       return xenbus_register_frontend(&netfront_driver);
 }
 module_init(netif_init);
 
@@ -1815,7 +1815,7 @@ static void __exit netif_exit(void)
        if (xen_initial_domain())
                return;
 
-       xenbus_unregister_driver(&netfront);
+       xenbus_unregister_driver(&netfront_driver);
 }
 module_exit(netif_exit);
 
index 28af496b441ee47b41a189ccc5b1f03d754b89dc..061d1ee0046aa2d419f7589aab0ed6992fcbc7c6 100644 (file)
@@ -2042,7 +2042,7 @@ static int __devinit pci_init(void)
        return 0;
 }
 
-static int __devinit pci_setup(char *str)
+static int __init pci_setup(char *str)
 {
        while (str) {
                char *k = strchr(str, ',');
index a926c896475ebc3839ef63e92b1bffd20c62ee82..643a6b98462b67062487fec8e37e505fe9c50cd1 100644 (file)
@@ -879,7 +879,7 @@ static void rio_update_route_tables(struct rio_mport *port)
  * link, then start recursive peer enumeration. Returns %0 if
  * enumeration succeeds or %-EBUSY if enumeration fails.
  */
-int rio_enum_mport(struct rio_mport *mport)
+int __devinit rio_enum_mport(struct rio_mport *mport)
 {
        struct rio_net *net = NULL;
        int rc = 0;
@@ -972,7 +972,7 @@ static void rio_enum_timeout(unsigned long data)
  * peer discovery. Returns %0 if discovery succeeds or %-EBUSY
  * on failure.
  */
-int rio_disc_mport(struct rio_mport *mport)
+int __devinit rio_disc_mport(struct rio_mport *mport)
 {
        struct rio_net *net = NULL;
        int enum_timeout_flag = 0;
index 680661abbc4b700ce537a8ad828124be26821187..6395c780008ba83534849cb47cd41267f4b63933 100644 (file)
@@ -467,7 +467,7 @@ static int __devinit rio_init(void)
 
 device_initcall(rio_init);
 
-int rio_init_mports(void)
+int __devinit rio_init_mports(void)
 {
        int rc = 0;
        struct rio_mport *port;
index 218777bfc143db8bc54b1967b4c07f0a29232492..399fe559e4defaf89a29c4883aaec7ca9ba0d9e4 100644 (file)
@@ -13872,8 +13872,10 @@ static int __devinit advansys_board_found(struct Scsi_Host *shost,
        advansys_wide_free_mem(boardp);
        free_irq(boardp->irq, shost);
  err_free_dma:
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA)
                free_dma(shost->dma_channel);
+#endif
  err_free_proc:
        kfree(boardp->prtbuf);
  err_unmap:
@@ -13894,10 +13896,12 @@ static int advansys_release(struct Scsi_Host *shost)
        ASC_DBG(1, "begin\n");
        scsi_remove_host(shost);
        free_irq(board->irq, shost);
+#ifdef CONFIG_ISA
        if (shost->dma_channel != NO_ISA_DMA) {
                ASC_DBG(1, "free_dma()\n");
                free_dma(shost->dma_channel);
        }
+#endif
        if (ASC_NARROW_BOARD(board)) {
                dma_unmap_single(board->dev,
                                        board->dvc_var.asc_dvc_var.overrun_dma,
index c387c15a21282e250b6291ac9872ba91877a1dc2..fb247fdfa2bd51d91ea567918d51cd3e818371a9 100644 (file)
@@ -588,7 +588,7 @@ static struct pci_driver gdth_pci_driver = {
        .remove         = gdth_pci_remove_one,
 };
 
-static void gdth_pci_remove_one(struct pci_dev *pdev)
+static void __devexit gdth_pci_remove_one(struct pci_dev *pdev)
 {
        gdth_ha_str *ha = pci_get_drvdata(pdev);
 
@@ -600,7 +600,7 @@ static void gdth_pci_remove_one(struct pci_dev *pdev)
        pci_disable_device(pdev);
 }
 
-static int gdth_pci_init_one(struct pci_dev *pdev,
+static int __devinit gdth_pci_init_one(struct pci_dev *pdev,
                                       const struct pci_device_id *ent)
 {
        ushort vendor = pdev->vendor;
@@ -853,7 +853,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
 #endif /* CONFIG_ISA */
 
 #ifdef CONFIG_PCI
-static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
+static int __devinit gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
                                   gdth_ha_str *ha)
 {
     register gdt6_dpram_str __iomem *dp6_ptr;
@@ -1237,7 +1237,7 @@ static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
 
 /* controller protocol functions */
 
-static void __init gdth_enable_int(gdth_ha_str *ha)
+static void __devinit gdth_enable_int(gdth_ha_str *ha)
 {
     ulong flags;
     gdt2_dpram_str __iomem *dp2_ptr;
@@ -1553,7 +1553,7 @@ static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode,
 
 /* search for devices */
 
-static int __init gdth_search_drives(gdth_ha_str *ha)
+static int __devinit gdth_search_drives(gdth_ha_str *ha)
 {
     ushort cdev_cnt, i;
     int ok;
@@ -4935,7 +4935,7 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
 #endif /* CONFIG_EISA */
 
 #ifdef CONFIG_PCI
-static int gdth_pci_probe_one(gdth_pci_str *pcistr,
+static int __devinit gdth_pci_probe_one(gdth_pci_str *pcistr,
                             gdth_ha_str **ha_out)
 {
        struct Scsi_Host *shp;
index 6a3f8fb0c9dd9eb1c1bff91382e1f426b73cb67f..3317148a4b93bd921100deecaedb9bc9fe7fb771 100644 (file)
@@ -286,8 +286,8 @@ static void ulite_release_port(struct uart_port *port)
 
 static int ulite_request_port(struct uart_port *port)
 {
-       pr_debug("ulite console: port=%p; port->mapbase=%x\n",
-                port, port->mapbase);
+       pr_debug("ulite console: port=%p; port->mapbase=%llx\n",
+                port, (unsigned long long) port->mapbase);
 
        if (!request_mem_region(port->mapbase, ULITE_REGION, "uartlite")) {
                dev_err(port->dev, "Memory region busy\n");
index 1fe8b44787b332c93e4b8261243c08e3816b2d27..b3408ff39fba07d8e289a9d69f28cc2b6b296512 100644 (file)
@@ -2363,6 +2363,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
                nuke(loop_ep, -ESHUTDOWN);
        spin_unlock_irqrestore(&udc_controller->lock, flags);
 
+       /* report disconnect; the controller is already quiesced */
+       driver->disconnect(&udc_controller->gadget);
+
        /* unbind gadget and unhook driver. */
        driver->unbind(&udc_controller->gadget);
        udc_controller->gadget.dev.driver = NULL;
index 091bb55c9aa7abaee80930e9e79bb955a9f47bf3..f3c6703cffda3c700399f8352f2ed5bf76530b6f 100644 (file)
@@ -1836,6 +1836,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
                nuke(loop_ep, -ESHUTDOWN);
        spin_unlock_irqrestore(&udc_controller->lock, flags);
 
+       /* report disconnect; the controller is already quiesced */
+       driver->disconnect(&udc_controller->gadget);
+
        /* unbind gadget and unhook driver. */
        driver->unbind(&udc_controller->gadget);
        udc_controller->gadget.dev.driver = NULL;
index da6e93c201d20183b7d804591f880cf6005e6683..2dbc0db0b46c66c5e455b33db339ae452cc25e16 100644 (file)
@@ -141,7 +141,11 @@ static int is_vbus_present(void)
 
        if (mach->gpio_vbus) {
                int value = gpio_get_value(mach->gpio_vbus);
-               return mach->gpio_vbus_inverted ? !value : value;
+
+               if (mach->gpio_vbus_inverted)
+                       return !value;
+               else
+                       return !!value;
        }
        if (mach->udc_is_connected)
                return mach->udc_is_connected();
@@ -982,7 +986,7 @@ static int pxa25x_udc_vbus_session(struct usb_gadget *_gadget, int is_active)
        struct pxa25x_udc       *udc;
 
        udc = container_of(_gadget, struct pxa25x_udc, gadget);
-       udc->vbus = (is_active != 0);
+       udc->vbus = is_active;
        DMSG("vbus %s\n", is_active ? "supplied" : "inactive");
        pullup(udc);
        return 0;
@@ -1399,12 +1403,8 @@ lubbock_vbus_irq(int irq, void *_dev)
 static irqreturn_t udc_vbus_irq(int irq, void *_dev)
 {
        struct pxa25x_udc       *dev = _dev;
-       int                     vbus = gpio_get_value(dev->mach->gpio_vbus);
 
-       if (dev->mach->gpio_vbus_inverted)
-               vbus = !vbus;
-
-       pxa25x_udc_vbus_session(&dev->gadget, vbus);
+       pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present());
        return IRQ_HANDLED;
 }
 
index 9d0ea573aef60c3e45afb3dec145c5f0f4ed843b..36864f9584445a41cf8bea70155c50b76f888cc2 100644 (file)
@@ -169,18 +169,21 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                }
                break;
        case PCI_VENDOR_ID_ATI:
-               /* SB700 old version has a bug in EHCI controller,
+               /* SB600 and old version of SB700 have a bug in EHCI controller,
                 * which causes usb devices lose response in some cases.
                 */
-               if (pdev->device == 0x4396) {
+               if ((pdev->device == 0x4386) || (pdev->device == 0x4396)) {
                        p_smbus = pci_get_device(PCI_VENDOR_ID_ATI,
                                                 PCI_DEVICE_ID_ATI_SBX00_SMBUS,
                                                 NULL);
                        if (!p_smbus)
                                break;
                        rev = p_smbus->revision;
-                       if ((rev == 0x3a) || (rev == 0x3b)) {
+                       if ((pdev->device == 0x4386) || (rev == 0x3a)
+                           || (rev == 0x3b)) {
                                u8 tmp;
+                               ehci_info(ehci, "applying AMD SB600/SB700 USB "
+                                       "freeze workaround\n");
                                pci_read_config_byte(pdev, 0x53, &tmp);
                                pci_write_config_byte(pdev, 0x53, tmp | (1<<3));
                        }
index b11798d17ae56f1e69233db67e916e681b9351eb..c7d4b5a06bdb049e424228560a9d0b51f4baf7fd 100644 (file)
@@ -183,16 +183,14 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
         * the async ring; just the I/O watchdog.  Note that if a
         * SHRINK were pending, OFF would never be requested.
         */
-       enum ehci_timer_action oldactions = ehci->actions;
+       if (timer_pending(&ehci->watchdog)
+                       && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
+                               & ehci->actions))
+               return;
 
        if (!test_and_set_bit (action, &ehci->actions)) {
                unsigned long t;
 
-               if (timer_pending(&ehci->watchdog)
-                       && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF))
-                               & oldactions))
-                       return;
-
                switch (action) {
                case TIMER_IO_WATCHDOG:
                        t = EHCI_IO_JIFFIES;
@@ -208,7 +206,7 @@ timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action)
                        t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
                        break;
                }
-               mod_timer(&ehci->watchdog, round_jiffies(t + jiffies));
+               mod_timer(&ehci->watchdog, t + jiffies);
        }
 }
 
index 5b20de130e08399045e3134dff18bfb8543af5f4..5b95009d2fbb104d28065010dc857da2eace6c42 100644 (file)
@@ -135,6 +135,7 @@ static int usb_console_setup(struct console *co, char *options)
                                err("no more memory");
                                goto reset_open_count;
                        }
+                       kref_init(&tty->kref);
                        termios = kzalloc(sizeof(*termios), GFP_KERNEL);
                        if (!termios) {
                                retval = -ENOMEM;
index 6fa1ec441b618d12575adf9bec5ee67a327fde6f..809697b3c7fcbed04a9d3a4e2eeac5d412a92adc 100644 (file)
@@ -224,6 +224,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 #define ONDA_VENDOR_ID                         0x19d2
 #define ONDA_PRODUCT_MSA501HS                  0x0001
 #define ONDA_PRODUCT_ET502HS                   0x0002
+#define ONDA_PRODUCT_MT503HS                   0x0200
 
 #define BANDRICH_VENDOR_ID                     0x1A8D
 #define BANDRICH_PRODUCT_C100_1                        0x1002
@@ -413,6 +414,40 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(AXESSTEL_VENDOR_ID, AXESSTEL_PRODUCT_MV110H) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MSA501HS) },
        { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0003) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0004) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0005) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0006) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0007) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0008) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0009) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000a) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000b) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000c) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000d) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000e) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x000f) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0010) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0011) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0012) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0013) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0014) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0015) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0016) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0017) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0018) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0019) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0020) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0021) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0022) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0023) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0024) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0025) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0026) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0027) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0028) },
+       { USB_DEVICE(ONDA_VENDOR_ID, 0x0029) },
+       { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_MT503HS) },
        { USB_DEVICE(YISO_VENDOR_ID, YISO_PRODUCT_U893) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
index 6da9a7a962a8a2790b30dd3f25fa952aec763ec8..e61f2bfc64add77ab938367c45c08db542c589e0 100644 (file)
@@ -318,6 +318,18 @@ UNUSUAL_DEV(  0x045a, 0x5210, 0x0101, 0x0101,
                US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),
 #endif
 
+/* Reported by Tamas Kerecsen <kerecsen@bigfoot.com>
+ * Obviously the PROM has not been customized by the VAR;
+ * the Vendor and Product string descriptors are:
+ *     Generic Mass Storage (PROTOTYPE--Remember to change idVendor)
+ *     Generic Manufacturer (PROTOTYPE--Remember to change idVendor)
+ */
+UNUSUAL_DEV(  0x045e, 0xffff, 0x0000, 0x0000,
+               "Mitac",
+               "GPS",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_MAX_SECTORS_64 ),
+
 /*
  * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.)
  * Reported by Pete Zaitcev <zaitcev@redhat.com>
@@ -377,6 +389,13 @@ UNUSUAL_DEV(  0x04b0, 0x0401, 0x0200, 0x0200,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
+/* Reported by Tobias Kunze Briseno <t-linux@fictive.com> */
+UNUSUAL_DEV(  0x04b0, 0x0403, 0x0200, 0x0200,
+               "NIKON",
+               "NIKON DSC D2H",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY),
+
 /* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */
 UNUSUAL_DEV(  0x04b0, 0x0409, 0x0100, 0x0100,
                "NIKON",
index 99da8b6d2c3650d6418f832add4d221e50ada887..ed13889c116223e16f99ec32de9c0c1762e54897 100644 (file)
@@ -23,7 +23,6 @@ objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o
 objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o
 objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o
 objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o
-objs-y$(CONFIG_MACH_SX1) += lcd_sx1.o
 
 omapfb-objs := $(objs-yy)
 
diff --git a/drivers/video/omap/lcd_sx1.c b/drivers/video/omap/lcd_sx1.c
deleted file mode 100644 (file)
index e55de20..0000000
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * LCD panel support for the Siemens SX1 mobile phone
- *
- * Current version : Vovan888@gmail.com, great help from FCA00000
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include <mach/gpio.h>
-#include <mach/omapfb.h>
-#include <mach/mcbsp.h>
-#include <mach/mux.h>
-
-/*
- * OMAP310 GPIO registers
- */
-#define GPIO_DATA_INPUT                0xfffce000
-#define GPIO_DATA_OUTPUT       0xfffce004
-#define GPIO_DIR_CONTROL       0xfffce008
-#define GPIO_INT_CONTROL       0xfffce00c
-#define GPIO_INT_MASK          0xfffce010
-#define GPIO_INT_STATUS                0xfffce014
-#define GPIO_PIN_CONTROL       0xfffce018
-
-
-#define A_LCD_SSC_RD   3
-#define A_LCD_SSC_SD   7
-#define _A_LCD_RESET   9
-#define _A_LCD_SSC_CS  12
-#define _A_LCD_SSC_A0  13
-
-#define DSP_REG                0xE1017024
-
-const unsigned char INIT_1[12] = {
-       0x1C, 0x02, 0x88, 0x00, 0x1E, 0xE0, 0x00, 0xDC, 0x00, 0x02, 0x00
-};
-
-const unsigned char INIT_2[127] = {
-       0x15, 0x00, 0x29, 0x00, 0x3E, 0x00, 0x51, 0x00,
-       0x65, 0x00, 0x7A, 0x00, 0x8D, 0x00, 0xA1, 0x00,
-       0xB6, 0x00, 0xC7, 0x00, 0xD8, 0x00, 0xEB, 0x00,
-       0xFB, 0x00, 0x0B, 0x01, 0x1B, 0x01, 0x27, 0x01,
-       0x34, 0x01, 0x41, 0x01, 0x4C, 0x01, 0x55, 0x01,
-       0x5F, 0x01, 0x68, 0x01, 0x70, 0x01, 0x78, 0x01,
-       0x7E, 0x01, 0x86, 0x01, 0x8C, 0x01, 0x94, 0x01,
-       0x9B, 0x01, 0xA1, 0x01, 0xA4, 0x01, 0xA9, 0x01,
-       0xAD, 0x01, 0xB2, 0x01, 0xB7, 0x01, 0xBC, 0x01,
-       0xC0, 0x01, 0xC4, 0x01, 0xC8, 0x01, 0xCB, 0x01,
-       0xCF, 0x01, 0xD2, 0x01, 0xD5, 0x01, 0xD8, 0x01,
-       0xDB, 0x01, 0xE0, 0x01, 0xE3, 0x01, 0xE6, 0x01,
-       0xE8, 0x01, 0xEB, 0x01, 0xEE, 0x01, 0xF1, 0x01,
-       0xF3, 0x01, 0xF8, 0x01, 0xF9, 0x01, 0xFC, 0x01,
-       0x00, 0x02, 0x03, 0x02, 0x07, 0x02, 0x09, 0x02,
-       0x0E, 0x02, 0x13, 0x02, 0x1C, 0x02, 0x00
-};
-
-const unsigned char INIT_3[15] = {
-       0x14, 0x26, 0x33, 0x3D, 0x45, 0x4D, 0x53, 0x59,
-       0x5E, 0x63, 0x67, 0x6D, 0x71, 0x78, 0xFF
-};
-
-static void epson_sendbyte(int flag, unsigned char byte)
-{
-       int i, shifter = 0x80;
-
-       if (!flag)
-               gpio_set_value(_A_LCD_SSC_A0, 0);
-       mdelay(2);
-       gpio_set_value(A_LCD_SSC_RD, 1);
-
-       gpio_set_value(A_LCD_SSC_SD, flag);
-
-       OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
-       OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
-       for (i = 0; i < 8; i++) {
-               OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2200);
-               gpio_set_value(A_LCD_SSC_SD, shifter & byte);
-               OMAP_MCBSP_WRITE(OMAP1510_MCBSP3_BASE, PCR0, 0x2202);
-               shifter >>= 1;
-       }
-       gpio_set_value(_A_LCD_SSC_A0, 1);
-}
-
-static void init_system(void)
-{
-       omap_mcbsp_request(OMAP_MCBSP3);
-       omap_mcbsp_stop(OMAP_MCBSP3);
-}
-
-static void setup_GPIO(void)
-{
-       /* new wave */
-       gpio_request(A_LCD_SSC_RD, "lcd_ssc_rd");
-       gpio_request(A_LCD_SSC_SD, "lcd_ssc_sd");
-       gpio_request(_A_LCD_RESET, "lcd_reset");
-       gpio_request(_A_LCD_SSC_CS, "lcd_ssc_cs");
-       gpio_request(_A_LCD_SSC_A0, "lcd_ssc_a0");
-
-       /* set GPIOs to output, with initial data */
-       gpio_direction_output(A_LCD_SSC_RD, 1);
-       gpio_direction_output(A_LCD_SSC_SD, 0);
-       gpio_direction_output(_A_LCD_RESET, 0);
-       gpio_direction_output(_A_LCD_SSC_CS, 1);
-       gpio_direction_output(_A_LCD_SSC_A0, 1);
-}
-
-static void display_init(void)
-{
-       int i;
-
-       omap_cfg_reg(MCBSP3_CLKX);
-
-       mdelay(2);
-       setup_GPIO();
-       mdelay(2);
-
-       /* reset LCD */
-       gpio_set_value(A_LCD_SSC_SD, 1);
-       epson_sendbyte(0, 0x25);
-
-       gpio_set_value(_A_LCD_RESET, 0);
-       mdelay(10);
-       gpio_set_value(_A_LCD_RESET, 1);
-
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       mdelay(2);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD, phase 1 */
-       epson_sendbyte(0, 0xCA);
-       for (i = 0; i < 10; i++)
-               epson_sendbyte(1, INIT_1[i]);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 2 */
-       epson_sendbyte(0, 0xCB);
-       for (i = 0; i < 125; i++)
-               epson_sendbyte(1, INIT_2[i]);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 2a */
-       epson_sendbyte(0, 0xCC);
-       for (i = 0; i < 14; i++)
-               epson_sendbyte(1, INIT_3[i]);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 3 */
-       epson_sendbyte(0, 0xBC);
-       epson_sendbyte(1, 0x08);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 4 */
-       epson_sendbyte(0, 0x07);
-       epson_sendbyte(1, 0x05);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 5 */
-       epson_sendbyte(0, 0x94);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 6 */
-       epson_sendbyte(0, 0xC6);
-       epson_sendbyte(1, 0x80);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       mdelay(100); /* used to be 1000 */
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 7 */
-       epson_sendbyte(0, 0x16);
-       epson_sendbyte(1, 0x02);
-       epson_sendbyte(1, 0x00);
-       epson_sendbyte(1, 0xB1);
-       epson_sendbyte(1, 0x00);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 8 */
-       epson_sendbyte(0, 0x76);
-       epson_sendbyte(1, 0x00);
-       epson_sendbyte(1, 0x00);
-       epson_sendbyte(1, 0xDB);
-       epson_sendbyte(1, 0x00);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       /* init LCD phase 9 */
-       epson_sendbyte(0, 0xAF);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-}
-
-static int sx1_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
-{
-       return 0;
-}
-
-static void sx1_panel_cleanup(struct lcd_panel *panel)
-{
-}
-
-static void sx1_panel_disable(struct lcd_panel *panel)
-{
-       printk(KERN_INFO "SX1: LCD panel disable\n");
-       sx1_setmmipower(0);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-
-       epson_sendbyte(0, 0x25);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       epson_sendbyte(0, 0xAE);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-       mdelay(100);
-       gpio_set_value(_A_LCD_SSC_CS, 0);
-
-       epson_sendbyte(0, 0x95);
-       gpio_set_value(_A_LCD_SSC_CS, 1);
-}
-
-static int sx1_panel_enable(struct lcd_panel *panel)
-{
-       printk(KERN_INFO "lcd_sx1: LCD panel enable\n");
-       init_system();
-       display_init();
-
-       sx1_setmmipower(1);
-       sx1_setbacklight(0x18);
-       sx1_setkeylight (0x06);
-       return 0;
-}
-
-
-static unsigned long sx1_panel_get_caps(struct lcd_panel *panel)
-{
-       return 0;
-}
-
-struct lcd_panel sx1_panel = {
-       .name           = "sx1",
-       .config         = OMAP_LCDC_PANEL_TFT | OMAP_LCDC_INV_VSYNC |
-                         OMAP_LCDC_INV_HSYNC | OMAP_LCDC_INV_PIX_CLOCK |
-                         OMAP_LCDC_INV_OUTPUT_EN,
-
-       .x_res          = 176,
-       .y_res          = 220,
-       .data_lines     = 16,
-       .bpp            = 16,
-       .hsw            = 5,
-       .hfp            = 5,
-       .hbp            = 5,
-       .vsw            = 2,
-       .vfp            = 1,
-       .vbp            = 1,
-       .pixel_clock    = 1500,
-
-       .init           = sx1_panel_init,
-       .cleanup        = sx1_panel_cleanup,
-       .enable         = sx1_panel_enable,
-       .disable        = sx1_panel_disable,
-       .get_caps       = sx1_panel_get_caps,
-};
-
-static int sx1_panel_probe(struct platform_device *pdev)
-{
-       omapfb_register_panel(&sx1_panel);
-       return 0;
-}
-
-static int sx1_panel_remove(struct platform_device *pdev)
-{
-       return 0;
-}
-
-static int sx1_panel_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-       return 0;
-}
-
-static int sx1_panel_resume(struct platform_device *pdev)
-{
-       return 0;
-}
-
-struct platform_driver sx1_panel_driver = {
-       .probe          = sx1_panel_probe,
-       .remove         = sx1_panel_remove,
-       .suspend        = sx1_panel_suspend,
-       .resume         = sx1_panel_resume,
-       .driver = {
-               .name   = "lcd_sx1",
-               .owner  = THIS_MODULE,
-       },
-};
-
-static int sx1_panel_drv_init(void)
-{
-       return platform_driver_register(&sx1_panel_driver);
-}
-
-static void sx1_panel_drv_cleanup(void)
-{
-       platform_driver_unregister(&sx1_panel_driver);
-}
-
-module_init(sx1_panel_drv_init);
-module_exit(sx1_panel_drv_cleanup);
index 97204497d9f7ed10de17f6290c7ac047fd6fabef..cc59c52e1103dfdd48cd161fb37a385023890b5a 100644 (file)
@@ -804,6 +804,9 @@ static int pxafb_smart_thread(void *arg)
 
 static int pxafb_smart_init(struct pxafb_info *fbi)
 {
+       if (!(fbi->lccr0 | LCCR0_LCDT))
+               return 0;
+
        fbi->smart_thread = kthread_run(pxafb_smart_thread, fbi,
                                        "lcd_refresh");
        if (IS_ERR(fbi->smart_thread)) {
@@ -1372,7 +1375,7 @@ static void pxafb_decode_mach_info(struct pxafb_info *fbi,
        fbi->cmap_inverse       = inf->cmap_inverse;
        fbi->cmap_static        = inf->cmap_static;
 
-       switch (lcd_conn & 0xf) {
+       switch (lcd_conn & LCD_TYPE_MASK) {
        case LCD_TYPE_MONO_STN:
                fbi->lccr0 = LCCR0_CMS;
                break;
index a463b3dd837b5b9d6db40f68081fca7f89678e0f..2493f05e9f6176588c0f0fc3471097f62c8ae68d 100644 (file)
@@ -668,7 +668,7 @@ static struct xenbus_device_id xenfb_ids[] = {
        { "" }
 };
 
-static struct xenbus_driver xenfb = {
+static struct xenbus_driver xenfb_driver = {
        .name = "vfb",
        .owner = THIS_MODULE,
        .ids = xenfb_ids,
@@ -687,12 +687,12 @@ static int __init xenfb_init(void)
        if (xen_initial_domain())
                return -ENODEV;
 
-       return xenbus_register_frontend(&xenfb);
+       return xenbus_register_frontend(&xenfb_driver);
 }
 
 static void __exit xenfb_cleanup(void)
 {
-       xenbus_unregister_driver(&xenfb);
+       xenbus_unregister_driver(&xenfb_driver);
 }
 
 module_init(xenfb_init);
index 5da3d2423cc0f4cc22ebd2f530414d0ef891bb00..40a3a2afbfe7588faed06e975be5fa0c82a21127 100644 (file)
@@ -298,8 +298,9 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
 
        /* Put a banner in the log (for DEBUG) */
        dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs);
-       dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
-               (void*)drvdata->fb_phys, drvdata->fb_virt, fbsize);
+       dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n",
+               (unsigned long long) drvdata->fb_phys, drvdata->fb_virt,
+               fbsize);
 
        return 0;       /* success */
 
index a14d5b6e4c7c280b831f9f87ea33ace10f8fc571..90616822cd2021ea9b1f8a195baf5dbda6f5e28e 100644 (file)
@@ -36,7 +36,7 @@ config W1_MASTER_DS2482
 
 config W1_MASTER_DS1WM
        tristate "Maxim DS1WM 1-wire busmaster"
-       depends on W1 && ARM
+       depends on W1 && ARM && HAVE_CLK
        help
          Say Y here to enable the DS1WM 1-wire driver, such as that
          in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like
index 6569fda5cfed892c7e4ed53daa2e9677e60c36d5..10179cfa11528683495886657bd643ebde590ce8 100644 (file)
@@ -878,6 +878,7 @@ void invalidate_inode_buffers(struct inode *inode)
                spin_unlock(&buffer_mapping->private_lock);
        }
 }
+EXPORT_SYMBOL(invalidate_inode_buffers);
 
 /*
  * Remove any clean buffers from the inode's buffer list.  This is called
index b691b893a848a8d4d74c1e0ecce800d561b99b67..f0a81e631ae60bed3ec139833a2a1a63cef45642 100644 (file)
@@ -1475,7 +1475,11 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
        cFYI(1, ("write_end for page %p from pos %lld with %d bytes",
                 page, pos, copied));
 
-       if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
+       if (PageChecked(page)) {
+               if (copied == len)
+                       SetPageUptodate(page);
+               ClearPageChecked(page);
+       } else if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
                SetPageUptodate(page);
 
        if (!PageUptodate(page)) {
@@ -2062,39 +2066,70 @@ static int cifs_write_begin(struct file *file, struct address_space *mapping,
 {
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
        loff_t offset = pos & (PAGE_CACHE_SIZE - 1);
+       loff_t page_start = pos & PAGE_MASK;
+       loff_t i_size;
+       struct page *page;
+       int rc = 0;
 
        cFYI(1, ("write_begin from %lld len %d", (long long)pos, len));
 
-       *pagep = __grab_cache_page(mapping, index);
-       if (!*pagep)
-               return -ENOMEM;
-
-       if (PageUptodate(*pagep))
-               return 0;
+       page = __grab_cache_page(mapping, index);
+       if (!page) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
-       /* If we are writing a full page it will be up to date,
-          no need to read from the server */
-       if (len == PAGE_CACHE_SIZE && flags & AOP_FLAG_UNINTERRUPTIBLE)
-               return 0;
+       if (PageUptodate(page))
+               goto out;
 
-       if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
-               int rc;
+       /*
+        * If we write a full page it will be up to date, no need to read from
+        * the server. If the write is short, we'll end up doing a sync write
+        * instead.
+        */
+       if (len == PAGE_CACHE_SIZE)
+               goto out;
 
-               /* might as well read a page, it is fast enough */
-               rc = cifs_readpage_worker(file, *pagep, &offset);
+       /*
+        * optimize away the read when we have an oplock, and we're not
+        * expecting to use any of the data we'd be reading in. That
+        * is, when the page lies beyond the EOF, or straddles the EOF
+        * and the write will cover all of the existing data.
+        */
+       if (CIFS_I(mapping->host)->clientCanCacheRead) {
+               i_size = i_size_read(mapping->host);
+               if (page_start >= i_size ||
+                   (offset == 0 && (pos + len) >= i_size)) {
+                       zero_user_segments(page, 0, offset,
+                                          offset + len,
+                                          PAGE_CACHE_SIZE);
+                       /*
+                        * PageChecked means that the parts of the page
+                        * to which we're not writing are considered up
+                        * to date. Once the data is copied to the
+                        * page, it can be set uptodate.
+                        */
+                       SetPageChecked(page);
+                       goto out;
+               }
+       }
 
-               /* we do not need to pass errors back
-                  e.g. if we do not have read access to the file
-                  because cifs_write_end will attempt synchronous writes
-                  -- shaggy */
+       if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
+               /*
+                * might as well read a page, it is fast enough. If we get
+                * an error, we don't need to return it. cifs_write_end will
+                * do a sync write instead since PG_uptodate isn't set.
+                */
+               cifs_readpage_worker(file, page, &page_start);
        } else {
                /* we could try using another file handle if there is one -
                   but how would we lock it to prevent close of that handle
                   racing with this read? In any case
                   this will be written out by write_end so is fine */
        }
-
-       return 0;
+out:
+       *pagep = page;
+       return rc;
 }
 
 const struct address_space_operations cifs_addr_ops = {
index 6e74b117aaf0e58d078e59d88817562de8379a1d..30ebde490f7f5ebc3a4b79331191706c180b5a8f 100644 (file)
@@ -106,6 +106,7 @@ void udf_clear_inode(struct inode *inode)
                udf_truncate_tail_extent(inode);
                unlock_kernel();
                write_inode_now(inode, 0);
+               invalidate_inode_buffers(inode);
        }
        iinfo = UDF_I(inode);
        kfree(iinfo->i_ext.i_data);
index 619fb75f8861b3822d8df03ab83bee0b809fe460..16a9ca9a66e41787ac62c5ded9a3201f780b4638 100644 (file)
@@ -167,7 +167,7 @@ static const union acpi_predefined_info predefined_names[] = {
        {.info = {"_BFS", 1, 0}},
        {.info = {"_BIF", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER,
                                          9,
-                                         ACPI_RTYPE_STRING, 4, 0}},    /* fixed (9 Int),(4 Str) */
+                                         ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 4, 0}},        /* fixed (9 Int),(4 Str) */
        {.info = {"_BLT", 3, 0}},
        {.info = {"_BMC", 1, 0}},
        {.info = {"_BMD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}},   /* fixed (5 Int) */
@@ -346,7 +346,7 @@ static const union acpi_predefined_info predefined_names[] = {
 
        /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */
 
-       {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_PACKAGE}},
+       {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}},
        {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}},      /* fixed (2 Int), but is optional */
        {.ret_info = {0, 0, 0, 0, 0, 0}}        /* Table terminator */
 };
index 28c7f1679d496f6981d0e14418ef29af448b5a0d..d5e8e5c8954825baaf69564e07716dd041ed0593 100644 (file)
@@ -1151,6 +1151,7 @@ extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
 extern void drm_handle_vblank(struct drm_device *dev, int crtc);
 extern int drm_vblank_get(struct drm_device *dev, int crtc);
 extern void drm_vblank_put(struct drm_device *dev, int crtc);
+extern void drm_vblank_cleanup(struct drm_device *dev);
 /* Modesetting support */
 extern int drm_modeset_ctl(struct drm_device *dev, void *data,
                           struct drm_file *file_priv);
index f061a1ea1b74d74fa7a3391bb47c6bbdca4d0b3e..e88f3ecf38b438e464fbac92a420ef9897c8e952 100644 (file)
@@ -252,12 +252,10 @@ extern int compat_ptrace_request(struct task_struct *child,
                                 compat_long_t request,
                                 compat_ulong_t addr, compat_ulong_t data);
 
-#ifdef __ARCH_WANT_COMPAT_SYS_PTRACE
 extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                               compat_ulong_t addr, compat_ulong_t data);
 asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
                                  compat_long_t addr, compat_long_t data);
-#endif /* __ARCH_WANT_COMPAT_SYS_PTRACE */
 
 /*
  * epoll (fs/eventpoll.c) compat bits follow ...
index 7dcbc82f3b7bf4a19969d0cf19824cf373a2a91b..13875ce9112ac0163b28e0816f20164e1ec39bae 100644 (file)
@@ -63,12 +63,14 @@ static inline void *kmap_atomic(struct page *page, enum km_type idx)
 #endif /* CONFIG_HIGHMEM */
 
 /* when CONFIG_HIGHMEM is not set these will be plain clear/copy_page */
+#ifndef clear_user_highpage
 static inline void clear_user_highpage(struct page *page, unsigned long vaddr)
 {
        void *addr = kmap_atomic(page, KM_USER0);
        clear_user_page(addr, vaddr, page);
        kunmap_atomic(addr, KM_USER0);
 }
+#endif
 
 #ifndef __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE
 /**
index d058c57be02d3508e27382e63980bfb593658649..3dddfa703ebd95ab1253c56397104c2607f98e90 100644 (file)
@@ -63,7 +63,8 @@ typedef       void (*irq_flow_handler_t)(unsigned int irq,
 #define IRQ_MOVE_PENDING       0x00200000      /* need to re-target IRQ destination */
 #define IRQ_NO_BALANCING       0x00400000      /* IRQ is excluded from balancing */
 #define IRQ_SPURIOUS_DISABLED  0x00800000      /* IRQ was disabled by the spurious trap */
-#define IRQ_MOVE_PCNTXT        0x01000000      /* IRQ migration from process context */
+#define IRQ_MOVE_PCNTXT                0x01000000      /* IRQ migration from process context */
+#define IRQ_AFFINITY_SET       0x02000000      /* IRQ affinity was set from userspace*/
 
 #ifdef CONFIG_IRQ_PER_CPU
 # define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
@@ -130,7 +131,7 @@ struct irq_chip {
 
 /**
  * struct irq_desc - interrupt descriptor
- *
+ * @irq:               interrupt number for this descriptor
  * @handle_irq:                highlevel irq-events handler [if NULL, __do_IRQ()]
  * @chip:              low level interrupt hardware access
  * @msi_desc:          MSI descriptor
@@ -149,7 +150,6 @@ struct irq_chip {
  * @cpu:               cpu index useful for balancing
  * @pending_mask:      pending rebalanced interrupts
  * @dir:               /proc/irq/ procfs entry
- * @affinity_entry:    /proc/irq/smp_affinity procfs entry on SMP
  * @name:              flow handler name for /proc/interrupts output
  */
 struct irq_desc {
@@ -210,7 +210,6 @@ extern int setup_irq(unsigned int irq, struct irqaction *new);
 
 #ifdef CONFIG_GENERIC_PENDING_IRQ
 
-void set_pending_irq(unsigned int irq, cpumask_t mask);
 void move_native_irq(int irq);
 void move_masked_irq(int irq);
 
@@ -228,10 +227,6 @@ static inline void move_masked_irq(int irq)
 {
 }
 
-static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
-{
-}
-
 #endif /* CONFIG_GENERIC_PENDING_IRQ */
 
 #else /* CONFIG_SMP */
index 2f5f8a5ef2a08a5e796294275ee095cae2319fd5..36c82c9e6ea70985243e56a2b41ac13fe060bd5b 100644 (file)
@@ -91,7 +91,7 @@ extern int memory_notify(unsigned long val, void *v);
 
 #ifdef CONFIG_MEMORY_HOTPLUG
 #define hotplug_memory_notifier(fn, pri) {                     \
-       static struct notifier_block fn##_mem_nb =              \
+       static __meminitdata struct notifier_block fn##_mem_nb =\
                { .notifier_call = fn, .priority = pri };       \
        register_memory_notifier(&fn##_mem_nb);                 \
 }
index 217bb22ebb8e81a532d7023312e64dba76776737..af95a1d2f3a11e333fbe6a00fcb2354f16657a2a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * audio.h  --  Audio Driver for Wolfson WM8350 PMIC
  *
- * Copyright 2007 Wolfson Microelectronics PLC
+ * Copyright 2007, 2008 Wolfson Microelectronics PLC
  *
  *  This program is free software; you can redistribute  it and/or modify it
  *  under  the terms of  the GNU General  Public License as published by the
@@ -70,9 +70,9 @@
 #define WM8350_CODEC_ISEL_0_5                   3      /* x0.5 */
 
 #define WM8350_VMID_OFF                         0
-#define WM8350_VMID_500K                        1
-#define WM8350_VMID_100K                        2
-#define WM8350_VMID_10K                         3
+#define WM8350_VMID_300K                        1
+#define WM8350_VMID_50K                         2
+#define WM8350_VMID_5K                          3
 
 /*
  * R40 (0x28) - Clock Control 1
 #define WM8350_IRQ_CODEC_MICSCD                        41
 #define WM8350_IRQ_CODEC_MICD                  42
 
+/*
+ * WM8350 Platform data.
+ *
+ * This must be initialised per platform for best audio performance.
+ * Please see WM8350 datasheet for information.
+ */
+struct wm8350_audio_platform_data {
+       int vmid_discharge_msecs;       /* VMID --> OFF discharge time */
+       int drain_msecs;        /* OFF drain time */
+       int cap_discharge_msecs;        /* Cap ON (from OFF) discharge time */
+       int vmid_charge_msecs;  /* vmid power up time */
+       u32 vmid_s_curve:2;     /* vmid enable s curve speed */
+       u32 dis_out4:2;         /* out4 discharge speed */
+       u32 dis_out3:2;         /* out3 discharge speed */
+       u32 dis_out2:2;         /* out2 discharge speed */
+       u32 dis_out1:2;         /* out1 discharge speed */
+       u32 vroi_out4:1;        /* out4 tie off */
+       u32 vroi_out3:1;        /* out3 tie off */
+       u32 vroi_out2:1;        /* out2 tie off */
+       u32 vroi_out1:1;        /* out1 tie off */
+       u32 vroi_enable:1;      /* enable tie off */
+       u32 codec_current_on:2; /* current level ON */
+       u32 codec_current_standby:2;    /* current level STANDBY */
+       u32 codec_current_charge:2;     /* codec current @ vmid charge */
+};
+
+struct snd_soc_codec;
+
 struct wm8350_codec {
        struct platform_device *pdev;
+       struct snd_soc_codec *codec;
+       struct wm8350_audio_platform_data *platform_data;
 };
 
 #endif
index f546ad6fc028d82989217eda2e8c8bb9bd5afa82..1e6d34bfa0945b5cdf5a7f8904e9fa182a80efa0 100644 (file)
@@ -17,7 +17,7 @@ struct page_cgroup {
        struct list_head lru;           /* per cgroup LRU list */
 };
 
-void __init pgdat_page_cgroup_init(struct pglist_data *pgdat);
+void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat);
 void __init page_cgroup_init(void);
 struct page_cgroup *lookup_page_cgroup(struct page *page);
 
@@ -91,7 +91,7 @@ static inline void unlock_page_cgroup(struct page_cgroup *pc)
 #else /* CONFIG_CGROUP_MEM_RES_CTLR */
 struct page_cgroup;
 
-static inline void pgdat_page_cgroup_init(struct pglist_data *pgdat)
+static inline void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat)
 {
 }
 
diff --git a/include/sound/l3.h b/include/sound/l3.h
new file mode 100644 (file)
index 0000000..423a08f
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef _L3_H_
+#define _L3_H_ 1
+
+struct l3_pins {
+       void (*setdat)(int);
+       void (*setclk)(int);
+       void (*setmode)(int);
+       int data_hold;
+       int data_setup;
+       int clock_high;
+       int mode_hold;
+       int mode;
+       int mode_setup;
+};
+
+int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len);
+
+#endif
diff --git a/include/sound/s3c24xx_uda134x.h b/include/sound/s3c24xx_uda134x.h
new file mode 100644 (file)
index 0000000..33df4cb
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _S3C24XX_UDA134X_H_
+#define _S3C24XX_UDA134X_H_ 1
+
+#include <sound/uda134x.h>
+
+struct s3c24xx_uda134x_platform_data {
+       int l3_clk;
+       int l3_mode;
+       int l3_data;
+       void (*power) (int);
+       int model;
+};
+
+#endif
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
new file mode 100644 (file)
index 0000000..24247f7
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * linux/sound/soc-dai.h -- ALSA SoC Layer
+ *
+ * Copyright:  2005-2008 Wolfson Microelectronics. PLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Digital Audio Interface (DAI) API.
+ */
+
+#ifndef __LINUX_SND_SOC_DAI_H
+#define __LINUX_SND_SOC_DAI_H
+
+
+#include <linux/list.h>
+
+struct snd_pcm_substream;
+
+/*
+ * DAI hardware audio formats.
+ *
+ * Describes the physical PCM data formating and clocking. Add new formats
+ * to the end.
+ */
+#define SND_SOC_DAIFMT_I2S             0 /* I2S mode */
+#define SND_SOC_DAIFMT_RIGHT_J         1 /* Right Justified mode */
+#define SND_SOC_DAIFMT_LEFT_J          2 /* Left Justified mode */
+#define SND_SOC_DAIFMT_DSP_A           3 /* L data msb after FRM LRC */
+#define SND_SOC_DAIFMT_DSP_B           4 /* L data msb during FRM LRC */
+#define SND_SOC_DAIFMT_AC97            5 /* AC97 */
+
+/* left and right justified also known as MSB and LSB respectively */
+#define SND_SOC_DAIFMT_MSB             SND_SOC_DAIFMT_LEFT_J
+#define SND_SOC_DAIFMT_LSB             SND_SOC_DAIFMT_RIGHT_J
+
+/*
+ * DAI Clock gating.
+ *
+ * DAI bit clocks can be be gated (disabled) when not the DAI is not
+ * sending or receiving PCM data in a frame. This can be used to save power.
+ */
+#define SND_SOC_DAIFMT_CONT            (0 << 4) /* continuous clock */
+#define SND_SOC_DAIFMT_GATED           (1 << 4) /* clock is gated */
+
+/*
+ * DAI Left/Right Clocks.
+ *
+ * Specifies whether the DAI can support different samples for similtanious
+ * playback and capture. This usually requires a seperate physical frame
+ * clock for playback and capture.
+ */
+#define SND_SOC_DAIFMT_SYNC            (0 << 5) /* Tx FRM = Rx FRM */
+#define SND_SOC_DAIFMT_ASYNC           (1 << 5) /* Tx FRM ~ Rx FRM */
+
+/*
+ * TDM
+ *
+ * Time Division Multiplexing. Allows PCM data to be multplexed with other
+ * data on the DAI.
+ */
+#define SND_SOC_DAIFMT_TDM             (1 << 6)
+
+/*
+ * DAI hardware signal inversions.
+ *
+ * Specifies whether the DAI can also support inverted clocks for the specified
+ * format.
+ */
+#define SND_SOC_DAIFMT_NB_NF           (0 << 8) /* normal bit clock + frame */
+#define SND_SOC_DAIFMT_NB_IF           (1 << 8) /* normal bclk + inv frm */
+#define SND_SOC_DAIFMT_IB_NF           (2 << 8) /* invert bclk + nor frm */
+#define SND_SOC_DAIFMT_IB_IF           (3 << 8) /* invert bclk + frm */
+
+/*
+ * DAI hardware clock masters.
+ *
+ * This is wrt the codec, the inverse is true for the interface
+ * i.e. if the codec is clk and frm master then the interface is
+ * clk and frame slave.
+ */
+#define SND_SOC_DAIFMT_CBM_CFM         (0 << 12) /* codec clk & frm master */
+#define SND_SOC_DAIFMT_CBS_CFM         (1 << 12) /* codec clk slave & frm master */
+#define SND_SOC_DAIFMT_CBM_CFS         (2 << 12) /* codec clk master & frame slave */
+#define SND_SOC_DAIFMT_CBS_CFS         (3 << 12) /* codec clk & frm slave */
+
+#define SND_SOC_DAIFMT_FORMAT_MASK     0x000f
+#define SND_SOC_DAIFMT_CLOCK_MASK      0x00f0
+#define SND_SOC_DAIFMT_INV_MASK                0x0f00
+#define SND_SOC_DAIFMT_MASTER_MASK     0xf000
+
+/*
+ * Master Clock Directions
+ */
+#define SND_SOC_CLOCK_IN               0
+#define SND_SOC_CLOCK_OUT              1
+
+struct snd_soc_dai_ops;
+struct snd_soc_dai;
+struct snd_ac97_bus_ops;
+
+/* Digital Audio Interface registration */
+int snd_soc_register_dai(struct snd_soc_dai *dai);
+void snd_soc_unregister_dai(struct snd_soc_dai *dai);
+int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count);
+void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count);
+
+/* Digital Audio Interface clocking API.*/
+int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+       unsigned int freq, int dir);
+
+int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
+       int div_id, int div);
+
+int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
+       int pll_id, unsigned int freq_in, unsigned int freq_out);
+
+/* Digital Audio interface formatting */
+int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
+
+int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
+       unsigned int mask, int slots);
+
+int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
+
+/* Digital Audio Interface mute */
+int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
+
+/*
+ * Digital Audio Interface.
+ *
+ * Describes the Digital Audio Interface in terms of it's ALSA, DAI and AC97
+ * operations an capabilities. Codec and platfom drivers will register a this
+ * structure for every DAI they have.
+ *
+ * This structure covers the clocking, formating and ALSA operations for each
+ * interface a
+ */
+struct snd_soc_dai_ops {
+       /*
+        * DAI clocking configuration, all optional.
+        * Called by soc_card drivers, normally in their hw_params.
+        */
+       int (*set_sysclk)(struct snd_soc_dai *dai,
+               int clk_id, unsigned int freq, int dir);
+       int (*set_pll)(struct snd_soc_dai *dai,
+               int pll_id, unsigned int freq_in, unsigned int freq_out);
+       int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
+
+       /*
+        * DAI format configuration
+        * Called by soc_card drivers, normally in their hw_params.
+        */
+       int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
+       int (*set_tdm_slot)(struct snd_soc_dai *dai,
+               unsigned int mask, int slots);
+       int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
+
+       /*
+        * DAI digital mute - optional.
+        * Called by soc-core to minimise any pops.
+        */
+       int (*digital_mute)(struct snd_soc_dai *dai, int mute);
+
+       /*
+        * ALSA PCM audio operations - all optional.
+        * Called by soc-core during audio PCM operations.
+        */
+       int (*startup)(struct snd_pcm_substream *,
+               struct snd_soc_dai *);
+       void (*shutdown)(struct snd_pcm_substream *,
+               struct snd_soc_dai *);
+       int (*hw_params)(struct snd_pcm_substream *,
+               struct snd_pcm_hw_params *, struct snd_soc_dai *);
+       int (*hw_free)(struct snd_pcm_substream *,
+               struct snd_soc_dai *);
+       int (*prepare)(struct snd_pcm_substream *,
+               struct snd_soc_dai *);
+       int (*trigger)(struct snd_pcm_substream *, int,
+               struct snd_soc_dai *);
+};
+
+/*
+ * Digital Audio Interface runtime data.
+ *
+ * Holds runtime data for a DAI.
+ */
+struct snd_soc_dai {
+       /* DAI description */
+       char *name;
+       unsigned int id;
+       int ac97_control;
+
+       struct device *dev;
+
+       /* DAI callbacks */
+       int (*probe)(struct platform_device *pdev,
+                    struct snd_soc_dai *dai);
+       void (*remove)(struct platform_device *pdev,
+                      struct snd_soc_dai *dai);
+       int (*suspend)(struct snd_soc_dai *dai);
+       int (*resume)(struct snd_soc_dai *dai);
+
+       /* ops */
+       struct snd_soc_dai_ops ops;
+
+       /* DAI capabilities */
+       struct snd_soc_pcm_stream capture;
+       struct snd_soc_pcm_stream playback;
+
+       /* DAI runtime info */
+       struct snd_pcm_runtime *runtime;
+       struct snd_soc_codec *codec;
+       unsigned int active;
+       unsigned char pop_wait:1;
+       void *dma_data;
+
+       /* DAI private data */
+       void *private_data;
+
+       /* parent codec/platform */
+       union {
+               struct snd_soc_codec *codec;
+               struct snd_soc_platform *platform;
+       };
+
+       struct list_head list;
+};
+
+#endif
index ca699a3017f39563fc8f6b1d4dc36841e724f125..7ee2f70ca42e9009038d02b60e147603ad919d13 100644 (file)
@@ -221,8 +221,6 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
        int num);
 
 /* dapm path setup */
-int  __deprecated snd_soc_dapm_connect_input(struct snd_soc_codec *codec,
-       const char *sink_name, const char *control_name, const char *src_name);
 int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec);
 void snd_soc_dapm_free(struct snd_soc_device *socdev);
 int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
index 5e0189876afda7a9d523ae705a113cce1be2c69d..f86e455d3828b222e6cab7331d6cbfda5fef0456 100644 (file)
@@ -21,8 +21,6 @@
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
 
-#define SND_SOC_VERSION "0.13.2"
-
 /*
  * Convenience kcontrol builders
  */
@@ -145,105 +143,31 @@ enum snd_soc_bias_level {
        SND_SOC_BIAS_OFF,
 };
 
-/*
- * Digital Audio Interface (DAI) types
- */
-#define SND_SOC_DAI_AC97       0x1
-#define SND_SOC_DAI_I2S                0x2
-#define SND_SOC_DAI_PCM                0x4
-#define SND_SOC_DAI_AC97_BUS   0x8     /* for custom i.e. non ac97_codec.c */
-
-/*
- * DAI hardware audio formats
- */
-#define SND_SOC_DAIFMT_I2S             0       /* I2S mode */
-#define SND_SOC_DAIFMT_RIGHT_J 1       /* Right justified mode */
-#define SND_SOC_DAIFMT_LEFT_J  2       /* Left Justified mode */
-#define SND_SOC_DAIFMT_DSP_A   3       /* L data msb after FRM or LRC */
-#define SND_SOC_DAIFMT_DSP_B   4       /* L data msb during FRM or LRC */
-#define SND_SOC_DAIFMT_AC97            5       /* AC97 */
-
-#define SND_SOC_DAIFMT_MSB     SND_SOC_DAIFMT_LEFT_J
-#define SND_SOC_DAIFMT_LSB     SND_SOC_DAIFMT_RIGHT_J
-
-/*
- * DAI Gating
- */
-#define SND_SOC_DAIFMT_CONT                    (0 << 4)        /* continuous clock */
-#define SND_SOC_DAIFMT_GATED           (1 << 4)        /* clock is gated when not Tx/Rx */
-
-/*
- * DAI Sync
- * Synchronous LR (Left Right) clocks and Frame signals.
- */
-#define SND_SOC_DAIFMT_SYNC            (0 << 5)        /* Tx FRM = Rx FRM */
-#define SND_SOC_DAIFMT_ASYNC           (1 << 5)        /* Tx FRM ~ Rx FRM */
-
-/*
- * TDM
- */
-#define SND_SOC_DAIFMT_TDM             (1 << 6)
-
-/*
- * DAI hardware signal inversions
- */
-#define SND_SOC_DAIFMT_NB_NF           (0 << 8)        /* normal bclk + frm */
-#define SND_SOC_DAIFMT_NB_IF           (1 << 8)        /* normal bclk + inv frm */
-#define SND_SOC_DAIFMT_IB_NF           (2 << 8)        /* invert bclk + nor frm */
-#define SND_SOC_DAIFMT_IB_IF           (3 << 8)        /* invert bclk + frm */
-
-/*
- * DAI hardware clock masters
- * This is wrt the codec, the inverse is true for the interface
- * i.e. if the codec is clk and frm master then the interface is
- * clk and frame slave.
- */
-#define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & frm master */
-#define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & frm master */
-#define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */
-#define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & frm slave */
-
-#define SND_SOC_DAIFMT_FORMAT_MASK             0x000f
-#define SND_SOC_DAIFMT_CLOCK_MASK              0x00f0
-#define SND_SOC_DAIFMT_INV_MASK                        0x0f00
-#define SND_SOC_DAIFMT_MASTER_MASK             0xf000
-
-
-/*
- * Master Clock Directions
- */
-#define SND_SOC_CLOCK_IN       0
-#define SND_SOC_CLOCK_OUT      1
-
-/*
- * AC97 codec ID's bitmask
- */
-#define SND_SOC_DAI_AC97_ID0   (1 << 0)
-#define SND_SOC_DAI_AC97_ID1   (1 << 1)
-#define SND_SOC_DAI_AC97_ID2   (1 << 2)
-#define SND_SOC_DAI_AC97_ID3   (1 << 3)
-
 struct snd_soc_device;
 struct snd_soc_pcm_stream;
 struct snd_soc_ops;
 struct snd_soc_dai_mode;
 struct snd_soc_pcm_runtime;
 struct snd_soc_dai;
+struct snd_soc_platform;
 struct snd_soc_codec;
-struct snd_soc_machine_config;
 struct soc_enum;
 struct snd_soc_ac97_ops;
-struct snd_soc_clock_info;
 
 typedef int (*hw_write_t)(void *,const char* ,int);
 typedef int (*hw_read_t)(void *,char* ,int);
 
 extern struct snd_ac97_bus_ops soc_ac97_ops;
 
+int snd_soc_register_platform(struct snd_soc_platform *platform);
+void snd_soc_unregister_platform(struct snd_soc_platform *platform);
+int snd_soc_register_codec(struct snd_soc_codec *codec);
+void snd_soc_unregister_codec(struct snd_soc_codec *codec);
+
 /* pcm <-> DAI connect */
 void snd_soc_free_pcms(struct snd_soc_device *socdev);
 int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid);
-int snd_soc_register_card(struct snd_soc_device *socdev);
+int snd_soc_init_card(struct snd_soc_device *socdev);
 
 /* set runtime hw params */
 int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
@@ -263,27 +187,6 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
        struct snd_ac97_bus_ops *ops, int num);
 void snd_soc_free_ac97_codec(struct snd_soc_codec *codec);
 
-/* Digital Audio Interface clocking API.*/
-int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
-       unsigned int freq, int dir);
-
-int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
-       int div_id, int div);
-
-int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
-       int pll_id, unsigned int freq_in, unsigned int freq_out);
-
-/* Digital Audio interface formatting */
-int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt);
-
-int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
-       unsigned int mask, int slots);
-
-int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate);
-
-/* Digital Audio Interface mute */
-int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute);
-
 /*
  *Controls
  */
@@ -341,66 +244,14 @@ struct snd_soc_ops {
        int (*trigger)(struct snd_pcm_substream *, int);
 };
 
-/* ASoC DAI ops */
-struct snd_soc_dai_ops {
-       /* DAI clocking configuration */
-       int (*set_sysclk)(struct snd_soc_dai *dai,
-               int clk_id, unsigned int freq, int dir);
-       int (*set_pll)(struct snd_soc_dai *dai,
-               int pll_id, unsigned int freq_in, unsigned int freq_out);
-       int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);
-
-       /* DAI format configuration */
-       int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);
-       int (*set_tdm_slot)(struct snd_soc_dai *dai,
-               unsigned int mask, int slots);
-       int (*set_tristate)(struct snd_soc_dai *dai, int tristate);
-
-       /* digital mute */
-       int (*digital_mute)(struct snd_soc_dai *dai, int mute);
-};
-
-/* SoC  DAI (Digital Audio Interface) */
-struct snd_soc_dai {
-       /* DAI description */
-       char *name;
-       unsigned int id;
-       unsigned char type;
-
-       /* DAI callbacks */
-       int (*probe)(struct platform_device *pdev,
-                    struct snd_soc_dai *dai);
-       void (*remove)(struct platform_device *pdev,
-                      struct snd_soc_dai *dai);
-       int (*suspend)(struct platform_device *pdev,
-               struct snd_soc_dai *dai);
-       int (*resume)(struct platform_device *pdev,
-               struct snd_soc_dai *dai);
-
-       /* ops */
-       struct snd_soc_ops ops;
-       struct snd_soc_dai_ops dai_ops;
-
-       /* DAI capabilities */
-       struct snd_soc_pcm_stream capture;
-       struct snd_soc_pcm_stream playback;
-
-       /* DAI runtime info */
-       struct snd_pcm_runtime *runtime;
-       struct snd_soc_codec *codec;
-       unsigned int active;
-       unsigned char pop_wait:1;
-       void *dma_data;
-
-       /* DAI private data */
-       void *private_data;
-};
-
 /* SoC Audio Codec */
 struct snd_soc_codec {
        char *name;
        struct module *owner;
        struct mutex mutex;
+       struct device *dev;
+
+       struct list_head list;
 
        /* callbacks */
        int (*set_bias_level)(struct snd_soc_codec *,
@@ -426,6 +277,7 @@ struct snd_soc_codec {
        short reg_cache_step;
 
        /* dapm */
+       u32 pop_time;
        struct list_head dapm_widgets;
        struct list_head dapm_paths;
        enum snd_soc_bias_level bias_level;
@@ -435,6 +287,11 @@ struct snd_soc_codec {
        /* codec DAI's */
        struct snd_soc_dai *dai;
        unsigned int num_dai;
+
+#ifdef CONFIG_DEBUG_FS
+       struct dentry *debugfs_reg;
+       struct dentry *debugfs_pop_time;
+#endif
 };
 
 /* codec device */
@@ -448,13 +305,12 @@ struct snd_soc_codec_device {
 /* SoC platform interface */
 struct snd_soc_platform {
        char *name;
+       struct list_head list;
 
        int (*probe)(struct platform_device *pdev);
        int (*remove)(struct platform_device *pdev);
-       int (*suspend)(struct platform_device *pdev,
-               struct snd_soc_dai *dai);
-       int (*resume)(struct platform_device *pdev,
-               struct snd_soc_dai *dai);
+       int (*suspend)(struct snd_soc_dai *dai);
+       int (*resume)(struct snd_soc_dai *dai);
 
        /* pcm creation and destruction */
        int (*pcm_new)(struct snd_card *, struct snd_soc_dai *,
@@ -484,9 +340,14 @@ struct snd_soc_dai_link  {
        struct snd_pcm *pcm;
 };
 
-/* SoC machine */
-struct snd_soc_machine {
+/* SoC card */
+struct snd_soc_card {
        char *name;
+       struct device *dev;
+
+       struct list_head list;
+
+       int instantiated;
 
        int (*probe)(struct platform_device *pdev);
        int (*remove)(struct platform_device *pdev);
@@ -499,23 +360,26 @@ struct snd_soc_machine {
        int (*resume_post)(struct platform_device *pdev);
 
        /* callbacks */
-       int (*set_bias_level)(struct snd_soc_machine *,
+       int (*set_bias_level)(struct snd_soc_card *,
                              enum snd_soc_bias_level level);
 
        /* CPU <--> Codec DAI links  */
        struct snd_soc_dai_link *dai_link;
        int num_links;
+
+       struct snd_soc_device *socdev;
+
+       struct snd_soc_platform *platform;
+       struct delayed_work delayed_work;
+       struct work_struct deferred_resume_work;
 };
 
 /* SoC Device - the audio subsystem */
 struct snd_soc_device {
        struct device *dev;
-       struct snd_soc_machine *machine;
-       struct snd_soc_platform *platform;
+       struct snd_soc_card *card;
        struct snd_soc_codec *codec;
        struct snd_soc_codec_device *codec_dev;
-       struct delayed_work delayed_work;
-       struct work_struct deferred_resume_work;
        void *codec_data;
 };
 
@@ -542,4 +406,6 @@ struct soc_enum {
        void *dapm;
 };
 
+#include <sound/soc-dai.h>
+
 #endif
diff --git a/include/sound/uda134x.h b/include/sound/uda134x.h
new file mode 100644 (file)
index 0000000..475ef8b
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * uda134x.h  --  UDA134x ALSA SoC Codec driver
+ *
+ * Copyright 2007 Dension Audio Systems Ltd.
+ * Author: Zoltan Devai
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _UDA134X_H
+#define _UDA134X_H
+
+#include <sound/l3.h>
+
+struct uda134x_platform_data {
+       struct l3_pins l3;
+       void (*power) (int);
+       int model;
+#define UDA134X_UDA1340 1
+#define UDA134X_UDA1341 2
+#define UDA134X_UDA1344 3
+};
+
+#endif /* _UDA134X_H */
index 5a732c5ef08b709dd2b7f6162432dfce3076fd11..8ea32e8d68b05c95b211830deee92d9a7929637b 100644 (file)
@@ -462,7 +462,7 @@ out:
  * It must be called by the arch code on the new cpu, before the new cpu
  * enables interrupts and before the "boot" cpu returns from __cpu_up().
  */
-void notify_cpu_starting(unsigned int cpu)
+void __cpuinit notify_cpu_starting(unsigned int cpu)
 {
        unsigned long val = CPU_STARTING;
 
index da7ff6137f375d44d7bf33dc8e10bd0e1751f89f..96c0ba13b8cd06add25de5043547b62cef6ef7b5 100644 (file)
@@ -585,7 +585,7 @@ static int generate_sched_domains(cpumask_t **domains,
        int i, j, k;            /* indices for partition finding loops */
        cpumask_t *doms;        /* resulting partition; i.e. sched domains */
        struct sched_domain_attr *dattr;  /* attributes for custom domains */
-       int ndoms;              /* number of sched domains in result */
+       int ndoms = 0;          /* number of sched domains in result */
        int nslot;              /* next empty doms[] cpumask_t slot */
 
        doms = NULL;
index c9767e641980e1b2ae91454fe723088ad9cc5f83..64c1c7253dae091b931652aa235ba3c44b6060c5 100644 (file)
@@ -25,6 +25,8 @@ static inline void unregister_handler_proc(unsigned int irq,
                                           struct irqaction *action) { }
 #endif
 
+extern int irq_select_affinity_usr(unsigned int irq);
+
 /*
  * Debugging printout:
  */
index c498a1b8c621e02894974b7f0e0cda8e96d81011..801addda3c43d4a7a767b27468fee05232cb6f89 100644 (file)
@@ -82,24 +82,27 @@ int irq_can_set_affinity(unsigned int irq)
 int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
 {
        struct irq_desc *desc = irq_to_desc(irq);
+       unsigned long flags;
 
        if (!desc->chip->set_affinity)
                return -EINVAL;
 
+       spin_lock_irqsave(&desc->lock, flags);
+
 #ifdef CONFIG_GENERIC_PENDING_IRQ
        if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) {
-               unsigned long flags;
-
-               spin_lock_irqsave(&desc->lock, flags);
                desc->affinity = cpumask;
                desc->chip->set_affinity(irq, cpumask);
-               spin_unlock_irqrestore(&desc->lock, flags);
-       } else
-               set_pending_irq(irq, cpumask);
+       } else {
+               desc->status |= IRQ_MOVE_PENDING;
+               desc->pending_mask = cpumask;
+       }
 #else
        desc->affinity = cpumask;
        desc->chip->set_affinity(irq, cpumask);
 #endif
+       desc->status |= IRQ_AFFINITY_SET;
+       spin_unlock_irqrestore(&desc->lock, flags);
        return 0;
 }
 
@@ -107,24 +110,59 @@ int irq_set_affinity(unsigned int irq, cpumask_t cpumask)
 /*
  * Generic version of the affinity autoselector.
  */
-int irq_select_affinity(unsigned int irq)
+int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc)
 {
        cpumask_t mask;
-       struct irq_desc *desc;
 
        if (!irq_can_set_affinity(irq))
                return 0;
 
        cpus_and(mask, cpu_online_map, irq_default_affinity);
 
-       desc = irq_to_desc(irq);
+       /*
+        * Preserve an userspace affinity setup, but make sure that
+        * one of the targets is online.
+        */
+       if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) {
+               if (cpus_intersects(desc->affinity, cpu_online_map))
+                       mask = desc->affinity;
+               else
+                       desc->status &= ~IRQ_AFFINITY_SET;
+       }
+
        desc->affinity = mask;
        desc->chip->set_affinity(irq, mask);
 
        return 0;
 }
+#else
+static inline int do_irq_select_affinity(unsigned int irq, struct irq_desc *d)
+{
+       return irq_select_affinity(irq);
+}
 #endif
 
+/*
+ * Called when affinity is set via /proc/irq
+ */
+int irq_select_affinity_usr(unsigned int irq)
+{
+       struct irq_desc *desc = irq_to_desc(irq);
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&desc->lock, flags);
+       ret = do_irq_select_affinity(irq, desc);
+       spin_unlock_irqrestore(&desc->lock, flags);
+
+       return ret;
+}
+
+#else
+static inline int do_irq_select_affinity(int irq, struct irq_desc *desc)
+{
+       return 0;
+}
 #endif
 
 /**
@@ -327,7 +365,7 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
                 * IRQF_TRIGGER_* but the PIC does not support multiple
                 * flow-types?
                 */
-               pr_warning("No set_type function for IRQ %d (%s)\n", irq,
+               pr_debug("No set_type function for IRQ %d (%s)\n", irq,
                                chip ? (chip->name ? : "unknown") : "unknown");
                return 0;
        }
@@ -445,8 +483,12 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
                        /* Undo nested disables: */
                        desc->depth = 1;
 
+               /* Exclude IRQ from balancing if requested */
+               if (new->flags & IRQF_NOBALANCING)
+                       desc->status |= IRQ_NO_BALANCING;
+
                /* Set default affinity mask once everything is setup */
-               irq_select_affinity(irq);
+               do_irq_select_affinity(irq, desc);
 
        } else if ((new->flags & IRQF_TRIGGER_MASK)
                        && (new->flags & IRQF_TRIGGER_MASK)
@@ -459,10 +501,6 @@ __setup_irq(unsigned int irq, struct irq_desc * desc, struct irqaction *new)
 
        *p = new;
 
-       /* Exclude IRQ from balancing */
-       if (new->flags & IRQF_NOBALANCING)
-               desc->status |= IRQ_NO_BALANCING;
-
        /* Reset broken irq detection when installing new handler */
        desc->irq_count = 0;
        desc->irqs_unhandled = 0;
index 90b920d3f52b3ca29f69cc204ab2481f4d95d4f6..9db681d95814baa2662fdccba0755b09579577cf 100644 (file)
@@ -1,17 +1,6 @@
 
 #include <linux/irq.h>
 
-void set_pending_irq(unsigned int irq, cpumask_t mask)
-{
-       struct irq_desc *desc = irq_to_desc(irq);
-       unsigned long flags;
-
-       spin_lock_irqsave(&desc->lock, flags);
-       desc->status |= IRQ_MOVE_PENDING;
-       desc->pending_mask = mask;
-       spin_unlock_irqrestore(&desc->lock, flags);
-}
-
 void move_masked_irq(int irq)
 {
        struct irq_desc *desc = irq_to_desc(irq);
index 4d161c70ba558507dc9be80537a50215052bd52f..d257e7d6a8a4ba4b10504dcd8490c812fe37504c 100644 (file)
@@ -62,7 +62,7 @@ static ssize_t irq_affinity_proc_write(struct file *file,
        if (!cpus_intersects(new_value, cpu_online_map))
                /* Special case for empty set - allow the architecture
                   code to set default SMP affinity. */
-               return irq_select_affinity(irq) ? -EINVAL : count;
+               return irq_select_affinity_usr(irq) ? -EINVAL : count;
 
        irq_set_affinity(irq, new_value);
 
index 06e157119d2b24d2b254c9a38b5ace0935a05886..46a404173db231a982baf3941c72e96911003906 100644 (file)
@@ -3276,10 +3276,10 @@ void __init lockdep_info(void)
 {
        printk("Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar\n");
 
-       printk("... MAX_LOCKDEP_SUBCLASSES:    %lu\n", MAX_LOCKDEP_SUBCLASSES);
+       printk("... MAX_LOCKDEP_SUBCLASSES:  %lu\n", MAX_LOCKDEP_SUBCLASSES);
        printk("... MAX_LOCK_DEPTH:          %lu\n", MAX_LOCK_DEPTH);
        printk("... MAX_LOCKDEP_KEYS:        %lu\n", MAX_LOCKDEP_KEYS);
-       printk("... CLASSHASH_SIZE:           %lu\n", CLASSHASH_SIZE);
+       printk("... CLASSHASH_SIZE:          %lu\n", CLASSHASH_SIZE);
        printk("... MAX_LOCKDEP_ENTRIES:     %lu\n", MAX_LOCKDEP_ENTRIES);
        printk("... MAX_LOCKDEP_CHAINS:      %lu\n", MAX_LOCKDEP_CHAINS);
        printk("... CHAINHASH_SIZE:          %lu\n", CHAINHASH_SIZE);
index 5b7d1ac7124c97e884d25c57bbf770f9f858d26f..dc41827fbfeea474c809ebc3adb6e54edcedb861 100644 (file)
@@ -351,7 +351,7 @@ out:
        put_cpu();
 }
 
-static int __devinit profile_cpu_callback(struct notifier_block *info,
+static int __cpuinit profile_cpu_callback(struct notifier_block *info,
                                        unsigned long action, void *__cpu)
 {
        int node, cpu = (unsigned long)__cpu;
@@ -596,7 +596,7 @@ out_cleanup:
 #define create_hash_tables()                   ({ 0; })
 #endif
 
-int create_proc_profile(void)
+int __ref create_proc_profile(void) /* false positive from hotcpu_notifier */
 {
        struct proc_dir_entry *entry;
 
index 1e68e4c39e2c05306dbfd9d111ef018aa0f8d9ca..4c8bcd7dd8e0831aa7a66e5c200324cff682721f 100644 (file)
@@ -612,7 +612,7 @@ int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
        return (copied == sizeof(data)) ? 0 : -EIO;
 }
 
-#if defined CONFIG_COMPAT && defined __ARCH_WANT_COMPAT_SYS_PTRACE
+#if defined CONFIG_COMPAT
 #include <linux/compat.h>
 
 int compat_ptrace_request(struct task_struct *child, compat_long_t request,
@@ -709,4 +709,4 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
        unlock_kernel();
        return ret;
 }
-#endif /* CONFIG_COMPAT && __ARCH_WANT_COMPAT_SYS_PTRACE */
+#endif /* CONFIG_COMPAT */
index 9b1e79371c207b37c1617d3f7c0460709a3cc39b..b7480fb5c3dc21a7bf6513a978cf0ed2e8c19a8f 100644 (file)
@@ -1453,9 +1453,10 @@ static int task_hot(struct task_struct *p, u64 now, struct sched_domain *sd);
 static unsigned long cpu_avg_load_per_task(int cpu)
 {
        struct rq *rq = cpu_rq(cpu);
+       unsigned long nr_running = ACCESS_ONCE(rq->nr_running);
 
-       if (rq->nr_running)
-               rq->avg_load_per_task = rq->load.weight / rq->nr_running;
+       if (nr_running)
+               rq->avg_load_per_task = rq->load.weight / nr_running;
        else
                rq->avg_load_per_task = 0;
 
index f780e9552f913e5b9674a218b148f27364e82723..668bbb5ef2bd154dc8084fe4480bfd251e484f41 100644 (file)
@@ -1215,7 +1215,7 @@ ring_buffer_lock_reserve(struct ring_buffer *buffer,
 
  out:
        if (resched)
-               preempt_enable_notrace();
+               preempt_enable_no_resched_notrace();
        else
                preempt_enable_notrace();
        return NULL;
index f28484618ff0de99b0c9d5062f23fe8eec25070a..e62cbf78eab6d6a6270a2a5c97f4ffc7ac443525 100644 (file)
@@ -18,12 +18,14 @@ struct header_iter {
 
 static struct trace_array *mmio_trace_array;
 static bool overrun_detected;
+static unsigned long prev_overruns;
 
 static void mmio_reset_data(struct trace_array *tr)
 {
        int cpu;
 
        overrun_detected = false;
+       prev_overruns = 0;
        tr->time_start = ftrace_now(tr->cpu);
 
        for_each_online_cpu(cpu)
@@ -128,16 +130,12 @@ static void mmio_close(struct trace_iterator *iter)
 
 static unsigned long count_overruns(struct trace_iterator *iter)
 {
-       int cpu;
        unsigned long cnt = 0;
-/* FIXME: */
-#if 0
-       for_each_online_cpu(cpu) {
-               cnt += iter->overrun[cpu];
-               iter->overrun[cpu] = 0;
-       }
-#endif
-       (void)cpu;
+       unsigned long over = ring_buffer_overruns(iter->tr->buffer);
+
+       if (over > prev_overruns)
+               cnt = over - prev_overruns;
+       prev_overruns = over;
        return cnt;
 }
 
index be682b62fe586285c77c36d7e7c6d6beb929541f..3bdb44bde4b7e5fa4af698c467f0c64b704e7699 100644 (file)
@@ -184,11 +184,16 @@ static struct file_operations stack_max_size_fops = {
 static void *
 t_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       long i = (long)m->private;
+       long i;
 
        (*pos)++;
 
-       i++;
+       if (v == SEQ_START_TOKEN)
+               i = 0;
+       else {
+               i = *(long *)v;
+               i++;
+       }
 
        if (i >= max_stack_trace.nr_entries ||
            stack_dump_trace[i] == ULONG_MAX)
@@ -201,12 +206,15 @@ t_next(struct seq_file *m, void *v, loff_t *pos)
 
 static void *t_start(struct seq_file *m, loff_t *pos)
 {
-       void *t = &m->private;
+       void *t = SEQ_START_TOKEN;
        loff_t l = 0;
 
        local_irq_disable();
        __raw_spin_lock(&max_stack_lock);
 
+       if (*pos == 0)
+               return SEQ_START_TOKEN;
+
        for (; t && l < *pos; t = t_next(m, t, &l))
                ;
 
@@ -235,10 +243,10 @@ static int trace_lookup_stack(struct seq_file *m, long i)
 
 static int t_show(struct seq_file *m, void *v)
 {
-       long i = *(long *)v;
+       long i;
        int size;
 
-       if (i < 0) {
+       if (v == SEQ_START_TOKEN) {
                seq_printf(m, "        Depth   Size      Location"
                           "    (%d entries)\n"
                           "        -----   ----      --------\n",
@@ -246,6 +254,8 @@ static int t_show(struct seq_file *m, void *v)
                return 0;
        }
 
+       i = *(long *)v;
+
        if (i >= max_stack_trace.nr_entries ||
            stack_dump_trace[i] == ULONG_MAX)
                return 0;
@@ -275,10 +285,6 @@ static int stack_trace_open(struct inode *inode, struct file *file)
        int ret;
 
        ret = seq_open(file, &stack_trace_seq_ops);
-       if (!ret) {
-               struct seq_file *m = file->private_data;
-               m->private = (void *)-1;
-       }
 
        return ret;
 }
index b5b2b15085a85383b1d8d14d8eff9ed2bf397611..b17371185468c7d00295d578d02f93508adba359 100644 (file)
@@ -189,7 +189,7 @@ static void grow_pgdat_span(struct pglist_data *pgdat, unsigned long start_pfn,
                                        pgdat->node_start_pfn;
 }
 
-static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
+static int __meminit __add_zone(struct zone *zone, unsigned long phys_start_pfn)
 {
        struct pglist_data *pgdat = zone->zone_pgdat;
        int nr_pages = PAGES_PER_SECTION;
@@ -216,7 +216,7 @@ static int __add_zone(struct zone *zone, unsigned long phys_start_pfn)
        return 0;
 }
 
-static int __add_section(struct zone *zone, unsigned long phys_start_pfn)
+static int __meminit __add_section(struct zone *zone, unsigned long phys_start_pfn)
 {
        int nr_pages = PAGES_PER_SECTION;
        int ret;
@@ -273,7 +273,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms)
  * call this function after deciding the zone to which to
  * add the new pages.
  */
-int __add_pages(struct zone *zone, unsigned long phys_start_pfn,
+int __ref __add_pages(struct zone *zone, unsigned long phys_start_pfn,
                 unsigned long nr_pages)
 {
        unsigned long i;
@@ -470,7 +470,8 @@ static void rollback_node_hotadd(int nid, pg_data_t *pgdat)
 }
 
 
-int add_memory(int nid, u64 start, u64 size)
+/* we are OK calling __meminit stuff here - we have CONFIG_MEMORY_HOTPLUG */
+int __ref add_memory(int nid, u64 start, u64 size)
 {
        pg_data_t *pgdat = NULL;
        int new_pgdat = 0;
index 1223d927904d196d652911e222bc4a50140c627b..436c00229e703f2d588e5064cb13592b9df014b3 100644 (file)
@@ -21,7 +21,7 @@ static unsigned long total_usage;
 #if !defined(CONFIG_SPARSEMEM)
 
 
-void __init pgdat_page_cgroup_init(struct pglist_data *pgdat)
+void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat)
 {
        pgdat->node_page_cgroup = NULL;
 }
@@ -97,7 +97,8 @@ struct page_cgroup *lookup_page_cgroup(struct page *page)
        return section->page_cgroup + pfn;
 }
 
-int __meminit init_section_page_cgroup(unsigned long pfn)
+/* __alloc_bootmem...() is protected by !slab_available() */
+int __init_refok init_section_page_cgroup(unsigned long pfn)
 {
        struct mem_section *section;
        struct page_cgroup *base, *pc;
@@ -158,7 +159,7 @@ void __free_page_cgroup(unsigned long pfn)
        }
 }
 
-int online_page_cgroup(unsigned long start_pfn,
+int __meminit online_page_cgroup(unsigned long start_pfn,
                        unsigned long nr_pages,
                        int nid)
 {
@@ -183,7 +184,7 @@ int online_page_cgroup(unsigned long start_pfn,
        return -ENOMEM;
 }
 
-int offline_page_cgroup(unsigned long start_pfn,
+int __meminit offline_page_cgroup(unsigned long start_pfn,
                unsigned long nr_pages, int nid)
 {
        unsigned long start, end, pfn;
@@ -197,7 +198,7 @@ int offline_page_cgroup(unsigned long start_pfn,
 
 }
 
-static int page_cgroup_callback(struct notifier_block *self,
+static int __meminit page_cgroup_callback(struct notifier_block *self,
                               unsigned long action, void *arg)
 {
        struct memory_notify *mn = arg;
@@ -248,7 +249,7 @@ void __init page_cgroup_init(void)
        " want\n");
 }
 
-void __init pgdat_page_cgroup_init(struct pglist_data *pgdat)
+void __meminit pgdat_page_cgroup_init(struct pglist_data *pgdat)
 {
        return;
 }
index 39db301b920d18383c8cac57416ad57f8f4976ca..083f5b63e7a8bdb8ab5196e11970691c2bd351d4 100644 (file)
@@ -570,7 +570,7 @@ static void free_section_usemap(struct page *memmap, unsigned long *usemap)
  * set.  If this is <=0, then that means that the passed-in
  * map was not consumed and must be freed.
  */
-int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
+int __meminit sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
                           int nr_pages)
 {
        unsigned long section_nr = pfn_to_section_nr(start_pfn);
index 7ea1440b53db23350112cb1a46c592542807e4ac..62e7f62fb559c7a09b5b15b4d7a0b3a7b5b4c5e5 100644 (file)
@@ -1248,6 +1248,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
                list_add(&page->lru, &l_inactive);
        }
 
+       spin_lock_irq(&zone->lru_lock);
        /*
         * Count referenced pages from currently used mappings as
         * rotated, even though they are moved to the inactive list.
@@ -1263,7 +1264,6 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
 
        pgmoved = 0;
        lru = LRU_BASE + file * LRU_FILE;
-       spin_lock_irq(&zone->lru_lock);
        while (!list_empty(&l_inactive)) {
                page = lru_to_page(&l_inactive);
                prefetchw_prev_lru_page(page, &l_inactive, flags);
index ba1ab737b55fe44010700aad11a3b316de91e861..eb9164176dab4e3fd0ccb006b77ac5f2eff6dcab 100644 (file)
@@ -1436,12 +1436,12 @@ static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
 {
        hda_nid_t *d;
 
-       snd_hda_codec_write(codec, nid, 0, verb, val);
+       snd_hda_codec_write_cache(codec, nid, 0, verb, val);
        d = codec->slave_dig_outs;
        if (!d)
                return;
        for (; *d; d++)
-               snd_hda_codec_write(codec, *d, 0, verb, val);
+               snd_hda_codec_write_cache(codec, *d, 0, verb, val);
 }
 
 static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
index 9563b5bbb272f41dda83997ceaf97bba7484af22..5dd3e89f620a2753511097d1fe86b4e6673afefa 100644 (file)
@@ -70,7 +70,9 @@ enum {
 
 enum {
        STAC_92HD73XX_REF,
-       STAC_DELL_M6,
+       STAC_DELL_M6_AMIC,
+       STAC_DELL_M6_DMIC,
+       STAC_DELL_M6_BOTH,
        STAC_DELL_EQ,
        STAC_92HD73XX_MODELS
 };
@@ -84,6 +86,7 @@ enum {
        STAC_92HD71BXX_REF,
        STAC_DELL_M4_1,
        STAC_DELL_M4_2,
+       STAC_DELL_M4_3,
        STAC_HP_M4,
        STAC_92HD71BXX_MODELS
 };
@@ -137,6 +140,7 @@ struct sigmatel_spec {
        unsigned int num_mixers;
 
        int board_config;
+       unsigned int eapd_switch: 1;
        unsigned int surr_switch: 1;
        unsigned int line_switch: 1;
        unsigned int mic_switch: 1;
@@ -1600,13 +1604,17 @@ static unsigned int dell_m6_pin_configs[13] = {
 
 static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
        [STAC_92HD73XX_REF]     = ref92hd73xx_pin_configs,
-       [STAC_DELL_M6]  = dell_m6_pin_configs,
+       [STAC_DELL_M6_AMIC]     = dell_m6_pin_configs,
+       [STAC_DELL_M6_DMIC]     = dell_m6_pin_configs,
+       [STAC_DELL_M6_BOTH]     = dell_m6_pin_configs,
        [STAC_DELL_EQ]  = dell_m6_pin_configs,
 };
 
 static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
        [STAC_92HD73XX_REF] = "ref",
-       [STAC_DELL_M6] = "dell-m6",
+       [STAC_DELL_M6_AMIC] = "dell-m6-amic",
+       [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
+       [STAC_DELL_M6_BOTH] = "dell-m6",
        [STAC_DELL_EQ] = "dell-eq",
 };
 
@@ -1615,19 +1623,23 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
        SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
                                "DFI LanParty", STAC_92HD73XX_REF),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254,
-                               "unknown Dell", STAC_DELL_M6),
+                               "Dell Studio 1535", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_DMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_BOTH),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_BOTH),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_AMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_AMIC),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271,
-                               "unknown Dell", STAC_DELL_M6),
+                               "unknown Dell", STAC_DELL_M6_DMIC),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0272,
+                               "unknown Dell", STAC_DELL_M6_DMIC),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
+                               "Dell Studio 1537", STAC_DELL_M6_DMIC),
        {} /* terminator */
 };
 
@@ -1670,10 +1682,17 @@ static unsigned int dell_m4_2_pin_configs[11] = {
        0x40f000f0, 0x044413b0, 0x044413b0,
 };
 
+static unsigned int dell_m4_3_pin_configs[11] = {
+       0x0421101f, 0x04a11221, 0x90a70330, 0x90170110,
+       0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0,
+       0x40f000f0, 0x044413b0, 0x044413b0,
+};
+
 static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
        [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs,
        [STAC_DELL_M4_1]        = dell_m4_1_pin_configs,
        [STAC_DELL_M4_2]        = dell_m4_2_pin_configs,
+       [STAC_DELL_M4_3]        = dell_m4_3_pin_configs,
        [STAC_HP_M4]            = NULL,
 };
 
@@ -1681,6 +1700,7 @@ static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
        [STAC_92HD71BXX_REF] = "ref",
        [STAC_DELL_M4_1] = "dell-m4-1",
        [STAC_DELL_M4_2] = "dell-m4-2",
+       [STAC_DELL_M4_3] = "dell-m4-3",
        [STAC_HP_M4] = "hp-m4",
 };
 
@@ -1716,6 +1736,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
                                "unknown Dell", STAC_DELL_M4_2),
        SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264,
                                "unknown Dell", STAC_DELL_M4_2),
+       SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02aa,
+                               "unknown Dell", STAC_DELL_M4_3),
        {} /* terminator */
 };
 
@@ -2877,7 +2899,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
                        cfg->hp_outs && !spec->multiout.hp_nid)
                spec->multiout.hp_nid = nid;
 
-       if (cfg->hp_outs > 1) {
+       if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
                err = stac92xx_add_control(spec,
                        STAC_CTL_WIDGET_HP_SWITCH,
                        "Headphone as Line Out Switch",
@@ -3683,10 +3705,14 @@ static void stac92xx_power_down(struct hda_codec *codec)
                                        AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
 }
 
+static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
+                                 int enable);
+
 static int stac92xx_init(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec = codec->spec;
        struct auto_pin_cfg *cfg = &spec->autocfg;
+       unsigned int gpio;
        int i;
 
        snd_hda_sequence_write(codec, spec->init);
@@ -3697,6 +3723,16 @@ static int stac92xx_init(struct hda_codec *codec)
                        snd_hda_codec_write_cache(codec,
                                spec->adc_nids[i], 0,
                                AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
+
+       /* set up GPIO */
+       gpio = spec->gpio_data;
+       /* turn on EAPD statically when spec->eapd_switch isn't set.
+        * otherwise, unsol event will turn it on/off dynamically
+        */
+       if (!spec->eapd_switch)
+               gpio |= spec->eapd_mask;
+       stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, gpio);
+
        /* set up pins */
        if (spec->hp_detect) {
                /* Enable unsolicited responses on the HP widget */
@@ -3736,39 +3772,43 @@ static int stac92xx_init(struct hda_codec *codec)
        for (i = 0; i < spec->num_dmics; i++)
                stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
                                        AC_PINCTL_IN_EN);
+       if (cfg->dig_out_pin)
+               stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
+                                        AC_PINCTL_OUT_EN);
+       if (cfg->dig_in_pin)
+               stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
+                                        AC_PINCTL_IN_EN);
        for (i = 0; i < spec->num_pwrs; i++)  {
-               int event = is_nid_hp_pin(cfg, spec->pwr_nids[i])
-                                       ? STAC_HP_EVENT : STAC_PWR_EVENT;
-               int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i],
-                                       0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-               int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i],
-                                       0, AC_VERB_GET_CONFIG_DEFAULT, 0);
-               def_conf = get_defcfg_connect(def_conf);
+               hda_nid_t nid = spec->pwr_nids[i];
+               int pinctl, def_conf;
+               int event = STAC_PWR_EVENT;
+
+               if (is_nid_hp_pin(cfg, nid) && spec->hp_detect)
+                       continue; /* already has an unsol event */
+
+               pinctl = snd_hda_codec_read(codec, nid, 0,
+                                           AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
                /* outputs are only ports capable of power management
                 * any attempts on powering down a input port cause the
                 * referenced VREF to act quirky.
                 */
                if (pinctl & AC_PINCTL_IN_EN)
                        continue;
+               def_conf = snd_hda_codec_read(codec, nid, 0,
+                                             AC_VERB_GET_CONFIG_DEFAULT, 0);
+               def_conf = get_defcfg_connect(def_conf);
                /* skip any ports that don't have jacks since presence
                 * detection is useless */
-               if (def_conf && def_conf != AC_JACK_PORT_FIXED)
+               if (def_conf != AC_JACK_PORT_COMPLEX) {
+                       if (def_conf != AC_JACK_PORT_NONE)
+                               stac_toggle_power_map(codec, nid, 1);
                        continue;
+               }
                enable_pin_detect(codec, spec->pwr_nids[i], event | i);
                codec->patch_ops.unsol_event(codec, (event | i) << 26);
        }
        if (spec->dac_list)
                stac92xx_power_down(codec);
-       if (cfg->dig_out_pin)
-               stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
-                                        AC_PINCTL_OUT_EN);
-       if (cfg->dig_in_pin)
-               stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin,
-                                        AC_PINCTL_IN_EN);
-
-       stac_gpio_set(codec, spec->gpio_mask,
-                                       spec->gpio_dir, spec->gpio_data);
-
        return 0;
 }
 
@@ -3901,7 +3941,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
                for (i = 0; i < cfg->speaker_outs; i++)
                        stac92xx_reset_pinctl(codec, cfg->speaker_pins[i],
                                                AC_PINCTL_OUT_EN);
-               if (spec->eapd_mask)
+               if (spec->eapd_mask && spec->eapd_switch)
                        stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data &
                                ~spec->eapd_mask);
@@ -3916,7 +3956,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
                for (i = 0; i < cfg->speaker_outs; i++)
                        stac92xx_set_pinctl(codec, cfg->speaker_pins[i],
                                                AC_PINCTL_OUT_EN);
-               if (spec->eapd_mask)
+               if (spec->eapd_mask && spec->eapd_switch)
                        stac_gpio_set(codec, spec->gpio_mask,
                                spec->gpio_dir, spec->gpio_data |
                                spec->eapd_mask);
@@ -3933,14 +3973,18 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
        }
 } 
 
-static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
+static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
+                                 int enable)
 {
        struct sigmatel_spec *spec = codec->spec;
-       hda_nid_t nid = spec->pwr_nids[idx];
-       int presence, val;
-       val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0)
-                                                       & 0x000000ff;
-       presence = get_hp_pin_presence(codec, nid);
+       unsigned int idx, val;
+
+       for (idx = 0; idx < spec->num_pwrs; idx++) {
+               if (spec->pwr_nids[idx] == nid)
+                       break;
+       }
+       if (idx >= spec->num_pwrs)
+               return;
 
        /* several codecs have two power down bits */
        if (spec->pwr_mapping)
@@ -3948,14 +3992,20 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx)
        else
                idx = 1 << idx;
 
-       if (presence)
+       val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0xff;
+       if (enable)
                val &= ~idx;
        else
                val |= idx;
 
        /* power down unused output ports */
        snd_hda_codec_write(codec, codec->afg, 0, 0x7ec, val);
-};
+}
+
+static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
+{
+       stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid));
+}
 
 static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
 {
@@ -4239,31 +4289,29 @@ again:
        case STAC_DELL_EQ:
                spec->init = dell_eq_core_init;
                /* fallthru */
-       case STAC_DELL_M6:
+       case STAC_DELL_M6_AMIC:
+       case STAC_DELL_M6_DMIC:
+       case STAC_DELL_M6_BOTH:
                spec->num_smuxes = 0;
                spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER];
                spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP];
+               spec->eapd_switch = 0;
                spec->num_amps = 1;
 
                if (!spec->init)
                        spec->init = dell_m6_core_init;
-               switch (codec->subsystem_id) {
-               case 0x1028025e: /* Analog Mics */
-               case 0x1028025f:
+               switch (spec->board_config) {
+               case STAC_DELL_M6_AMIC: /* Analog Mics */
                        stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
                        spec->num_dmics = 0;
                        spec->private_dimux.num_items = 1;
                        break;
-               case 0x10280271: /* Digital Mics */
-               case 0x10280272:
-               case 0x10280254:
-               case 0x10280255:
+               case STAC_DELL_M6_DMIC: /* Digital Mics */
                        stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
                        spec->num_dmics = 1;
                        spec->private_dimux.num_items = 2;
                        break;
-               case 0x10280256: /* Both */
-               case 0x10280057:
+               case STAC_DELL_M6_BOTH: /* Both */
                        stac92xx_set_config_reg(codec, 0x0b, 0x90A70170);
                        stac92xx_set_config_reg(codec, 0x13, 0x90A60160);
                        spec->num_dmics = 1;
@@ -4274,6 +4322,7 @@ again:
        default:
                spec->num_dmics = STAC92HD73XX_NUM_DMICS;
                spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids);
+               spec->eapd_switch = 1;
        }
        if (spec->board_config > STAC_92HD73XX_REF) {
                /* GPIO0 High = Enable EAPD */
@@ -4419,7 +4468,13 @@ static int stac92hd71xx_resume(struct hda_codec *codec)
 
 static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
 {
+       struct sigmatel_spec *spec = codec->spec;
+
        stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
+       if (spec->eapd_mask)
+               stac_gpio_set(codec, spec->gpio_mask,
+                               spec->gpio_dir, spec->gpio_data &
+                               ~spec->eapd_mask);
        return 0;
 };
 
@@ -4562,14 +4617,21 @@ again:
 
        switch (spec->board_config) {
        case STAC_HP_M4:
-               spec->num_dmics = 0;
-               spec->num_smuxes = 0;
-               spec->num_dmuxes = 0;
-
                /* enable internal microphone */
                stac92xx_set_config_reg(codec, 0x0e, 0x01813040);
                stac92xx_auto_set_pinctl(codec, 0x0e,
                        AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
+               /* fallthru */
+       case STAC_DELL_M4_2:
+               spec->num_dmics = 0;
+               spec->num_smuxes = 0;
+               spec->num_dmuxes = 0;
+               break;
+       case STAC_DELL_M4_1:
+       case STAC_DELL_M4_3:
+               spec->num_dmics = 1;
+               spec->num_smuxes = 0;
+               spec->num_dmuxes = 0;
                break;
        default:
                spec->num_dmics = STAC92HD71BXX_NUM_DMICS;
@@ -4806,6 +4868,7 @@ static int patch_stac927x(struct hda_codec *codec)
        spec->num_pwrs = 0;
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
+       spec->eapd_switch = 1;
 
        err = stac92xx_parse_auto_config(codec, 0x1e, 0x20);
        if (!err) {
@@ -4886,6 +4949,7 @@ static int patch_stac9205(struct hda_codec *codec)
 
        spec->aloopback_mask = 0x40;
        spec->aloopback_shift = 0;
+       spec->eapd_switch = 1;
        spec->multiout.dac_nids = spec->dac_nids;
        
        switch (spec->board_config){
index 4dfda6674bec98507ee354a5c7a84f9606a9ab37..ef025c66cc669c49c7b4537893ba76860fbd2397 100644 (file)
@@ -22,17 +22,16 @@ if SND_SOC
 config SND_SOC_AC97_BUS
        bool
 
-# All the supported Soc's
-source "sound/soc/at32/Kconfig"
-source "sound/soc/at91/Kconfig"
+# All the supported SoCs
+source "sound/soc/atmel/Kconfig"
 source "sound/soc/au1x/Kconfig"
+source "sound/soc/blackfin/Kconfig"
+source "sound/soc/davinci/Kconfig"
+source "sound/soc/fsl/Kconfig"
+source "sound/soc/omap/Kconfig"
 source "sound/soc/pxa/Kconfig"
 source "sound/soc/s3c24xx/Kconfig"
 source "sound/soc/sh/Kconfig"
-source "sound/soc/fsl/Kconfig"
-source "sound/soc/davinci/Kconfig"
-source "sound/soc/omap/Kconfig"
-source "sound/soc/blackfin/Kconfig"
 
 # Supported codecs
 source "sound/soc/codecs/Kconfig"
index d849349f2c6607ddb5a0da9a1097eae024b22848..86a9b1f5b0f3cbf83c315505613fd751c8356306 100644 (file)
@@ -1,5 +1,13 @@
 snd-soc-core-objs := soc-core.o soc-dapm.o
 
 obj-$(CONFIG_SND_SOC)  += snd-soc-core.o
-obj-$(CONFIG_SND_SOC)  += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/
-obj-$(CONFIG_SND_SOC)  += omap/ au1x/ blackfin/
+obj-$(CONFIG_SND_SOC)  += codecs/
+obj-$(CONFIG_SND_SOC)  += atmel/
+obj-$(CONFIG_SND_SOC)  += au1x/
+obj-$(CONFIG_SND_SOC)  += blackfin/
+obj-$(CONFIG_SND_SOC)  += davinci/
+obj-$(CONFIG_SND_SOC)  += fsl/
+obj-$(CONFIG_SND_SOC)  += omap/
+obj-$(CONFIG_SND_SOC)  += pxa/
+obj-$(CONFIG_SND_SOC)  += s3c24xx/
+obj-$(CONFIG_SND_SOC)  += sh/
diff --git a/sound/soc/at32/Kconfig b/sound/soc/at32/Kconfig
deleted file mode 100644 (file)
index b0765e8..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-config SND_AT32_SOC
-        tristate "SoC Audio for the Atmel AT32 System-on-a-Chip"
-        depends on AVR32 && SND_SOC
-        help
-          Say Y or M if you want to add support for codecs attached to 
-          the AT32 SSC interface.  You will also need to
-          to select the audio interfaces to support below.
-
-
-config SND_AT32_SOC_SSC
-        tristate
-
-
-
-config SND_AT32_SOC_PLAYPAQ
-        tristate "SoC Audio support for PlayPaq with WM8510"
-        depends on SND_AT32_SOC && BOARD_PLAYPAQ
-        select SND_AT32_SOC_SSC
-        select SND_SOC_WM8510
-        help
-          Say Y or M here if you want to add support for SoC audio
-          on the LRS PlayPaq.
-
-
-
-config SND_AT32_SOC_PLAYPAQ_SLAVE
-        bool "Run CODEC on PlayPaq in slave mode"
-        depends on SND_AT32_SOC_PLAYPAQ
-        default n
-        help
-          Say Y if you want to run with the AT32 SSC generating the BCLK
-          and FRAME signals on the PlayPaq.  Unless you want to play
-          with the AT32 as the SSC master, you probably want to say N here,
-          as this will give you better sound quality.
diff --git a/sound/soc/at32/Makefile b/sound/soc/at32/Makefile
deleted file mode 100644 (file)
index c03e55e..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-# AT32 Platform Support
-snd-soc-at32-objs := at32-pcm.o
-snd-soc-at32-ssc-objs := at32-ssc.o
-
-obj-$(CONFIG_SND_AT32_SOC) += snd-soc-at32.o
-obj-$(CONFIG_SND_AT32_SOC_SSC) += snd-soc-at32-ssc.o
-
-# AT32 Machine Support
-snd-soc-playpaq-objs := playpaq_wm8510.o
-
-obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
deleted file mode 100644 (file)
index c83584f..0000000
+++ /dev/null
@@ -1,492 +0,0 @@
-/* sound/soc/at32/at32-pcm.c
- * ASoC PCM interface for Atmel AT32 SoC
- *
- * Copyright (C) 2008 Long Range Systems
- *    Geoffrey Wossum <gwossum@acm.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Note that this is basically a port of the sound/soc/at91-pcm.c to
- * the AVR32 kernel.  Thanks to Frank Mandarino for that code.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include "at32-pcm.h"
-
-
-
-/*--------------------------------------------------------------------------*\
- * Hardware definition
-\*--------------------------------------------------------------------------*/
-/* TODO: These values were taken from the AT91 platform driver, check
- *      them against real values for AT32
- */
-static const struct snd_pcm_hardware at32_pcm_hardware = {
-       .info = (SNDRV_PCM_INFO_MMAP |
-                SNDRV_PCM_INFO_MMAP_VALID |
-                SNDRV_PCM_INFO_INTERLEAVED |
-                SNDRV_PCM_INFO_BLOCK_TRANSFER |
-                SNDRV_PCM_INFO_PAUSE),
-
-       .formats = SNDRV_PCM_FMTBIT_S16,
-       .period_bytes_min = 32,
-       .period_bytes_max = 8192,       /* 512 frames * 16 bytes / frame */
-       .periods_min = 2,
-       .periods_max = 1024,
-       .buffer_bytes_max = 32 * 1024,
-};
-
-
-
-/*--------------------------------------------------------------------------*\
- * Data types
-\*--------------------------------------------------------------------------*/
-struct at32_runtime_data {
-       struct at32_pcm_dma_params *params;
-       dma_addr_t dma_buffer;  /* physical address of DMA buffer */
-       dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
-       size_t period_size;
-
-       dma_addr_t period_ptr;  /* physical address of next period */
-       int periods;            /* period index of period_ptr */
-
-       /* Save PDC registers (for power management) */
-       u32 pdc_xpr_save;
-       u32 pdc_xcr_save;
-       u32 pdc_xnpr_save;
-       u32 pdc_xncr_save;
-};
-
-
-
-/*--------------------------------------------------------------------------*\
- * Helper functions
-\*--------------------------------------------------------------------------*/
-static int at32_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *dmabuf = &substream->dma_buffer;
-       size_t size = at32_pcm_hardware.buffer_bytes_max;
-
-       dmabuf->dev.type = SNDRV_DMA_TYPE_DEV;
-       dmabuf->dev.dev = pcm->card->dev;
-       dmabuf->private_data = NULL;
-       dmabuf->area = dma_alloc_coherent(pcm->card->dev, size,
-                                         &dmabuf->addr, GFP_KERNEL);
-       pr_debug("at32_pcm: preallocate_dma_buffer: "
-                "area=%p, addr=%p, size=%ld\n",
-                (void *)dmabuf->area, (void *)dmabuf->addr, size);
-
-       if (!dmabuf->area)
-               return -ENOMEM;
-
-       dmabuf->bytes = size;
-       return 0;
-}
-
-
-
-/*--------------------------------------------------------------------------*\
- * ISR
-\*--------------------------------------------------------------------------*/
-static void at32_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *rtd = substream->runtime;
-       struct at32_runtime_data *prtd = rtd->private_data;
-       struct at32_pcm_dma_params *params = prtd->params;
-       static int count;
-
-       count++;
-       if (ssc_sr & params->mask->ssc_endbuf) {
-               pr_warning("at32-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
-                          substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-                          "underrun" : "overrun", params->name, ssc_sr, count);
-
-               /* re-start the PDC */
-               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                          params->mask->pdc_disable);
-               prtd->period_ptr += prtd->period_size;
-               if (prtd->period_ptr >= prtd->dma_buffer_end)
-                       prtd->period_ptr = prtd->dma_buffer;
-
-
-               ssc_writex(params->ssc->regs, params->pdc->xpr,
-                          prtd->period_ptr);
-               ssc_writex(params->ssc->regs, params->pdc->xcr,
-                          prtd->period_size / params->pdc_xfer_size);
-               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                          params->mask->pdc_enable);
-       }
-
-
-       if (ssc_sr & params->mask->ssc_endx) {
-               /* Load the PDC next pointer and counter registers */
-               prtd->period_ptr += prtd->period_size;
-               if (prtd->period_ptr >= prtd->dma_buffer_end)
-                       prtd->period_ptr = prtd->dma_buffer;
-               ssc_writex(params->ssc->regs, params->pdc->xnpr,
-                          prtd->period_ptr);
-               ssc_writex(params->ssc->regs, params->pdc->xncr,
-                          prtd->period_size / params->pdc_xfer_size);
-       }
-
-
-       snd_pcm_period_elapsed(substream);
-}
-
-
-
-/*--------------------------------------------------------------------------*\
- * PCM operations
-\*--------------------------------------------------------------------------*/
-static int at32_pcm_hw_params(struct snd_pcm_substream *substream,
-                             struct snd_pcm_hw_params *params)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at32_runtime_data *prtd = runtime->private_data;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
-       /* this may get called several times by oss emulation
-        * with different params
-        */
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-       runtime->dma_bytes = params_buffer_bytes(params);
-
-       prtd->params = rtd->dai->cpu_dai->dma_data;
-       prtd->params->dma_intr_handler = at32_pcm_dma_irq;
-
-       prtd->dma_buffer = runtime->dma_addr;
-       prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
-       prtd->period_size = params_period_bytes(params);
-
-       pr_debug("hw_params: DMA for %s initialized "
-                "(dma_bytes=%ld, period_size=%ld)\n",
-                prtd->params->name, runtime->dma_bytes, prtd->period_size);
-
-       return 0;
-}
-
-
-
-static int at32_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-       struct at32_runtime_data *prtd = substream->runtime->private_data;
-       struct at32_pcm_dma_params *params = prtd->params;
-
-       if (params != NULL) {
-               ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
-                          params->mask->pdc_disable);
-               prtd->params->dma_intr_handler = NULL;
-       }
-
-       return 0;
-}
-
-
-
-static int at32_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct at32_runtime_data *prtd = substream->runtime->private_data;
-       struct at32_pcm_dma_params *params = prtd->params;
-
-       ssc_writex(params->ssc->regs, SSC_IDR,
-                  params->mask->ssc_endx | params->mask->ssc_endbuf);
-       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                  params->mask->pdc_disable);
-
-       return 0;
-}
-
-
-static int at32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
-{
-       struct snd_pcm_runtime *rtd = substream->runtime;
-       struct at32_runtime_data *prtd = rtd->private_data;
-       struct at32_pcm_dma_params *params = prtd->params;
-       int ret = 0;
-
-       pr_debug("at32_pcm_trigger: buffer_size = %ld, "
-                "dma_area = %p, dma_bytes = %ld\n",
-                rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               prtd->period_ptr = prtd->dma_buffer;
-
-               ssc_writex(params->ssc->regs, params->pdc->xpr,
-                          prtd->period_ptr);
-               ssc_writex(params->ssc->regs, params->pdc->xcr,
-                          prtd->period_size / params->pdc_xfer_size);
-
-               prtd->period_ptr += prtd->period_size;
-               ssc_writex(params->ssc->regs, params->pdc->xnpr,
-                          prtd->period_ptr);
-               ssc_writex(params->ssc->regs, params->pdc->xncr,
-                          prtd->period_size / params->pdc_xfer_size);
-
-               pr_debug("trigger: period_ptr=%lx, xpr=%x, "
-                        "xcr=%d, xnpr=%x, xncr=%d\n",
-                        (unsigned long)prtd->period_ptr,
-                        ssc_readx(params->ssc->regs, params->pdc->xpr),
-                        ssc_readx(params->ssc->regs, params->pdc->xcr),
-                        ssc_readx(params->ssc->regs, params->pdc->xnpr),
-                        ssc_readx(params->ssc->regs, params->pdc->xncr));
-
-               ssc_writex(params->ssc->regs, SSC_IER,
-                          params->mask->ssc_endx | params->mask->ssc_endbuf);
-               ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
-                          params->mask->pdc_enable);
-
-               pr_debug("sr=%x, imr=%x\n",
-                        ssc_readx(params->ssc->regs, SSC_SR),
-                        ssc_readx(params->ssc->regs, SSC_IER));
-               break;          /* SNDRV_PCM_TRIGGER_START */
-
-
-
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                          params->mask->pdc_disable);
-               break;
-
-
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                          params->mask->pdc_enable);
-               break;
-
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-
-
-static snd_pcm_uframes_t at32_pcm_pointer(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at32_runtime_data *prtd = runtime->private_data;
-       struct at32_pcm_dma_params *params = prtd->params;
-       dma_addr_t ptr;
-       snd_pcm_uframes_t x;
-
-       ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
-       x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
-
-       if (x == runtime->buffer_size)
-               x = 0;
-
-       return x;
-}
-
-
-
-static int at32_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at32_runtime_data *prtd;
-       int ret = 0;
-
-       snd_soc_set_runtime_hwparams(substream, &at32_pcm_hardware);
-
-       /* ensure that buffer size is a multiple of period size */
-       ret = snd_pcm_hw_constraint_integer(runtime,
-                                           SNDRV_PCM_HW_PARAM_PERIODS);
-       if (ret < 0)
-               goto out;
-
-       prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
-       if (prtd == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       runtime->private_data = prtd;
-
-
-out:
-       return ret;
-}
-
-
-
-static int at32_pcm_close(struct snd_pcm_substream *substream)
-{
-       struct at32_runtime_data *prtd = substream->runtime->private_data;
-
-       kfree(prtd);
-       return 0;
-}
-
-
-static int at32_pcm_mmap(struct snd_pcm_substream *substream,
-                        struct vm_area_struct *vma)
-{
-       return remap_pfn_range(vma, vma->vm_start,
-                              substream->dma_buffer.addr >> PAGE_SHIFT,
-                              vma->vm_end - vma->vm_start, vma->vm_page_prot);
-}
-
-
-
-static struct snd_pcm_ops at32_pcm_ops = {
-       .open = at32_pcm_open,
-       .close = at32_pcm_close,
-       .ioctl = snd_pcm_lib_ioctl,
-       .hw_params = at32_pcm_hw_params,
-       .hw_free = at32_pcm_hw_free,
-       .prepare = at32_pcm_prepare,
-       .trigger = at32_pcm_trigger,
-       .pointer = at32_pcm_pointer,
-       .mmap = at32_pcm_mmap,
-};
-
-
-
-/*--------------------------------------------------------------------------*\
- * ASoC platform driver
-\*--------------------------------------------------------------------------*/
-static u64 at32_pcm_dmamask = 0xffffffff;
-
-static int at32_pcm_new(struct snd_card *card,
-                       struct snd_soc_dai *dai,
-                       struct snd_pcm *pcm)
-{
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &at32_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = 0xffffffff;
-
-       if (dai->playback.channels_min) {
-               ret = at32_pcm_preallocate_dma_buffer(
-                         pcm, SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       goto out;
-       }
-
-       if (dai->capture.channels_min) {
-               pr_debug("at32-pcm: Allocating PCM capture DMA buffer\n");
-               ret = at32_pcm_preallocate_dma_buffer(
-                         pcm, SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       goto out;
-       }
-
-
-out:
-       return ret;
-}
-
-
-
-static void at32_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (substream == NULL)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-               dma_free_coherent(pcm->card->dev, buf->bytes,
-                                 buf->area, buf->addr);
-               buf->area = NULL;
-       }
-}
-
-
-
-#ifdef CONFIG_PM
-static int at32_pcm_suspend(struct platform_device *pdev,
-                           struct snd_soc_dai *dai)
-{
-       struct snd_pcm_runtime *runtime = dai->runtime;
-       struct at32_runtime_data *prtd;
-       struct at32_pcm_dma_params *params;
-
-       if (runtime == NULL)
-               return 0;
-       prtd = runtime->private_data;
-       params = prtd->params;
-
-       /* Disable the PDC and save the PDC registers */
-       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
-                  params->mask->pdc_disable);
-
-       prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
-       prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
-       prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
-       prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
-
-       return 0;
-}
-
-
-
-static int at32_pcm_resume(struct platform_device *pdev,
-                          struct snd_soc_dai *dai)
-{
-       struct snd_pcm_runtime *runtime = dai->runtime;
-       struct at32_runtime_data *prtd;
-       struct at32_pcm_dma_params *params;
-
-       if (runtime == NULL)
-               return 0;
-       prtd = runtime->private_data;
-       params = prtd->params;
-
-       /* Restore the PDC registers and enable the PDC */
-       ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
-       ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
-       ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
-       ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
-
-       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
-       return 0;
-}
-#else /* CONFIG_PM */
-#  define at32_pcm_suspend     NULL
-#  define at32_pcm_resume      NULL
-#endif /* CONFIG_PM */
-
-
-
-struct snd_soc_platform at32_soc_platform = {
-       .name = "at32-audio",
-       .pcm_ops = &at32_pcm_ops,
-       .pcm_new = at32_pcm_new,
-       .pcm_free = at32_pcm_free_dma_buffers,
-       .suspend = at32_pcm_suspend,
-       .resume = at32_pcm_resume,
-};
-EXPORT_SYMBOL_GPL(at32_soc_platform);
-
-
-
-MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
-MODULE_DESCRIPTION("Atmel AT32 PCM module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-pcm.h b/sound/soc/at32/at32-pcm.h
deleted file mode 100644 (file)
index 2a52430..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/* sound/soc/at32/at32-pcm.h
- * ASoC PCM interface for Atmel AT32 SoC
- *
- * Copyright (C) 2008 Long Range Systems
- *    Geoffrey Wossum <gwossum@acm.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SOUND_SOC_AT32_AT32_PCM_H
-#define __SOUND_SOC_AT32_AT32_PCM_H __FILE__
-
-#include <linux/atmel-ssc.h>
-
-
-/*
- * Registers and status bits that are required by the PCM driver
- * TODO: Is ptcr really used?
- */
-struct at32_pdc_regs {
-       u32 xpr;                /* PDC RX/TX pointer */
-       u32 xcr;                /* PDC RX/TX counter */
-       u32 xnpr;               /* PDC next RX/TX pointer */
-       u32 xncr;               /* PDC next RX/TX counter */
-       u32 ptcr;               /* PDC transfer control */
-};
-
-
-
-/*
- * SSC mask info
- */
-struct at32_ssc_mask {
-       u32 ssc_enable;         /* SSC RX/TX enable */
-       u32 ssc_disable;        /* SSC RX/TX disable */
-       u32 ssc_endx;           /* SSC ENDTX or ENDRX */
-       u32 ssc_endbuf;         /* SSC TXBUFF or RXBUFF */
-       u32 pdc_enable;         /* PDC RX/TX enable */
-       u32 pdc_disable;        /* PDC RX/TX disable */
-};
-
-
-
-/*
- * This structure, shared between the PCM driver and the interface,
- * contains all information required by the PCM driver to perform the
- * PDC DMA operation.  All fields except dma_intr_handler() are initialized
- * by the interface.  The dms_intr_handler() pointer is set by the PCM
- * driver and called by the interface SSC interrupt handler if it is
- * non-NULL.
- */
-struct at32_pcm_dma_params {
-       char *name;             /* stream identifier */
-       int pdc_xfer_size;      /* PDC counter increment in bytes */
-       struct ssc_device *ssc; /* SSC device for stream */
-       struct at32_pdc_regs *pdc;      /* PDC register info */
-       struct at32_ssc_mask *mask;     /* SSC mask info */
-       struct snd_pcm_substream *substream;
-       void (*dma_intr_handler) (u32, struct snd_pcm_substream *);
-};
-
-
-
-/*
- * The AT32 ASoC platform driver
- */
-extern struct snd_soc_platform at32_soc_platform;
-
-
-
-/*
- * SSC register access (since ssc_writel() / ssc_readl() require literal name)
- */
-#define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
-#define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))
-
-#endif /* __SOUND_SOC_AT32_AT32_PCM_H */
diff --git a/sound/soc/at32/at32-ssc.c b/sound/soc/at32/at32-ssc.c
deleted file mode 100644 (file)
index 4ef6492..0000000
+++ /dev/null
@@ -1,849 +0,0 @@
-/* sound/soc/at32/at32-ssc.c
- * ASoC platform driver for AT32 using SSC as DAI
- *
- * Copyright (C) 2008 Long Range Systems
- *    Geoffrey Wossum <gwossum@acm.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Note that this is basically a port of the sound/soc/at91-ssc.c to
- * the AVR32 kernel.  Thanks to Frank Mandarino for that code.
- */
-
-/* #define DEBUG */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/atmel_pdc.h>
-#include <linux/atmel-ssc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "at32-pcm.h"
-#include "at32-ssc.h"
-
-
-
-/*-------------------------------------------------------------------------*\
- * Constants
-\*-------------------------------------------------------------------------*/
-#define NUM_SSC_DEVICES                3
-
-/*
- * SSC direction masks
- */
-#define SSC_DIR_MASK_UNUSED    0
-#define SSC_DIR_MASK_PLAYBACK  1
-#define SSC_DIR_MASK_CAPTURE   2
-
-/*
- * SSC register values that Atmel left out of <linux/atmel-ssc.h>.  These
- * are expected to be used with SSC_BF
- */
-/* START bit field values */
-#define SSC_START_CONTINUOUS   0
-#define SSC_START_TX_RX                1
-#define SSC_START_LOW_RF       2
-#define SSC_START_HIGH_RF      3
-#define SSC_START_FALLING_RF   4
-#define SSC_START_RISING_RF    5
-#define SSC_START_LEVEL_RF     6
-#define SSC_START_EDGE_RF      7
-#define SSS_START_COMPARE_0    8
-
-/* CKI bit field values */
-#define SSC_CKI_FALLING                0
-#define SSC_CKI_RISING         1
-
-/* CKO bit field values */
-#define SSC_CKO_NONE           0
-#define SSC_CKO_CONTINUOUS     1
-#define SSC_CKO_TRANSFER       2
-
-/* CKS bit field values */
-#define SSC_CKS_DIV            0
-#define SSC_CKS_CLOCK          1
-#define SSC_CKS_PIN            2
-
-/* FSEDGE bit field values */
-#define SSC_FSEDGE_POSITIVE    0
-#define SSC_FSEDGE_NEGATIVE    1
-
-/* FSOS bit field values */
-#define SSC_FSOS_NONE          0
-#define SSC_FSOS_NEGATIVE      1
-#define SSC_FSOS_POSITIVE      2
-#define SSC_FSOS_LOW           3
-#define SSC_FSOS_HIGH          4
-#define SSC_FSOS_TOGGLE                5
-
-#define START_DELAY            1
-
-
-
-/*-------------------------------------------------------------------------*\
- * Module data
-\*-------------------------------------------------------------------------*/
-/*
- * SSC PDC registered required by the PCM DMA engine
- */
-static struct at32_pdc_regs pdc_tx_reg = {
-       .xpr = SSC_PDC_TPR,
-       .xcr = SSC_PDC_TCR,
-       .xnpr = SSC_PDC_TNPR,
-       .xncr = SSC_PDC_TNCR,
-};
-
-
-
-static struct at32_pdc_regs pdc_rx_reg = {
-       .xpr = SSC_PDC_RPR,
-       .xcr = SSC_PDC_RCR,
-       .xnpr = SSC_PDC_RNPR,
-       .xncr = SSC_PDC_RNCR,
-};
-
-
-
-/*
- * SSC and PDC status bits for transmit and receive
- */
-static struct at32_ssc_mask ssc_tx_mask = {
-       .ssc_enable = SSC_BIT(CR_TXEN),
-       .ssc_disable = SSC_BIT(CR_TXDIS),
-       .ssc_endx = SSC_BIT(SR_ENDTX),
-       .ssc_endbuf = SSC_BIT(SR_TXBUFE),
-       .pdc_enable = SSC_BIT(PDC_PTCR_TXTEN),
-       .pdc_disable = SSC_BIT(PDC_PTCR_TXTDIS),
-};
-
-
-
-static struct at32_ssc_mask ssc_rx_mask = {
-       .ssc_enable = SSC_BIT(CR_RXEN),
-       .ssc_disable = SSC_BIT(CR_RXDIS),
-       .ssc_endx = SSC_BIT(SR_ENDRX),
-       .ssc_endbuf = SSC_BIT(SR_RXBUFF),
-       .pdc_enable = SSC_BIT(PDC_PTCR_RXTEN),
-       .pdc_disable = SSC_BIT(PDC_PTCR_RXTDIS),
-};
-
-
-
-/*
- * DMA parameters for each SSC
- */
-static struct at32_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
-       {
-        {
-         .name = "SSC0 PCM out",
-         .pdc = &pdc_tx_reg,
-         .mask = &ssc_tx_mask,
-         },
-        {
-         .name = "SSC0 PCM in",
-         .pdc = &pdc_rx_reg,
-         .mask = &ssc_rx_mask,
-         },
-        },
-       {
-        {
-         .name = "SSC1 PCM out",
-         .pdc = &pdc_tx_reg,
-         .mask = &ssc_tx_mask,
-         },
-        {
-         .name = "SSC1 PCM in",
-         .pdc = &pdc_rx_reg,
-         .mask = &ssc_rx_mask,
-         },
-        },
-       {
-        {
-         .name = "SSC2 PCM out",
-         .pdc = &pdc_tx_reg,
-         .mask = &ssc_tx_mask,
-         },
-        {
-         .name = "SSC2 PCM in",
-         .pdc = &pdc_rx_reg,
-         .mask = &ssc_rx_mask,
-         },
-        },
-};
-
-
-
-static struct at32_ssc_info ssc_info[NUM_SSC_DEVICES] = {
-       {
-        .name = "ssc0",
-        .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
-        .dir_mask = SSC_DIR_MASK_UNUSED,
-        .initialized = 0,
-        },
-       {
-        .name = "ssc1",
-        .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
-        .dir_mask = SSC_DIR_MASK_UNUSED,
-        .initialized = 0,
-        },
-       {
-        .name = "ssc2",
-        .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
-        .dir_mask = SSC_DIR_MASK_UNUSED,
-        .initialized = 0,
-        },
-};
-
-
-
-
-/*-------------------------------------------------------------------------*\
- * ISR
-\*-------------------------------------------------------------------------*/
-/*
- * SSC interrupt handler.  Passes PDC interrupts to the DMA interrupt
- * handler in the PCM driver.
- */
-static irqreturn_t at32_ssc_interrupt(int irq, void *dev_id)
-{
-       struct at32_ssc_info *ssc_p = dev_id;
-       struct at32_pcm_dma_params *dma_params;
-       u32 ssc_sr;
-       u32 ssc_substream_mask;
-       int i;
-
-       ssc_sr = (ssc_readl(ssc_p->ssc->regs, SR) &
-                 ssc_readl(ssc_p->ssc->regs, IMR));
-
-       /*
-        * Loop through substreams attached to this SSC.  If a DMA-related
-        * interrupt occured on that substream, call the DMA interrupt
-        * handler function, if one has been registered in the dma_param
-        * structure by the PCM driver.
-        */
-       for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
-               dma_params = ssc_p->dma_params[i];
-
-               if ((dma_params != NULL) &&
-                   (dma_params->dma_intr_handler != NULL)) {
-                       ssc_substream_mask = (dma_params->mask->ssc_endx |
-                                             dma_params->mask->ssc_endbuf);
-                       if (ssc_sr & ssc_substream_mask) {
-                               dma_params->dma_intr_handler(ssc_sr,
-                                                            dma_params->
-                                                            substream);
-                       }
-               }
-       }
-
-
-       return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*\
- * DAI functions
-\*-------------------------------------------------------------------------*/
-/*
- * Startup.  Only that one substream allowed in each direction.
- */
-static int at32_ssc_startup(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       int dir_mask;
-
-       dir_mask = ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
-                   SSC_DIR_MASK_PLAYBACK : SSC_DIR_MASK_CAPTURE);
-
-       spin_lock_irq(&ssc_p->lock);
-       if (ssc_p->dir_mask & dir_mask) {
-               spin_unlock_irq(&ssc_p->lock);
-               return -EBUSY;
-       }
-       ssc_p->dir_mask |= dir_mask;
-       spin_unlock_irq(&ssc_p->lock);
-
-       return 0;
-}
-
-
-
-/*
- * Shutdown.  Clear DMA parameters and shutdown the SSC if there
- * are no other substreams open.
- */
-static void at32_ssc_shutdown(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at32_pcm_dma_params *dma_params;
-       int dir_mask;
-
-       dma_params = ssc_p->dma_params[substream->stream];
-
-       if (dma_params != NULL) {
-               ssc_writel(dma_params->ssc->regs, CR,
-                          dma_params->mask->ssc_disable);
-               pr_debug("%s disabled SSC_SR=0x%08x\n",
-                        (substream->stream ? "receiver" : "transmit"),
-                        ssc_readl(ssc_p->ssc->regs, SR));
-
-               dma_params->ssc = NULL;
-               dma_params->substream = NULL;
-               ssc_p->dma_params[substream->stream] = NULL;
-       }
-
-
-       dir_mask = 1 << substream->stream;
-       spin_lock_irq(&ssc_p->lock);
-       ssc_p->dir_mask &= ~dir_mask;
-       if (!ssc_p->dir_mask) {
-               /* Shutdown the SSC clock */
-               pr_debug("at32-ssc: Stopping user %d clock\n",
-                        ssc_p->ssc->user);
-               clk_disable(ssc_p->ssc->clk);
-
-               if (ssc_p->initialized) {
-                       free_irq(ssc_p->ssc->irq, ssc_p);
-                       ssc_p->initialized = 0;
-               }
-
-               /* Reset the SSC */
-               ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
-
-               /* clear the SSC dividers */
-               ssc_p->cmr_div = 0;
-               ssc_p->tcmr_period = 0;
-               ssc_p->rcmr_period = 0;
-       }
-       spin_unlock_irq(&ssc_p->lock);
-}
-
-
-
-/*
- * Set the SSC system clock rate
- */
-static int at32_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
-                                  int clk_id, unsigned int freq, int dir)
-{
-       /* TODO: What the heck do I do here? */
-       return 0;
-}
-
-
-
-/*
- * Record DAI format for use by hw_params()
- */
-static int at32_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-                               unsigned int fmt)
-{
-       struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       ssc_p->daifmt = fmt;
-       return 0;
-}
-
-
-
-/*
- * Record SSC clock dividers for use in hw_params()
- */
-static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
-                                  int div_id, int div)
-{
-       struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       switch (div_id) {
-       case AT32_SSC_CMR_DIV:
-               /*
-                * The same master clock divider is used for both
-                * transmit and receive, so if a value has already
-                * been set, it must match this value
-                */
-               if (ssc_p->cmr_div == 0)
-                       ssc_p->cmr_div = div;
-               else if (div != ssc_p->cmr_div)
-                       return -EBUSY;
-               break;
-
-       case AT32_SSC_TCMR_PERIOD:
-               ssc_p->tcmr_period = div;
-               break;
-
-       case AT32_SSC_RCMR_PERIOD:
-               ssc_p->rcmr_period = div;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-
-/*
- * Configure the SSC
- */
-static int at32_ssc_hw_params(struct snd_pcm_substream *substream,
-                             struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int id = rtd->dai->cpu_dai->id;
-       struct at32_ssc_info *ssc_p = &ssc_info[id];
-       struct at32_pcm_dma_params *dma_params;
-       int channels, bits;
-       u32 tfmr, rfmr, tcmr, rcmr;
-       int start_event;
-       int ret;
-
-
-       /*
-        * Currently, there is only one set of dma_params for each direction.
-        * If more are added, this code will have to be changed to select
-        * the proper set
-        */
-       dma_params = &ssc_dma_params[id][substream->stream];
-       dma_params->ssc = ssc_p->ssc;
-       dma_params->substream = substream;
-
-       ssc_p->dma_params[substream->stream] = dma_params;
-
-
-       /*
-        * The cpu_dai->dma_data field is only used to communicate the
-        * appropriate DMA parameters to the PCM driver's hw_params()
-        * function.  It should not be used for other purposes as it
-        * is common to all substreams.
-        */
-       rtd->dai->cpu_dai->dma_data = dma_params;
-
-       channels = params_channels(params);
-
-
-       /*
-        * Determine sample size in bits and the PDC increment
-        */
-       switch (params_format(params)) {
-       case SNDRV_PCM_FORMAT_S8:
-               bits = 8;
-               dma_params->pdc_xfer_size = 1;
-               break;
-
-       case SNDRV_PCM_FORMAT_S16:
-               bits = 16;
-               dma_params->pdc_xfer_size = 2;
-               break;
-
-       case SNDRV_PCM_FORMAT_S24:
-               bits = 24;
-               dma_params->pdc_xfer_size = 4;
-               break;
-
-       case SNDRV_PCM_FORMAT_S32:
-               bits = 32;
-               dma_params->pdc_xfer_size = 4;
-               break;
-
-       default:
-               pr_warning("at32-ssc: Unsupported PCM format %d",
-                          params_format(params));
-               return -EINVAL;
-       }
-       pr_debug("at32-ssc: bits = %d, pdc_xfer_size = %d, channels = %d\n",
-                bits, dma_params->pdc_xfer_size, channels);
-
-
-       /*
-        * The SSC only supports up to 16-bit samples in I2S format, due
-        * to the size of the Frame Mode Register FSLEN field.
-        */
-       if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
-               if (bits > 16) {
-                       pr_warning("at32-ssc: "
-                                  "sample size %d is too large for I2S\n",
-                                  bits);
-                       return -EINVAL;
-               }
-
-
-       /*
-        * Compute the SSC register settings
-        */
-       switch (ssc_p->daifmt & (SND_SOC_DAIFMT_FORMAT_MASK |
-                                SND_SOC_DAIFMT_MASTER_MASK)) {
-       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
-               /*
-                * I2S format, SSC provides BCLK and LRS clocks.
-                *
-                * The SSC transmit and receive clocks are generated from the
-                * MCK divider, and the BCLK signal is output on the SSC TK line
-                */
-               pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME master\n");
-               rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
-                       SSC_BF(RCMR_STTDLY, START_DELAY) |
-                       SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
-                       SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
-                       SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
-                       SSC_BF(RCMR_CKS, SSC_CKS_DIV));
-
-               rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
-                       SSC_BF(RFMR_FSLEN, bits - 1) |
-                       SSC_BF(RFMR_DATNB, channels - 1) |
-                       SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
-
-               tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
-                       SSC_BF(TCMR_STTDLY, START_DELAY) |
-                       SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
-                       SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
-                       SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
-                       SSC_BF(TCMR_CKS, SSC_CKS_DIV));
-
-               tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
-                       SSC_BF(TFMR_FSLEN, bits - 1) |
-                       SSC_BF(TFMR_DATNB, channels - 1) | SSC_BIT(TFMR_MSBF) |
-                       SSC_BF(TFMR_DATLEN, bits - 1));
-               break;
-
-
-       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
-               /*
-                * I2S format, CODEC supplies BCLK and LRC clock.
-                *
-                * The SSC transmit clock is obtained from the BCLK signal
-                * on the TK line, and the SSC receive clock is generated from
-                * the transmit clock.
-                *
-                * For single channel data, one sample is transferred on the
-                * falling edge of the LRC clock.  For two channel data, one
-                * sample is transferred on both edges of the LRC clock.
-                */
-               pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME slave\n");
-               start_event = ((channels == 1) ?
-                              SSC_START_FALLING_RF : SSC_START_EDGE_RF);
-
-               rcmr = (SSC_BF(RCMR_STTDLY, START_DELAY) |
-                       SSC_BF(RCMR_START, start_event) |
-                       SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
-                       SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
-                       SSC_BF(RCMR_CKS, SSC_CKS_CLOCK));
-
-               rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
-                       SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
-
-               tcmr = (SSC_BF(TCMR_STTDLY, START_DELAY) |
-                       SSC_BF(TCMR_START, start_event) |
-                       SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
-                       SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
-                       SSC_BF(TCMR_CKS, SSC_CKS_PIN));
-
-               tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
-                       SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
-               break;
-
-
-       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
-               /*
-                * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
-                *
-                * The SSC transmit and receive clocks are generated from the
-                * MCK divider, and the BCLK signal is output on the SSC TK line
-                */
-               pr_debug("at32-ssc: SSC mode is DSP A BCLK / FRAME master\n");
-               rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
-                       SSC_BF(RCMR_STTDLY, 1) |
-                       SSC_BF(RCMR_START, SSC_START_RISING_RF) |
-                       SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
-                       SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
-                       SSC_BF(RCMR_CKS, SSC_CKS_DIV));
-
-               rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) |
-                       SSC_BF(RFMR_DATNB, channels - 1) |
-                       SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
-
-               tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
-                       SSC_BF(TCMR_STTDLY, 1) |
-                       SSC_BF(TCMR_START, SSC_START_RISING_RF) |
-                       SSC_BF(TCMR_CKI, SSC_CKI_RISING) |
-                       SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
-                       SSC_BF(TCMR_CKS, SSC_CKS_DIV));
-
-               tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
-                       SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) |
-                       SSC_BF(TFMR_DATNB, channels - 1) |
-                       SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
-               break;
-
-
-       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
-       default:
-               pr_warning("at32-ssc: unsupported DAI format 0x%x\n",
-                          ssc_p->daifmt);
-               return -EINVAL;
-               break;
-       }
-       pr_debug("at32-ssc: RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
-                rcmr, rfmr, tcmr, tfmr);
-
-
-       if (!ssc_p->initialized) {
-               /* enable peripheral clock */
-               pr_debug("at32-ssc: Starting clock\n");
-               clk_enable(ssc_p->ssc->clk);
-
-               /* Reset the SSC and its PDC registers */
-               ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
-
-               ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
-
-               ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
-               ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
-
-               ret = request_irq(ssc_p->ssc->irq, at32_ssc_interrupt, 0,
-                                 ssc_p->name, ssc_p);
-               if (ret < 0) {
-                       pr_warning("at32-ssc: request irq failed (%d)\n", ret);
-                       pr_debug("at32-ssc: Stopping clock\n");
-                       clk_disable(ssc_p->ssc->clk);
-                       return ret;
-               }
-
-               ssc_p->initialized = 1;
-       }
-
-       /* Set SSC clock mode register */
-       ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
-
-       /* set receive clock mode and format */
-       ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
-       ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
-
-       /* set transmit clock mode and format */
-       ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
-       ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
-
-       pr_debug("at32-ssc: SSC initialized\n");
-       return 0;
-}
-
-
-
-static int at32_ssc_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at32_pcm_dma_params *dma_params;
-
-       dma_params = ssc_p->dma_params[substream->stream];
-
-       ssc_writel(dma_params->ssc->regs, CR, dma_params->mask->ssc_enable);
-
-       return 0;
-}
-
-
-
-#ifdef CONFIG_PM
-static int at32_ssc_suspend(struct platform_device *pdev,
-                           struct snd_soc_dai *cpu_dai)
-{
-       struct at32_ssc_info *ssc_p;
-
-       if (!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       /* Save the status register before disabling transmit and receive */
-       ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
-       ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
-
-       /* Save the current interrupt mask, then disable unmasked interrupts */
-       ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
-       ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
-
-       ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
-       ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
-       ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
-       ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
-       ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
-
-       return 0;
-}
-
-
-
-static int at32_ssc_resume(struct platform_device *pdev,
-                          struct snd_soc_dai *cpu_dai)
-{
-       struct at32_ssc_info *ssc_p;
-       u32 cr;
-
-       if (!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       /* restore SSC register settings */
-       ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
-       ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
-       ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
-       ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
-       ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
-
-       /* re-enable interrupts */
-       ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
-
-       /* Re-enable recieve and transmit as appropriate */
-       cr = 0;
-       cr |=
-           (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
-       cr |=
-           (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
-       ssc_writel(ssc_p->ssc->regs, CR, cr);
-
-       return 0;
-}
-#else /* CONFIG_PM */
-#  define at32_ssc_suspend     NULL
-#  define at32_ssc_resume      NULL
-#endif /* CONFIG_PM */
-
-
-#define AT32_SSC_RATES \
-    (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
-     SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
-     SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
-
-
-#define AT32_SSC_FORMATS \
-    (SNDRV_PCM_FMTBIT_S8  | SNDRV_PCM_FMTBIT_S16 | \
-     SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32)
-
-
-struct snd_soc_dai at32_ssc_dai[NUM_SSC_DEVICES] = {
-       {
-        .name = "at32-ssc0",
-        .id = 0,
-        .type = SND_SOC_DAI_PCM,
-        .suspend = at32_ssc_suspend,
-        .resume = at32_ssc_resume,
-        .playback = {
-                     .channels_min = 1,
-                     .channels_max = 2,
-                     .rates = AT32_SSC_RATES,
-                     .formats = AT32_SSC_FORMATS,
-                     },
-        .capture = {
-                    .channels_min = 1,
-                    .channels_max = 2,
-                    .rates = AT32_SSC_RATES,
-                    .formats = AT32_SSC_FORMATS,
-                    },
-        .ops = {
-                .startup = at32_ssc_startup,
-                .shutdown = at32_ssc_shutdown,
-                .prepare = at32_ssc_prepare,
-                .hw_params = at32_ssc_hw_params,
-                },
-        .dai_ops = {
-                    .set_sysclk = at32_ssc_set_dai_sysclk,
-                    .set_fmt = at32_ssc_set_dai_fmt,
-                    .set_clkdiv = at32_ssc_set_dai_clkdiv,
-                    },
-        .private_data = &ssc_info[0],
-        },
-       {
-        .name = "at32-ssc1",
-        .id = 1,
-        .type = SND_SOC_DAI_PCM,
-        .suspend = at32_ssc_suspend,
-        .resume = at32_ssc_resume,
-        .playback = {
-                     .channels_min = 1,
-                     .channels_max = 2,
-                     .rates = AT32_SSC_RATES,
-                     .formats = AT32_SSC_FORMATS,
-                     },
-        .capture = {
-                    .channels_min = 1,
-                    .channels_max = 2,
-                    .rates = AT32_SSC_RATES,
-                    .formats = AT32_SSC_FORMATS,
-                    },
-        .ops = {
-                .startup = at32_ssc_startup,
-                .shutdown = at32_ssc_shutdown,
-                .prepare = at32_ssc_prepare,
-                .hw_params = at32_ssc_hw_params,
-                },
-        .dai_ops = {
-                    .set_sysclk = at32_ssc_set_dai_sysclk,
-                    .set_fmt = at32_ssc_set_dai_fmt,
-                    .set_clkdiv = at32_ssc_set_dai_clkdiv,
-                    },
-        .private_data = &ssc_info[1],
-        },
-       {
-        .name = "at32-ssc2",
-        .id = 2,
-        .type = SND_SOC_DAI_PCM,
-        .suspend = at32_ssc_suspend,
-        .resume = at32_ssc_resume,
-        .playback = {
-                     .channels_min = 1,
-                     .channels_max = 2,
-                     .rates = AT32_SSC_RATES,
-                     .formats = AT32_SSC_FORMATS,
-                     },
-        .capture = {
-                    .channels_min = 1,
-                    .channels_max = 2,
-                    .rates = AT32_SSC_RATES,
-                    .formats = AT32_SSC_FORMATS,
-                    },
-        .ops = {
-                .startup = at32_ssc_startup,
-                .shutdown = at32_ssc_shutdown,
-                .prepare = at32_ssc_prepare,
-                .hw_params = at32_ssc_hw_params,
-                },
-        .dai_ops = {
-                    .set_sysclk = at32_ssc_set_dai_sysclk,
-                    .set_fmt = at32_ssc_set_dai_fmt,
-                    .set_clkdiv = at32_ssc_set_dai_clkdiv,
-                    },
-        .private_data = &ssc_info[2],
-        },
-};
-EXPORT_SYMBOL_GPL(at32_ssc_dai);
-
-
-MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
-MODULE_DESCRIPTION("AT32 SSC ASoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-ssc.h b/sound/soc/at32/at32-ssc.h
deleted file mode 100644 (file)
index 3c052db..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* sound/soc/at32/at32-ssc.h
- * ASoC SSC interface for Atmel AT32 SoC
- *
- * Copyright (C) 2008 Long Range Systems
- *    Geoffrey Wossum <gwossum@acm.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __SOUND_SOC_AT32_AT32_SSC_H
-#define __SOUND_SOC_AT32_AT32_SSC_H __FILE__
-
-#include <linux/types.h>
-#include <linux/atmel-ssc.h>
-
-#include "at32-pcm.h"
-
-
-
-struct at32_ssc_state {
-       u32 ssc_cmr;
-       u32 ssc_rcmr;
-       u32 ssc_rfmr;
-       u32 ssc_tcmr;
-       u32 ssc_tfmr;
-       u32 ssc_sr;
-       u32 ssc_imr;
-};
-
-
-
-struct at32_ssc_info {
-       char *name;
-       struct ssc_device *ssc;
-       spinlock_t lock;        /* lock for dir_mask */
-       unsigned short dir_mask;        /* 0=unused, 1=playback, 2=capture */
-       unsigned short initialized;     /* true if SSC has been initialized */
-       unsigned short daifmt;
-       unsigned short cmr_div;
-       unsigned short tcmr_period;
-       unsigned short rcmr_period;
-       struct at32_pcm_dma_params *dma_params[2];
-       struct at32_ssc_state ssc_state;
-};
-
-
-/* SSC divider ids */
-#define AT32_SSC_CMR_DIV        0      /* MCK divider for BCLK */
-#define AT32_SSC_TCMR_PERIOD    1      /* BCLK divider for transmit FS */
-#define AT32_SSC_RCMR_PERIOD    2      /* BCLK divider for receive FS */
-
-
-extern struct snd_soc_dai at32_ssc_dai[];
-
-
-
-#endif /* __SOUND_SOC_AT32_AT32_SSC_H */
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
deleted file mode 100644 (file)
index 85a8832..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-config SND_AT91_SOC
-       tristate "SoC Audio for the Atmel AT91 System-on-Chip"
-       depends on ARCH_AT91
-       help
-         Say Y or M if you want to add support for codecs attached to
-         the AT91 SSC interface. You will also need
-         to select the audio interfaces to support below.
-
-config SND_AT91_SOC_SSC
-       tristate
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
deleted file mode 100644 (file)
index b817f11..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-# AT91 Platform Support
-snd-soc-at91-objs := at91-pcm.o
-snd-soc-at91-ssc-objs := at91-ssc.o
-
-obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
-obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
deleted file mode 100644 (file)
index 7ab48bd..0000000
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * at91-pcm.c -- ALSA PCM interface for the Atmel AT91 SoC
- *
- * Author:     Frank Mandarino <fmandarino@endrelia.com>
- *             Endrelia Technologies Inc.
- * Created:    Mar 3, 2006
- *
- * Based on pxa2xx-pcm.c by:
- *
- * Author:     Nicolas Pitre
- * Created:    Nov 30, 2004
- * Copyright:  (C) 2004 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/dma-mapping.h>
-#include <linux/atmel_pdc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-#include <mach/at91_ssc.h>
-
-#include "at91-pcm.h"
-
-#if 0
-#define        DBG(x...)       printk(KERN_INFO "at91-pcm: " x)
-#else
-#define        DBG(x...)
-#endif
-
-static const struct snd_pcm_hardware at91_pcm_hardware = {
-       .info                   = SNDRV_PCM_INFO_MMAP |
-                                 SNDRV_PCM_INFO_MMAP_VALID |
-                                 SNDRV_PCM_INFO_INTERLEAVED |
-                                 SNDRV_PCM_INFO_PAUSE,
-       .formats                = SNDRV_PCM_FMTBIT_S16_LE,
-       .period_bytes_min       = 32,
-       .period_bytes_max       = 8192,
-       .periods_min            = 2,
-       .periods_max            = 1024,
-       .buffer_bytes_max       = 32 * 1024,
-};
-
-struct at91_runtime_data {
-       struct at91_pcm_dma_params *params;
-       dma_addr_t dma_buffer;                  /* physical address of dma buffer */
-       dma_addr_t dma_buffer_end;              /* first address beyond DMA buffer */
-       size_t period_size;
-       dma_addr_t period_ptr;                  /* physical address of next period */
-       u32 pdc_xpr_save;                       /* PDC register save */
-       u32 pdc_xcr_save;
-       u32 pdc_xnpr_save;
-       u32 pdc_xncr_save;
-};
-
-static void at91_pcm_dma_irq(u32 ssc_sr,
-       struct snd_pcm_substream *substream)
-{
-       struct at91_runtime_data *prtd = substream->runtime->private_data;
-       struct at91_pcm_dma_params *params = prtd->params;
-       static int count = 0;
-
-       count++;
-
-       if (ssc_sr & params->mask->ssc_endbuf) {
-
-               printk(KERN_WARNING
-                       "at91-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
-                       substream->stream == SNDRV_PCM_STREAM_PLAYBACK
-                               ? "underrun" : "overrun",
-                       params->name, ssc_sr, count);
-
-               /* re-start the PDC */
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
-
-               prtd->period_ptr += prtd->period_size;
-               if (prtd->period_ptr >= prtd->dma_buffer_end) {
-                       prtd->period_ptr = prtd->dma_buffer;
-               }
-
-               at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
-               at91_ssc_write(params->ssc_base + params->pdc->xcr,
-                               prtd->period_size / params->pdc_xfer_size);
-
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
-       }
-
-       if (ssc_sr & params->mask->ssc_endx) {
-
-               /* Load the PDC next pointer and counter registers */
-               prtd->period_ptr += prtd->period_size;
-               if (prtd->period_ptr >= prtd->dma_buffer_end) {
-                       prtd->period_ptr = prtd->dma_buffer;
-               }
-               at91_ssc_write(params->ssc_base + params->pdc->xnpr,
-                              prtd->period_ptr);
-               at91_ssc_write(params->ssc_base + params->pdc->xncr,
-                               prtd->period_size / params->pdc_xfer_size);
-       }
-
-       snd_pcm_period_elapsed(substream);
-}
-
-static int at91_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at91_runtime_data *prtd = runtime->private_data;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-
-       /* this may get called several times by oss emulation
-        * with different params */
-
-       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
-       runtime->dma_bytes = params_buffer_bytes(params);
-
-       prtd->params = rtd->dai->cpu_dai->dma_data;
-       prtd->params->dma_intr_handler = at91_pcm_dma_irq;
-
-       prtd->dma_buffer = runtime->dma_addr;
-       prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
-       prtd->period_size = params_period_bytes(params);
-
-       DBG("hw_params: DMA for %s initialized (dma_bytes=%d, period_size=%d)\n",
-               prtd->params->name, runtime->dma_bytes, prtd->period_size);
-       return 0;
-}
-
-static int at91_pcm_hw_free(struct snd_pcm_substream *substream)
-{
-       struct at91_runtime_data *prtd = substream->runtime->private_data;
-       struct at91_pcm_dma_params *params = prtd->params;
-
-       if (params != NULL) {
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
-               prtd->params->dma_intr_handler = NULL;
-       }
-
-       return 0;
-}
-
-static int at91_pcm_prepare(struct snd_pcm_substream *substream)
-{
-       struct at91_runtime_data *prtd = substream->runtime->private_data;
-       struct at91_pcm_dma_params *params = prtd->params;
-
-       at91_ssc_write(params->ssc_base + AT91_SSC_IDR,
-                       params->mask->ssc_endx | params->mask->ssc_endbuf);
-
-       at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
-       return 0;
-}
-
-static int at91_pcm_trigger(struct snd_pcm_substream *substream,
-       int cmd)
-{
-       struct at91_runtime_data *prtd = substream->runtime->private_data;
-       struct at91_pcm_dma_params *params = prtd->params;
-       int ret = 0;
-
-       switch (cmd) {
-       case SNDRV_PCM_TRIGGER_START:
-               prtd->period_ptr = prtd->dma_buffer;
-
-               at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
-               at91_ssc_write(params->ssc_base + params->pdc->xcr,
-                               prtd->period_size / params->pdc_xfer_size);
-
-               prtd->period_ptr += prtd->period_size;
-               at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
-               at91_ssc_write(params->ssc_base + params->pdc->xncr,
-                               prtd->period_size / params->pdc_xfer_size);
-
-               DBG("trigger: period_ptr=%lx, xpr=%lx, xcr=%ld, xnpr=%lx, xncr=%ld\n",
-                       (unsigned long) prtd->period_ptr,
-                       at91_ssc_read(params->ssc_base + params->pdc->xpr),
-                       at91_ssc_read(params->ssc_base + params->pdc->xcr),
-                       at91_ssc_read(params->ssc_base + params->pdc->xnpr),
-                       at91_ssc_read(params->ssc_base + params->pdc->xncr));
-
-               at91_ssc_write(params->ssc_base + AT91_SSC_IER,
-                       params->mask->ssc_endx | params->mask->ssc_endbuf);
-
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
-                       params->mask->pdc_enable);
-
-               DBG("sr=%lx imr=%lx\n",
-                   at91_ssc_read(params->ssc_base + AT91_SSC_SR),
-                   at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
-               break;
-
-       case SNDRV_PCM_TRIGGER_STOP:
-       case SNDRV_PCM_TRIGGER_SUSPEND:
-       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
-               break;
-
-       case SNDRV_PCM_TRIGGER_RESUME:
-       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-               at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
-               break;
-
-       default:
-               ret = -EINVAL;
-       }
-
-       return ret;
-}
-
-static snd_pcm_uframes_t at91_pcm_pointer(
-       struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at91_runtime_data *prtd = runtime->private_data;
-       struct at91_pcm_dma_params *params = prtd->params;
-       dma_addr_t ptr;
-       snd_pcm_uframes_t x;
-
-       ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr);
-       x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
-
-       if (x == runtime->buffer_size)
-               x = 0;
-       return x;
-}
-
-static int at91_pcm_open(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct at91_runtime_data *prtd;
-       int ret = 0;
-
-       snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware);
-
-       /* ensure that buffer size is a multiple of period size */
-       ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
-       if (ret < 0)
-               goto out;
-
-       prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL);
-       if (prtd == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
-       runtime->private_data = prtd;
-
- out:
-       return ret;
-}
-
-static int at91_pcm_close(struct snd_pcm_substream *substream)
-{
-       struct at91_runtime_data *prtd = substream->runtime->private_data;
-
-       kfree(prtd);
-       return 0;
-}
-
-static int at91_pcm_mmap(struct snd_pcm_substream *substream,
-       struct vm_area_struct *vma)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-
-       return dma_mmap_writecombine(substream->pcm->card->dev, vma,
-                                    runtime->dma_area,
-                                    runtime->dma_addr,
-                                    runtime->dma_bytes);
-}
-
-struct snd_pcm_ops at91_pcm_ops = {
-       .open           = at91_pcm_open,
-       .close          = at91_pcm_close,
-       .ioctl          = snd_pcm_lib_ioctl,
-       .hw_params      = at91_pcm_hw_params,
-       .hw_free        = at91_pcm_hw_free,
-       .prepare        = at91_pcm_prepare,
-       .trigger        = at91_pcm_trigger,
-       .pointer        = at91_pcm_pointer,
-       .mmap           = at91_pcm_mmap,
-};
-
-static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
-       int stream)
-{
-       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
-       struct snd_dma_buffer *buf = &substream->dma_buffer;
-       size_t size = at91_pcm_hardware.buffer_bytes_max;
-
-       buf->dev.type = SNDRV_DMA_TYPE_DEV;
-       buf->dev.dev = pcm->card->dev;
-       buf->private_data = NULL;
-       buf->area = dma_alloc_writecombine(pcm->card->dev, size,
-                                          &buf->addr, GFP_KERNEL);
-
-       DBG("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
-               (void *) buf->area,
-               (void *) buf->addr,
-               size);
-
-       if (!buf->area)
-               return -ENOMEM;
-
-       buf->bytes = size;
-       return 0;
-}
-
-static u64 at91_pcm_dmamask = 0xffffffff;
-
-static int at91_pcm_new(struct snd_card *card,
-       struct snd_soc_dai *dai, struct snd_pcm *pcm)
-{
-       int ret = 0;
-
-       if (!card->dev->dma_mask)
-               card->dev->dma_mask = &at91_pcm_dmamask;
-       if (!card->dev->coherent_dma_mask)
-               card->dev->coherent_dma_mask = 0xffffffff;
-
-       if (dai->playback.channels_min) {
-               ret = at91_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_PLAYBACK);
-               if (ret)
-                       goto out;
-       }
-
-       if (dai->capture.channels_min) {
-               ret = at91_pcm_preallocate_dma_buffer(pcm,
-                       SNDRV_PCM_STREAM_CAPTURE);
-               if (ret)
-                       goto out;
-       }
- out:
-       return ret;
-}
-
-static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm)
-{
-       struct snd_pcm_substream *substream;
-       struct snd_dma_buffer *buf;
-       int stream;
-
-       for (stream = 0; stream < 2; stream++) {
-               substream = pcm->streams[stream].substream;
-               if (!substream)
-                       continue;
-
-               buf = &substream->dma_buffer;
-               if (!buf->area)
-                       continue;
-
-               dma_free_writecombine(pcm->card->dev, buf->bytes,
-                                     buf->area, buf->addr);
-               buf->area = NULL;
-       }
-}
-
-#ifdef CONFIG_PM
-static int at91_pcm_suspend(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
-{
-       struct snd_pcm_runtime *runtime = dai->runtime;
-       struct at91_runtime_data *prtd;
-       struct at91_pcm_dma_params *params;
-
-       if (!runtime)
-               return 0;
-
-       prtd = runtime->private_data;
-       params = prtd->params;
-
-       /* disable the PDC and save the PDC registers */
-
-       at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
-
-       prtd->pdc_xpr_save  = at91_ssc_read(params->ssc_base + params->pdc->xpr);
-       prtd->pdc_xcr_save  = at91_ssc_read(params->ssc_base + params->pdc->xcr);
-       prtd->pdc_xnpr_save = at91_ssc_read(params->ssc_base + params->pdc->xnpr);
-       prtd->pdc_xncr_save = at91_ssc_read(params->ssc_base + params->pdc->xncr);
-
-       return 0;
-}
-
-static int at91_pcm_resume(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
-{
-       struct snd_pcm_runtime *runtime = dai->runtime;
-       struct at91_runtime_data *prtd;
-       struct at91_pcm_dma_params *params;
-
-       if (!runtime)
-               return 0;
-
-       prtd = runtime->private_data;
-       params = prtd->params;
-
-       /* restore the PDC registers and enable the PDC */
-       at91_ssc_write(params->ssc_base + params->pdc->xpr,  prtd->pdc_xpr_save);
-       at91_ssc_write(params->ssc_base + params->pdc->xcr,  prtd->pdc_xcr_save);
-       at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->pdc_xnpr_save);
-       at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->pdc_xncr_save);
-
-       at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
-       return 0;
-}
-#else
-#define at91_pcm_suspend       NULL
-#define at91_pcm_resume                NULL
-#endif
-
-struct snd_soc_platform at91_soc_platform = {
-       .name           = "at91-audio",
-       .pcm_ops        = &at91_pcm_ops,
-       .pcm_new        = at91_pcm_new,
-       .pcm_free       = at91_pcm_free_dma_buffers,
-       .suspend        = at91_pcm_suspend,
-       .resume         = at91_pcm_resume,
-};
-
-EXPORT_SYMBOL_GPL(at91_soc_platform);
-
-MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
-MODULE_DESCRIPTION("Atmel AT91 PCM module");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h
deleted file mode 100644 (file)
index e5aada2..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC
- *
- * Author:     Frank Mandarino <fmandarino@endrelia.com>
- *             Endrelia Technologies Inc.
- * Created:    Mar 3, 2006
- *
- * Based on pxa2xx-pcm.h by:
- *
- * Author:     Nicolas Pitre
- * Created:    Nov 30, 2004
- * Copyright:  MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AT91_PCM_H
-#define _AT91_PCM_H
-
-#include <mach/hardware.h>
-
-struct at91_ssc_periph {
-       void __iomem    *base;
-       u32             pid;
-};
-
-/*
- * Registers and status bits that are required by the PCM driver.
- */
-struct at91_pdc_regs {
-       unsigned int    xpr;            /* PDC recv/trans pointer */
-       unsigned int    xcr;            /* PDC recv/trans counter */
-       unsigned int    xnpr;           /* PDC next recv/trans pointer */
-       unsigned int    xncr;           /* PDC next recv/trans counter */
-       unsigned int    ptcr;           /* PDC transfer control */
-};
-
-struct at91_ssc_mask {
-       u32     ssc_enable;             /* SSC recv/trans enable */
-       u32     ssc_disable;            /* SSC recv/trans disable */
-       u32     ssc_endx;               /* SSC ENDTX or ENDRX */
-       u32     ssc_endbuf;             /* SSC TXBUFE or RXBUFF */
-       u32     pdc_enable;             /* PDC recv/trans enable */
-       u32     pdc_disable;            /* PDC recv/trans disable */
-};
-
-/*
- * This structure, shared between the PCM driver and the interface,
- * contains all information required by the PCM driver to perform the
- * PDC DMA operation.  All fields except dma_intr_handler() are initialized
- * by the interface.  The dms_intr_handler() pointer is set by the PCM
- * driver and called by the interface SSC interrupt handler if it is
- * non-NULL.
- */
-struct at91_pcm_dma_params {
-       char *name;                     /* stream identifier */
-       int pdc_xfer_size;              /* PDC counter increment in bytes */
-       void __iomem *ssc_base;         /* SSC base address */
-       struct at91_pdc_regs *pdc; /* PDC receive or transmit registers */
-       struct at91_ssc_mask *mask;/* SSC & PDC status bits */
-       struct snd_pcm_substream *substream;
-       void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
-};
-
-extern struct snd_soc_platform at91_soc_platform;
-
-#define at91_ssc_read(a)       ((unsigned long) __raw_readl(a))
-#define at91_ssc_write(a,v)    __raw_writel((v),(a))
-
-#endif /* _AT91_PCM_H */
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
deleted file mode 100644 (file)
index 1b61cc4..0000000
+++ /dev/null
@@ -1,791 +0,0 @@
-/*
- * at91-ssc.c  --  ALSA SoC AT91 SSC Audio Layer Platform driver
- *
- * Author: Frank Mandarino <fmandarino@endrelia.com>
- *         Endrelia Technologies Inc.
- *
- * Based on pxa2xx Platform drivers by
- * Liam Girdwood <lrg@slimlogic.co.uk>
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/atmel_pdc.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include <mach/hardware.h>
-#include <mach/at91_pmc.h>
-#include <mach/at91_ssc.h>
-
-#include "at91-pcm.h"
-#include "at91-ssc.h"
-
-#if 0
-#define        DBG(x...)       printk(KERN_DEBUG "at91-ssc:" x)
-#else
-#define        DBG(x...)
-#endif
-
-#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
-#define NUM_SSC_DEVICES                1
-#else
-#define NUM_SSC_DEVICES                3
-#endif
-
-
-/*
- * SSC PDC registers required by the PCM DMA engine.
- */
-static struct at91_pdc_regs pdc_tx_reg = {
-       .xpr            = ATMEL_PDC_TPR,
-       .xcr            = ATMEL_PDC_TCR,
-       .xnpr           = ATMEL_PDC_TNPR,
-       .xncr           = ATMEL_PDC_TNCR,
-};
-
-static struct at91_pdc_regs pdc_rx_reg = {
-       .xpr            = ATMEL_PDC_RPR,
-       .xcr            = ATMEL_PDC_RCR,
-       .xnpr           = ATMEL_PDC_RNPR,
-       .xncr           = ATMEL_PDC_RNCR,
-};
-
-/*
- * SSC & PDC status bits for transmit and receive.
- */
-static struct at91_ssc_mask ssc_tx_mask = {
-       .ssc_enable     = AT91_SSC_TXEN,
-       .ssc_disable    = AT91_SSC_TXDIS,
-       .ssc_endx       = AT91_SSC_ENDTX,
-       .ssc_endbuf     = AT91_SSC_TXBUFE,
-       .pdc_enable     = ATMEL_PDC_TXTEN,
-       .pdc_disable    = ATMEL_PDC_TXTDIS,
-};
-
-static struct at91_ssc_mask ssc_rx_mask = {
-       .ssc_enable     = AT91_SSC_RXEN,
-       .ssc_disable    = AT91_SSC_RXDIS,
-       .ssc_endx       = AT91_SSC_ENDRX,
-       .ssc_endbuf     = AT91_SSC_RXBUFF,
-       .pdc_enable     = ATMEL_PDC_RXTEN,
-       .pdc_disable    = ATMEL_PDC_RXTDIS,
-};
-
-
-/*
- * DMA parameters.
- */
-static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
-       {{
-       .name           = "SSC0 PCM out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC0 PCM in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-#if NUM_SSC_DEVICES == 3
-       {{
-       .name           = "SSC1 PCM out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC1 PCM in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-       {{
-       .name           = "SSC2 PCM out",
-       .pdc            = &pdc_tx_reg,
-       .mask           = &ssc_tx_mask,
-       },
-       {
-       .name           = "SSC2 PCM in",
-       .pdc            = &pdc_rx_reg,
-       .mask           = &ssc_rx_mask,
-       }},
-#endif
-};
-
-struct at91_ssc_state {
-       u32     ssc_cmr;
-       u32     ssc_rcmr;
-       u32     ssc_rfmr;
-       u32     ssc_tcmr;
-       u32     ssc_tfmr;
-       u32     ssc_sr;
-       u32     ssc_imr;
-};
-
-static struct at91_ssc_info {
-       char            *name;
-       struct at91_ssc_periph ssc;
-       spinlock_t      lock;           /* lock for dir_mask */
-       unsigned short  dir_mask;       /* 0=unused, 1=playback, 2=capture */
-       unsigned short  initialized;    /* 1=SSC has been initialized */
-       unsigned short  daifmt;
-       unsigned short  cmr_div;
-       unsigned short  tcmr_period;
-       unsigned short  rcmr_period;
-       struct at91_pcm_dma_params *dma_params[2];
-       struct at91_ssc_state ssc_state;
-
-} ssc_info[NUM_SSC_DEVICES] = {
-       {
-       .name           = "ssc0",
-       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-#if NUM_SSC_DEVICES == 3
-       {
-       .name           = "ssc1",
-       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-       {
-       .name           = "ssc2",
-       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
-       .dir_mask       = 0,
-       .initialized    = 0,
-       },
-#endif
-};
-
-static unsigned int at91_ssc_sysclk;
-
-/*
- * SSC interrupt handler.  Passes PDC interrupts to the DMA
- * interrupt handler in the PCM driver.
- */
-static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
-{
-       struct at91_ssc_info *ssc_p = dev_id;
-       struct at91_pcm_dma_params *dma_params;
-       u32 ssc_sr;
-       int i;
-
-       ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
-                       & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
-
-       /*
-        * Loop through the substreams attached to this SSC.  If
-        * a DMA-related interrupt occurred on that substream, call
-        * the DMA interrupt handler function, if one has been
-        * registered in the dma_params structure by the PCM driver.
-        */
-       for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
-               dma_params = ssc_p->dma_params[i];
-
-               if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
-                       (ssc_sr &
-                       (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
-
-                       dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
-       }
-
-       return IRQ_HANDLED;
-}
-
-/*
- * Startup.  Only that one substream allowed in each direction.
- */
-static int at91_ssc_startup(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       int dir_mask;
-
-       DBG("ssc_startup: SSC_SR=0x%08lx\n",
-                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
-       dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
-
-       spin_lock_irq(&ssc_p->lock);
-       if (ssc_p->dir_mask & dir_mask) {
-               spin_unlock_irq(&ssc_p->lock);
-               return -EBUSY;
-       }
-       ssc_p->dir_mask |= dir_mask;
-       spin_unlock_irq(&ssc_p->lock);
-
-       return 0;
-}
-
-/*
- * Shutdown.  Clear DMA parameters and shutdown the SSC if there
- * are no other substreams open.
- */
-static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir, dir_mask;
-
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-       dma_params = ssc_p->dma_params[dir];
-
-       if (dma_params != NULL) {
-               at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
-                               dma_params->mask->ssc_disable);
-               DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
-                       at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
-
-               dma_params->ssc_base = NULL;
-               dma_params->substream = NULL;
-               ssc_p->dma_params[dir] = NULL;
-       }
-
-       dir_mask = 1 << dir;
-
-       spin_lock_irq(&ssc_p->lock);
-       ssc_p->dir_mask &= ~dir_mask;
-       if (!ssc_p->dir_mask) {
-               /* Shutdown the SSC clock. */
-               DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-               at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
-
-               if (ssc_p->initialized) {
-                       free_irq(ssc_p->ssc.pid, ssc_p);
-                       ssc_p->initialized = 0;
-               }
-
-               /* Reset the SSC */
-               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
-
-               /* Clear the SSC dividers */
-               ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
-       }
-       spin_unlock_irq(&ssc_p->lock);
-}
-
-/*
- * Record the SSC system clock rate.
- */
-static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
-               int clk_id, unsigned int freq, int dir)
-{
-       /*
-        * The only clock supplied to the SSC is the AT91 master clock,
-        * which is only used if the SSC is generating BCLK and/or
-        * LRC clocks.
-        */
-       switch (clk_id) {
-       case AT91_SYSCLK_MCK:
-               at91_ssc_sysclk = freq;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * Record the DAI format for use in hw_params().
- */
-static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
-               unsigned int fmt)
-{
-       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       ssc_p->daifmt = fmt;
-       return 0;
-}
-
-/*
- * Record SSC clock dividers for use in hw_params().
- */
-static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
-       int div_id, int div)
-{
-       struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
-
-       switch (div_id) {
-       case AT91SSC_CMR_DIV:
-               /*
-                * The same master clock divider is used for both
-                * transmit and receive, so if a value has already
-                * been set, it must match this value.
-                */
-               if (ssc_p->cmr_div == 0)
-                       ssc_p->cmr_div = div;
-               else
-                       if (div != ssc_p->cmr_div)
-                               return -EBUSY;
-               break;
-
-       case AT91SSC_TCMR_PERIOD:
-               ssc_p->tcmr_period = div;
-               break;
-
-       case AT91SSC_RCMR_PERIOD:
-               ssc_p->rcmr_period = div;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/*
- * Configure the SSC.
- */
-static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       int id = rtd->dai->cpu_dai->id;
-       struct at91_ssc_info *ssc_p = &ssc_info[id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir, channels, bits;
-       u32 tfmr, rfmr, tcmr, rcmr;
-       int start_event;
-       int ret;
-
-       /*
-        * Currently, there is only one set of dma params for
-        * each direction.  If more are added, this code will
-        * have to be changed to select the proper set.
-        */
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-
-       dma_params = &ssc_dma_params[id][dir];
-       dma_params->ssc_base = ssc_p->ssc.base;
-       dma_params->substream = substream;
-
-       ssc_p->dma_params[dir] = dma_params;
-
-       /*
-        * The cpu_dai->dma_data field is only used to communicate the
-        * appropriate DMA parameters to the pcm driver hw_params()
-        * function.  It should not be used for other purposes
-        * as it is common to all substreams.
-        */
-       rtd->dai->cpu_dai->dma_data = dma_params;
-
-       channels = params_channels(params);
-
-       /*
-        * Determine sample size in bits and the PDC increment.
-        */
-       switch(params_format(params)) {
-       case SNDRV_PCM_FORMAT_S8:
-               bits = 8;
-               dma_params->pdc_xfer_size = 1;
-               break;
-       case SNDRV_PCM_FORMAT_S16_LE:
-               bits = 16;
-               dma_params->pdc_xfer_size = 2;
-               break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               bits = 24;
-               dma_params->pdc_xfer_size = 4;
-               break;
-       case SNDRV_PCM_FORMAT_S32_LE:
-               bits = 32;
-               dma_params->pdc_xfer_size = 4;
-               break;
-       default:
-               printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
-               return -EINVAL;
-       }
-
-       /*
-        * The SSC only supports up to 16-bit samples in I2S format, due
-        * to the size of the Frame Mode Register FSLEN field.
-        */
-       if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
-               && bits > 16) {
-               printk(KERN_WARNING
-                       "at91-ssc: sample size %d is too large for I2S\n", bits);
-               return -EINVAL;
-       }
-
-       /*
-        * Compute SSC register settings.
-        */
-       switch (ssc_p->daifmt
-               & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
-
-       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
-               /*
-                * I2S format, SSC provides BCLK and LRC clocks.
-                *
-                * The SSC transmit and receive clocks are generated from the
-                * MCK divider, and the BCLK signal is output on the SSC TK line.
-                */
-               rcmr =    (( ssc_p->rcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
-                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_LOOP)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-               tcmr =    (( ssc_p->tcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_FALLING_RF       ) & AT91_SSC_START)
-                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_CONTINUOUS         ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( 0                          << 23) & AT91_SSC_FSDEN)
-                       | (( AT91_SSC_FSOS_NEGATIVE          ) & AT91_SSC_FSOS)
-                       | (((bits - 1)                  << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-               break;
-
-       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
-               /*
-                * I2S format, CODEC supplies BCLK and LRC clocks.
-                *
-                * The SSC transmit clock is obtained from the BCLK signal on
-                * on the TK line, and the SSC receive clock is generated from the
-                * transmit clock.
-                *
-                * For single channel data, one sample is transferred on the falling
-                * edge of the LRC clock.  For two channel data, one sample is
-                * transferred on both edges of the LRC clock.
-                */
-               start_event = channels == 1
-                               ? AT91_SSC_START_FALLING_RF
-                               : AT91_SSC_START_EDGE_RF;
-
-               rcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( start_event                     ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_CLOCK              ) & AT91_SSC_CKS);
-
-               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (( 0                          <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_LOOP)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-               tcmr =    (( 0                          << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( start_event                     ) & AT91_SSC_START)
-                       | (( AT91_SSC_CKI_FALLING            ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_PIN                ) & AT91_SSC_CKS);
-
-               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( 0                          << 23) & AT91_SSC_FSDEN)
-                       | (( AT91_SSC_FSOS_NONE              ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (( 0                          <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-               break;
-
-       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
-               /*
-                * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
-                *
-                * The SSC transmit and receive clocks are generated from the
-                * MCK divider, and the BCLK signal is output on the SSC TK line.
-                */
-               rcmr =    (( ssc_p->rcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_RISING_RF        ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_NONE               ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               rfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( AT91_SSC_FSOS_POSITIVE          ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_LOOP)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-               tcmr =    (( ssc_p->tcmr_period         << 24) & AT91_SSC_PERIOD)
-                       | (( 1                          << 16) & AT91_SSC_STTDLY)
-                       | (( AT91_SSC_START_RISING_RF        ) & AT91_SSC_START)
-                       | (( AT91_SSC_CK_RISING              ) & AT91_SSC_CKI)
-                       | (( AT91_SSC_CKO_CONTINUOUS         ) & AT91_SSC_CKO)
-                       | (( AT91_SSC_CKS_DIV                ) & AT91_SSC_CKS);
-
-               tfmr =    (( AT91_SSC_FSEDGE_POSITIVE        ) & AT91_SSC_FSEDGE)
-                       | (( 0                          << 23) & AT91_SSC_FSDEN)
-                       | (( AT91_SSC_FSOS_POSITIVE          ) & AT91_SSC_FSOS)
-                       | (( 0                          << 16) & AT91_SSC_FSLEN)
-                       | (((channels - 1)              <<  8) & AT91_SSC_DATNB)
-                       | (( 1                          <<  7) & AT91_SSC_MSBF)
-                       | (( 0                          <<  5) & AT91_SSC_DATDEF)
-                       | (((bits - 1)                  <<  0) & AT91_SSC_DATALEN);
-
-
-
-                       break;
-
-       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
-       default:
-               printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
-                       ssc_p->daifmt);
-               return -EINVAL;
-               break;
-       }
-       DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
-
-       if (!ssc_p->initialized) {
-
-               /* Enable PMC peripheral clock for this SSC */
-               DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
-               at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
-
-               /* Reset the SSC and its PDC registers */
-               at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
-
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
-               at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
-
-               if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
-                                       0, ssc_p->name, ssc_p)) < 0) {
-                       printk(KERN_WARNING "at91-ssc: request_irq failure\n");
-
-                       DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
-                       at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
-                       return ret;
-               }
-
-               ssc_p->initialized = 1;
-       }
-
-       /* set SSC clock mode register */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
-
-       /* set receive clock mode and format */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
-
-       /* set transmit clock mode and format */
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
-
-       DBG("hw_params: SSC initialized\n");
-       return 0;
-}
-
-
-static int at91_ssc_prepare(struct snd_pcm_substream *substream)
-{
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
-       struct at91_pcm_dma_params *dma_params;
-       int dir;
-
-       dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
-       dma_params = ssc_p->dma_params[dir];
-
-       at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
-                       dma_params->mask->ssc_enable);
-
-       DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
-               at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
-       return 0;
-}
-
-
-#ifdef CONFIG_PM
-static int at91_ssc_suspend(struct platform_device *pdev,
-       struct snd_soc_dai *cpu_dai)
-{
-       struct at91_ssc_info *ssc_p;
-
-       if(!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       /* Save the status register before disabling transmit and receive. */
-       ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
-                       AT91_SSC_TXDIS | AT91_SSC_RXDIS);
-
-       /* Save the current interrupt mask, then disable unmasked interrupts. */
-       ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
-
-       ssc_p->ssc_state.ssc_cmr  = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
-       ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
-       ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
-       ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
-       ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
-
-       return 0;
-}
-
-static int at91_ssc_resume(struct platform_device *pdev,
-       struct snd_soc_dai *cpu_dai)
-{
-       struct at91_ssc_info *ssc_p;
-
-       if(!cpu_dai->active)
-               return 0;
-
-       ssc_p = &ssc_info[cpu_dai->id];
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR,  ssc_p->ssc_state.ssc_cmr);
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER,  ssc_p->ssc_state.ssc_imr);
-
-       at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
-               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
-               ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
-
-       return 0;
-}
-
-#else
-#define at91_ssc_suspend       NULL
-#define at91_ssc_resume                NULL
-#endif
-
-#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000  | SNDRV_PCM_RATE_11025 |\
-                       SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
-                       SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
-                       SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
-                       SNDRV_PCM_RATE_96000)
-
-#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_LE |\
-                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
-
-struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
-       {       .name = "at91-ssc0",
-               .id = 0,
-               .type = SND_SOC_DAI_PCM,
-               .suspend = at91_ssc_suspend,
-               .resume = at91_ssc_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .ops = {
-                       .startup = at91_ssc_startup,
-                       .shutdown = at91_ssc_shutdown,
-                       .prepare = at91_ssc_prepare,
-                       .hw_params = at91_ssc_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_ssc_set_dai_sysclk,
-                       .set_fmt = at91_ssc_set_dai_fmt,
-                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
-               .private_data = &ssc_info[0].ssc,
-       },
-#if NUM_SSC_DEVICES == 3
-       {       .name = "at91-ssc1",
-               .id = 1,
-               .type = SND_SOC_DAI_PCM,
-               .suspend = at91_ssc_suspend,
-               .resume = at91_ssc_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .ops = {
-                       .startup = at91_ssc_startup,
-                       .shutdown = at91_ssc_shutdown,
-                       .prepare = at91_ssc_prepare,
-                       .hw_params = at91_ssc_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_ssc_set_dai_sysclk,
-                       .set_fmt = at91_ssc_set_dai_fmt,
-                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
-               .private_data = &ssc_info[1].ssc,
-       },
-       {       .name = "at91-ssc2",
-               .id = 2,
-               .type = SND_SOC_DAI_PCM,
-               .suspend = at91_ssc_suspend,
-               .resume = at91_ssc_resume,
-               .playback = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .capture = {
-                       .channels_min = 1,
-                       .channels_max = 2,
-                       .rates = AT91_SSC_RATES,
-                       .formats = AT91_SSC_FORMATS,},
-               .ops = {
-                       .startup = at91_ssc_startup,
-                       .shutdown = at91_ssc_shutdown,
-                       .prepare = at91_ssc_prepare,
-                       .hw_params = at91_ssc_hw_params,},
-               .dai_ops = {
-                       .set_sysclk = at91_ssc_set_dai_sysclk,
-                       .set_fmt = at91_ssc_set_dai_fmt,
-                       .set_clkdiv = at91_ssc_set_dai_clkdiv,},
-               .private_data = &ssc_info[2].ssc,
-       },
-#endif
-};
-
-EXPORT_SYMBOL_GPL(at91_ssc_dai);
-
-/* Module information */
-MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
-MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
-MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
deleted file mode 100644 (file)
index 6b7bf38..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
- *
- * Author:     Frank Mandarino <fmandarino@endrelia.com>
- *             Endrelia Technologies Inc.
- * Created:    Jan 9, 2007
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef _AT91_SSC_H
-#define _AT91_SSC_H
-
-/* SSC system clock ids */
-#define AT91_SYSCLK_MCK                0 /* SSC uses AT91 MCK as system clock */
-
-/* SSC divider ids */
-#define AT91SSC_CMR_DIV                0 /* MCK divider for BCLK */
-#define AT91SSC_TCMR_PERIOD    1 /* BCLK divider for transmit FS */
-#define AT91SSC_RCMR_PERIOD    2 /* BCLK divider for receive FS */
-
-extern struct snd_soc_dai at91_ssc_dai[];
-
-#endif /* _AT91_SSC_H */
-
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
new file mode 100644 (file)
index 0000000..a608d70
--- /dev/null
@@ -0,0 +1,43 @@
+config SND_ATMEL_SOC
+       tristate "SoC Audio for the Atmel System-on-Chip"
+       depends on ARCH_AT91 || AVR32
+       help
+         Say Y or M if you want to add support for codecs attached to
+         the ATMEL SSC interface. You will also need
+         to select the audio interfaces to support below.
+
+config SND_ATMEL_SOC_SSC
+       tristate
+       depends on SND_ATMEL_SOC
+       help
+         Say Y or M if you want to add support for codecs the
+         ATMEL SSC interface. You will also needs to select the individual
+         machine drivers to support below.
+
+config SND_AT91_SOC_SAM9G20_WM8731
+       tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
+       depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
+       select SND_ATMEL_SOC_SSC
+       select SND_SOC_WM8731
+       help
+         Say Y if you want to add support for SoC audio on WM8731-based
+         AT91sam9g20 evaluation board.
+
+config SND_AT32_SOC_PLAYPAQ
+        tristate "SoC Audio support for PlayPaq with WM8510"
+        depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
+        select SND_ATMEL_SOC_SSC
+        select SND_SOC_WM8510
+        help
+          Say Y or M here if you want to add support for SoC audio
+          on the LRS PlayPaq.
+
+config SND_AT32_SOC_PLAYPAQ_SLAVE
+        bool "Run CODEC on PlayPaq in slave mode"
+        depends on SND_AT32_SOC_PLAYPAQ
+        default n
+        help
+          Say Y if you want to run with the AT32 SSC generating the BCLK
+          and FRAME signals on the PlayPaq.  Unless you want to play
+          with the AT32 as the SSC master, you probably want to say N here,
+          as this will give you better sound quality.
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
new file mode 100644 (file)
index 0000000..f54a7cc
--- /dev/null
@@ -0,0 +1,15 @@
+# AT91 Platform Support
+snd-soc-atmel-pcm-objs := atmel-pcm.o
+snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
+
+obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
+obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
+
+# AT91 Machine Support
+snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
+
+# AT32 Machine Support
+snd-soc-playpaq-objs := playpaq_wm8510.o
+
+obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
+obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
new file mode 100644 (file)
index 0000000..1fac5ef
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+ * atmel-pcm.c  --  ALSA PCM interface for the Atmel atmel SoC.
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *
+ * Based on at91-pcm. by:
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Copyright 2006 Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx-pcm.c by:
+ *
+ * Author:     Nicolas Pitre
+ * Created:    Nov 30, 2004
+ * Copyright:  (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/dma-mapping.h>
+#include <linux/atmel_pdc.h>
+#include <linux/atmel-ssc.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+
+#include <mach/hardware.h>
+
+#include "atmel-pcm.h"
+
+
+/*--------------------------------------------------------------------------*\
+ * Hardware definition
+\*--------------------------------------------------------------------------*/
+/* TODO: These values were taken from the AT91 platform driver, check
+ *      them against real values for AT32
+ */
+static const struct snd_pcm_hardware atmel_pcm_hardware = {
+       .info                   = SNDRV_PCM_INFO_MMAP |
+                                 SNDRV_PCM_INFO_MMAP_VALID |
+                                 SNDRV_PCM_INFO_INTERLEAVED |
+                                 SNDRV_PCM_INFO_PAUSE,
+       .formats                = SNDRV_PCM_FMTBIT_S16_LE,
+       .period_bytes_min       = 32,
+       .period_bytes_max       = 8192,
+       .periods_min            = 2,
+       .periods_max            = 1024,
+       .buffer_bytes_max       = 32 * 1024,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * Data types
+\*--------------------------------------------------------------------------*/
+struct atmel_runtime_data {
+       struct atmel_pcm_dma_params *params;
+       dma_addr_t dma_buffer;          /* physical address of dma buffer */
+       dma_addr_t dma_buffer_end;      /* first address beyond DMA buffer */
+       size_t period_size;
+
+       dma_addr_t period_ptr;          /* physical address of next period */
+       int periods;                    /* period index of period_ptr */
+
+       /* PDC register save */
+       u32 pdc_xpr_save;
+       u32 pdc_xcr_save;
+       u32 pdc_xnpr_save;
+       u32 pdc_xncr_save;
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * Helper functions
+\*--------------------------------------------------------------------------*/
+static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
+       int stream)
+{
+       struct snd_pcm_substream *substream = pcm->streams[stream].substream;
+       struct snd_dma_buffer *buf = &substream->dma_buffer;
+       size_t size = atmel_pcm_hardware.buffer_bytes_max;
+
+       buf->dev.type = SNDRV_DMA_TYPE_DEV;
+       buf->dev.dev = pcm->card->dev;
+       buf->private_data = NULL;
+       buf->area = dma_alloc_coherent(pcm->card->dev, size,
+                                         &buf->addr, GFP_KERNEL);
+       pr_debug("atmel-pcm:"
+               "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
+               (void *) buf->area,
+               (void *) buf->addr,
+               size);
+
+       if (!buf->area)
+               return -ENOMEM;
+
+       buf->bytes = size;
+       return 0;
+}
+/*--------------------------------------------------------------------------*\
+ * ISR
+\*--------------------------------------------------------------------------*/
+static void atmel_pcm_dma_irq(u32 ssc_sr,
+       struct snd_pcm_substream *substream)
+{
+       struct atmel_runtime_data *prtd = substream->runtime->private_data;
+       struct atmel_pcm_dma_params *params = prtd->params;
+       static int count;
+
+       count++;
+
+       if (ssc_sr & params->mask->ssc_endbuf) {
+               pr_warning("atmel-pcm: buffer %s on %s"
+                               " (SSC_SR=%#x, count=%d)\n",
+                               substream->stream == SNDRV_PCM_STREAM_PLAYBACK
+                               ? "underrun" : "overrun",
+                               params->name, ssc_sr, count);
+
+               /* re-start the PDC */
+               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                          params->mask->pdc_disable);
+               prtd->period_ptr += prtd->period_size;
+               if (prtd->period_ptr >= prtd->dma_buffer_end)
+                       prtd->period_ptr = prtd->dma_buffer;
+
+               ssc_writex(params->ssc->regs, params->pdc->xpr,
+                          prtd->period_ptr);
+               ssc_writex(params->ssc->regs, params->pdc->xcr,
+                          prtd->period_size / params->pdc_xfer_size);
+               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                          params->mask->pdc_enable);
+       }
+
+       if (ssc_sr & params->mask->ssc_endx) {
+               /* Load the PDC next pointer and counter registers */
+               prtd->period_ptr += prtd->period_size;
+               if (prtd->period_ptr >= prtd->dma_buffer_end)
+                       prtd->period_ptr = prtd->dma_buffer;
+
+               ssc_writex(params->ssc->regs, params->pdc->xnpr,
+                          prtd->period_ptr);
+               ssc_writex(params->ssc->regs, params->pdc->xncr,
+                          prtd->period_size / params->pdc_xfer_size);
+       }
+
+       snd_pcm_period_elapsed(substream);
+}
+
+
+/*--------------------------------------------------------------------------*\
+ * PCM operations
+\*--------------------------------------------------------------------------*/
+static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct atmel_runtime_data *prtd = runtime->private_data;
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+
+       /* this may get called several times by oss emulation
+        * with different params */
+
+       snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
+       runtime->dma_bytes = params_buffer_bytes(params);
+
+       prtd->params = rtd->dai->cpu_dai->dma_data;
+       prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
+
+       prtd->dma_buffer = runtime->dma_addr;
+       prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
+       prtd->period_size = params_period_bytes(params);
+
+       pr_debug("atmel-pcm: "
+               "hw_params: DMA for %s initialized "
+               "(dma_bytes=%u, period_size=%u)\n",
+               prtd->params->name,
+               runtime->dma_bytes,
+               prtd->period_size);
+       return 0;
+}
+
+static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
+{
+       struct atmel_runtime_data *prtd = substream->runtime->private_data;
+       struct atmel_pcm_dma_params *params = prtd->params;
+
+       if (params != NULL) {
+               ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+                          params->mask->pdc_disable);
+               prtd->params->dma_intr_handler = NULL;
+       }
+
+       return 0;
+}
+
+static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
+{
+       struct atmel_runtime_data *prtd = substream->runtime->private_data;
+       struct atmel_pcm_dma_params *params = prtd->params;
+
+       ssc_writex(params->ssc->regs, SSC_IDR,
+                  params->mask->ssc_endx | params->mask->ssc_endbuf);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                  params->mask->pdc_disable);
+       return 0;
+}
+
+static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
+       int cmd)
+{
+       struct snd_pcm_runtime *rtd = substream->runtime;
+       struct atmel_runtime_data *prtd = rtd->private_data;
+       struct atmel_pcm_dma_params *params = prtd->params;
+       int ret = 0;
+
+       pr_debug("atmel-pcm:buffer_size = %ld,"
+               "dma_area = %p, dma_bytes = %u\n",
+               rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_START:
+               prtd->period_ptr = prtd->dma_buffer;
+
+               ssc_writex(params->ssc->regs, params->pdc->xpr,
+                          prtd->period_ptr);
+               ssc_writex(params->ssc->regs, params->pdc->xcr,
+                          prtd->period_size / params->pdc_xfer_size);
+
+               prtd->period_ptr += prtd->period_size;
+               ssc_writex(params->ssc->regs, params->pdc->xnpr,
+                          prtd->period_ptr);
+               ssc_writex(params->ssc->regs, params->pdc->xncr,
+                          prtd->period_size / params->pdc_xfer_size);
+
+               pr_debug("atmel-pcm: trigger: "
+                       "period_ptr=%lx, xpr=%u, "
+                       "xcr=%u, xnpr=%u, xncr=%u\n",
+                       (unsigned long)prtd->period_ptr,
+                       ssc_readx(params->ssc->regs, params->pdc->xpr),
+                       ssc_readx(params->ssc->regs, params->pdc->xcr),
+                       ssc_readx(params->ssc->regs, params->pdc->xnpr),
+                       ssc_readx(params->ssc->regs, params->pdc->xncr));
+
+               ssc_writex(params->ssc->regs, SSC_IER,
+                          params->mask->ssc_endx | params->mask->ssc_endbuf);
+               ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
+                          params->mask->pdc_enable);
+
+               pr_debug("sr=%u imr=%u\n",
+                       ssc_readx(params->ssc->regs, SSC_SR),
+                       ssc_readx(params->ssc->regs, SSC_IER));
+               break;          /* SNDRV_PCM_TRIGGER_START */
+
+       case SNDRV_PCM_TRIGGER_STOP:
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                          params->mask->pdc_disable);
+               break;
+
+       case SNDRV_PCM_TRIGGER_RESUME:
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                          params->mask->pdc_enable);
+               break;
+
+       default:
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static snd_pcm_uframes_t atmel_pcm_pointer(
+       struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct atmel_runtime_data *prtd = runtime->private_data;
+       struct atmel_pcm_dma_params *params = prtd->params;
+       dma_addr_t ptr;
+       snd_pcm_uframes_t x;
+
+       ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
+       x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
+
+       if (x == runtime->buffer_size)
+               x = 0;
+
+       return x;
+}
+
+static int atmel_pcm_open(struct snd_pcm_substream *substream)
+{
+       struct snd_pcm_runtime *runtime = substream->runtime;
+       struct atmel_runtime_data *prtd;
+       int ret = 0;
+
+       snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
+
+       /* ensure that buffer size is a multiple of period size */
+       ret = snd_pcm_hw_constraint_integer(runtime,
+                                               SNDRV_PCM_HW_PARAM_PERIODS);
+       if (ret < 0)
+               goto out;
+
+       prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
+       if (prtd == NULL) {
+               ret = -ENOMEM;
+               goto out;
+       }
+       runtime->private_data = prtd;
+
+ out:
+       return ret;
+}
+
+static int atmel_pcm_close(struct snd_pcm_substream *substream)
+{
+       struct atmel_runtime_data *prtd = substream->runtime->private_data;
+
+       kfree(prtd);
+       return 0;
+}
+
+static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
+       struct vm_area_struct *vma)
+{
+       return remap_pfn_range(vma, vma->vm_start,
+                      substream->dma_buffer.addr >> PAGE_SHIFT,
+                      vma->vm_end - vma->vm_start, vma->vm_page_prot);
+}
+
+struct snd_pcm_ops atmel_pcm_ops = {
+       .open           = atmel_pcm_open,
+       .close          = atmel_pcm_close,
+       .ioctl          = snd_pcm_lib_ioctl,
+       .hw_params      = atmel_pcm_hw_params,
+       .hw_free        = atmel_pcm_hw_free,
+       .prepare        = atmel_pcm_prepare,
+       .trigger        = atmel_pcm_trigger,
+       .pointer        = atmel_pcm_pointer,
+       .mmap           = atmel_pcm_mmap,
+};
+
+
+/*--------------------------------------------------------------------------*\
+ * ASoC platform driver
+\*--------------------------------------------------------------------------*/
+static u64 atmel_pcm_dmamask = 0xffffffff;
+
+static int atmel_pcm_new(struct snd_card *card,
+       struct snd_soc_dai *dai, struct snd_pcm *pcm)
+{
+       int ret = 0;
+
+       if (!card->dev->dma_mask)
+               card->dev->dma_mask = &atmel_pcm_dmamask;
+       if (!card->dev->coherent_dma_mask)
+               card->dev->coherent_dma_mask = 0xffffffff;
+
+       if (dai->playback.channels_min) {
+               ret = atmel_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_PLAYBACK);
+               if (ret)
+                       goto out;
+       }
+
+       if (dai->capture.channels_min) {
+               pr_debug("at32-pcm:"
+                               "Allocating PCM capture DMA buffer\n");
+               ret = atmel_pcm_preallocate_dma_buffer(pcm,
+                       SNDRV_PCM_STREAM_CAPTURE);
+               if (ret)
+                       goto out;
+       }
+ out:
+       return ret;
+}
+
+static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
+{
+       struct snd_pcm_substream *substream;
+       struct snd_dma_buffer *buf;
+       int stream;
+
+       for (stream = 0; stream < 2; stream++) {
+               substream = pcm->streams[stream].substream;
+               if (!substream)
+                       continue;
+
+               buf = &substream->dma_buffer;
+               if (!buf->area)
+                       continue;
+               dma_free_coherent(pcm->card->dev, buf->bytes,
+                                 buf->area, buf->addr);
+               buf->area = NULL;
+       }
+}
+
+#ifdef CONFIG_PM
+static int atmel_pcm_suspend(struct snd_soc_dai *dai)
+{
+       struct snd_pcm_runtime *runtime = dai->runtime;
+       struct atmel_runtime_data *prtd;
+       struct atmel_pcm_dma_params *params;
+
+       if (!runtime)
+               return 0;
+
+       prtd = runtime->private_data;
+       params = prtd->params;
+
+       /* disable the PDC and save the PDC registers */
+
+       ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+
+       prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
+       prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
+       prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
+       prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
+
+       return 0;
+}
+
+static int atmel_pcm_resume(struct snd_soc_dai *dai)
+{
+       struct snd_pcm_runtime *runtime = dai->runtime;
+       struct atmel_runtime_data *prtd;
+       struct atmel_pcm_dma_params *params;
+
+       if (!runtime)
+               return 0;
+
+       prtd = runtime->private_data;
+       params = prtd->params;
+
+       /* restore the PDC registers and enable the PDC */
+       ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
+       ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
+       ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
+       ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
+
+       ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+       return 0;
+}
+#else
+#define atmel_pcm_suspend      NULL
+#define atmel_pcm_resume       NULL
+#endif
+
+struct snd_soc_platform atmel_soc_platform = {
+       .name           = "atmel-audio",
+       .pcm_ops        = &atmel_pcm_ops,
+       .pcm_new        = atmel_pcm_new,
+       .pcm_free       = atmel_pcm_free_dma_buffers,
+       .suspend        = atmel_pcm_suspend,
+       .resume         = atmel_pcm_resume,
+};
+EXPORT_SYMBOL_GPL(atmel_soc_platform);
+
+static int __init atmel_pcm_modinit(void)
+{
+       return snd_soc_register_platform(&atmel_soc_platform);
+}
+module_init(atmel_pcm_modinit);
+
+static void __exit atmel_pcm_modexit(void)
+{
+       snd_soc_unregister_platform(&atmel_soc_platform);
+}
+module_exit(atmel_pcm_modexit);
+
+MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
+MODULE_DESCRIPTION("Atmel PCM module");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
new file mode 100644 (file)
index 0000000..ec9b282
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC.
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *
+ * Based on at91-pcm. by:
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Copyright 2006 Endrelia Technologies Inc.
+ *
+ * Based on pxa2xx-pcm.c by:
+ *
+ * Author:     Nicolas Pitre
+ * Created:    Nov 30, 2004
+ * Copyright:  (C) 2004 MontaVista Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ATMEL_PCM_H
+#define _ATMEL_PCM_H
+
+#include <linux/atmel-ssc.h>
+
+/*
+ * Registers and status bits that are required by the PCM driver.
+ */
+struct atmel_pdc_regs {
+       unsigned int    xpr;            /* PDC recv/trans pointer */
+       unsigned int    xcr;            /* PDC recv/trans counter */
+       unsigned int    xnpr;           /* PDC next recv/trans pointer */
+       unsigned int    xncr;           /* PDC next recv/trans counter */
+       unsigned int    ptcr;           /* PDC transfer control */
+};
+
+struct atmel_ssc_mask {
+       u32     ssc_enable;             /* SSC recv/trans enable */
+       u32     ssc_disable;            /* SSC recv/trans disable */
+       u32     ssc_endx;               /* SSC ENDTX or ENDRX */
+       u32     ssc_endbuf;             /* SSC TXBUFE or RXBUFF */
+       u32     pdc_enable;             /* PDC recv/trans enable */
+       u32     pdc_disable;            /* PDC recv/trans disable */
+};
+
+/*
+ * This structure, shared between the PCM driver and the interface,
+ * contains all information required by the PCM driver to perform the
+ * PDC DMA operation.  All fields except dma_intr_handler() are initialized
+ * by the interface.  The dms_intr_handler() pointer is set by the PCM
+ * driver and called by the interface SSC interrupt handler if it is
+ * non-NULL.
+ */
+struct atmel_pcm_dma_params {
+       char *name;                     /* stream identifier */
+       int pdc_xfer_size;              /* PDC counter increment in bytes */
+       struct ssc_device *ssc;         /* SSC device for stream */
+       struct atmel_pdc_regs *pdc;     /* PDC receive or transmit registers */
+       struct atmel_ssc_mask *mask;    /* SSC & PDC status bits */
+       struct snd_pcm_substream *substream;
+       void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
+};
+
+extern struct snd_soc_platform atmel_soc_platform;
+
+
+/*
+ * SSC register access (since ssc_writel() / ssc_readl() require literal name)
+ */
+#define ssc_readx(base, reg)            (__raw_readl((base) + (reg)))
+#define ssc_writex(base, reg, value)    __raw_writel((value), (base) + (reg))
+
+#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
new file mode 100644 (file)
index 0000000..c5d6790
--- /dev/null
@@ -0,0 +1,790 @@
+/*
+ * atmel_ssc_dai.c  --  ALSA SoC ATMEL SSC Audio Layer Platform driver
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ *
+ * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *         ATMEL CORP.
+ *
+ * Based on at91-ssc.c by
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Based on pxa2xx Platform drivers by
+ * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/atmel_pdc.h>
+
+#include <linux/atmel-ssc.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include <mach/hardware.h>
+
+#include "atmel-pcm.h"
+#include "atmel_ssc_dai.h"
+
+
+#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
+#define NUM_SSC_DEVICES                1
+#else
+#define NUM_SSC_DEVICES                3
+#endif
+
+/*
+ * SSC PDC registers required by the PCM DMA engine.
+ */
+static struct atmel_pdc_regs pdc_tx_reg = {
+       .xpr            = ATMEL_PDC_TPR,
+       .xcr            = ATMEL_PDC_TCR,
+       .xnpr           = ATMEL_PDC_TNPR,
+       .xncr           = ATMEL_PDC_TNCR,
+};
+
+static struct atmel_pdc_regs pdc_rx_reg = {
+       .xpr            = ATMEL_PDC_RPR,
+       .xcr            = ATMEL_PDC_RCR,
+       .xnpr           = ATMEL_PDC_RNPR,
+       .xncr           = ATMEL_PDC_RNCR,
+};
+
+/*
+ * SSC & PDC status bits for transmit and receive.
+ */
+static struct atmel_ssc_mask ssc_tx_mask = {
+       .ssc_enable     = SSC_BIT(CR_TXEN),
+       .ssc_disable    = SSC_BIT(CR_TXDIS),
+       .ssc_endx       = SSC_BIT(SR_ENDTX),
+       .ssc_endbuf     = SSC_BIT(SR_TXBUFE),
+       .pdc_enable     = ATMEL_PDC_TXTEN,
+       .pdc_disable    = ATMEL_PDC_TXTDIS,
+};
+
+static struct atmel_ssc_mask ssc_rx_mask = {
+       .ssc_enable     = SSC_BIT(CR_RXEN),
+       .ssc_disable    = SSC_BIT(CR_RXDIS),
+       .ssc_endx       = SSC_BIT(SR_ENDRX),
+       .ssc_endbuf     = SSC_BIT(SR_RXBUFF),
+       .pdc_enable     = ATMEL_PDC_RXTEN,
+       .pdc_disable    = ATMEL_PDC_RXTDIS,
+};
+
+
+/*
+ * DMA parameters.
+ */
+static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
+       {{
+       .name           = "SSC0 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC0 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       } },
+#if NUM_SSC_DEVICES == 3
+       {{
+       .name           = "SSC1 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC1 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       } },
+       {{
+       .name           = "SSC2 PCM out",
+       .pdc            = &pdc_tx_reg,
+       .mask           = &ssc_tx_mask,
+       },
+       {
+       .name           = "SSC2 PCM in",
+       .pdc            = &pdc_rx_reg,
+       .mask           = &ssc_rx_mask,
+       } },
+#endif
+};
+
+
+static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
+       {
+       .name           = "ssc0",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
+       .dir_mask       = SSC_DIR_MASK_UNUSED,
+       .initialized    = 0,
+       },
+#if NUM_SSC_DEVICES == 3
+       {
+       .name           = "ssc1",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
+       .dir_mask       = SSC_DIR_MASK_UNUSED,
+       .initialized    = 0,
+       },
+       {
+       .name           = "ssc2",
+       .lock           = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
+       .dir_mask       = SSC_DIR_MASK_UNUSED,
+       .initialized    = 0,
+       },
+#endif
+};
+
+
+/*
+ * SSC interrupt handler.  Passes PDC interrupts to the DMA
+ * interrupt handler in the PCM driver.
+ */
+static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
+{
+       struct atmel_ssc_info *ssc_p = dev_id;
+       struct atmel_pcm_dma_params *dma_params;
+       u32 ssc_sr;
+       u32 ssc_substream_mask;
+       int i;
+
+       ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
+                       & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
+
+       /*
+        * Loop through the substreams attached to this SSC.  If
+        * a DMA-related interrupt occurred on that substream, call
+        * the DMA interrupt handler function, if one has been
+        * registered in the dma_params structure by the PCM driver.
+        */
+       for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
+               dma_params = ssc_p->dma_params[i];
+
+               if ((dma_params != NULL) &&
+                       (dma_params->dma_intr_handler != NULL)) {
+                       ssc_substream_mask = (dma_params->mask->ssc_endx |
+                                       dma_params->mask->ssc_endbuf);
+                       if (ssc_sr & ssc_substream_mask) {
+                               dma_params->dma_intr_handler(ssc_sr,
+                                               dma_params->
+                                               substream);
+                       }
+               }
+       }
+
+       return IRQ_HANDLED;
+}
+
+
+/*-------------------------------------------------------------------------*\
+ * DAI functions
+\*-------------------------------------------------------------------------*/
+/*
+ * Startup.  Only that one substream allowed in each direction.
+ */
+static int atmel_ssc_startup(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       int dir_mask;
+
+       pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
+               ssc_readl(ssc_p->ssc->regs, SR));
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dir_mask = SSC_DIR_MASK_PLAYBACK;
+       else
+               dir_mask = SSC_DIR_MASK_CAPTURE;
+
+       spin_lock_irq(&ssc_p->lock);
+       if (ssc_p->dir_mask & dir_mask) {
+               spin_unlock_irq(&ssc_p->lock);
+               return -EBUSY;
+       }
+       ssc_p->dir_mask |= dir_mask;
+       spin_unlock_irq(&ssc_p->lock);
+
+       return 0;
+}
+
+/*
+ * Shutdown.  Clear DMA parameters and shutdown the SSC if there
+ * are no other substreams open.
+ */
+static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       struct atmel_pcm_dma_params *dma_params;
+       int dir, dir_mask;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dir = 0;
+       else
+               dir = 1;
+
+       dma_params = ssc_p->dma_params[dir];
+
+       if (dma_params != NULL) {
+               ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
+               pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
+                       (dir ? "receive" : "transmit"),
+                       ssc_readl(ssc_p->ssc->regs, SR));
+
+               dma_params->ssc = NULL;
+               dma_params->substream = NULL;
+               ssc_p->dma_params[dir] = NULL;
+       }
+
+       dir_mask = 1 << dir;
+
+       spin_lock_irq(&ssc_p->lock);
+       ssc_p->dir_mask &= ~dir_mask;
+       if (!ssc_p->dir_mask) {
+               if (ssc_p->initialized) {
+                       /* Shutdown the SSC clock. */
+                       pr_debug("atmel_ssc_dau: Stopping clock\n");
+                       clk_disable(ssc_p->ssc->clk);
+
+                       free_irq(ssc_p->ssc->irq, ssc_p);
+                       ssc_p->initialized = 0;
+               }
+
+               /* Reset the SSC */
+               ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
+               /* Clear the SSC dividers */
+               ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
+       }
+       spin_unlock_irq(&ssc_p->lock);
+}
+
+
+/*
+ * Record the DAI format for use in hw_params().
+ */
+static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+               unsigned int fmt)
+{
+       struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+
+       ssc_p->daifmt = fmt;
+       return 0;
+}
+
+/*
+ * Record SSC clock dividers for use in hw_params().
+ */
+static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
+       int div_id, int div)
+{
+       struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
+
+       switch (div_id) {
+       case ATMEL_SSC_CMR_DIV:
+               /*
+                * The same master clock divider is used for both
+                * transmit and receive, so if a value has already
+                * been set, it must match this value.
+                */
+               if (ssc_p->cmr_div == 0)
+                       ssc_p->cmr_div = div;
+               else
+                       if (div != ssc_p->cmr_div)
+                               return -EBUSY;
+               break;
+
+       case ATMEL_SSC_TCMR_PERIOD:
+               ssc_p->tcmr_period = div;
+               break;
+
+       case ATMEL_SSC_RCMR_PERIOD:
+               ssc_p->rcmr_period = div;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/*
+ * Configure the SSC.
+ */
+static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       int id = rtd->dai->cpu_dai->id;
+       struct atmel_ssc_info *ssc_p = &ssc_info[id];
+       struct atmel_pcm_dma_params *dma_params;
+       int dir, channels, bits;
+       u32 tfmr, rfmr, tcmr, rcmr;
+       int start_event;
+       int ret;
+
+       /*
+        * Currently, there is only one set of dma params for
+        * each direction.  If more are added, this code will
+        * have to be changed to select the proper set.
+        */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dir = 0;
+       else
+               dir = 1;
+
+       dma_params = &ssc_dma_params[id][dir];
+       dma_params->ssc = ssc_p->ssc;
+       dma_params->substream = substream;
+
+       ssc_p->dma_params[dir] = dma_params;
+
+       /*
+        * The cpu_dai->dma_data field is only used to communicate the
+        * appropriate DMA parameters to the pcm driver hw_params()
+        * function.  It should not be used for other purposes
+        * as it is common to all substreams.
+        */
+       rtd->dai->cpu_dai->dma_data = dma_params;
+
+       channels = params_channels(params);
+
+       /*
+        * Determine sample size in bits and the PDC increment.
+        */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S8:
+               bits = 8;
+               dma_params->pdc_xfer_size = 1;
+               break;
+       case SNDRV_PCM_FORMAT_S16_LE:
+               bits = 16;
+               dma_params->pdc_xfer_size = 2;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               bits = 24;
+               dma_params->pdc_xfer_size = 4;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               bits = 32;
+               dma_params->pdc_xfer_size = 4;
+               break;
+       default:
+               printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
+               return -EINVAL;
+       }
+
+       /*
+        * The SSC only supports up to 16-bit samples in I2S format, due
+        * to the size of the Frame Mode Register FSLEN field.
+        */
+       if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
+               && bits > 16) {
+               printk(KERN_WARNING
+                               "atmel_ssc_dai: sample size %d"
+                               "is too large for I2S\n", bits);
+               return -EINVAL;
+       }
+
+       /*
+        * Compute SSC register settings.
+        */
+       switch (ssc_p->daifmt
+               & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
+
+       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
+               /*
+                * I2S format, SSC provides BCLK and LRC clocks.
+                *
+                * The SSC transmit and receive clocks are generated
+                * from the MCK divider, and the BCLK signal
+                * is output on the SSC TK line.
+                */
+               rcmr =    SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
+                       | SSC_BF(RCMR_STTDLY, START_DELAY)
+                       | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
+                       | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
+                       | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
+
+               rfmr =    SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
+                       | SSC_BF(RFMR_FSLEN, (bits - 1))
+                       | SSC_BF(RFMR_DATNB, (channels - 1))
+                       | SSC_BIT(RFMR_MSBF)
+                       | SSC_BF(RFMR_LOOP, 0)
+                       | SSC_BF(RFMR_DATLEN, (bits - 1));
+
+               tcmr =    SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
+                       | SSC_BF(TCMR_STTDLY, START_DELAY)
+                       | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
+                       | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
+                       | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
+                       | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
+
+               tfmr =    SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(TFMR_FSDEN, 0)
+                       | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
+                       | SSC_BF(TFMR_FSLEN, (bits - 1))
+                       | SSC_BF(TFMR_DATNB, (channels - 1))
+                       | SSC_BIT(TFMR_MSBF)
+                       | SSC_BF(TFMR_DATDEF, 0)
+                       | SSC_BF(TFMR_DATLEN, (bits - 1));
+               break;
+
+       case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
+               /*
+                * I2S format, CODEC supplies BCLK and LRC clocks.
+                *
+                * The SSC transmit clock is obtained from the BCLK signal on
+                * on the TK line, and the SSC receive clock is
+                * generated from the transmit clock.
+                *
+                *  For single channel data, one sample is transferred
+                * on the falling edge of the LRC clock.
+                * For two channel data, one sample is
+                * transferred on both edges of the LRC clock.
+                */
+               start_event = ((channels == 1)
+                               ? SSC_START_FALLING_RF
+                               : SSC_START_EDGE_RF);
+
+               rcmr =    SSC_BF(RCMR_PERIOD, 0)
+                       | SSC_BF(RCMR_STTDLY, START_DELAY)
+                       | SSC_BF(RCMR_START, start_event)
+                       | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
+                       | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
+
+               rfmr =    SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
+                       | SSC_BF(RFMR_FSLEN, 0)
+                       | SSC_BF(RFMR_DATNB, 0)
+                       | SSC_BIT(RFMR_MSBF)
+                       | SSC_BF(RFMR_LOOP, 0)
+                       | SSC_BF(RFMR_DATLEN, (bits - 1));
+
+               tcmr =    SSC_BF(TCMR_PERIOD, 0)
+                       | SSC_BF(TCMR_STTDLY, START_DELAY)
+                       | SSC_BF(TCMR_START, start_event)
+                       | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
+                       | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
+
+               tfmr =    SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(TFMR_FSDEN, 0)
+                       | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
+                       | SSC_BF(TFMR_FSLEN, 0)
+                       | SSC_BF(TFMR_DATNB, 0)
+                       | SSC_BIT(TFMR_MSBF)
+                       | SSC_BF(TFMR_DATDEF, 0)
+                       | SSC_BF(TFMR_DATLEN, (bits - 1));
+               break;
+
+       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
+               /*
+                * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
+                *
+                * The SSC transmit and receive clocks are generated from the
+                * MCK divider, and the BCLK signal is output
+                * on the SSC TK line.
+                */
+               rcmr =    SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
+                       | SSC_BF(RCMR_STTDLY, 1)
+                       | SSC_BF(RCMR_START, SSC_START_RISING_RF)
+                       | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
+                       | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
+                       | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
+
+               rfmr =    SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
+                       | SSC_BF(RFMR_FSLEN, 0)
+                       | SSC_BF(RFMR_DATNB, (channels - 1))
+                       | SSC_BIT(RFMR_MSBF)
+                       | SSC_BF(RFMR_LOOP, 0)
+                       | SSC_BF(RFMR_DATLEN, (bits - 1));
+
+               tcmr =    SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
+                       | SSC_BF(TCMR_STTDLY, 1)
+                       | SSC_BF(TCMR_START, SSC_START_RISING_RF)
+                       | SSC_BF(TCMR_CKI, SSC_CKI_RISING)
+                       | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
+                       | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
+
+               tfmr =    SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
+                       | SSC_BF(TFMR_FSDEN, 0)
+                       | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
+                       | SSC_BF(TFMR_FSLEN, 0)
+                       | SSC_BF(TFMR_DATNB, (channels - 1))
+                       | SSC_BIT(TFMR_MSBF)
+                       | SSC_BF(TFMR_DATDEF, 0)
+                       | SSC_BF(TFMR_DATLEN, (bits - 1));
+               break;
+
+       case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
+       default:
+               printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
+                       ssc_p->daifmt);
+               return -EINVAL;
+               break;
+       }
+       pr_debug("atmel_ssc_hw_params: "
+                       "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
+                       rcmr, rfmr, tcmr, tfmr);
+
+       if (!ssc_p->initialized) {
+
+               /* Enable PMC peripheral clock for this SSC */
+               pr_debug("atmel_ssc_dai: Starting clock\n");
+               clk_enable(ssc_p->ssc->clk);
+
+               /* Reset the SSC and its PDC registers */
+               ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
+
+               ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
+
+               ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
+               ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
+
+               ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
+                               ssc_p->name, ssc_p);
+               if (ret < 0) {
+                       printk(KERN_WARNING
+                                       "atmel_ssc_dai: request_irq failure\n");
+                       pr_debug("Atmel_ssc_dai: Stoping clock\n");
+                       clk_disable(ssc_p->ssc->clk);
+                       return ret;
+               }
+
+               ssc_p->initialized = 1;
+       }
+
+       /* set SSC clock mode register */
+       ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
+
+       /* set receive clock mode and format */
+       ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
+       ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
+
+       /* set transmit clock mode and format */
+       ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
+       ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
+
+       pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
+       return 0;
+}
+
+
+static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
+       struct atmel_pcm_dma_params *dma_params;
+       int dir;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               dir = 0;
+       else
+               dir = 1;
+
+       dma_params = ssc_p->dma_params[dir];
+
+       ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
+
+       pr_debug("%s enabled SSC_SR=0x%08x\n",
+                       dir ? "receive" : "transmit",
+                       ssc_readl(ssc_p->ssc->regs, SR));
+       return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
+{
+       struct atmel_ssc_info *ssc_p;
+
+       if (!cpu_dai->active)
+               return 0;
+
+       ssc_p = &ssc_info[cpu_dai->id];
+
+       /* Save the status register before disabling transmit and receive */
+       ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
+       ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
+
+       /* Save the current interrupt mask, then disable unmasked interrupts */
+       ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
+       ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
+
+       ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
+       ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
+       ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
+       ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
+       ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
+
+       return 0;
+}
+
+
+
+static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
+{
+       struct atmel_ssc_info *ssc_p;
+       u32 cr;
+
+       if (!cpu_dai->active)
+               return 0;
+
+       ssc_p = &ssc_info[cpu_dai->id];
+
+       /* restore SSC register settings */
+       ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
+       ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
+       ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
+       ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
+       ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
+
+       /* re-enable interrupts */
+       ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
+
+       /* Re-enable recieve and transmit as appropriate */
+       cr = 0;
+       cr |=
+           (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
+       cr |=
+           (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
+       ssc_writel(ssc_p->ssc->regs, CR, cr);
+
+       return 0;
+}
+#else /* CONFIG_PM */
+#  define atmel_ssc_suspend    NULL
+#  define atmel_ssc_resume     NULL
+#endif /* CONFIG_PM */
+
+
+#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
+
+#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8     | SNDRV_PCM_FMTBIT_S16_LE |\
+                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
+struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
+       {       .name = "atmel-ssc0",
+               .id = 0,
+               .suspend = atmel_ssc_suspend,
+               .resume = atmel_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .ops = {
+                       .startup = atmel_ssc_startup,
+                       .shutdown = atmel_ssc_shutdown,
+                       .prepare = atmel_ssc_prepare,
+                       .hw_params = atmel_ssc_hw_params,
+                       .set_fmt = atmel_ssc_set_dai_fmt,
+                       .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[0],
+       },
+#if NUM_SSC_DEVICES == 3
+       {       .name = "atmel-ssc1",
+               .id = 1,
+               .suspend = atmel_ssc_suspend,
+               .resume = atmel_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .ops = {
+                       .startup = atmel_ssc_startup,
+                       .shutdown = atmel_ssc_shutdown,
+                       .prepare = atmel_ssc_prepare,
+                       .hw_params = atmel_ssc_hw_params,
+                       .set_fmt = atmel_ssc_set_dai_fmt,
+                       .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[1],
+       },
+       {       .name = "atmel-ssc2",
+               .id = 2,
+               .suspend = atmel_ssc_suspend,
+               .resume = atmel_ssc_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = ATMEL_SSC_RATES,
+                       .formats = ATMEL_SSC_FORMATS,},
+               .ops = {
+                       .startup = atmel_ssc_startup,
+                       .shutdown = atmel_ssc_shutdown,
+                       .prepare = atmel_ssc_prepare,
+                       .hw_params = atmel_ssc_hw_params,
+                       .set_fmt = atmel_ssc_set_dai_fmt,
+                       .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
+               .private_data = &ssc_info[2],
+       },
+#endif
+};
+EXPORT_SYMBOL_GPL(atmel_ssc_dai);
+
+static int __init atmel_ssc_modinit(void)
+{
+       return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
+}
+module_init(atmel_ssc_modinit);
+
+static void __exit atmel_ssc_modexit(void)
+{
+       snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
+}
+module_exit(atmel_ssc_modexit);
+
+/* Module information */
+MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
+MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
new file mode 100644 (file)
index 0000000..a828746
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * atmel_ssc_dai.h - ALSA SSC interface for the Atmel  SoC
+ *
+ * Copyright (C) 2005 SAN People
+ * Copyright (C) 2008 Atmel
+ *
+ * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *         ATMEL CORP.
+ *
+ * Based on at91-ssc.c by
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Based on pxa2xx Platform drivers by
+ * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _ATMEL_SSC_DAI_H
+#define _ATMEL_SSC_DAI_H
+
+#include <linux/types.h>
+#include <linux/atmel-ssc.h>
+
+#include "atmel-pcm.h"
+
+/* SSC system clock ids */
+#define ATMEL_SYSCLK_MCK       0 /* SSC uses AT91 MCK as system clock */
+
+/* SSC divider ids */
+#define ATMEL_SSC_CMR_DIV      0 /* MCK divider for BCLK */
+#define ATMEL_SSC_TCMR_PERIOD  1 /* BCLK divider for transmit FS */
+#define ATMEL_SSC_RCMR_PERIOD  2 /* BCLK divider for receive FS */
+/*
+ * SSC direction masks
+ */
+#define SSC_DIR_MASK_UNUSED    0
+#define SSC_DIR_MASK_PLAYBACK  1
+#define SSC_DIR_MASK_CAPTURE   2
+
+/*
+ * SSC register values that Atmel left out of <linux/atmel-ssc.h>.  These
+ * are expected to be used with SSC_BF
+ */
+/* START bit field values */
+#define SSC_START_CONTINUOUS   0
+#define SSC_START_TX_RX                1
+#define SSC_START_LOW_RF       2
+#define SSC_START_HIGH_RF      3
+#define SSC_START_FALLING_RF   4
+#define SSC_START_RISING_RF    5
+#define SSC_START_LEVEL_RF     6
+#define SSC_START_EDGE_RF      7
+#define SSS_START_COMPARE_0    8
+
+/* CKI bit field values */
+#define SSC_CKI_FALLING                0
+#define SSC_CKI_RISING         1
+
+/* CKO bit field values */
+#define SSC_CKO_NONE           0
+#define SSC_CKO_CONTINUOUS     1
+#define SSC_CKO_TRANSFER       2
+
+/* CKS bit field values */
+#define SSC_CKS_DIV            0
+#define SSC_CKS_CLOCK          1
+#define SSC_CKS_PIN            2
+
+/* FSEDGE bit field values */
+#define SSC_FSEDGE_POSITIVE    0
+#define SSC_FSEDGE_NEGATIVE    1
+
+/* FSOS bit field values */
+#define SSC_FSOS_NONE          0
+#define SSC_FSOS_NEGATIVE      1
+#define SSC_FSOS_POSITIVE      2
+#define SSC_FSOS_LOW           3
+#define SSC_FSOS_HIGH          4
+#define SSC_FSOS_TOGGLE                5
+
+#define START_DELAY            1
+
+struct atmel_ssc_state {
+       u32 ssc_cmr;
+       u32 ssc_rcmr;
+       u32 ssc_rfmr;
+       u32 ssc_tcmr;
+       u32 ssc_tfmr;
+       u32 ssc_sr;
+       u32 ssc_imr;
+};
+
+
+struct atmel_ssc_info {
+       char *name;
+       struct ssc_device *ssc;
+       spinlock_t lock;        /* lock for dir_mask */
+       unsigned short dir_mask;        /* 0=unused, 1=playback, 2=capture */
+       unsigned short initialized;     /* true if SSC has been initialized */
+       unsigned short daifmt;
+       unsigned short cmr_div;
+       unsigned short tcmr_period;
+       unsigned short rcmr_period;
+       struct atmel_pcm_dma_params *dma_params[2];
+       struct atmel_ssc_state ssc_state;
+};
+extern struct snd_soc_dai atmel_ssc_dai[];
+
+#endif /* _AT91_SSC_DAI_H */
similarity index 98%
rename from sound/soc/at32/playpaq_wm8510.c
rename to sound/soc/atmel/playpaq_wm8510.c
index b1966e4dfcd3e7b2035c15f47b5842d2438d253e..43dd8cee83c64e2d87bd2574fbcb31c7cafabf9c 100644 (file)
@@ -22,7 +22,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/clk.h>
@@ -40,8 +39,8 @@
 #include <mach/portmux.h>
 
 #include "../codecs/wm8510.h"
-#include "at32-pcm.h"
-#include "at32-ssc.h"
+#include "atmel-pcm.h"
+#include "atmel_ssc_dai.h"
 
 
 /*-------------------------------------------------------------------------*\
@@ -362,8 +361,9 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
 
 
 
-static struct snd_soc_machine snd_soc_machine_playpaq = {
+static struct snd_soc_card snd_soc_playpaq = {
        .name = "LRS_PlayPaq_WM8510",
+       .platform = &at32_soc_platform,
        .dai_link = &playpaq_wm8510_dai,
        .num_links = 1,
 };
@@ -378,8 +378,7 @@ static struct wm8510_setup_data playpaq_wm8510_setup = {
 
 
 static struct snd_soc_device playpaq_wm8510_snd_devdata = {
-       .machine = &snd_soc_machine_playpaq,
-       .platform = &at32_soc_platform,
+       .card = &snd_soc_playpaq,
        .codec_dev = &soc_codec_dev_wm8510,
        .codec_data = &playpaq_wm8510_setup,
 };
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
new file mode 100644 (file)
index 0000000..1fb59a9
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * sam9g20_wm8731  --  SoC audio for AT91SAM9G20-based
+ *                     ATMEL AT91SAM9G20ek board.
+ *
+ *  Copyright (C) 2005 SAN People
+ *  Copyright (C) 2008 Atmel
+ *
+ * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
+ *
+ * Based on ati_b1_wm8731.c by:
+ * Frank Mandarino <fmandarino@endrelia.com>
+ * Copyright 2006 Endrelia Technologies Inc.
+ * Based on corgi.c by:
+ * Copyright 2005 Wolfson Microelectronics PLC.
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <linux/atmel-ssc.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+#include "../codecs/wm8731.h"
+#include "atmel-pcm.h"
+#include "atmel_ssc_dai.h"
+
+
+static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       int ret;
+
+       /* codec system clock is supplied by PCK0, set to 12MHz */
+       ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
+               12000000, SND_SOC_CLOCK_IN);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
+
+       dev_dbg(rtd->socdev->dev, "shutdown");
+}
+
+static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
+       struct ssc_device *ssc = ssc_p->ssc;
+       int ret;
+
+       unsigned int rate;
+       int cmr_div, period;
+
+       if (ssc == NULL) {
+               printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
+               return -EINVAL;
+       }
+
+       /* set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       /* set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       /*
+        * The SSC clock dividers depend on the sample rate.  The CMR.DIV
+        * field divides the system master clock MCK to drive the SSC TK
+        * signal which provides the codec BCLK.  The TCMR.PERIOD and
+        * RCMR.PERIOD fields further divide the BCLK signal to drive
+        * the SSC TF and RF signals which provide the codec DACLRC and
+        * ADCLRC clocks.
+        *
+        * The dividers were determined through trial and error, where a
+        * CMR.DIV value is chosen such that the resulting BCLK value is
+        * divisible, or almost divisible, by (2 * sample rate), and then
+        * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
+        */
+       rate = params_rate(params);
+
+       switch (rate) {
+       case 8000:
+               cmr_div = 55;   /* BCLK = 133MHz/(2*55) = 1.209MHz */
+               period = 74;    /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
+               break;
+       case 11025:
+               cmr_div = 67;   /* BCLK = 133MHz/(2*60) = 1.108MHz */
+               period = 45;    /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
+               break;
+       case 16000:
+               cmr_div = 63;   /* BCLK = 133MHz/(2*63) = 1.055MHz */
+               period = 32;    /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
+               break;
+       case 22050:
+               cmr_div = 52;   /* BCLK = 133MHz/(2*52) = 1.278MHz */
+               period = 28;    /* LRC = BCLK/(2*(28+1)) = 22049Hz */
+               break;
+       case 32000:
+               cmr_div = 66;   /* BCLK = 133MHz/(2*66) = 1.007MHz */
+               period = 15;    /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
+               break;
+       case 44100:
+               cmr_div = 29;   /* BCLK = 133MHz/(2*29) = 2.293MHz */
+               period = 25;    /* LRC = BCLK/(2*(25+1)) = 44098Hz */
+               break;
+       case 48000:
+               cmr_div = 33;   /* BCLK = 133MHz/(2*33) = 2.015MHz */
+               period = 20;    /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
+               break;
+       case 88200:
+               cmr_div = 29;   /* BCLK = 133MHz/(2*29) = 2.293MHz */
+               period = 12;    /* LRC = BCLK/(2*(12+1)) = 88196Hz */
+               break;
+       case 96000:
+               cmr_div = 23;   /* BCLK = 133MHz/(2*23) = 2.891MHz */
+               period = 14;    /* LRC = BCLK/(2*(14+1)) = 96376Hz */
+               break;
+       default:
+               printk(KERN_WARNING "unsupported rate %d"
+                               " on at91sam9g20ek board\n", rate);
+               return -EINVAL;
+       }
+
+       /* set the MCK divider for BCLK */
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
+       if (ret < 0)
+               return ret;
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               /* set the BCLK divider for DACLRC */
+               ret = snd_soc_dai_set_clkdiv(cpu_dai,
+                                               ATMEL_SSC_TCMR_PERIOD, period);
+       } else {
+               /* set the BCLK divider for ADCLRC */
+               ret = snd_soc_dai_set_clkdiv(cpu_dai,
+                                               ATMEL_SSC_RCMR_PERIOD, period);
+       }
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops at91sam9g20ek_ops = {
+       .startup = at91sam9g20ek_startup,
+       .hw_params = at91sam9g20ek_hw_params,
+       .shutdown = at91sam9g20ek_shutdown,
+};
+
+
+static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
+       SND_SOC_DAPM_MIC("Int Mic", NULL),
+       SND_SOC_DAPM_SPK("Ext Spk", NULL),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+
+       /* speaker connected to LHPOUT */
+       {"Ext Spk", NULL, "LHPOUT"},
+
+       /* mic is connected to Mic Jack, with WM8731 Mic Bias */
+       {"MICIN", NULL, "Mic Bias"},
+       {"Mic Bias", NULL, "Int Mic"},
+};
+
+/*
+ * Logic for a wm8731 as connected on a at91sam9g20ek board.
+ */
+static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
+{
+       printk(KERN_DEBUG
+                       "at91sam9g20ek_wm8731 "
+                       ": at91sam9g20ek_wm8731_init() called\n");
+
+       /* Add specific widgets */
+       snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
+                                 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
+       /* Set up specific audio path interconnects */
+       snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
+       /* not connected */
+       snd_soc_dapm_disable_pin(codec, "RLINEIN");
+       snd_soc_dapm_disable_pin(codec, "LLINEIN");
+
+       /* always connected */
+       snd_soc_dapm_enable_pin(codec, "Int Mic");
+       snd_soc_dapm_enable_pin(codec, "Ext Spk");
+
+       snd_soc_dapm_sync(codec);
+
+       return 0;
+}
+
+static struct snd_soc_dai_link at91sam9g20ek_dai = {
+       .name = "WM8731",
+       .stream_name = "WM8731 PCM",
+       .cpu_dai = &atmel_ssc_dai[0],
+       .codec_dai = &wm8731_dai,
+       .init = at91sam9g20ek_wm8731_init,
+       .ops = &at91sam9g20ek_ops,
+};
+
+static struct snd_soc_card snd_soc_at91sam9g20ek = {
+       .name = "WM8731",
+       .platform = &atmel_soc_platform,
+       .dai_link = &at91sam9g20ek_dai,
+       .num_links = 1,
+};
+
+static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = {
+       .i2c_bus = 0,
+       .i2c_address = 0x1b,
+};
+
+static struct snd_soc_device at91sam9g20ek_snd_devdata = {
+       .card = &snd_soc_at91sam9g20ek,
+       .codec_dev = &soc_codec_dev_wm8731,
+       .codec_data = &at91sam9g20ek_wm8731_setup,
+};
+
+static struct platform_device *at91sam9g20ek_snd_device;
+
+static int __init at91sam9g20ek_init(void)
+{
+       struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
+       struct ssc_device *ssc = NULL;
+       int ret;
+
+       /*
+        * Request SSC device
+        */
+       ssc = ssc_request(0);
+       if (IS_ERR(ssc)) {
+               ret = PTR_ERR(ssc);
+               ssc = NULL;
+               goto err_ssc;
+       }
+       ssc_p->ssc = ssc;
+
+       at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!at91sam9g20ek_snd_device) {
+               printk(KERN_DEBUG
+                               "platform device allocation failed\n");
+               ret = -ENOMEM;
+       }
+
+       platform_set_drvdata(at91sam9g20ek_snd_device,
+                       &at91sam9g20ek_snd_devdata);
+       at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
+
+       ret = platform_device_add(at91sam9g20ek_snd_device);
+       if (ret) {
+               printk(KERN_DEBUG
+                               "platform device allocation failed\n");
+               platform_device_put(at91sam9g20ek_snd_device);
+       }
+
+       return ret;
+
+err_ssc:
+       return ret;
+}
+
+static void __exit at91sam9g20ek_exit(void)
+{
+       struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
+       struct ssc_device *ssc;
+
+       if (ssc_p != NULL) {
+               ssc = ssc_p->ssc;
+               if (ssc != NULL)
+                       ssc_free(ssc);
+               ssc_p->ssc = NULL;
+       }
+
+       platform_device_unregister(at91sam9g20ek_snd_device);
+       at91sam9g20ek_snd_device = NULL;
+}
+
+module_init(at91sam9g20ek_init);
+module_exit(at91sam9g20ek_exit);
+
+/* Module information */
+MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
+MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
+MODULE_LICENSE("GPL");
index 1466d932880026a99cd32f9e339c55fda0c3033f..74c823d60f91b4662184dcf60b76eeb2eaae4303 100644 (file)
@@ -406,11 +406,12 @@ static int __init au1xpsc_audio_dbdma_init(void)
 {
        au1xpsc_audio_pcmdma[PCM_TX] = NULL;
        au1xpsc_audio_pcmdma[PCM_RX] = NULL;
-       return 0;
+       return snd_soc_register_platform(&au1xpsc_soc_platform);
 }
 
 static void __exit au1xpsc_audio_dbdma_exit(void)
 {
+       snd_soc_unregister_platform(&au1xpsc_soc_platform);
 }
 
 module_init(au1xpsc_audio_dbdma_init);
index 57facbad68254cc4b21ecb189bb3ad161afb495e..f0e30aec7f233621a23a35f9fa8100facdc4a189 100644 (file)
@@ -160,7 +160,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
 static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
-                                 struct snd_pcm_hw_params *params)
+                                 struct snd_pcm_hw_params *params,
+                                 struct snd_soc_dai *dai)
 {
        /* FIXME */
        struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -210,7 +211,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
 }
 
 static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
-                               int cmd)
+                               int cmd, struct snd_soc_dai *dai)
 {
        /* FIXME */
        struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -313,8 +314,7 @@ static void au1xpsc_ac97_remove(struct platform_device *pdev,
        au1xpsc_ac97_workdata = NULL;
 }
 
-static int au1xpsc_ac97_suspend(struct platform_device *pdev,
-                               struct snd_soc_dai *dai)
+static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai)
 {
        /* save interesting registers and disable PSC */
        au1xpsc_ac97_workdata->pm[0] =
@@ -328,8 +328,7 @@ static int au1xpsc_ac97_suspend(struct platform_device *pdev,
        return 0;
 }
 
-static int au1xpsc_ac97_resume(struct platform_device *pdev,
-                              struct snd_soc_dai *dai)
+static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
 {
        /* restore PSC clock config */
        au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE,
@@ -345,7 +344,7 @@ static int au1xpsc_ac97_resume(struct platform_device *pdev,
 
 struct snd_soc_dai au1xpsc_ac97_dai = {
        .name                   = "au1xpsc_ac97",
-       .type                   = SND_SOC_DAI_AC97,
+       .ac97_control           = 1,
        .probe                  = au1xpsc_ac97_probe,
        .remove                 = au1xpsc_ac97_remove,
        .suspend                = au1xpsc_ac97_suspend,
@@ -372,11 +371,12 @@ EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
 static int __init au1xpsc_ac97_init(void)
 {
        au1xpsc_ac97_workdata = NULL;
-       return 0;
+       return snd_soc_register_dai(&au1xpsc_ac97_dai);
 }
 
 static void __exit au1xpsc_ac97_exit(void)
 {
+       snd_soc_unregister_dai(&au1xpsc_ac97_dai);
 }
 
 module_init(au1xpsc_ac97_init);
index 9384702c7ebd7c09f0df6d4e25f9161ac854cc37..f916de4400edcc358a58a33d227f9fafd0ce88af 100644 (file)
@@ -116,7 +116,8 @@ out:
 }
 
 static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
 
@@ -240,7 +241,8 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
        return 0;
 }
 
-static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *dai)
 {
        struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
        int ret, stype = SUBSTREAM_TYPE(substream);
@@ -337,8 +339,7 @@ static void au1xpsc_i2s_remove(struct platform_device *pdev,
        au1xpsc_i2s_workdata = NULL;
 }
 
-static int au1xpsc_i2s_suspend(struct platform_device *pdev,
-                              struct snd_soc_dai *cpu_dai)
+static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai)
 {
        /* save interesting register and disable PSC */
        au1xpsc_i2s_workdata->pm[0] =
@@ -352,8 +353,7 @@ static int au1xpsc_i2s_suspend(struct platform_device *pdev,
        return 0;
 }
 
-static int au1xpsc_i2s_resume(struct platform_device *pdev,
-                             struct snd_soc_dai *cpu_dai)
+static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai)
 {
        /* select I2S mode and PSC clock */
        au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
@@ -369,7 +369,6 @@ static int au1xpsc_i2s_resume(struct platform_device *pdev,
 
 struct snd_soc_dai au1xpsc_i2s_dai = {
        .name                   = "au1xpsc_i2s",
-       .type                   = SND_SOC_DAI_I2S,
        .probe                  = au1xpsc_i2s_probe,
        .remove                 = au1xpsc_i2s_remove,
        .suspend                = au1xpsc_i2s_suspend,
@@ -389,8 +388,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
        .ops = {
                .trigger        = au1xpsc_i2s_trigger,
                .hw_params      = au1xpsc_i2s_hw_params,
-       },
-       .dai_ops = {
                .set_fmt        = au1xpsc_i2s_set_fmt,
        },
 };
@@ -399,11 +396,12 @@ EXPORT_SYMBOL(au1xpsc_i2s_dai);
 static int __init au1xpsc_i2s_init(void)
 {
        au1xpsc_i2s_workdata = NULL;
-       return 0;
+       return snd_soc_register_dai(&au1xpsc_i2s_dai);
 }
 
 static void __exit au1xpsc_i2s_exit(void)
 {
+       snd_soc_unregister_dai(&au1xpsc_i2s_dai);
 }
 
 module_init(au1xpsc_i2s_init);
index f75ae7f62c3d4c157ec1b51729b972e173464474..27683eb7905e305f800211dcfa21718e73a4c5c9 100644 (file)
@@ -42,14 +42,14 @@ static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
        .ops            = NULL,
 };
 
-static struct snd_soc_machine au1xpsc_sample_ac97_machine = {
+static struct snd_soc_card au1xpsc_sample_ac97_machine = {
        .name           = "Au1xxx PSC AC97 Audio",
        .dai_link       = &au1xpsc_sample_ac97_dai,
        .num_links      = 1,
 };
 
 static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
-       .machine        = &au1xpsc_sample_ac97_machine,
+       .card           = &au1xpsc_sample_ac97_machine,
        .platform       = &au1xpsc_soc_platform, /* see dbdma2.c */
        .codec_dev      = &soc_codec_dev_ac97,
 };
index dc006206f622d043d4257162e71466f3b77bf0fb..0a2f8f9eff53f616b32c330f5e1befb7dbf972d2 100644 (file)
@@ -1,6 +1,6 @@
 config SND_BF5XX_I2S
        tristate "SoC I2S Audio for the ADI BF5xx chip"
-       depends on BLACKFIN && SND_SOC
+       depends on BLACKFIN
        help
          Say Y or M if you want to add support for codecs attached to
          the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -13,7 +13,6 @@ config SND_BF5XX_SOC_SSM2602
        select SND_BF5XX_SOC_I2S
        select SND_SOC_SSM2602
        select I2C
-       select I2C_BLACKFIN_TWI
        help
          Say Y if you want to add support for SoC audio on BF527-EZKIT.
 
@@ -35,7 +34,7 @@ config SND_BFIN_AD73311_SE
 
 config SND_BF5XX_AC97
        tristate "SoC AC97 Audio for the ADI BF5xx chip"
-       depends on BLACKFIN && SND_SOC
+       depends on BLACKFIN
        help
          Say Y or M if you want to add support for codecs attached to
          the Blackfin SPORT (synchronous serial ports) interface in slot 16
@@ -47,7 +46,7 @@ config SND_BF5XX_AC97
          properly with this driver. This driver is known to work with the
          Analog Devices line of AC97 codecs.
 
-config SND_MMAP_SUPPORT
+config SND_BF5XX_MMAP_SUPPORT
        bool "Enable MMAP Support"
        depends on SND_BF5XX_AC97
        default y
@@ -55,9 +54,17 @@ config SND_MMAP_SUPPORT
          Say y if you want AC97 driver to support mmap mode.
          We introduce an intermediate buffer to simulate mmap.
 
+config SND_BF5XX_MULTICHAN_SUPPORT
+       bool "Enable Multichannel Support"
+       depends on SND_BF5XX_AC97
+       default n
+       help
+         Say y if you want AC97 driver to support up to 5.1 channel audio.
+         this mode will consume much more memory for DMA.
+
 config SND_BF5XX_SOC_SPORT
        tristate
-       
+
 config SND_BF5XX_SOC_I2S
        tristate
        select SND_BF5XX_SOC_SPORT
@@ -80,7 +87,7 @@ config SND_BF5XX_SPORT_NUM
        int "Set a SPORT for Sound chip"
        depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
        range 0 3 if BF54x
-       range 0 1 if (BF53x || BF561)
+       range 0 1 if !BF54x
        default 0
        help
          Set the correct SPORT for sound chip.
@@ -90,12 +97,13 @@ config SND_BF5XX_HAVE_COLD_RESET
        depends on SND_BF5XX_AC97
        default y if BFIN548_EZKIT
        default n if !BFIN548_EZKIT
-       
+
 config SND_BF5XX_RESET_GPIO_NUM
        int "Set a GPIO for cold reset"
        depends on SND_BF5XX_HAVE_COLD_RESET
        range 0 159
        default 19 if BFIN548_EZKIT
        default 5 if BFIN537_STAMP
+       default 0
        help
          Set the correct GPIO for RESET the sound chip.
index 25e50d2ea1ec321d4140295f6d6ce587d79f0a9a..8067cfafa3a703ea5e0f9dacb30f4c13e882f0ff 100644 (file)
 #include "bf5xx-ac97.h"
 #include "bf5xx-sport.h"
 
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+static unsigned int ac97_chan_mask[] = {
+       SP_FL, /* Mono */
+       SP_STEREO, /* Stereo */
+       SP_2DOT1, /* 2.1*/
+       SP_QUAD,/*Quadraquic*/
+       SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
+       SP_5DOT1, /* 5.1 */
+};
+
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
 static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
         snd_pcm_uframes_t count)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct sport_device *sport = runtime->private_data;
+       unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               bf5xx_pcm_to_ac97(
-                       (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos,
-                       (__u32 *)runtime->dma_area + sport->tx_pos, count);
+               bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
+               sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
+               runtime->channels, count, chan_mask);
                sport->tx_pos += runtime->period_size;
                if (sport->tx_pos >= runtime->buffer_size)
                        sport->tx_pos %= runtime->buffer_size;
                sport->tx_delay_pos = sport->tx_pos;
        } else {
-               bf5xx_ac97_to_pcm(
-                       (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos,
-                       (__u32 *)runtime->dma_area + sport->rx_pos, count);
+               bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
+               sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
+               runtime->channels, count);
                sport->rx_pos += runtime->period_size;
                if (sport->rx_pos >= runtime->buffer_size)
                        sport->rx_pos %= runtime->buffer_size;
@@ -71,7 +81,7 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
 static void bf5xx_dma_irq(void *data)
 {
        struct snd_pcm_substream *pcm = data;
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        struct snd_pcm_runtime *runtime = pcm->runtime;
        struct sport_device *sport = runtime->private_data;
        bf5xx_mmap_copy(pcm, runtime->period_size);
@@ -90,17 +100,14 @@ static void bf5xx_dma_irq(void *data)
  * The total rx/tx buffer is for ac97 frame to hold all pcm data
  * is  0x20000 * sizeof(struct ac97_frame) / 4.
  */
-#ifdef CONFIG_SND_MMAP_SUPPORT
 static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
        .info                   = SNDRV_PCM_INFO_INTERLEAVED |
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
                                   SNDRV_PCM_INFO_MMAP |
                                   SNDRV_PCM_INFO_MMAP_VALID |
-                                  SNDRV_PCM_INFO_BLOCK_TRANSFER,
-#else
-static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
-       .info                   = SNDRV_PCM_INFO_INTERLEAVED |
-                                 SNDRV_PCM_INFO_BLOCK_TRANSFER,
 #endif
+                                  SNDRV_PCM_INFO_BLOCK_TRANSFER,
+
        .formats                = SNDRV_PCM_FMTBIT_S16_LE,
        .period_bytes_min       = 32,
        .period_bytes_max       = 0x10000,
@@ -123,10 +130,20 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
 
 static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
 {
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        struct snd_pcm_runtime *runtime = substream->runtime;
+       struct sport_device *sport = runtime->private_data;
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-       memset(runtime->dma_area, 0, runtime->buffer_size);
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               sport->once = 0;
+               if (runtime->dma_area)
+                       memset(runtime->dma_area, 0, runtime->buffer_size);
+               memset(sport->tx_dma_buf, 0, runtime->buffer_size *
+                       sizeof(struct ac97_frame));
+       } else
+               memset(sport->rx_dma_buf, 0, runtime->buffer_size *
+                       sizeof(struct ac97_frame));
+#endif
        snd_pcm_lib_free_pages(substream);
        return 0;
 }
@@ -139,7 +156,7 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
        /* An intermediate buffer is introduced for implementing mmap for
         * SPORT working in TMD mode(include AC97).
         */
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
                sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
@@ -173,24 +190,24 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        switch (cmd) {
        case SNDRV_PCM_TRIGGER_START:
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
                        bf5xx_mmap_copy(substream, runtime->period_size);
-                       snd_pcm_period_elapsed(substream);
                        sport->tx_delay_pos = 0;
+#endif
                        sport_tx_start(sport);
-               }
-               else
+               } else
                        sport_rx_start(sport);
                break;
        case SNDRV_PCM_TRIGGER_STOP:
        case SNDRV_PCM_TRIGGER_SUSPEND:
        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
                if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
                        sport->tx_pos = 0;
 #endif
                        sport_tx_stop(sport);
                } else {
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
                        sport->rx_pos = 0;
 #endif
                        sport_rx_stop(sport);
@@ -208,7 +225,7 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
        struct sport_device *sport = runtime->private_data;
        unsigned int curr;
 
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                curr = sport->tx_delay_pos;
        else
@@ -249,22 +266,7 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
        return ret;
 }
 
-static int bf5xx_pcm_close(struct snd_pcm_substream *substream)
-{
-       struct snd_pcm_runtime *runtime = substream->runtime;
-       struct sport_device *sport = runtime->private_data;
-
-       pr_debug("%s enter\n", __func__);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               sport->once = 0;
-               memset(sport->tx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
-       } else
-               memset(sport->rx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
-
-       return 0;
-}
-
-#ifdef CONFIG_SND_MMAP_SUPPORT
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
 static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
        struct vm_area_struct *vma)
 {
@@ -281,32 +283,29 @@ static    int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
                    void __user *buf, snd_pcm_uframes_t count)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
-
+       unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
        pr_debug("%s copy pos:0x%lx count:0x%lx\n",
                        substream->stream ? "Capture" : "Playback", pos, count);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-               bf5xx_pcm_to_ac97(
-                               (struct ac97_frame *)runtime->dma_area + pos,
-                               buf, count);
+               bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos,
+                       (__u16 *)buf, count, chan_mask);
        else
-               bf5xx_ac97_to_pcm(
-                               (struct ac97_frame *)runtime->dma_area + pos,
-                               buf, count);
+               bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos,
+                       (__u16 *)buf, count);
        return 0;
 }
 #endif
 
 struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
        .open           = bf5xx_pcm_open,
-       .close          = bf5xx_pcm_close,
        .ioctl          = snd_pcm_lib_ioctl,
        .hw_params      = bf5xx_pcm_hw_params,
        .hw_free        = bf5xx_pcm_hw_free,
        .prepare        = bf5xx_pcm_prepare,
        .trigger        = bf5xx_pcm_trigger,
        .pointer        = bf5xx_pcm_pointer,
-#ifdef CONFIG_SND_MMAP_SUPPORT
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        .mmap           = bf5xx_pcm_mmap,
 #else
        .copy           = bf5xx_pcm_copy,
@@ -344,7 +343,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
  * Need to allocate local buffer when enable
  * MMAP for SPORT working in TMD mode (include AC97).
  */
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                if (!sport_handle->tx_dma_buf) {
                        sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
@@ -381,7 +380,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
        struct snd_pcm_substream *substream;
        struct snd_dma_buffer *buf;
        int stream;
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
                sizeof(struct ac97_frame) / 4;
 #endif
@@ -395,7 +394,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
                        continue;
                dma_free_coherent(NULL, buf->bytes, buf->area, 0);
                buf->area = NULL;
-#if defined(CONFIG_SND_MMAP_SUPPORT)
+#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                if (sport_handle->tx_dma_buf)
                        dma_free_coherent(NULL, size, \
@@ -452,6 +451,18 @@ struct snd_soc_platform bf5xx_ac97_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
 
+static int __init bfin_ac97_init(void)
+{
+       return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
+}
+module_init(bfin_ac97_init);
+
+static void __exit bfin_ac97_exit(void)
+{
+       snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
+}
+module_exit(bfin_ac97_exit);
+
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
 MODULE_LICENSE("GPL");
index 5e5aafb6485f0bce67bf211a24bc475db69f686b..3be2be60576df8bc336f7a8130cdce27404d92a6 100644 (file)
 static int *cmd_count;
 static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
 
-#if defined(CONFIG_BF54x)
+static u16 sport_req[][7] = {
+               PIN_REQ_SPORT_0,
+#ifdef PIN_REQ_SPORT_1
+               PIN_REQ_SPORT_1,
+#endif
+#ifdef PIN_REQ_SPORT_2
+               PIN_REQ_SPORT_2,
+#endif
+#ifdef PIN_REQ_SPORT_3
+               PIN_REQ_SPORT_3,
+#endif
+       };
+
 static struct sport_param sport_params[4] = {
        {
                .dma_rx_chan    = CH_SPORT0_RX,
                .dma_tx_chan    = CH_SPORT0_TX,
-               .err_irq        = IRQ_SPORT0_ERR,
+               .err_irq        = IRQ_SPORT0_ERROR,
                .regs           = (struct sport_register *)SPORT0_TCR1,
        },
+#ifdef PIN_REQ_SPORT_1
        {
                .dma_rx_chan    = CH_SPORT1_RX,
                .dma_tx_chan    = CH_SPORT1_TX,
-               .err_irq        = IRQ_SPORT1_ERR,
+               .err_irq        = IRQ_SPORT1_ERROR,
                .regs           = (struct sport_register *)SPORT1_TCR1,
        },
+#endif
+#ifdef PIN_REQ_SPORT_2
        {
                .dma_rx_chan    = CH_SPORT2_RX,
                .dma_tx_chan    = CH_SPORT2_TX,
-               .err_irq        = IRQ_SPORT2_ERR,
+               .err_irq        = IRQ_SPORT2_ERROR,
                .regs           = (struct sport_register *)SPORT2_TCR1,
        },
+#endif
+#ifdef PIN_REQ_SPORT_3
        {
                .dma_rx_chan    = CH_SPORT3_RX,
                .dma_tx_chan    = CH_SPORT3_TX,
-               .err_irq        = IRQ_SPORT3_ERR,
+               .err_irq        = IRQ_SPORT3_ERROR,
                .regs           = (struct sport_register *)SPORT3_TCR1,
        }
-};
-#else
-static struct sport_param sport_params[2] = {
-       {
-               .dma_rx_chan    = CH_SPORT0_RX,
-               .dma_tx_chan    = CH_SPORT0_TX,
-               .err_irq        = IRQ_SPORT0_ERROR,
-               .regs           = (struct sport_register *)SPORT0_TCR1,
-       },
-       {
-               .dma_rx_chan    = CH_SPORT1_RX,
-               .dma_tx_chan    = CH_SPORT1_TX,
-               .err_irq        = IRQ_SPORT1_ERROR,
-               .regs           = (struct sport_register *)SPORT1_TCR1,
-       }
-};
 #endif
+};
 
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
-               size_t count)
+void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
+               size_t count, unsigned int chan_mask)
 {
        while (count--) {
-               dst->ac97_tag = TAG_VALID | TAG_PCM;
-               (dst++)->ac97_pcm = *src++;
+               dst->ac97_tag = TAG_VALID;
+               if (chan_mask & SP_FL) {
+                       dst->ac97_pcm_r = *src++;
+                       dst->ac97_tag |= TAG_PCM_RIGHT;
+               }
+               if (chan_mask & SP_FR) {
+                       dst->ac97_pcm_l = *src++;
+                       dst->ac97_tag |= TAG_PCM_LEFT;
+
+               }
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+               if (chan_mask & SP_SR) {
+                       dst->ac97_sl = *src++;
+                       dst->ac97_tag |= TAG_PCM_SL;
+               }
+               if (chan_mask & SP_SL) {
+                       dst->ac97_sr = *src++;
+                       dst->ac97_tag |= TAG_PCM_SR;
+               }
+               if (chan_mask & SP_LFE) {
+                       dst->ac97_lfe = *src++;
+                       dst->ac97_tag |= TAG_PCM_LFE;
+               }
+               if (chan_mask & SP_FC) {
+                       dst->ac97_center = *src++;
+                       dst->ac97_tag |= TAG_PCM_CENTER;
+               }
+#endif
+               dst++;
        }
 }
 EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
 
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
+void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
                size_t count)
 {
-       while (count--)
-               *(dst++) = (src++)->ac97_pcm;
+       while (count--) {
+               *(dst++) = src->ac97_pcm_l;
+               *(dst++) = src->ac97_pcm_r;
+               src++;
+       }
 }
 EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
 
 static unsigned int sport_tx_curr_frag(struct sport_device *sport)
 {
-       return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \
+       return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
                        sport->tx_fragsize;
 }
 
@@ -130,7 +162,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
 
        sport_incfrag(sport, &nextfrag, 1);
 
-       nextwrite = (struct ac97_frame *)(sport->tx_buf + \
+       nextwrite = (struct ac97_frame *)(sport->tx_buf +
                        nextfrag * sport->tx_fragsize);
        pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
                sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
@@ -237,8 +269,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
 #ifdef CONFIG_PM
-static int bf5xx_ac97_suspend(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
+static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
 {
        struct sport_device *sport =
                (struct sport_device *)dai->private_data;
@@ -253,8 +284,7 @@ static int bf5xx_ac97_suspend(struct platform_device *pdev,
        return 0;
 }
 
-static int bf5xx_ac97_resume(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
+static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
 {
        int ret;
        struct sport_device *sport =
@@ -297,20 +327,15 @@ static int bf5xx_ac97_resume(struct platform_device *pdev,
 static int bf5xx_ac97_probe(struct platform_device *pdev,
                            struct snd_soc_dai *dai)
 {
-       int ret;
-#if defined(CONFIG_BF54x)
-       u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1,
-                                PIN_REQ_SPORT_2, PIN_REQ_SPORT_3};
-#else
-       u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1};
-#endif
+       int ret = 0;
        cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
        if (cmd_count == NULL)
                return -ENOMEM;
 
        if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
                pr_err("Requesting Peripherals failed\n");
-               return -EFAULT;
+               ret =  -EFAULT;
+               goto peripheral_err;
                }
 
 #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
@@ -318,54 +343,54 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
        if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
                pr_err("Failed to request GPIO_%d for reset\n",
                                CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-               peripheral_free_list(&sport_req[sport_num][0]);
-               return -1;
+               ret =  -1;
+               goto gpio_err;
        }
        gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
 #endif
        sport_handle = sport_init(&sport_params[sport_num], 2, \
                        sizeof(struct ac97_frame), NULL);
        if (!sport_handle) {
-               peripheral_free_list(&sport_req[sport_num][0]);
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-               gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
-               return -ENODEV;
+               ret = -ENODEV;
+               goto sport_err;
        }
        /*SPORT works in TDM mode to simulate AC97 transfers*/
        ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
        if (ret) {
                pr_err("SPORT is busy!\n");
-               kfree(sport_handle);
-               peripheral_free_list(&sport_req[sport_num][0]);
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-               gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
-               return -EBUSY;
+               ret = -EBUSY;
+               goto sport_config_err;
        }
 
        ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
        if (ret) {
                pr_err("SPORT is busy!\n");
-               kfree(sport_handle);
-               peripheral_free_list(&sport_req[sport_num][0]);
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-               gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
-               return -EBUSY;
+               ret = -EBUSY;
+               goto sport_config_err;
        }
 
        ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
        if (ret) {
                pr_err("SPORT is busy!\n");
-               kfree(sport_handle);
-               peripheral_free_list(&sport_req[sport_num][0]);
-#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
-               gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
-#endif
-               return -EBUSY;
+               ret = -EBUSY;
+               goto sport_config_err;
        }
+
        return 0;
+
+sport_config_err:
+       kfree(sport_handle);
+sport_err:
+#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
+       gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
+#endif
+gpio_err:
+       peripheral_free_list(&sport_req[sport_num][0]);
+peripheral_err:
+       free_page((unsigned long)cmd_count);
+       cmd_count = NULL;
+
+       return ret;
 }
 
 static void bf5xx_ac97_remove(struct platform_device *pdev,
@@ -373,6 +398,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
 {
        free_page((unsigned long)cmd_count);
        cmd_count = NULL;
+       peripheral_free_list(&sport_req[sport_num][0]);
 #ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
        gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
 #endif
@@ -381,7 +407,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
 struct snd_soc_dai bfin_ac97_dai = {
        .name = "bf5xx-ac97",
        .id = 0,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .probe = bf5xx_ac97_probe,
        .remove = bf5xx_ac97_remove,
        .suspend = bf5xx_ac97_suspend,
@@ -389,7 +415,11 @@ struct snd_soc_dai bfin_ac97_dai = {
        .playback = {
                .stream_name = "AC97 Playback",
                .channels_min = 2,
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+               .channels_max = 6,
+#else
                .channels_max = 2,
+#endif
                .rates = SNDRV_PCM_RATE_48000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE, },
        .capture = {
@@ -401,6 +431,18 @@ struct snd_soc_dai bfin_ac97_dai = {
 };
 EXPORT_SYMBOL_GPL(bfin_ac97_dai);
 
+static int __init bfin_ac97_init(void)
+{
+       return snd_soc_register_dai(&bfin_ac97_dai);
+}
+module_init(bfin_ac97_init);
+
+static void __exit bfin_ac97_exit(void)
+{
+       snd_soc_unregister_dai(&bfin_ac97_dai);
+}
+module_exit(bfin_ac97_exit);
+
 MODULE_AUTHOR("Roy Huang");
 MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
 MODULE_LICENSE("GPL");
index 3f77cc558dc03fe4a4847096f5bc07f8152dd7d6..3f2a911fe0cb2adda1c45473babef9845d9280c9 100644 (file)
@@ -16,21 +16,46 @@ struct ac97_frame {
        u16 ac97_tag;           /* slot 0 */
        u16 ac97_addr;          /* slot 1 */
        u16 ac97_data;          /* slot 2 */
-       u32 ac97_pcm;           /* slot 3 and 4: left and right pcm data */
+       u16 ac97_pcm_l;         /*slot 3:front left*/
+       u16 ac97_pcm_r;         /*slot 4:front left*/
+#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
+       u16 ac97_mdm_l1;
+       u16 ac97_center;        /*slot 6:center*/
+       u16 ac97_sl;            /*slot 7:surround left*/
+       u16 ac97_sr;            /*slot 8:surround right*/
+       u16 ac97_lfe;           /*slot 9:lfe*/
+#endif
 } __attribute__ ((packed));
 
+/* Speaker location */
+#define SP_FL          0x0001
+#define SP_FR          0x0010
+#define SP_FC          0x0002
+#define SP_LFE         0x0020
+#define SP_SL          0x0004
+#define SP_SR          0x0040
+
+#define SP_STEREO      (SP_FL | SP_FR)
+#define SP_2DOT1       (SP_FL | SP_FR | SP_LFE)
+#define SP_QUAD                (SP_FL | SP_FR | SP_SL | SP_SR)
+#define SP_5DOT1       (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
+
 #define TAG_VALID              0x8000
 #define TAG_CMD                        0x6000
 #define TAG_PCM_LEFT           0x1000
 #define TAG_PCM_RIGHT          0x0800
-#define TAG_PCM                        (TAG_PCM_LEFT | TAG_PCM_RIGHT)
+#define TAG_PCM_MDM_L1         0x0400
+#define TAG_PCM_CENTER         0x0200
+#define TAG_PCM_SL             0x0100
+#define TAG_PCM_SR             0x0080
+#define TAG_PCM_LFE            0x0040
 
 extern struct snd_soc_dai bfin_ac97_dai;
 
-void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \
-               size_t count);
+void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
+               size_t count, unsigned int chan_mask);
 
-void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \
+void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
                size_t count);
 
 #endif
index 124425d223202aeb308a45023616e26a152dc4c0..d8f5912737788d871c1fd6478d45cc64a4c7ee79 100644 (file)
@@ -43,7 +43,7 @@
 #include "bf5xx-ac97-pcm.h"
 #include "bf5xx-ac97.h"
 
-static struct snd_soc_machine bf5xx_board;
+static struct snd_soc_card bf5xx_board;
 
 static int bf5xx_board_startup(struct snd_pcm_substream *substream)
 {
@@ -67,15 +67,15 @@ static struct snd_soc_dai_link bf5xx_board_dai = {
        .ops = &bf5xx_board_ops,
 };
 
-static struct snd_soc_machine bf5xx_board = {
+static struct snd_soc_card bf5xx_board = {
        .name = "bf5xx-board",
+       .platform = &bf5xx_ac97_soc_platform,
        .dai_link = &bf5xx_board_dai,
        .num_links = 1,
 };
 
 static struct snd_soc_device bf5xx_board_snd_devdata = {
-       .machine = &bf5xx_board,
-       .platform = &bf5xx_ac97_soc_platform,
+       .card = &bf5xx_board,
        .codec_dev = &soc_codec_dev_ad1980,
 };
 
index 622c9b9095328a46bdf9b5ed9619916a8d456c92..7f2a5e199075421ef0ebee1097139a2671f2f6d2 100644 (file)
@@ -65,7 +65,7 @@
 
 #define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
 
-static struct snd_soc_machine bf5xx_ad73311;
+static struct snd_soc_card bf5xx_ad73311;
 
 static int snd_ad73311_startup(void)
 {
@@ -168,7 +168,7 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
                params_format(params));
 
        /* set cpu DAI configuration */
-       ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
                return ret;
@@ -190,16 +190,16 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai = {
        .ops = &bf5xx_ad73311_ops,
 };
 
-static struct snd_soc_machine bf5xx_ad73311 = {
+static struct snd_soc_card bf5xx_ad73311 = {
        .name = "bf5xx_ad73311",
+       .platform = &bf5xx_i2s_soc_platform,
        .probe = bf5xx_probe,
        .dai_link = &bf5xx_ad73311_dai,
        .num_links = 1,
 };
 
 static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
-       .machine = &bf5xx_ad73311,
-       .platform = &bf5xx_i2s_soc_platform,
+       .card = &bf5xx_ad73311,
        .codec_dev = &soc_codec_dev_ad73311,
 };
 
index 61fccf925192e62697908fadcb1e78507125edb3..53d290b3ea47d9e2cf974cd1b83721f7199180da 100644 (file)
@@ -283,6 +283,18 @@ struct snd_soc_platform bf5xx_i2s_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
 
+static int __init bfin_i2s_init(void)
+{
+       return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
+}
+module_init(bfin_i2s_init);
+
+static void __exit bfin_i2s_exit(void)
+{
+       snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
+}
+module_exit(bfin_i2s_exit);
+
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
 MODULE_LICENSE("GPL");
index e020c160ee441e815b6b6c59159cd30c77ed38ec..d1d95d2393feb81ea8352d52e04e00b6d59d3d1b 100644 (file)
@@ -132,7 +132,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
        return ret;
 }
 
-static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
+static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
 {
        pr_debug("%s enter\n", __func__);
 
@@ -142,7 +143,8 @@ static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
 }
 
 static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        int ret = 0;
 
@@ -193,7 +195,8 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream)
+static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
 {
        pr_debug("%s enter\n", __func__);
        bf5xx_i2s.counter--;
@@ -219,16 +222,14 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
        return 0;
 }
 
-static void bf5xx_i2s_remove(struct platform_device *pdev,
-                          struct snd_soc_dai *dai)
+static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
 {
        pr_debug("%s enter\n", __func__);
        peripheral_free_list(&sport_req[sport_num][0]);
 }
 
 #ifdef CONFIG_PM
-static int bf5xx_i2s_suspend(struct platform_device *dev,
-                            struct snd_soc_dai *dai)
+static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
 {
        struct sport_device *sport =
                (struct sport_device *)dai->private_data;
@@ -289,7 +290,6 @@ static int bf5xx_i2s_resume(struct platform_device *pdev,
 struct snd_soc_dai bf5xx_i2s_dai = {
        .name = "bf5xx-i2s",
        .id = 0,
-       .type = SND_SOC_DAI_I2S,
        .probe = bf5xx_i2s_probe,
        .remove = bf5xx_i2s_remove,
        .suspend = bf5xx_i2s_suspend,
@@ -307,13 +307,24 @@ struct snd_soc_dai bf5xx_i2s_dai = {
        .ops = {
                .startup   = bf5xx_i2s_startup,
                .shutdown  = bf5xx_i2s_shutdown,
-               .hw_params = bf5xx_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = bf5xx_i2s_hw_params,
                .set_fmt = bf5xx_i2s_set_dai_fmt,
        },
 };
 EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
 
+static int __init bfin_i2s_init(void)
+{
+       return snd_soc_register_dai(&bf5xx_i2s_dai);
+}
+module_init(bfin_i2s_init);
+
+static void __exit bfin_i2s_exit(void)
+{
+       snd_soc_unregister_dai(&bf5xx_i2s_dai);
+}
+module_exit(bfin_i2s_exit);
+
 /* Module information */
 MODULE_AUTHOR("Cliff Cai");
 MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
index fcadcc081f7fe4994a2dc3dbc0514656c7c6cd06..2e63dea73e9c64631a980dd8cc5934504e19f84b 100644 (file)
@@ -116,7 +116,7 @@ struct sport_device {
        void *err_data;
        unsigned char *tx_dma_buf;
        unsigned char *rx_dma_buf;
-#ifdef CONFIG_SND_MMAP_SUPPORT
+#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
        dma_addr_t tx_dma_phy;
        dma_addr_t rx_dma_phy;
        int tx_pos;/*pcm sample count*/
index e15f67fd7769a8b4fdb7a26c53ef5c3ecbcb8342..bc0cdded711664ccd0437e82fb62e41807a6a790 100644 (file)
@@ -44,7 +44,7 @@
 #include "bf5xx-i2s-pcm.h"
 #include "bf5xx-i2s.h"
 
-static struct snd_soc_machine bf5xx_ssm2602;
+static struct snd_soc_card bf5xx_ssm2602;
 
 static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
 {
@@ -92,17 +92,17 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
         */
 
        /* set codec DAI configuration */
-       ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
                return ret;
        /* set cpu DAI configuration */
-       ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
                SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
        if (ret < 0)
                return ret;
 
-       ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
+       ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
                SND_SOC_CLOCK_IN);
        if (ret < 0)
                return ret;
@@ -135,15 +135,15 @@ static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
        .i2c_address = 0x1b,
 };
 
-static struct snd_soc_machine bf5xx_ssm2602 = {
+static struct snd_soc_card bf5xx_ssm2602 = {
        .name = "bf5xx_ssm2602",
+       .platform = &bf5xx_i2s_soc_platform,
        .dai_link = &bf5xx_ssm2602_dai,
        .num_links = 1,
 };
 
 static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
-       .machine = &bf5xx_ssm2602,
-       .platform = &bf5xx_i2s_soc_platform,
+       .card = &bf5xx_ssm2602,
        .codec_dev = &soc_codec_dev_ssm2602,
        .codec_data = &bf5xx_ssm2602_setup,
 };
index 38a0e3b620a750ad4845ee861f18b323b74cf0f4..c41289b5f58671276d73b51b47b3448901136f0f 100644 (file)
@@ -1,31 +1,40 @@
 config SND_SOC_ALL_CODECS
        tristate "Build all ASoC CODEC drivers"
-       depends on I2C
-       select SPI
-       select SPI_MASTER
-       select SND_SOC_AD73311
-       select SND_SOC_AK4535
-       select SND_SOC_CS4270
-       select SND_SOC_SSM2602
-       select SND_SOC_TLV320AIC23
-       select SND_SOC_TLV320AIC26
-       select SND_SOC_TLV320AIC3X
-       select SND_SOC_UDA1380
-       select SND_SOC_WM8510
-       select SND_SOC_WM8580
-       select SND_SOC_WM8731
-       select SND_SOC_WM8750
-       select SND_SOC_WM8753
-       select SND_SOC_WM8900
-       select SND_SOC_WM8903
-       select SND_SOC_WM8971
-       select SND_SOC_WM8990
+       select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
+       select SND_SOC_AD1980 if SND_SOC_AC97_BUS
+       select SND_SOC_AD73311 if I2C
+       select SND_SOC_AK4535 if I2C
+       select SND_SOC_CS4270 if I2C
+       select SND_SOC_PCM3008
+       select SND_SOC_SSM2602 if I2C
+       select SND_SOC_TLV320AIC23 if I2C
+       select SND_SOC_TLV320AIC26 if SPI_MASTER
+       select SND_SOC_TLV320AIC3X if I2C
+       select SND_SOC_TWL4030 if TWL4030_CORE
+       select SND_SOC_UDA134X
+       select SND_SOC_UDA1380 if I2C
+       select SND_SOC_WM8350 if MFD_WM8350
+       select SND_SOC_WM8510 if (I2C || SPI_MASTER)
+       select SND_SOC_WM8580 if I2C
+       select SND_SOC_WM8728 if (I2C || SPI_MASTER)
+       select SND_SOC_WM8731 if (I2C || SPI_MASTER)
+       select SND_SOC_WM8750 if (I2C || SPI_MASTER)
+       select SND_SOC_WM8753 if (I2C || SPI_MASTER)
+       select SND_SOC_WM8900 if I2C
+       select SND_SOC_WM8903 if I2C
+       select SND_SOC_WM8971 if I2C
+       select SND_SOC_WM8990 if I2C
+       select SND_SOC_WM9712 if SND_SOC_AC97_BUS
+       select SND_SOC_WM9713 if SND_SOC_AC97_BUS
         help
           Normally ASoC codec drivers are only built if a machine driver which
           uses them is also built since they are only usable with a machine
           driver.  Selecting this option will allow these drivers to be built
           without an explicit machine driver for test and development purposes.
 
+         Support for the bus types used to access the codecs to be built must
+         be selected separately.
+
           If unsure select "N".
 
 
@@ -60,6 +69,12 @@ config SND_SOC_CS4270_VD33_ERRATA
        bool
        depends on SND_SOC_CS4270
 
+config SND_SOC_L3
+       tristate
+
+config SND_SOC_PCM3008
+       tristate
+
 config SND_SOC_SSM2602
        tristate
 
@@ -75,15 +90,29 @@ config SND_SOC_TLV320AIC3X
        tristate
        depends on I2C
 
+config SND_SOC_TWL4030
+       tristate
+       depends on TWL4030_CORE
+
+config SND_SOC_UDA134X
+       tristate
+       select SND_SOC_L3
+
 config SND_SOC_UDA1380
         tristate
 
+config SND_SOC_WM8350
+       tristate
+
 config SND_SOC_WM8510
        tristate
 
 config SND_SOC_WM8580
        tristate
 
+config SND_SOC_WM8728
+       tristate
+
 config SND_SOC_WM8731
        tristate
 
index 90f0a585fc70e1f5a4d9a9be1b8514a22100917a..c4ddc9aa2bbd8aaa5a35bd7ecc3a487603990a97 100644 (file)
@@ -3,13 +3,19 @@ snd-soc-ad1980-objs := ad1980.o
 snd-soc-ad73311-objs := ad73311.o
 snd-soc-ak4535-objs := ak4535.o
 snd-soc-cs4270-objs := cs4270.o
+snd-soc-l3-objs := l3.o
+snd-soc-pcm3008-objs := pcm3008.o
 snd-soc-ssm2602-objs := ssm2602.o
 snd-soc-tlv320aic23-objs := tlv320aic23.o
 snd-soc-tlv320aic26-objs := tlv320aic26.o
 snd-soc-tlv320aic3x-objs := tlv320aic3x.o
+snd-soc-twl4030-objs := twl4030.o
+snd-soc-uda134x-objs := uda134x.o
 snd-soc-uda1380-objs := uda1380.o
+snd-soc-wm8350-objs := wm8350.o
 snd-soc-wm8510-objs := wm8510.o
 snd-soc-wm8580-objs := wm8580.o
+snd-soc-wm8728-objs := wm8728.o
 snd-soc-wm8731-objs := wm8731.o
 snd-soc-wm8750-objs := wm8750.o
 snd-soc-wm8753-objs := wm8753.o
@@ -25,13 +31,19 @@ obj-$(CONFIG_SND_SOC_AD1980)        += snd-soc-ad1980.o
 obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
 obj-$(CONFIG_SND_SOC_AK4535)   += snd-soc-ak4535.o
 obj-$(CONFIG_SND_SOC_CS4270)   += snd-soc-cs4270.o
+obj-$(CONFIG_SND_SOC_L3)       += snd-soc-l3.o
+obj-$(CONFIG_SND_SOC_PCM3008)  += snd-soc-pcm3008.o
 obj-$(CONFIG_SND_SOC_SSM2602)  += snd-soc-ssm2602.o
 obj-$(CONFIG_SND_SOC_TLV320AIC23)      += snd-soc-tlv320aic23.o
 obj-$(CONFIG_SND_SOC_TLV320AIC26)      += snd-soc-tlv320aic26.o
 obj-$(CONFIG_SND_SOC_TLV320AIC3X)      += snd-soc-tlv320aic3x.o
+obj-$(CONFIG_SND_SOC_TWL4030)  += snd-soc-twl4030.o
+obj-$(CONFIG_SND_SOC_UDA134X)  += snd-soc-uda134x.o
 obj-$(CONFIG_SND_SOC_UDA1380)  += snd-soc-uda1380.o
+obj-$(CONFIG_SND_SOC_WM8350)   += snd-soc-wm8350.o
 obj-$(CONFIG_SND_SOC_WM8510)   += snd-soc-wm8510.o
 obj-$(CONFIG_SND_SOC_WM8580)   += snd-soc-wm8580.o
+obj-$(CONFIG_SND_SOC_WM8728)   += snd-soc-wm8728.o
 obj-$(CONFIG_SND_SOC_WM8731)   += snd-soc-wm8731.o
 obj-$(CONFIG_SND_SOC_WM8750)   += snd-soc-wm8750.o
 obj-$(CONFIG_SND_SOC_WM8753)   += snd-soc-wm8753.o
index bd1ebdc6c86ce0e6ef021139f5ac10b93831f4d4..fb53e6511af25d0b0d0dd164a1b1de0a511f73c7 100644 (file)
@@ -24,7 +24,8 @@
 
 #define AC97_VERSION "0.6"
 
-static int ac97_prepare(struct snd_pcm_substream *substream)
+static int ac97_prepare(struct snd_pcm_substream *substream,
+                       struct snd_soc_dai *dai)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -42,7 +43,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
 
 struct snd_soc_dai ac97_dai = {
        .name = "AC97 HiFi",
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .playback = {
                .stream_name = "AC97 Playback",
                .channels_min = 1,
@@ -113,7 +114,7 @@ static int ac97_soc_probe(struct platform_device *pdev)
        if (ret < 0)
                goto bus_err;
 
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0)
                goto bus_err;
        return 0;
index 1397b8e06c0b41eda7002815a276baba8f3ea035..73fdbb4d4a3d4702cbf6d9b3b25d59d00a287e2b 100644 (file)
@@ -85,6 +85,9 @@ SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
 SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
 SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
 
+SOC_DOUBLE("Center/LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 0, 31, 1),
+SOC_DOUBLE("Center/LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 7, 1, 1),
+
 SOC_ENUM("Capture Source", ad1980_cap_src),
 
 SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
@@ -142,10 +145,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
 
 struct snd_soc_dai ad1980_dai = {
        .name = "AC97",
+       .ac97_control = 1,
        .playback = {
                .stream_name = "Playback",
                .channels_min = 2,
-               .channels_max = 2,
+               .channels_max = 6,
                .rates = SNDRV_PCM_RATE_48000,
                .formats = SNDRV_PCM_FMTBIT_S16_LE, },
        .capture = {
@@ -192,6 +196,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
        struct snd_soc_codec *codec;
        int ret = 0;
        u16 vendor_id2;
+       u16 ext_status;
 
        printk(KERN_INFO "AD1980 SoC Audio Codec\n");
 
@@ -234,7 +239,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
 
        ret = ad1980_reset(codec, 0);
        if (ret < 0) {
-               printk(KERN_ERR "AC97 link error\n");
+               printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
                goto reset_err;
        }
 
@@ -253,12 +258,19 @@ static int ad1980_soc_probe(struct platform_device *pdev)
                                "supported\n");
        }
 
-       ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */
-       ac97_write(codec, AC97_PCM, 0x0000);    /* unmute PCM out volume */
-       ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */
+       /* unmute captures and playbacks volume */
+       ac97_write(codec, AC97_MASTER, 0x0000);
+       ac97_write(codec, AC97_PCM, 0x0000);
+       ac97_write(codec, AC97_REC_GAIN, 0x0000);
+       ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
+       ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
+
+       /*power on LFE/CENTER/Surround DACs*/
+       ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
+       ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
 
        ad1980_add_controls(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "ad1980: failed to register card\n");
                goto reset_err;
index 37af8607b00a1f293aad10b8f5cfd3b120719549..b09289a1e55af93460f68cb6f5e76707a884a51a 100644 (file)
@@ -8,14 +8,10 @@
  *  under  the terms of  the GNU General  Public License as published by the
  *  Free Software Foundation;  either version 2 of the  License, or (at your
  *  option) any later version.
- *
- *  Revision history
- *    25th Sep 2008   Initial version.
  */
 
 #include <linux/init.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 #include <sound/core.h>
@@ -68,7 +64,7 @@ static int ad73311_soc_probe(struct platform_device *pdev)
                goto pcm_err;
        }
 
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "ad73311: failed to register card\n");
                goto register_err;
@@ -102,6 +98,18 @@ struct snd_soc_codec_device soc_codec_dev_ad73311 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
 
+static int __init ad73311_init(void)
+{
+       return snd_soc_register_dai(&ad73311_dai);
+}
+module_init(ad73311_init);
+
+static void __exit ad73311_exit(void)
+{
+       snd_soc_unregister_dai(&ad73311_dai);
+}
+module_exit(ad73311_exit);
+
 MODULE_DESCRIPTION("ASoC ad73311 driver");
 MODULE_AUTHOR("Cliff Cai ");
 MODULE_LICENSE("GPL");
index 2a89b5888e11c33bdedf44b817e0c61282b95d0d..81300d8d42ca2a5f2648665fec39aef5490c0f37 100644 (file)
@@ -339,7 +339,8 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
 }
 
 static int ak4535_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -451,8 +452,6 @@ struct snd_soc_dai ak4535_dai = {
                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
        .ops = {
                .hw_params = ak4535_hw_params,
-       },
-       .dai_ops = {
                .set_fmt = ak4535_set_dai_fmt,
                .digital_mute = ak4535_mute,
                .set_sysclk = ak4535_set_dai_sysclk,
@@ -513,7 +512,7 @@ static int ak4535_init(struct snd_soc_device *socdev)
 
        ak4535_add_controls(codec);
        ak4535_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "ak4535: failed to register card\n");
                goto card_err;
@@ -689,6 +688,18 @@ struct snd_soc_codec_device soc_codec_dev_ak4535 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
 
+static int __init ak4535_modinit(void)
+{
+       return snd_soc_register_dai(&ak4535_dai);
+}
+module_init(ak4535_modinit);
+
+static void __exit ak4535_exit(void)
+{
+       snd_soc_unregister_dai(&ak4535_dai);
+}
+module_exit(ak4535_exit);
+
 MODULE_DESCRIPTION("Soc AK4535 driver");
 MODULE_AUTHOR("Richard Purdie");
 MODULE_LICENSE("GPL");
index 0bbd94501d7ea45f1aa8b491bf43d275ffb779c9..f1aa0c34421c76f5e63f029847a62fc1a26d954f 100644 (file)
@@ -360,13 +360,14 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
 /*
  * Program the CS4270 with the given hardware parameters.
  *
- * The .dai_ops functions are used to provide board-specific data, like
+ * The .ops functions are used to provide board-specific data, like
  * input frequencies, to this driver.  This function takes that information,
  * combines it with the hardware parameters provided, and programs the
  * hardware accordingly.
  */
 static int cs4270_hw_params(struct snd_pcm_substream *substream,
-                           struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -450,6 +451,19 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
                return ret;
        }
 
+       /* Disable automatic volume control.  It's enabled by default, and
+        * it causes volume change commands to be delayed, sometimes until
+        * after playback has started.
+        */
+
+       reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
+       reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
+       ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
+       if (ret < 0) {
+               printk(KERN_ERR "I2C write failed\n");
+               return ret;
+       }
+
        /* Thaw and power-up the codec */
 
        ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
@@ -697,10 +711,10 @@ static int cs4270_probe(struct platform_device *pdev)
        if (codec->control_data) {
                /* Initialize codec ops */
                cs4270_dai.ops.hw_params = cs4270_hw_params;
-               cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk;
-               cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt;
+               cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk;
+               cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
 #ifdef CONFIG_SND_SOC_CS4270_HWMUTE
-               cs4270_dai.dai_ops.digital_mute = cs4270_mute;
+               cs4270_dai.ops.digital_mute = cs4270_mute;
 #endif
        } else
                printk(KERN_INFO "cs4270: no I2C device found, "
@@ -709,7 +723,7 @@ static int cs4270_probe(struct platform_device *pdev)
        printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
 #endif
 
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "cs4270: failed to register card\n");
                goto error_del_driver;
@@ -760,6 +774,18 @@ struct snd_soc_codec_device soc_codec_device_cs4270 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
 
+static int __init cs4270_init(void)
+{
+       return snd_soc_register_dai(&cs4270_dai);
+}
+module_init(cs4270_init);
+
+static void __exit cs4270_exit(void)
+{
+       snd_soc_unregister_dai(&cs4270_dai);
+}
+module_exit(cs4270_exit);
+
 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c
new file mode 100644 (file)
index 0000000..5353af5
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * L3 code
+ *
+ *  Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *
+ * based on:
+ *
+ * L3 bus algorithm module.
+ *
+ *  Copyright (C) 2001 Russell King, All Rights Reserved.
+ *
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+
+#include <sound/l3.h>
+
+/*
+ * Send one byte of data to the chip.  Data is latched into the chip on
+ * the rising edge of the clock.
+ */
+static void sendbyte(struct l3_pins *adap, unsigned int byte)
+{
+       int i;
+
+       for (i = 0; i < 8; i++) {
+               adap->setclk(0);
+               udelay(adap->data_hold);
+               adap->setdat(byte & 1);
+               udelay(adap->data_setup);
+               adap->setclk(1);
+               udelay(adap->clock_high);
+               byte >>= 1;
+       }
+}
+
+/*
+ * Send a set of bytes to the chip.  We need to pulse the MODE line
+ * between each byte, but never at the start nor at the end of the
+ * transfer.
+ */
+static void sendbytes(struct l3_pins *adap, const u8 *buf,
+                     int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               if (i) {
+                       udelay(adap->mode_hold);
+                       adap->setmode(0);
+                       udelay(adap->mode);
+               }
+               adap->setmode(1);
+               udelay(adap->mode_setup);
+               sendbyte(adap, buf[i]);
+       }
+}
+
+int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
+{
+       adap->setclk(1);
+       adap->setdat(1);
+       adap->setmode(1);
+       udelay(adap->mode);
+
+       adap->setmode(0);
+       udelay(adap->mode_setup);
+       sendbyte(adap, addr);
+       udelay(adap->mode_hold);
+
+       sendbytes(adap, data, len);
+
+       adap->setclk(1);
+       adap->setdat(1);
+       adap->setmode(0);
+
+       return len;
+}
+EXPORT_SYMBOL_GPL(l3_write);
+
+MODULE_DESCRIPTION("L3 bit-banging driver");
+MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
new file mode 100644 (file)
index 0000000..9a3e67e
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ * ALSA Soc PCM3008 codec support
+ *
+ * Author:     Hugo Villeneuve
+ * Copyright (C) 2008 Lyrtech inc
+ *
+ * Based on AC97 Soc codec, original copyright follow:
+ * Copyright 2005 Wolfson Microelectronics PLC.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * Generic PCM3008 support.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/soc.h>
+
+#include "pcm3008.h"
+
+#define PCM3008_VERSION "0.2"
+
+#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |   \
+                      SNDRV_PCM_RATE_48000)
+
+struct snd_soc_dai pcm3008_dai = {
+       .name = "PCM3008 HiFi",
+       .playback = {
+               .stream_name = "PCM3008 Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = PCM3008_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+       .capture = {
+               .stream_name = "PCM3008 Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = PCM3008_RATES,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
+       },
+};
+EXPORT_SYMBOL_GPL(pcm3008_dai);
+
+static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
+{
+       gpio_free(setup->dem0_pin);
+       gpio_free(setup->dem1_pin);
+       gpio_free(setup->pdad_pin);
+       gpio_free(setup->pdda_pin);
+}
+
+static int pcm3008_soc_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec;
+       struct pcm3008_setup_data *setup = socdev->codec_data;
+       int ret = 0;
+
+       printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
+
+       socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+       if (!socdev->codec)
+               return -ENOMEM;
+
+       codec = socdev->codec;
+       mutex_init(&codec->mutex);
+
+       codec->name = "PCM3008";
+       codec->owner = THIS_MODULE;
+       codec->dai = &pcm3008_dai;
+       codec->num_dai = 1;
+       codec->write = NULL;
+       codec->read = NULL;
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+
+       /* Register PCMs. */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               printk(KERN_ERR "pcm3008: failed to create pcms\n");
+               goto pcm_err;
+       }
+
+       /* Register Card. */
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               printk(KERN_ERR "pcm3008: failed to register card\n");
+               goto card_err;
+       }
+
+       /* DEM1  DEM0  DE-EMPHASIS_MODE
+        * Low   Low   De-emphasis 44.1 kHz ON
+        * Low   High  De-emphasis OFF
+        * High  Low   De-emphasis 48 kHz ON
+        * High  High  De-emphasis 32 kHz ON
+        */
+
+       /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
+       ret = gpio_request(setup->dem0_pin, "codec_dem0");
+       if (ret == 0)
+               ret = gpio_direction_output(setup->dem0_pin, 1);
+       if (ret != 0)
+               goto gpio_err;
+
+       /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
+       ret = gpio_request(setup->dem1_pin, "codec_dem1");
+       if (ret == 0)
+               ret = gpio_direction_output(setup->dem1_pin, 0);
+       if (ret != 0)
+               goto gpio_err;
+
+       /* Configure PDAD GPIO. */
+       ret = gpio_request(setup->pdad_pin, "codec_pdad");
+       if (ret == 0)
+               ret = gpio_direction_output(setup->pdad_pin, 1);
+       if (ret != 0)
+               goto gpio_err;
+
+       /* Configure PDDA GPIO. */
+       ret = gpio_request(setup->pdda_pin, "codec_pdda");
+       if (ret == 0)
+               ret = gpio_direction_output(setup->pdda_pin, 1);
+       if (ret != 0)
+               goto gpio_err;
+
+       return ret;
+
+gpio_err:
+       pcm3008_gpio_free(setup);
+card_err:
+       snd_soc_free_pcms(socdev);
+pcm_err:
+       kfree(socdev->codec);
+
+       return ret;
+}
+
+static int pcm3008_soc_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+       struct pcm3008_setup_data *setup = socdev->codec_data;
+
+       if (!codec)
+               return 0;
+
+       pcm3008_gpio_free(setup);
+       snd_soc_free_pcms(socdev);
+       kfree(socdev->codec);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct pcm3008_setup_data *setup = socdev->codec_data;
+
+       gpio_set_value(setup->pdad_pin, 0);
+       gpio_set_value(setup->pdda_pin, 0);
+
+       return 0;
+}
+
+static int pcm3008_soc_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct pcm3008_setup_data *setup = socdev->codec_data;
+
+       gpio_set_value(setup->pdad_pin, 1);
+       gpio_set_value(setup->pdda_pin, 1);
+
+       return 0;
+}
+#else
+#define pcm3008_soc_suspend NULL
+#define pcm3008_soc_resume NULL
+#endif
+
+struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
+       .probe =        pcm3008_soc_probe,
+       .remove =       pcm3008_soc_remove,
+       .suspend =      pcm3008_soc_suspend,
+       .resume =       pcm3008_soc_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
+
+static int __init pcm3008_init(void)
+{
+       return snd_soc_register_dai(&pcm3008_dai);
+}
+module_init(pcm3008_init);
+
+static void __exit pcm3008_exit(void)
+{
+       snd_soc_unregister_dai(&pcm3008_dai);
+}
+module_exit(pcm3008_exit);
+
+MODULE_DESCRIPTION("Soc PCM3008 driver");
+MODULE_AUTHOR("Hugo Villeneuve");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
new file mode 100644 (file)
index 0000000..d04e87d
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * PCM3008 ALSA SoC Layer
+ *
+ * Author:     Hugo Villeneuve
+ * Copyright (C) 2008 Lyrtech inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_SND_SOC_PCM3008_H
+#define __LINUX_SND_SOC_PCM3008_H
+
+struct pcm3008_setup_data {
+       unsigned dem0_pin;
+       unsigned dem1_pin;
+       unsigned pdad_pin;
+       unsigned pdda_pin;
+};
+
+extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
+extern struct snd_soc_dai pcm3008_dai;
+
+#endif
index 44ef0dacd564701b3999316d9c2e21c5b41ec4a8..2325aefea4117222898a24f4f9b7fd8a85694ca5 100644 (file)
@@ -285,16 +285,23 @@ static inline int get_coeff(int mclk, int rate)
 }
 
 static int ssm2602_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
 {
        u16 srate;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
        struct ssm2602_priv *ssm2602 = codec->private_data;
+       struct i2c_client *i2c = codec->control_data;
        u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
        int i = get_coeff(ssm2602->sysclk, params_rate(params));
 
+       if (substream == ssm2602->slave_substream) {
+               dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
+               return 0;
+       }
+
        /*no match is found*/
        if (i == ARRAY_SIZE(coeff_div))
                return -EINVAL;
@@ -324,19 +331,26 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int ssm2602_startup(struct snd_pcm_substream *substream)
+static int ssm2602_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
        struct ssm2602_priv *ssm2602 = codec->private_data;
+       struct i2c_client *i2c = codec->control_data;
        struct snd_pcm_runtime *master_runtime;
 
        /* The DAI has shared clocks so if we already have a playback or
         * capture going then constrain this substream to match it.
+        * TODO: the ssm2602 allows pairs of non-matching PB/REC rates
         */
        if (ssm2602->master_substream) {
                master_runtime = ssm2602->master_substream->runtime;
+               dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
+                       master_runtime->sample_bits,
+                       master_runtime->rate);
+
                snd_pcm_hw_constraint_minmax(substream->runtime,
                                             SNDRV_PCM_HW_PARAM_RATE,
                                             master_runtime->rate,
@@ -354,7 +368,8 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
+static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -365,14 +380,21 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static void ssm2602_shutdown(struct snd_pcm_substream *substream)
+static void ssm2602_shutdown(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
+       struct ssm2602_priv *ssm2602 = codec->private_data;
        /* deactivate */
        if (!codec->active)
                ssm2602_write(codec, SSM2602_ACTIVE, 0);
+
+       if (ssm2602->master_substream == substream)
+               ssm2602->master_substream = ssm2602->slave_substream;
+
+       ssm2602->slave_substream = NULL;
 }
 
 static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
@@ -496,6 +518,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
                SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
                SNDRV_PCM_RATE_96000)
 
+#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+               SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
+
 struct snd_soc_dai ssm2602_dai = {
        .name = "SSM2602",
        .playback = {
@@ -503,20 +528,18 @@ struct snd_soc_dai ssm2602_dai = {
                .channels_min = 2,
                .channels_max = 2,
                .rates = SSM2602_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
+               .formats = SSM2602_FORMATS,},
        .capture = {
                .stream_name = "Capture",
                .channels_min = 2,
                .channels_max = 2,
                .rates = SSM2602_RATES,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE,},
+               .formats = SSM2602_FORMATS,},
        .ops = {
                .startup = ssm2602_startup,
                .prepare = ssm2602_pcm_prepare,
                .hw_params = ssm2602_hw_params,
                .shutdown = ssm2602_shutdown,
-       },
-       .dai_ops = {
                .digital_mute = ssm2602_mute,
                .set_sysclk = ssm2602_set_dai_sysclk,
                .set_fmt = ssm2602_set_dai_fmt,
@@ -601,7 +624,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
 
        ssm2602_add_controls(codec);
        ssm2602_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                pr_err("ssm2602: failed to register card\n");
                goto card_err;
@@ -770,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
 
+static int __init ssm2602_modinit(void)
+{
+       return snd_soc_register_dai(&ssm2602_dai);
+}
+module_init(ssm2602_modinit);
+
+static void __exit ssm2602_exit(void)
+{
+       snd_soc_unregister_dai(&ssm2602_dai);
+}
+module_exit(ssm2602_exit);
+
 MODULE_DESCRIPTION("ASoC ssm2602 driver");
 MODULE_AUTHOR("Cliff Cai");
 MODULE_LICENSE("GPL");
index 44308dac9e18de9d268ccea819f5376c1ec24a92..39f5b981d25a3d269311887ec5e113e3f9a578c9 100644 (file)
 
 #define AIC23_VERSION "0.1"
 
-struct tlv320aic23_srate_reg_info {
-       u32 sample_rate;
-       u8 control;             /* SR3, SR2, SR1, SR0 and BOSR */
-       u8 divider;             /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
-};
-
 /*
  * AIC23 register cache
  */
@@ -261,20 +255,156 @@ static const struct snd_soc_dapm_route intercon[] = {
 
 };
 
-/* tlv320aic23 related */
-static const struct tlv320aic23_srate_reg_info srate_reg_info[] = {
-       {4000, 0x06, 1},        /*  4000 */
-       {8000, 0x06, 0},        /*  8000 */
-       {16000, 0x0C, 1},       /* 16000 */
-       {22050, 0x11, 1},       /* 22050 */
-       {24000, 0x00, 1},       /* 24000 */
-       {32000, 0x0C, 0},       /* 32000 */
-       {44100, 0x11, 0},       /* 44100 */
-       {48000, 0x00, 0},       /* 48000 */
-       {88200, 0x1F, 0},       /* 88200 */
-       {96000, 0x0E, 0},       /* 96000 */
+/* AIC23 driver data */
+struct aic23 {
+       struct snd_soc_codec codec;
+       int mclk;
+       int requested_adc;
+       int requested_dac;
+};
+
+/*
+ * Common Crystals used
+ * 11.2896 Mhz /128 = *88.2k  /192 = 58.8k
+ * 12.0000 Mhz /125 = *96k    /136 = 88.235K
+ * 12.2880 Mhz /128 = *96k    /192 = 64k
+ * 16.9344 Mhz /128 = 132.3k /192 = *88.2k
+ * 18.4320 Mhz /128 = 144k   /192 = *96k
+ */
+
+/*
+ * Normal BOSR 0-256/2 = 128, 1-384/2 = 192
+ * USB BOSR 0-250/2 = 125, 1-272/2 = 136
+ */
+static const int bosr_usb_divisor_table[] = {
+       128, 125, 192, 136
+};
+#define LOWER_GROUP ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7))
+#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11)        | (1<<15))
+static const unsigned short sr_valid_mask[] = {
+       LOWER_GROUP|UPPER_GROUP,        /* Normal, bosr - 0*/
+       LOWER_GROUP|UPPER_GROUP,        /* Normal, bosr - 1*/
+       LOWER_GROUP,                    /* Usb, bosr - 0*/
+       UPPER_GROUP,                    /* Usb, bosr - 1*/
+};
+/*
+ * Every divisor is a factor of 11*12
+ */
+#define SR_MULT (11*12)
+#define A(x) (x) ? (SR_MULT/x) : 0
+static const unsigned char sr_adc_mult_table[] = {
+       A(2), A(2), A(12), A(12),  A(0), A(0), A(3), A(1),
+       A(2), A(2), A(11), A(11),  A(0), A(0), A(0), A(1)
+};
+static const unsigned char sr_dac_mult_table[] = {
+       A(2), A(12), A(2), A(12),  A(0), A(0), A(3), A(1),
+       A(2), A(11), A(2), A(11),  A(0), A(0), A(0), A(1)
 };
 
+static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
+               int dac, int dac_l, int dac_h, int need_dac)
+{
+       if ((adc >= adc_l) && (adc <= adc_h) &&
+                       (dac >= dac_l) && (dac <= dac_h)) {
+               int diff_adc = need_adc - adc;
+               int diff_dac = need_dac - dac;
+               return abs(diff_adc) + abs(diff_dac);
+       }
+       return UINT_MAX;
+}
+
+static int find_rate(int mclk, u32 need_adc, u32 need_dac)
+{
+       int i, j;
+       int best_i = -1;
+       int best_j = -1;
+       int best_div = 0;
+       unsigned best_score = UINT_MAX;
+       int adc_l, adc_h, dac_l, dac_h;
+
+       need_adc *= SR_MULT;
+       need_dac *= SR_MULT;
+       /*
+        * rates given are +/- 1/32
+        */
+       adc_l = need_adc - (need_adc >> 5);
+       adc_h = need_adc + (need_adc >> 5);
+       dac_l = need_dac - (need_dac >> 5);
+       dac_h = need_dac + (need_dac >> 5);
+       for (i = 0; i < ARRAY_SIZE(bosr_usb_divisor_table); i++) {
+               int base = mclk / bosr_usb_divisor_table[i];
+               int mask = sr_valid_mask[i];
+               for (j = 0; j < ARRAY_SIZE(sr_adc_mult_table);
+                               j++, mask >>= 1) {
+                       int adc;
+                       int dac;
+                       int score;
+                       if ((mask & 1) == 0)
+                               continue;
+                       adc = base * sr_adc_mult_table[j];
+                       dac = base * sr_dac_mult_table[j];
+                       score = get_score(adc, adc_l, adc_h, need_adc,
+                                       dac, dac_l, dac_h, need_dac);
+                       if (best_score > score) {
+                               best_score = score;
+                               best_i = i;
+                               best_j = j;
+                               best_div = 0;
+                       }
+                       score = get_score((adc >> 1), adc_l, adc_h, need_adc,
+                                       (dac >> 1), dac_l, dac_h, need_dac);
+                       /* prefer to have a /2 */
+                       if ((score != UINT_MAX) && (best_score >= score)) {
+                               best_score = score;
+                               best_i = i;
+                               best_j = j;
+                               best_div = 1;
+                       }
+               }
+       }
+       return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT);
+}
+
+#ifdef DEBUG
+static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
+               u32 *sample_rate_adc, u32 *sample_rate_dac)
+{
+       int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE);
+       int sr = (src >> 2) & 0x0f;
+       int val = (mclk / bosr_usb_divisor_table[src & 3]);
+       int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
+       int dac = (val * sr_dac_mult_table[sr]) / SR_MULT;
+       if (src & TLV320AIC23_CLKIN_HALF) {
+               adc >>= 1;
+               dac >>= 1;
+       }
+       *sample_rate_adc = adc;
+       *sample_rate_dac = dac;
+}
+#endif
+
+static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
+               u32 sample_rate_adc, u32 sample_rate_dac)
+{
+       /* Search for the right sample rate */
+       int data = find_rate(mclk, sample_rate_adc, sample_rate_dac);
+       if (data < 0) {
+               printk(KERN_ERR "%s:Invalid rate %u,%u requested\n",
+                               __func__, sample_rate_adc, sample_rate_dac);
+               return -EINVAL;
+       }
+       tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
+#ifdef DEBUG
+       {
+               u32 adc, dac;
+               get_current_sample_rates(codec, mclk, &adc, &dac);
+               printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
+                       adc, dac, data);
+       }
+#endif
+       return 0;
+}
+
 static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
 {
        snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -288,32 +418,36 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
 }
 
 static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       u16 iface_reg, data;
-       u8 count = 0;
+       u16 iface_reg;
+       int ret;
+       struct aic23 *aic23 = container_of(codec, struct aic23, codec);
+       u32 sample_rate_adc = aic23->requested_adc;
+       u32 sample_rate_dac = aic23->requested_dac;
+       u32 sample_rate = params_rate(params);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               aic23->requested_dac = sample_rate_dac = sample_rate;
+               if (!sample_rate_adc)
+                       sample_rate_adc = sample_rate;
+       } else {
+               aic23->requested_adc = sample_rate_adc = sample_rate;
+               if (!sample_rate_dac)
+                       sample_rate_dac = sample_rate;
+       }
+       ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
+                       sample_rate_dac);
+       if (ret < 0)
+               return ret;
 
        iface_reg =
            tlv320aic23_read_reg_cache(codec,
                                       TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
-
-       /* Search for the right sample rate */
-       /* Verify what happens if the rate is not supported
-        * now it goes to 96Khz */
-       while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
-              (count < ARRAY_SIZE(srate_reg_info))) {
-               count++;
-       }
-
-       data =  (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
-               (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
-               TLV320AIC23_USB_CLK_ON;
-
-       tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
-
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
                break;
@@ -332,7 +466,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
+static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
+                                  struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -344,17 +479,23 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static void tlv320aic23_shutdown(struct snd_pcm_substream *substream)
+static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
+       struct aic23 *aic23 = container_of(codec, struct aic23, codec);
 
        /* deactivate */
        if (!codec->active) {
                udelay(50);
                tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
        }
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               aic23->requested_dac = 0;
+       else
+               aic23->requested_adc = 0;
 }
 
 static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
@@ -422,12 +563,9 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
                                      int clk_id, unsigned int freq, int dir)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
-
-       switch (freq) {
-       case 12000000:
-               return 0;
-       }
-       return -EINVAL;
+       struct aic23 *aic23 = container_of(codec, struct aic23, codec);
+       aic23->mclk = freq;
+       return 0;
 }
 
 static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
@@ -478,12 +616,10 @@ struct snd_soc_dai tlv320aic23_dai = {
                .prepare = tlv320aic23_pcm_prepare,
                .hw_params = tlv320aic23_hw_params,
                .shutdown = tlv320aic23_shutdown,
-               },
-       .dai_ops = {
-                   .digital_mute = tlv320aic23_mute,
-                   .set_fmt = tlv320aic23_set_dai_fmt,
-                   .set_sysclk = tlv320aic23_set_dai_sysclk,
-                   }
+               .digital_mute = tlv320aic23_mute,
+               .set_fmt = tlv320aic23_set_dai_fmt,
+               .set_sysclk = tlv320aic23_set_dai_sysclk,
+       }
 };
 EXPORT_SYMBOL_GPL(tlv320aic23_dai);
 
@@ -584,7 +720,7 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
 
        tlv320aic23_add_controls(codec);
        tlv320aic23_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "tlv320aic23: failed to register card\n");
                goto card_err;
@@ -659,14 +795,15 @@ static int tlv320aic23_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec;
+       struct aic23 *aic23;
        int ret = 0;
 
        printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
 
-       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-       if (codec == NULL)
+       aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
+       if (aic23 == NULL)
                return -ENOMEM;
-
+       codec = &aic23->codec;
        socdev->codec = codec;
        mutex_init(&codec->mutex);
        INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -687,6 +824,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
        struct snd_soc_codec *codec = socdev->codec;
+       struct aic23 *aic23 = container_of(codec, struct aic23, codec);
 
        if (codec->control_data)
                tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -697,7 +835,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
        i2c_del_driver(&tlv320aic23_i2c_driver);
 #endif
        kfree(codec->reg_cache);
-       kfree(codec);
+       kfree(aic23);
 
        return 0;
 }
@@ -709,6 +847,18 @@ struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
 
+static int __init tlv320aic23_modinit(void)
+{
+       return snd_soc_register_dai(&tlv320aic23_dai);
+}
+module_init(tlv320aic23_modinit);
+
+static void __exit tlv320aic23_exit(void)
+{
+       snd_soc_unregister_dai(&tlv320aic23_dai);
+}
+module_exit(tlv320aic23_exit);
+
 MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
 MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
 MODULE_LICENSE("GPL");
index bed8a9e63ddc86fd0a8c2d9274b812867149fcb4..29f2f1a017fde8744816005584ca9b676d6fdfa5 100644 (file)
@@ -125,7 +125,8 @@ static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
  * Digital Audio Interface Operations
  */
 static int aic26_hw_params(struct snd_pcm_substream *substream,
-                          struct snd_pcm_hw_params *params)
+                          struct snd_pcm_hw_params *params,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -287,8 +288,6 @@ struct snd_soc_dai aic26_dai = {
        },
        .ops = {
                .hw_params = aic26_hw_params,
-       },
-       .dai_ops = {
                .digital_mute = aic26_mute,
                .set_sysclk = aic26_set_sysclk,
                .set_fmt = aic26_set_fmt,
@@ -360,7 +359,7 @@ static int aic26_probe(struct platform_device *pdev)
 
        /* CODEC is setup, we can register the card now */
        dev_dbg(&pdev->dev, "Registering card\n");
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                dev_err(&pdev->dev, "aic26: failed to register card\n");
                goto card_err;
@@ -427,7 +426,7 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
 static int aic26_spi_probe(struct spi_device *spi)
 {
        struct aic26 *aic26;
-       int rc, i, reg;
+       int ret, i, reg;
 
        dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
 
@@ -457,6 +456,14 @@ static int aic26_spi_probe(struct spi_device *spi)
        aic26->codec.reg_cache_size = AIC26_NUM_REGS;
        aic26->codec.reg_cache = aic26->reg_cache;
 
+       aic26_dai.dev = &spi->dev;
+       ret = snd_soc_register_dai(&aic26_dai);
+       if (ret != 0) {
+               dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
+               kfree(aic26);
+               return ret;
+       }
+
        /* Reset the codec to power on defaults */
        aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
 
@@ -475,8 +482,8 @@ static int aic26_spi_probe(struct spi_device *spi)
 
        /* Register the sysfs files for debugging */
        /* Create SysFS files */
-       rc = device_create_file(&spi->dev, &dev_attr_keyclick);
-       if (rc)
+       ret = device_create_file(&spi->dev, &dev_attr_keyclick);
+       if (ret)
                dev_info(&spi->dev, "error creating sysfs files\n");
 
 #if defined(CONFIG_SND_SOC_OF_SIMPLE)
@@ -493,6 +500,7 @@ static int aic26_spi_remove(struct spi_device *spi)
 {
        struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
 
+       snd_soc_unregister_dai(&aic26_dai);
        kfree(aic26);
 
        return 0;
index cff276ee261e7a2ecca843b23bc74d4fec761df7..8da9e5d2e2fbbe76ad237f4ef7904795869dc024 100644 (file)
@@ -253,11 +253,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
 
        SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL,
                     DACR1_2_RLOPM_VOL, 0, 0x7f, 1),
-       SOC_DOUBLE_R("Line DAC Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3,
-                    0x01, 0),
-       SOC_DOUBLE_R("Line PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL,
-                    PGAR_2_RLOPM_VOL, 0, 0x7f, 1),
-       SOC_DOUBLE_R("Line Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL,
+       SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0),
+       SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0),
+       SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL,
+                    DACR1_2_LLOPM_VOL, 0, 0x7f, 1),
+       SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL,
+                    0, 0x7f, 1),
+       SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL,
+                    0, 0x7f, 1),
+       SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL,
+                    LINE2R_2_LLOPM_VOL, 0, 0x7f, 1),
+       SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL,
                     LINE2R_2_RLOPM_VOL, 0, 0x7f, 1),
 
        SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL,
@@ -272,8 +278,12 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
                     DACR1_2_HPROUT_VOL, 0, 0x7f, 1),
        SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
                     0x01, 0),
-       SOC_DOUBLE_R("HP PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL,
+       SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL,
                     PGAR_2_HPROUT_VOL, 0, 0x7f, 1),
+       SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL,
+                    0, 0x7f, 1),
+       SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL,
+                    0, 0x7f, 1),
        SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL,
                     LINE2R_2_HPROUT_VOL, 0, 0x7f, 1),
 
@@ -281,8 +291,10 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
                     DACR1_2_HPRCOM_VOL, 0, 0x7f, 1),
        SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
                     0x01, 0),
-       SOC_DOUBLE_R("HPCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL,
-                    PGAR_2_HPRCOM_VOL, 0, 0x7f, 1),
+       SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL,
+                    0, 0x7f, 1),
+       SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL,
+                    0, 0x7f, 1),
        SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL,
                     LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1),
 
@@ -333,7 +345,8 @@ SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
 
 /* Left DAC_L1 Mixer */
 static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
@@ -341,7 +354,8 @@ static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
 
 /* Right DAC_R1 Mixer */
 static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
@@ -350,14 +364,18 @@ static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
 /* Left PGA Mixer */
 static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
        SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
+       SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
        SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
        SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
+       SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
 };
 
 /* Right PGA Mixer */
 static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
        SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
+       SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
        SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
+       SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
        SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
 };
 
@@ -379,34 +397,42 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
 
 /* Left PGA Bypass Mixer */
 static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HP Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HPCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPL Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPR Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPLCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPRCOM Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
 };
 
 /* Right PGA Bypass Mixer */
 static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HP Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HPCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPL Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPR Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPLCOM Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPRCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
 };
 
 /* Left Line2 Bypass Mixer */
 static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HPCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPLCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
 };
 
 /* Right Line2 Bypass Mixer */
 static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = {
-       SOC_DAPM_SINGLE("Line Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineL Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("LineR Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
        SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
-       SOC_DAPM_SINGLE("HPCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
+       SOC_DAPM_SINGLE("HPRCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
 };
 
 static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
@@ -439,22 +465,26 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
        /* Mono Output */
        SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
 
-       /* Left Inputs to Left ADC */
+       /* Inputs to Left ADC */
        SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
        SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
                           &aic3x_left_pga_mixer_controls[0],
                           ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
        SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
                         &aic3x_left_line1_mux_controls),
+       SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
+                        &aic3x_left_line1_mux_controls),
        SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
                         &aic3x_left_line2_mux_controls),
 
-       /* Right Inputs to Right ADC */
+       /* Inputs to Right ADC */
        SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
                         LINE1R_2_RADC_CTRL, 2, 0),
        SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
                           &aic3x_right_pga_mixer_controls[0],
                           ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
+       SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
+                        &aic3x_right_line1_mux_controls),
        SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
                         &aic3x_right_line1_mux_controls),
        SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
@@ -531,7 +561,8 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Left DAC Mux", "DAC_L2", "Left DAC"},
        {"Left DAC Mux", "DAC_L3", "Left DAC"},
 
-       {"Left DAC_L1 Mixer", "Line Switch", "Left DAC Mux"},
+       {"Left DAC_L1 Mixer", "LineL Switch", "Left DAC Mux"},
+       {"Left DAC_L1 Mixer", "LineR Switch", "Left DAC Mux"},
        {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"},
        {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"},
        {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"},
@@ -557,7 +588,8 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Right DAC Mux", "DAC_R2", "Right DAC"},
        {"Right DAC Mux", "DAC_R3", "Right DAC"},
 
-       {"Right DAC_R1 Mixer", "Line Switch", "Right DAC Mux"},
+       {"Right DAC_R1 Mixer", "LineL Switch", "Right DAC Mux"},
+       {"Right DAC_R1 Mixer", "LineR Switch", "Right DAC Mux"},
        {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"},
        {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"},
        {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"},
@@ -592,8 +624,10 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Left Line2L Mux", "differential", "LINE2L"},
 
        {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
+       {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
        {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
        {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
+       {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
 
        {"Left ADC", NULL, "Left PGA Mixer"},
        {"Left ADC", NULL, "GPIO1 dmic modclk"},
@@ -605,18 +639,23 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Right Line2R Mux", "single-ended", "LINE2R"},
        {"Right Line2R Mux", "differential", "LINE2R"},
 
+       {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
        {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
        {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
+       {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
        {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
 
        {"Right ADC", NULL, "Right PGA Mixer"},
        {"Right ADC", NULL, "GPIO1 dmic modclk"},
 
        /* Left PGA Bypass */
-       {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "LineL Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "LineR Switch", "Left PGA Mixer"},
        {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"},
-       {"Left PGA Bypass Mixer", "HP Switch", "Left PGA Mixer"},
-       {"Left PGA Bypass Mixer", "HPCOM Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "HPL Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "HPR Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "HPLCOM Switch", "Left PGA Mixer"},
+       {"Left PGA Bypass Mixer", "HPRCOM Switch", "Left PGA Mixer"},
 
        {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"},
        {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"},
@@ -627,10 +666,13 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Left HP Out", NULL, "Left PGA Bypass Mixer"},
 
        /* Right PGA Bypass */
-       {"Right PGA Bypass Mixer", "Line Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "LineL Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "LineR Switch", "Right PGA Mixer"},
        {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"},
-       {"Right PGA Bypass Mixer", "HP Switch", "Right PGA Mixer"},
-       {"Right PGA Bypass Mixer", "HPCOM Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "HPL Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "HPR Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "HPLCOM Switch", "Right PGA Mixer"},
+       {"Right PGA Bypass Mixer", "HPRCOM Switch", "Right PGA Mixer"},
 
        {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"},
        {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"},
@@ -643,10 +685,11 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Right HP Out", NULL, "Right PGA Bypass Mixer"},
 
        /* Left Line2 Bypass */
-       {"Left Line2 Bypass Mixer", "Line Switch", "Left Line2L Mux"},
+       {"Left Line2 Bypass Mixer", "LineL Switch", "Left Line2L Mux"},
+       {"Left Line2 Bypass Mixer", "LineR Switch", "Left Line2L Mux"},
        {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"},
        {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"},
-       {"Left Line2 Bypass Mixer", "HPCOM Switch", "Left Line2L Mux"},
+       {"Left Line2 Bypass Mixer", "HPLCOM Switch", "Left Line2L Mux"},
 
        {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"},
        {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"},
@@ -657,10 +700,11 @@ static const struct snd_soc_dapm_route intercon[] = {
        {"Left HP Out", NULL, "Left Line2 Bypass Mixer"},
 
        /* Right Line2 Bypass */
-       {"Right Line2 Bypass Mixer", "Line Switch", "Right Line2R Mux"},
+       {"Right Line2 Bypass Mixer", "LineL Switch", "Right Line2R Mux"},
+       {"Right Line2 Bypass Mixer", "LineR Switch", "Right Line2R Mux"},
        {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"},
        {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"},
-       {"Right Line2 Bypass Mixer", "HPCOM Switch", "Right Line2R Mux"},
+       {"Right Line2 Bypass Mixer", "HPRCOM Switch", "Right Line2R Mux"},
 
        {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"},
        {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"},
@@ -694,7 +738,8 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
 }
 
 static int aic3x_hw_params(struct snd_pcm_substream *substream,
-                          struct snd_pcm_hw_params *params)
+                          struct snd_pcm_hw_params *params,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -981,14 +1026,41 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
 }
 EXPORT_SYMBOL_GPL(aic3x_get_gpio);
 
+void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
+                                int headset_debounce, int button_debounce)
+{
+       u8 val;
+
+       val = ((detect & AIC3X_HEADSET_DETECT_MASK)
+               << AIC3X_HEADSET_DETECT_SHIFT) |
+             ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
+               << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
+             ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
+               << AIC3X_BUTTON_DEBOUNCE_SHIFT);
+
+       if (detect & AIC3X_HEADSET_DETECT_MASK)
+               val |= AIC3X_HEADSET_DETECT_ENABLED;
+
+       aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
+}
+EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
+
 int aic3x_headset_detected(struct snd_soc_codec *codec)
 {
        u8 val;
-       aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val);
-       return (val >> 2) & 1;
+       aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
+       return (val >> 4) & 1;
 }
 EXPORT_SYMBOL_GPL(aic3x_headset_detected);
 
+int aic3x_button_pressed(struct snd_soc_codec *codec)
+{
+       u8 val;
+       aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
+       return (val >> 5) & 1;
+}
+EXPORT_SYMBOL_GPL(aic3x_button_pressed);
+
 #define AIC3X_RATES    SNDRV_PCM_RATE_8000_96000
 #define AIC3X_FORMATS  (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
                         SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -1009,8 +1081,6 @@ struct snd_soc_dai aic3x_dai = {
                .formats = AIC3X_FORMATS,},
        .ops = {
                .hw_params = aic3x_hw_params,
-       },
-       .dai_ops = {
                .digital_mute = aic3x_mute,
                .set_sysclk = aic3x_set_dai_sysclk,
                .set_fmt = aic3x_set_dai_fmt,
@@ -1152,7 +1222,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
 
        aic3x_add_controls(codec);
        aic3x_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "aic3x: failed to register card\n");
                goto card_err;
@@ -1341,6 +1411,18 @@ struct snd_soc_codec_device soc_codec_dev_aic3x = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
 
+static int __init aic3x_modinit(void)
+{
+       return snd_soc_register_dai(&aic3x_dai);
+}
+module_init(aic3x_modinit);
+
+static void __exit aic3x_exit(void)
+{
+       snd_soc_unregister_dai(&aic3x_dai);
+}
+module_exit(aic3x_exit);
+
 MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_LICENSE("GPL");
index 00a195aa02e4e2321d9437f964688f532cf0fde8..73e35b6ec9291ac9a302dab1412bc148af181a6c 100644 (file)
@@ -39,7 +39,9 @@
 #define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
 /* Audio codec digital filter control register */
 #define AIC3X_CODEC_DFILT_CTRL         12
-
+/* Headset/button press detection register */
+#define AIC3X_HEADSET_DETECT_CTRL_A    13
+#define AIC3X_HEADSET_DETECT_CTRL_B    14
 /* ADC PGA Gain control registers */
 #define LADC_VOL                       15
 #define RADC_VOL                       16
@@ -48,7 +50,9 @@
 #define MIC3LR_2_RADC_CTRL             18
 /* Line1 Input control registers */
 #define LINE1L_2_LADC_CTRL             19
+#define LINE1R_2_LADC_CTRL             21
 #define LINE1R_2_RADC_CTRL             22
+#define LINE1L_2_RADC_CTRL             24
 /* Line2 Input control registers */
 #define LINE2L_2_LADC_CTRL             20
 #define LINE2R_2_RADC_CTRL             23
@@ -79,6 +83,8 @@
 #define LINE2L_2_HPLOUT_VOL            45
 #define LINE2R_2_HPROUT_VOL            62
 #define PGAL_2_HPLOUT_VOL              46
+#define PGAL_2_HPROUT_VOL              60
+#define PGAR_2_HPLOUT_VOL              49
 #define PGAR_2_HPROUT_VOL              63
 #define DACL1_2_HPLOUT_VOL             47
 #define DACR1_2_HPROUT_VOL             64
@@ -88,6 +94,8 @@
 #define LINE2L_2_HPLCOM_VOL            52
 #define LINE2R_2_HPRCOM_VOL            69
 #define PGAL_2_HPLCOM_VOL              53
+#define PGAR_2_HPLCOM_VOL              56
+#define PGAL_2_HPRCOM_VOL              67
 #define PGAR_2_HPRCOM_VOL              70
 #define DACL1_2_HPLCOM_VOL             54
 #define DACR1_2_HPRCOM_VOL             71
 #define MONOLOPM_CTRL                  79
 /* Line Output Plus/Minus control registers */
 #define LINE2L_2_LLOPM_VOL             80
+#define LINE2L_2_RLOPM_VOL             87
+#define LINE2R_2_LLOPM_VOL             83
 #define LINE2R_2_RLOPM_VOL             90
 #define PGAL_2_LLOPM_VOL               81
+#define PGAL_2_RLOPM_VOL               88
+#define PGAR_2_LLOPM_VOL               84
 #define PGAR_2_RLOPM_VOL               91
 #define DACL1_2_LLOPM_VOL              82
+#define DACL1_2_RLOPM_VOL              89
 #define DACR1_2_RLOPM_VOL              92
+#define DACR1_2_LLOPM_VOL              85
 #define LLOPM_CTRL                     86
 #define RLOPM_CTRL                     93
 /* GPIO/IRQ registers */
@@ -221,7 +235,49 @@ enum {
 
 void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
 int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
+
+/* headset detection / button API */
+
+/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
+ * and cellular headsets (GND + speaker output + microphone input).
+ * It is recommended to enable MIC bias for this function to work properly.
+ * For more information, please refer to the datasheet. */
+enum {
+       AIC3X_HEADSET_DETECT_OFF        = 0,
+       AIC3X_HEADSET_DETECT_STEREO     = 1,
+       AIC3X_HEADSET_DETECT_CELLULAR   = 2,
+       AIC3X_HEADSET_DETECT_BOTH       = 3
+};
+
+enum {
+       AIC3X_HEADSET_DEBOUNCE_16MS     = 0,
+       AIC3X_HEADSET_DEBOUNCE_32MS     = 1,
+       AIC3X_HEADSET_DEBOUNCE_64MS     = 2,
+       AIC3X_HEADSET_DEBOUNCE_128MS    = 3,
+       AIC3X_HEADSET_DEBOUNCE_256MS    = 4,
+       AIC3X_HEADSET_DEBOUNCE_512MS    = 5
+};
+
+enum {
+       AIC3X_BUTTON_DEBOUNCE_0MS       = 0,
+       AIC3X_BUTTON_DEBOUNCE_8MS       = 1,
+       AIC3X_BUTTON_DEBOUNCE_16MS      = 2,
+       AIC3X_BUTTON_DEBOUNCE_32MS      = 3
+};
+
+#define AIC3X_HEADSET_DETECT_ENABLED   0x80
+#define AIC3X_HEADSET_DETECT_SHIFT     5
+#define AIC3X_HEADSET_DETECT_MASK      3
+#define AIC3X_HEADSET_DEBOUNCE_SHIFT   2
+#define AIC3X_HEADSET_DEBOUNCE_MASK    7
+#define AIC3X_BUTTON_DEBOUNCE_SHIFT    0
+#define AIC3X_BUTTON_DEBOUNCE_MASK     3
+
+/* see the enums above for valid parameters to this function */
+void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
+                                int headset_debounce, int button_debounce);
 int aic3x_headset_detected(struct snd_soc_codec *codec);
+int aic3x_button_pressed(struct snd_soc_codec *codec);
 
 struct aic3x_setup_data {
        int i2c_bus;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
new file mode 100644 (file)
index 0000000..5184888
--- /dev/null
@@ -0,0 +1,1317 @@
+/*
+ * ALSA SoC TWL4030 codec driver
+ *
+ * Author:      Steve Sakoman, <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/i2c/twl4030.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "twl4030.h"
+
+/*
+ * twl4030 register cache & default register settings
+ */
+static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
+       0x00, /* this register not used         */
+       0x93, /* REG_CODEC_MODE         (0x1)   */
+       0xc3, /* REG_OPTION             (0x2)   */
+       0x00, /* REG_UNKNOWN            (0x3)   */
+       0x00, /* REG_MICBIAS_CTL        (0x4)   */
+       0x20, /* REG_ANAMICL            (0x5)   */
+       0x00, /* REG_ANAMICR            (0x6)   */
+       0x00, /* REG_AVADC_CTL          (0x7)   */
+       0x00, /* REG_ADCMICSEL          (0x8)   */
+       0x00, /* REG_DIGMIXING          (0x9)   */
+       0x0c, /* REG_ATXL1PGA           (0xA)   */
+       0x0c, /* REG_ATXR1PGA           (0xB)   */
+       0x00, /* REG_AVTXL2PGA          (0xC)   */
+       0x00, /* REG_AVTXR2PGA          (0xD)   */
+       0x01, /* REG_AUDIO_IF           (0xE)   */
+       0x00, /* REG_VOICE_IF           (0xF)   */
+       0x00, /* REG_ARXR1PGA           (0x10)  */
+       0x00, /* REG_ARXL1PGA           (0x11)  */
+       0x6c, /* REG_ARXR2PGA           (0x12)  */
+       0x6c, /* REG_ARXL2PGA           (0x13)  */
+       0x00, /* REG_VRXPGA             (0x14)  */
+       0x00, /* REG_VSTPGA             (0x15)  */
+       0x00, /* REG_VRX2ARXPGA         (0x16)  */
+       0x0c, /* REG_AVDAC_CTL          (0x17)  */
+       0x00, /* REG_ARX2VTXPGA         (0x18)  */
+       0x00, /* REG_ARXL1_APGA_CTL     (0x19)  */
+       0x00, /* REG_ARXR1_APGA_CTL     (0x1A)  */
+       0x4b, /* REG_ARXL2_APGA_CTL     (0x1B)  */
+       0x4b, /* REG_ARXR2_APGA_CTL     (0x1C)  */
+       0x00, /* REG_ATX2ARXPGA         (0x1D)  */
+       0x00, /* REG_BT_IF              (0x1E)  */
+       0x00, /* REG_BTPGA              (0x1F)  */
+       0x00, /* REG_BTSTPGA            (0x20)  */
+       0x00, /* REG_EAR_CTL            (0x21)  */
+       0x24, /* REG_HS_SEL             (0x22)  */
+       0x0a, /* REG_HS_GAIN_SET        (0x23)  */
+       0x00, /* REG_HS_POPN_SET        (0x24)  */
+       0x00, /* REG_PREDL_CTL          (0x25)  */
+       0x00, /* REG_PREDR_CTL          (0x26)  */
+       0x00, /* REG_PRECKL_CTL         (0x27)  */
+       0x00, /* REG_PRECKR_CTL         (0x28)  */
+       0x00, /* REG_HFL_CTL            (0x29)  */
+       0x00, /* REG_HFR_CTL            (0x2A)  */
+       0x00, /* REG_ALC_CTL            (0x2B)  */
+       0x00, /* REG_ALC_SET1           (0x2C)  */
+       0x00, /* REG_ALC_SET2           (0x2D)  */
+       0x00, /* REG_BOOST_CTL          (0x2E)  */
+       0x00, /* REG_SOFTVOL_CTL        (0x2F)  */
+       0x00, /* REG_DTMF_FREQSEL       (0x30)  */
+       0x00, /* REG_DTMF_TONEXT1H      (0x31)  */
+       0x00, /* REG_DTMF_TONEXT1L      (0x32)  */
+       0x00, /* REG_DTMF_TONEXT2H      (0x33)  */
+       0x00, /* REG_DTMF_TONEXT2L      (0x34)  */
+       0x00, /* REG_DTMF_TONOFF        (0x35)  */
+       0x00, /* REG_DTMF_WANONOFF      (0x36)  */
+       0x00, /* REG_I2S_RX_SCRAMBLE_H  (0x37)  */
+       0x00, /* REG_I2S_RX_SCRAMBLE_M  (0x38)  */
+       0x00, /* REG_I2S_RX_SCRAMBLE_L  (0x39)  */
+       0x16, /* REG_APLL_CTL           (0x3A)  */
+       0x00, /* REG_DTMF_CTL           (0x3B)  */
+       0x00, /* REG_DTMF_PGA_CTL2      (0x3C)  */
+       0x00, /* REG_DTMF_PGA_CTL1      (0x3D)  */
+       0x00, /* REG_MISC_SET_1         (0x3E)  */
+       0x00, /* REG_PCMBTMUX           (0x3F)  */
+       0x00, /* not used               (0x40)  */
+       0x00, /* not used               (0x41)  */
+       0x00, /* not used               (0x42)  */
+       0x00, /* REG_RX_PATH_SEL        (0x43)  */
+       0x00, /* REG_VDL_APGA_CTL       (0x44)  */
+       0x00, /* REG_VIBRA_CTL          (0x45)  */
+       0x00, /* REG_VIBRA_SET          (0x46)  */
+       0x00, /* REG_VIBRA_PWM_SET      (0x47)  */
+       0x00, /* REG_ANAMIC_GAIN        (0x48)  */
+       0x00, /* REG_MISC_SET_2         (0x49)  */
+};
+
+/*
+ * read twl4030 register cache
+ */
+static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
+       unsigned int reg)
+{
+       u8 *cache = codec->reg_cache;
+
+       return cache[reg];
+}
+
+/*
+ * write twl4030 register cache
+ */
+static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
+                                               u8 reg, u8 value)
+{
+       u8 *cache = codec->reg_cache;
+
+       if (reg >= TWL4030_CACHEREGNUM)
+               return;
+       cache[reg] = value;
+}
+
+/*
+ * write to the twl4030 register space
+ */
+static int twl4030_write(struct snd_soc_codec *codec,
+                       unsigned int reg, unsigned int value)
+{
+       twl4030_write_reg_cache(codec, reg, value);
+       return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
+}
+
+static void twl4030_clear_codecpdz(struct snd_soc_codec *codec)
+{
+       u8 mode;
+
+       mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
+       twl4030_write(codec, TWL4030_REG_CODEC_MODE,
+               mode & ~TWL4030_CODECPDZ);
+
+       /* REVISIT: this delay is present in TI sample drivers */
+       /* but there seems to be no TRM requirement for it     */
+       udelay(10);
+}
+
+static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
+{
+       u8 mode;
+
+       mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
+       twl4030_write(codec, TWL4030_REG_CODEC_MODE,
+               mode | TWL4030_CODECPDZ);
+
+       /* REVISIT: this delay is present in TI sample drivers */
+       /* but there seems to be no TRM requirement for it     */
+       udelay(10);
+}
+
+static void twl4030_init_chip(struct snd_soc_codec *codec)
+{
+       int i;
+
+       /* clear CODECPDZ prior to setting register defaults */
+       twl4030_clear_codecpdz(codec);
+
+       /* set all audio section registers to reasonable defaults */
+       for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
+               twl4030_write(codec, i, twl4030_reg[i]);
+
+}
+
+/* Earpiece */
+static const char *twl4030_earpiece_texts[] =
+               {"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
+
+static const struct soc_enum twl4030_earpiece_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
+                       ARRAY_SIZE(twl4030_earpiece_texts),
+                       twl4030_earpiece_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
+SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
+
+/* PreDrive Left */
+static const char *twl4030_predrivel_texts[] =
+               {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
+
+static const struct soc_enum twl4030_predrivel_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
+                       ARRAY_SIZE(twl4030_predrivel_texts),
+                       twl4030_predrivel_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
+SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
+
+/* PreDrive Right */
+static const char *twl4030_predriver_texts[] =
+               {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
+
+static const struct soc_enum twl4030_predriver_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
+                       ARRAY_SIZE(twl4030_predriver_texts),
+                       twl4030_predriver_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
+SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
+
+/* Headset Left */
+static const char *twl4030_hsol_texts[] =
+               {"Off", "DACL1", "DACL2"};
+
+static const struct soc_enum twl4030_hsol_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
+                       ARRAY_SIZE(twl4030_hsol_texts),
+                       twl4030_hsol_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
+SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
+
+/* Headset Right */
+static const char *twl4030_hsor_texts[] =
+               {"Off", "DACR1", "DACR2"};
+
+static const struct soc_enum twl4030_hsor_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
+                       ARRAY_SIZE(twl4030_hsor_texts),
+                       twl4030_hsor_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
+SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
+
+/* Carkit Left */
+static const char *twl4030_carkitl_texts[] =
+               {"Off", "DACL1", "DACL2"};
+
+static const struct soc_enum twl4030_carkitl_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
+                       ARRAY_SIZE(twl4030_carkitl_texts),
+                       twl4030_carkitl_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
+SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
+
+/* Carkit Right */
+static const char *twl4030_carkitr_texts[] =
+               {"Off", "DACR1", "DACR2"};
+
+static const struct soc_enum twl4030_carkitr_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
+                       ARRAY_SIZE(twl4030_carkitr_texts),
+                       twl4030_carkitr_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
+SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
+
+/* Handsfree Left */
+static const char *twl4030_handsfreel_texts[] =
+               {"Voice", "DACL1", "DACL2", "DACR2"};
+
+static const struct soc_enum twl4030_handsfreel_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
+                       ARRAY_SIZE(twl4030_handsfreel_texts),
+                       twl4030_handsfreel_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
+SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
+
+/* Handsfree Right */
+static const char *twl4030_handsfreer_texts[] =
+               {"Voice", "DACR1", "DACR2", "DACL2"};
+
+static const struct soc_enum twl4030_handsfreer_enum =
+       SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
+                       ARRAY_SIZE(twl4030_handsfreer_texts),
+                       twl4030_handsfreer_texts);
+
+static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
+SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
+
+static int outmixer_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *kcontrol, int event)
+{
+       struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+       int ret = 0;
+       int val;
+
+       switch (e->reg) {
+       case TWL4030_REG_PREDL_CTL:
+       case TWL4030_REG_PREDR_CTL:
+       case TWL4030_REG_EAR_CTL:
+               val = w->value >> e->shift_l;
+               if (val == 3) {
+                       printk(KERN_WARNING
+                       "Invalid MUX setting for register 0x%02x (%d)\n",
+                             e->reg, val);
+                       ret = -1;
+               }
+               break;
+       }
+
+       return ret;
+}
+
+static int handsfree_event(struct snd_soc_dapm_widget *w,
+               struct snd_kcontrol *kcontrol, int event)
+{
+       struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
+       unsigned char hs_ctl;
+
+       hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
+
+       if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
+               hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
+               twl4030_write(w->codec, e->reg, hs_ctl);
+               hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
+               twl4030_write(w->codec, e->reg, hs_ctl);
+               hs_ctl |= TWL4030_HF_CTL_HB_EN;
+               twl4030_write(w->codec, e->reg, hs_ctl);
+       } else {
+               hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
+                               | TWL4030_HF_CTL_HB_EN);
+               twl4030_write(w->codec, e->reg, hs_ctl);
+       }
+
+       return 0;
+}
+
+/*
+ * Some of the gain controls in TWL (mostly those which are associated with
+ * the outputs) are implemented in an interesting way:
+ * 0x0 : Power down (mute)
+ * 0x1 : 6dB
+ * 0x2 : 0 dB
+ * 0x3 : -6 dB
+ * Inverting not going to help with these.
+ * Custom volsw and volsw_2r get/put functions to handle these gain bits.
+ */
+#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
+                              xinvert, tlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+                SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw, \
+       .get = snd_soc_get_volsw_twl4030, \
+       .put = snd_soc_put_volsw_twl4030, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) \
+               {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
+                .max = xmax, .invert = xinvert} }
+#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
+                                xinvert, tlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
+                SNDRV_CTL_ELEM_ACCESS_READWRITE,\
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw_2r, \
+       .get = snd_soc_get_volsw_r2_twl4030,\
+       .put = snd_soc_put_volsw_r2_twl4030, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) \
+               {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+                .rshift = xshift, .max = xmax, .invert = xinvert} }
+#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
+       SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
+                              xinvert, tlv_array)
+
+static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = mc->reg;
+       unsigned int shift = mc->shift;
+       unsigned int rshift = mc->rshift;
+       int max = mc->max;
+       int mask = (1 << fls(max)) - 1;
+
+       ucontrol->value.integer.value[0] =
+               (snd_soc_read(codec, reg) >> shift) & mask;
+       if (ucontrol->value.integer.value[0])
+               ucontrol->value.integer.value[0] =
+                       max + 1 - ucontrol->value.integer.value[0];
+
+       if (shift != rshift) {
+               ucontrol->value.integer.value[1] =
+                       (snd_soc_read(codec, reg) >> rshift) & mask;
+               if (ucontrol->value.integer.value[1])
+                       ucontrol->value.integer.value[1] =
+                               max + 1 - ucontrol->value.integer.value[1];
+       }
+
+       return 0;
+}
+
+static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = mc->reg;
+       unsigned int shift = mc->shift;
+       unsigned int rshift = mc->rshift;
+       int max = mc->max;
+       int mask = (1 << fls(max)) - 1;
+       unsigned short val, val2, val_mask;
+
+       val = (ucontrol->value.integer.value[0] & mask);
+
+       val_mask = mask << shift;
+       if (val)
+               val = max + 1 - val;
+       val = val << shift;
+       if (shift != rshift) {
+               val2 = (ucontrol->value.integer.value[1] & mask);
+               val_mask |= mask << rshift;
+               if (val2)
+                       val2 = max + 1 - val2;
+               val |= val2 << rshift;
+       }
+       return snd_soc_update_bits(codec, reg, val_mask, val);
+}
+
+static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = mc->reg;
+       unsigned int reg2 = mc->rreg;
+       unsigned int shift = mc->shift;
+       int max = mc->max;
+       int mask = (1<<fls(max))-1;
+
+       ucontrol->value.integer.value[0] =
+               (snd_soc_read(codec, reg) >> shift) & mask;
+       ucontrol->value.integer.value[1] =
+               (snd_soc_read(codec, reg2) >> shift) & mask;
+
+       if (ucontrol->value.integer.value[0])
+               ucontrol->value.integer.value[0] =
+                       max + 1 - ucontrol->value.integer.value[0];
+       if (ucontrol->value.integer.value[1])
+               ucontrol->value.integer.value[1] =
+                       max + 1 - ucontrol->value.integer.value[1];
+
+       return 0;
+}
+
+static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       unsigned int reg = mc->reg;
+       unsigned int reg2 = mc->rreg;
+       unsigned int shift = mc->shift;
+       int max = mc->max;
+       int mask = (1 << fls(max)) - 1;
+       int err;
+       unsigned short val, val2, val_mask;
+
+       val_mask = mask << shift;
+       val = (ucontrol->value.integer.value[0] & mask);
+       val2 = (ucontrol->value.integer.value[1] & mask);
+
+       if (val)
+               val = max + 1 - val;
+       if (val2)
+               val2 = max + 1 - val2;
+
+       val = val << shift;
+       val2 = val2 << shift;
+
+       err = snd_soc_update_bits(codec, reg, val_mask, val);
+       if (err < 0)
+               return err;
+
+       err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+       return err;
+}
+
+static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = kcontrol->private_data;
+       u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
+       int result = 0;
+
+       /* one bit must be set a time */
+       reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
+                       | TWL4030_MAINMIC_EN;
+       if (reg != 0) {
+               result++;
+               while ((reg & 1) == 0) {
+                       result++;
+                       reg >>= 1;
+               }
+       }
+
+       ucontrol->value.integer.value[0] = result;
+       return 0;
+}
+
+static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = kcontrol->private_data;
+       int value = ucontrol->value.integer.value[0];
+       u8 anamicl, micbias, avadc_ctl;
+
+       anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
+       anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
+                       | TWL4030_MAINMIC_EN);
+       micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
+       micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
+       avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
+
+       switch (value) {
+       case 1:
+               anamicl |= TWL4030_MAINMIC_EN;
+               micbias |= TWL4030_MICBIAS1_EN;
+               break;
+       case 2:
+               anamicl |= TWL4030_HSMIC_EN;
+               micbias |= TWL4030_HSMICBIAS_EN;
+               break;
+       case 3:
+               anamicl |= TWL4030_AUXL_EN;
+               break;
+       case 4:
+               anamicl |= TWL4030_CKMIC_EN;
+               break;
+       default:
+               break;
+       }
+
+       /* If some input is selected, enable amp and ADC */
+       if (value != 0) {
+               anamicl |= TWL4030_MICAMPL_EN;
+               avadc_ctl |= TWL4030_ADCL_EN;
+       } else {
+               anamicl &= ~TWL4030_MICAMPL_EN;
+               avadc_ctl &= ~TWL4030_ADCL_EN;
+       }
+
+       twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
+       twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
+       twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
+
+       return 1;
+}
+
+static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = kcontrol->private_data;
+       u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
+       int value = 0;
+
+       reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
+       switch (reg) {
+       case TWL4030_SUBMIC_EN:
+               value = 1;
+               break;
+       case TWL4030_AUXR_EN:
+               value = 2;
+               break;
+       default:
+               break;
+       }
+
+       ucontrol->value.integer.value[0] = value;
+       return 0;
+}
+
+static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = kcontrol->private_data;
+       int value = ucontrol->value.integer.value[0];
+       u8 anamicr, micbias, avadc_ctl;
+
+       anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
+       anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
+       micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
+       micbias &= ~TWL4030_MICBIAS2_EN;
+       avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
+
+       switch (value) {
+       case 1:
+               anamicr |= TWL4030_SUBMIC_EN;
+               micbias |= TWL4030_MICBIAS2_EN;
+               break;
+       case 2:
+               anamicr |= TWL4030_AUXR_EN;
+               break;
+       default:
+               break;
+       }
+
+       if (value != 0) {
+               anamicr |= TWL4030_MICAMPR_EN;
+               avadc_ctl |= TWL4030_ADCR_EN;
+       } else {
+               anamicr &= ~TWL4030_MICAMPR_EN;
+               avadc_ctl &= ~TWL4030_ADCR_EN;
+       }
+
+       twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
+       twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
+       twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
+
+       return 1;
+}
+
+static const char *twl4030_left_in_sel[] = {
+       "None",
+       "Main Mic",
+       "Headset Mic",
+       "Line In",
+       "Carkit Mic",
+};
+
+static const char *twl4030_right_in_sel[] = {
+       "None",
+       "Sub Mic",
+       "Line In",
+};
+
+static const struct soc_enum twl4030_left_input_mux =
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
+               twl4030_left_in_sel);
+
+static const struct soc_enum twl4030_right_input_mux =
+       SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
+               twl4030_right_in_sel);
+
+/*
+ * FGAIN volume control:
+ * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
+ */
+static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
+
+/*
+ * CGAIN volume control:
+ * 0 dB to 12 dB in 6 dB steps
+ * value 2 and 3 means 12 dB
+ */
+static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
+
+/*
+ * Analog playback gain
+ * -24 dB to 12 dB in 2 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
+
+/*
+ * Gain controls tied to outputs
+ * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
+ */
+static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
+
+/*
+ * Capture gain after the ADCs
+ * from 0 dB to 31 dB in 1 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
+
+/*
+ * Gain control for input amplifiers
+ * 0 dB to 30 dB in 6 dB steps
+ */
+static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
+
+static const struct snd_kcontrol_new twl4030_snd_controls[] = {
+       /* Common playback gain controls */
+       SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
+               TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
+               0, 0x3f, 0, digital_fine_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
+               TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
+               0, 0x3f, 0, digital_fine_tlv),
+
+       SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
+               TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
+               6, 0x2, 0, digital_coarse_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
+               TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
+               6, 0x2, 0, digital_coarse_tlv),
+
+       SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
+               TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
+               3, 0x12, 1, analog_tlv),
+       SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
+               TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
+               3, 0x12, 1, analog_tlv),
+       SOC_DOUBLE_R("DAC1 Analog Playback Switch",
+               TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
+               1, 1, 0),
+       SOC_DOUBLE_R("DAC2 Analog Playback Switch",
+               TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
+               1, 1, 0),
+
+       /* Separate output gain controls */
+       SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
+               TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
+               4, 3, 0, output_tvl),
+
+       SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
+               TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
+
+       SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
+               TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
+               4, 3, 0, output_tvl),
+
+       SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
+               TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
+
+       /* Common capture gain controls */
+       SOC_DOUBLE_R_TLV("Capture Volume",
+               TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
+               0, 0x1f, 0, digital_capture_tlv),
+
+       SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
+               0, 3, 5, 0, input_gain_tlv),
+
+       /* Input source controls */
+       SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
+               twl4030_get_left_input, twl4030_put_left_input),
+       SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
+               twl4030_get_right_input, twl4030_put_right_input),
+};
+
+/* add non dapm controls */
+static int twl4030_add_controls(struct snd_soc_codec *codec)
+{
+       int err, i;
+
+       for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
+               err = snd_ctl_add(codec->card,
+                                 snd_soc_cnew(&twl4030_snd_controls[i],
+                                               codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
+       SND_SOC_DAPM_INPUT("INL"),
+       SND_SOC_DAPM_INPUT("INR"),
+
+       SND_SOC_DAPM_OUTPUT("OUTL"),
+       SND_SOC_DAPM_OUTPUT("OUTR"),
+       SND_SOC_DAPM_OUTPUT("EARPIECE"),
+       SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
+       SND_SOC_DAPM_OUTPUT("PREDRIVER"),
+       SND_SOC_DAPM_OUTPUT("HSOL"),
+       SND_SOC_DAPM_OUTPUT("HSOR"),
+       SND_SOC_DAPM_OUTPUT("CARKITL"),
+       SND_SOC_DAPM_OUTPUT("CARKITR"),
+       SND_SOC_DAPM_OUTPUT("HFL"),
+       SND_SOC_DAPM_OUTPUT("HFR"),
+
+       /* DACs */
+       SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
+                       TWL4030_REG_AVDAC_CTL, 0, 0),
+       SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
+                       TWL4030_REG_AVDAC_CTL, 1, 0),
+       SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
+                       TWL4030_REG_AVDAC_CTL, 2, 0),
+       SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
+                       TWL4030_REG_AVDAC_CTL, 3, 0),
+
+       /* Analog PGAs */
+       SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
+                       0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
+                       0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
+                       0, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
+                       0, 0, NULL, 0),
+
+       /* Output MUX controls */
+       /* Earpiece */
+       SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_earpiece_control, outmixer_event,
+               SND_SOC_DAPM_PRE_REG),
+       /* PreDrivL/R */
+       SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_predrivel_control, outmixer_event,
+               SND_SOC_DAPM_PRE_REG),
+       SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_predriver_control, outmixer_event,
+               SND_SOC_DAPM_PRE_REG),
+       /* HeadsetL/R */
+       SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_hsol_control),
+       SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_hsor_control),
+       /* CarkitL/R */
+       SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_carkitl_control),
+       SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
+               &twl4030_dapm_carkitr_control),
+       /* HandsfreeL/R */
+       SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
+               &twl4030_dapm_handsfreel_control, handsfree_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+       SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
+               &twl4030_dapm_handsfreer_control, handsfree_event,
+               SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
+
+       SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+       {"ARXL1_APGA", NULL, "DAC Left1"},
+       {"ARXR1_APGA", NULL, "DAC Right1"},
+       {"ARXL2_APGA", NULL, "DAC Left2"},
+       {"ARXR2_APGA", NULL, "DAC Right2"},
+
+       /* Internal playback routings */
+       /* Earpiece */
+       {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
+       {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
+       {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
+       /* PreDrivL */
+       {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
+       {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
+       {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
+       /* PreDrivR */
+       {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
+       {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
+       {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
+       /* HeadsetL */
+       {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
+       {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
+       /* HeadsetR */
+       {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
+       {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
+       /* CarkitL */
+       {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
+       {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
+       /* CarkitR */
+       {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
+       {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
+       /* HandsfreeL */
+       {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
+       {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
+       {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
+       /* HandsfreeR */
+       {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
+       {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
+       {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
+
+       /* outputs */
+       {"OUTL", NULL, "ARXL2_APGA"},
+       {"OUTR", NULL, "ARXR2_APGA"},
+       {"EARPIECE", NULL, "Earpiece Mux"},
+       {"PREDRIVEL", NULL, "PredriveL Mux"},
+       {"PREDRIVER", NULL, "PredriveR Mux"},
+       {"HSOL", NULL, "HeadsetL Mux"},
+       {"HSOR", NULL, "HeadsetR Mux"},
+       {"CARKITL", NULL, "CarkitL Mux"},
+       {"CARKITR", NULL, "CarkitR Mux"},
+       {"HFL", NULL, "HandsfreeL Mux"},
+       {"HFR", NULL, "HandsfreeR Mux"},
+
+       /* inputs */
+       {"ADCL", NULL, "INL"},
+       {"ADCR", NULL, "INR"},
+};
+
+static int twl4030_add_widgets(struct snd_soc_codec *codec)
+{
+       snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
+                                ARRAY_SIZE(twl4030_dapm_widgets));
+
+       snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
+       snd_soc_dapm_new_widgets(codec);
+       return 0;
+}
+
+static void twl4030_power_up(struct snd_soc_codec *codec)
+{
+       u8 anamicl, regmisc1, byte, popn;
+       int i = 0;
+
+       /* set CODECPDZ to turn on codec */
+       twl4030_set_codecpdz(codec);
+
+       /* initiate offset cancellation */
+       anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
+       twl4030_write(codec, TWL4030_REG_ANAMICL,
+               anamicl | TWL4030_CNCL_OFFSET_START);
+
+       /* wait for offset cancellation to complete */
+       do {
+               /* this takes a little while, so don't slam i2c */
+               udelay(2000);
+               twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
+                                   TWL4030_REG_ANAMICL);
+       } while ((i++ < 100) &&
+                ((byte & TWL4030_CNCL_OFFSET_START) ==
+                 TWL4030_CNCL_OFFSET_START));
+
+       /* anti-pop when changing analog gain */
+       regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
+       twl4030_write(codec, TWL4030_REG_MISC_SET_1,
+               regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
+
+       /* toggle CODECPDZ as per TRM */
+       twl4030_clear_codecpdz(codec);
+       twl4030_set_codecpdz(codec);
+
+       /* program anti-pop with bias ramp delay */
+       popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
+       popn &= TWL4030_RAMP_DELAY;
+       popn |= TWL4030_RAMP_DELAY_645MS;
+       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
+       popn |= TWL4030_VMID_EN;
+       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
+
+       /* enable anti-pop ramp */
+       popn |= TWL4030_RAMP_EN;
+       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
+}
+
+static void twl4030_power_down(struct snd_soc_codec *codec)
+{
+       u8 popn;
+
+       /* disable anti-pop ramp */
+       popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
+       popn &= ~TWL4030_RAMP_EN;
+       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
+
+       /* disable bias out */
+       popn &= ~TWL4030_VMID_EN;
+       twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
+
+       /* power down */
+       twl4030_clear_codecpdz(codec);
+}
+
+static int twl4030_set_bias_level(struct snd_soc_codec *codec,
+                                 enum snd_soc_bias_level level)
+{
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               twl4030_power_up(codec);
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               /* TODO: develop a twl4030_prepare function */
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               /* TODO: develop a twl4030_standby function */
+               twl4030_power_down(codec);
+               break;
+       case SND_SOC_BIAS_OFF:
+               twl4030_power_down(codec);
+               break;
+       }
+       codec->bias_level = level;
+
+       return 0;
+}
+
+static int twl4030_hw_params(struct snd_pcm_substream *substream,
+                          struct snd_pcm_hw_params *params,
+                          struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       u8 mode, old_mode, format, old_format;
+
+
+       /* bit rate */
+       old_mode = twl4030_read_reg_cache(codec,
+                       TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
+       mode = old_mode & ~TWL4030_APLL_RATE;
+
+       switch (params_rate(params)) {
+       case 8000:
+               mode |= TWL4030_APLL_RATE_8000;
+               break;
+       case 11025:
+               mode |= TWL4030_APLL_RATE_11025;
+               break;
+       case 12000:
+               mode |= TWL4030_APLL_RATE_12000;
+               break;
+       case 16000:
+               mode |= TWL4030_APLL_RATE_16000;
+               break;
+       case 22050:
+               mode |= TWL4030_APLL_RATE_22050;
+               break;
+       case 24000:
+               mode |= TWL4030_APLL_RATE_24000;
+               break;
+       case 32000:
+               mode |= TWL4030_APLL_RATE_32000;
+               break;
+       case 44100:
+               mode |= TWL4030_APLL_RATE_44100;
+               break;
+       case 48000:
+               mode |= TWL4030_APLL_RATE_48000;
+               break;
+       default:
+               printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
+                       params_rate(params));
+               return -EINVAL;
+       }
+
+       if (mode != old_mode) {
+               /* change rate and set CODECPDZ */
+               twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+               twl4030_set_codecpdz(codec);
+       }
+
+       /* sample size */
+       old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
+       format = old_format;
+       format &= ~TWL4030_DATA_WIDTH;
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               format |= TWL4030_DATA_WIDTH_16S_16W;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               format |= TWL4030_DATA_WIDTH_32S_24W;
+               break;
+       default:
+               printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
+                       params_format(params));
+               return -EINVAL;
+       }
+
+       if (format != old_format) {
+
+               /* clear CODECPDZ before changing format (codec requirement) */
+               twl4030_clear_codecpdz(codec);
+
+               /* change format */
+               twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+
+               /* set CODECPDZ afterwards */
+               twl4030_set_codecpdz(codec);
+       }
+       return 0;
+}
+
+static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+               int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u8 infreq;
+
+       switch (freq) {
+       case 19200000:
+               infreq = TWL4030_APLL_INFREQ_19200KHZ;
+               break;
+       case 26000000:
+               infreq = TWL4030_APLL_INFREQ_26000KHZ;
+               break;
+       case 38400000:
+               infreq = TWL4030_APLL_INFREQ_38400KHZ;
+               break;
+       default:
+               printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
+                       freq);
+               return -EINVAL;
+       }
+
+       infreq |= TWL4030_APLL_EN;
+       twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
+
+       return 0;
+}
+
+static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                            unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u8 old_format, format;
+
+       /* get format */
+       old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
+       format = old_format;
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               format &= ~(TWL4030_AIF_SLAVE_EN);
+               format &= ~(TWL4030_CLK256FS_EN);
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               format |= TWL4030_AIF_SLAVE_EN;
+               format |= TWL4030_CLK256FS_EN;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* interface format */
+       format &= ~TWL4030_AIF_FORMAT;
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               format |= TWL4030_AIF_FORMAT_CODEC;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (format != old_format) {
+
+               /* clear CODECPDZ before changing format (codec requirement) */
+               twl4030_clear_codecpdz(codec);
+
+               /* change format */
+               twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+
+               /* set CODECPDZ afterwards */
+               twl4030_set_codecpdz(codec);
+       }
+
+       return 0;
+}
+
+#define TWL4030_RATES   (SNDRV_PCM_RATE_8000_48000)
+#define TWL4030_FORMATS         (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
+
+struct snd_soc_dai twl4030_dai = {
+       .name = "twl4030",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = TWL4030_RATES,
+               .formats = TWL4030_FORMATS,},
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = TWL4030_RATES,
+               .formats = TWL4030_FORMATS,},
+       .ops = {
+               .hw_params = twl4030_hw_params,
+               .set_sysclk = twl4030_set_dai_sysclk,
+               .set_fmt = twl4030_set_dai_fmt,
+       }
+};
+EXPORT_SYMBOL_GPL(twl4030_dai);
+
+static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       return 0;
+}
+
+static int twl4030_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       twl4030_set_bias_level(codec, codec->suspend_bias_level);
+       return 0;
+}
+
+/*
+ * initialize the driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+
+static int twl4030_init(struct snd_soc_device *socdev)
+{
+       struct snd_soc_codec *codec = socdev->codec;
+       int ret = 0;
+
+       printk(KERN_INFO "TWL4030 Audio Codec init \n");
+
+       codec->name = "twl4030";
+       codec->owner = THIS_MODULE;
+       codec->read = twl4030_read_reg_cache;
+       codec->write = twl4030_write;
+       codec->set_bias_level = twl4030_set_bias_level;
+       codec->dai = &twl4030_dai;
+       codec->num_dai = 1;
+       codec->reg_cache_size = sizeof(twl4030_reg);
+       codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
+                                       GFP_KERNEL);
+       if (codec->reg_cache == NULL)
+               return -ENOMEM;
+
+       /* register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               printk(KERN_ERR "twl4030: failed to create pcms\n");
+               goto pcm_err;
+       }
+
+       twl4030_init_chip(codec);
+
+       /* power on device */
+       twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       twl4030_add_controls(codec);
+       twl4030_add_widgets(codec);
+
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               printk(KERN_ERR "twl4030: failed to register card\n");
+               goto card_err;
+       }
+
+       return ret;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+pcm_err:
+       kfree(codec->reg_cache);
+       return ret;
+}
+
+static struct snd_soc_device *twl4030_socdev;
+
+static int twl4030_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec;
+
+       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+       if (codec == NULL)
+               return -ENOMEM;
+
+       socdev->codec = codec;
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+
+       twl4030_socdev = socdev;
+       twl4030_init(socdev);
+
+       return 0;
+}
+
+static int twl4030_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       printk(KERN_INFO "TWL4030 Audio Codec remove\n");
+       kfree(codec);
+
+       return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_twl4030 = {
+       .probe = twl4030_probe,
+       .remove = twl4030_remove,
+       .suspend = twl4030_suspend,
+       .resume = twl4030_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
+
+static int __init twl4030_modinit(void)
+{
+       return snd_soc_register_dai(&twl4030_dai);
+}
+module_init(twl4030_modinit);
+
+static void __exit twl4030_exit(void)
+{
+       snd_soc_unregister_dai(&twl4030_dai);
+}
+module_exit(twl4030_exit);
+
+MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
+MODULE_AUTHOR("Steve Sakoman");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
new file mode 100644 (file)
index 0000000..54615c7
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * ALSA SoC TWL4030 codec driver
+ *
+ * Author: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __TWL4030_AUDIO_H__
+#define __TWL4030_AUDIO_H__
+
+#define TWL4030_REG_CODEC_MODE         0x1
+#define TWL4030_REG_OPTION             0x2
+#define TWL4030_REG_UNKNOWN            0x3
+#define TWL4030_REG_MICBIAS_CTL                0x4
+#define TWL4030_REG_ANAMICL            0x5
+#define TWL4030_REG_ANAMICR            0x6
+#define TWL4030_REG_AVADC_CTL          0x7
+#define TWL4030_REG_ADCMICSEL          0x8
+#define TWL4030_REG_DIGMIXING          0x9
+#define TWL4030_REG_ATXL1PGA           0xA
+#define TWL4030_REG_ATXR1PGA           0xB
+#define TWL4030_REG_AVTXL2PGA          0xC
+#define TWL4030_REG_AVTXR2PGA          0xD
+#define TWL4030_REG_AUDIO_IF           0xE
+#define TWL4030_REG_VOICE_IF           0xF
+#define TWL4030_REG_ARXR1PGA           0x10
+#define TWL4030_REG_ARXL1PGA           0x11
+#define TWL4030_REG_ARXR2PGA           0x12
+#define TWL4030_REG_ARXL2PGA           0x13
+#define TWL4030_REG_VRXPGA             0x14
+#define TWL4030_REG_VSTPGA             0x15
+#define TWL4030_REG_VRX2ARXPGA         0x16
+#define TWL4030_REG_AVDAC_CTL          0x17
+#define TWL4030_REG_ARX2VTXPGA         0x18
+#define TWL4030_REG_ARXL1_APGA_CTL     0x19
+#define TWL4030_REG_ARXR1_APGA_CTL     0x1A
+#define TWL4030_REG_ARXL2_APGA_CTL     0x1B
+#define TWL4030_REG_ARXR2_APGA_CTL     0x1C
+#define TWL4030_REG_ATX2ARXPGA         0x1D
+#define TWL4030_REG_BT_IF              0x1E
+#define TWL4030_REG_BTPGA              0x1F
+#define TWL4030_REG_BTSTPGA            0x20
+#define TWL4030_REG_EAR_CTL            0x21
+#define TWL4030_REG_HS_SEL             0x22
+#define TWL4030_REG_HS_GAIN_SET                0x23
+#define TWL4030_REG_HS_POPN_SET                0x24
+#define TWL4030_REG_PREDL_CTL          0x25
+#define TWL4030_REG_PREDR_CTL          0x26
+#define TWL4030_REG_PRECKL_CTL         0x27
+#define TWL4030_REG_PRECKR_CTL         0x28
+#define TWL4030_REG_HFL_CTL            0x29
+#define TWL4030_REG_HFR_CTL            0x2A
+#define TWL4030_REG_ALC_CTL            0x2B
+#define TWL4030_REG_ALC_SET1           0x2C
+#define TWL4030_REG_ALC_SET2           0x2D
+#define TWL4030_REG_BOOST_CTL          0x2E
+#define TWL4030_REG_SOFTVOL_CTL                0x2F
+#define TWL4030_REG_DTMF_FREQSEL       0x30
+#define TWL4030_REG_DTMF_TONEXT1H      0x31
+#define TWL4030_REG_DTMF_TONEXT1L      0x32
+#define TWL4030_REG_DTMF_TONEXT2H      0x33
+#define TWL4030_REG_DTMF_TONEXT2L      0x34
+#define TWL4030_REG_DTMF_TONOFF                0x35
+#define TWL4030_REG_DTMF_WANONOFF      0x36
+#define TWL4030_REG_I2S_RX_SCRAMBLE_H  0x37
+#define TWL4030_REG_I2S_RX_SCRAMBLE_M  0x38
+#define TWL4030_REG_I2S_RX_SCRAMBLE_L  0x39
+#define TWL4030_REG_APLL_CTL           0x3A
+#define TWL4030_REG_DTMF_CTL           0x3B
+#define TWL4030_REG_DTMF_PGA_CTL2      0x3C
+#define TWL4030_REG_DTMF_PGA_CTL1      0x3D
+#define TWL4030_REG_MISC_SET_1         0x3E
+#define TWL4030_REG_PCMBTMUX           0x3F
+#define TWL4030_REG_RX_PATH_SEL                0x43
+#define TWL4030_REG_VDL_APGA_CTL       0x44
+#define TWL4030_REG_VIBRA_CTL          0x45
+#define TWL4030_REG_VIBRA_SET          0x46
+#define TWL4030_REG_VIBRA_PWM_SET      0x47
+#define TWL4030_REG_ANAMIC_GAIN                0x48
+#define TWL4030_REG_MISC_SET_2         0x49
+
+#define TWL4030_CACHEREGNUM    (TWL4030_REG_MISC_SET_2 + 1)
+
+/* Bitfield Definitions */
+
+/* TWL4030_CODEC_MODE (0x01) Fields */
+
+#define TWL4030_APLL_RATE              0xF0
+#define TWL4030_APLL_RATE_8000         0x00
+#define TWL4030_APLL_RATE_11025                0x10
+#define TWL4030_APLL_RATE_12000                0x20
+#define TWL4030_APLL_RATE_16000                0x40
+#define TWL4030_APLL_RATE_22050                0x50
+#define TWL4030_APLL_RATE_24000                0x60
+#define TWL4030_APLL_RATE_32000                0x80
+#define TWL4030_APLL_RATE_44100                0x90
+#define TWL4030_APLL_RATE_48000                0xA0
+#define TWL4030_SEL_16K                        0x04
+#define TWL4030_CODECPDZ               0x02
+#define TWL4030_OPT_MODE               0x01
+
+/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
+
+#define TWL4030_MICBIAS2_CTL           0x40
+#define TWL4030_MICBIAS1_CTL           0x20
+#define TWL4030_HSMICBIAS_EN           0x04
+#define TWL4030_MICBIAS2_EN            0x02
+#define TWL4030_MICBIAS1_EN            0x01
+
+/* ANAMICL (0x05) Fields */
+
+#define TWL4030_CNCL_OFFSET_START      0x80
+#define TWL4030_OFFSET_CNCL_SEL                0x60
+#define TWL4030_OFFSET_CNCL_SEL_ARX1   0x00
+#define TWL4030_OFFSET_CNCL_SEL_ARX2   0x20
+#define TWL4030_OFFSET_CNCL_SEL_VRX    0x40
+#define TWL4030_OFFSET_CNCL_SEL_ALL    0x60
+#define TWL4030_MICAMPL_EN             0x10
+#define TWL4030_CKMIC_EN               0x08
+#define TWL4030_AUXL_EN                        0x04
+#define TWL4030_HSMIC_EN               0x02
+#define TWL4030_MAINMIC_EN             0x01
+
+/* ANAMICR (0x06) Fields */
+
+#define TWL4030_MICAMPR_EN             0x10
+#define TWL4030_AUXR_EN                        0x04
+#define TWL4030_SUBMIC_EN              0x01
+
+/* AVADC_CTL (0x07) Fields */
+
+#define TWL4030_ADCL_EN                        0x08
+#define TWL4030_AVADC_CLK_PRIORITY     0x04
+#define TWL4030_ADCR_EN                        0x02
+
+/* AUDIO_IF (0x0E) Fields */
+
+#define TWL4030_AIF_SLAVE_EN           0x80
+#define TWL4030_DATA_WIDTH             0x60
+#define TWL4030_DATA_WIDTH_16S_16W     0x00
+#define TWL4030_DATA_WIDTH_32S_16W     0x40
+#define TWL4030_DATA_WIDTH_32S_24W     0x60
+#define TWL4030_AIF_FORMAT             0x18
+#define TWL4030_AIF_FORMAT_CODEC       0x00
+#define TWL4030_AIF_FORMAT_LEFT                0x08
+#define TWL4030_AIF_FORMAT_RIGHT       0x10
+#define TWL4030_AIF_FORMAT_TDM         0x18
+#define TWL4030_AIF_TRI_EN             0x04
+#define TWL4030_CLK256FS_EN            0x02
+#define TWL4030_AIF_EN                 0x01
+
+/* HS_GAIN_SET (0x23) Fields */
+
+#define TWL4030_HSR_GAIN               0x0C
+#define TWL4030_HSR_GAIN_PWR_DOWN      0x00
+#define TWL4030_HSR_GAIN_PLUS_6DB      0x04
+#define TWL4030_HSR_GAIN_0DB           0x08
+#define TWL4030_HSR_GAIN_MINUS_6DB     0x0C
+#define TWL4030_HSL_GAIN               0x03
+#define TWL4030_HSL_GAIN_PWR_DOWN      0x00
+#define TWL4030_HSL_GAIN_PLUS_6DB      0x01
+#define TWL4030_HSL_GAIN_0DB           0x02
+#define TWL4030_HSL_GAIN_MINUS_6DB     0x03
+
+/* HS_POPN_SET (0x24) Fields */
+
+#define TWL4030_VMID_EN                        0x40
+#define        TWL4030_EXTMUTE                 0x20
+#define TWL4030_RAMP_DELAY             0x1C
+#define TWL4030_RAMP_DELAY_20MS                0x00
+#define TWL4030_RAMP_DELAY_40MS                0x04
+#define TWL4030_RAMP_DELAY_81MS                0x08
+#define TWL4030_RAMP_DELAY_161MS       0x0C
+#define TWL4030_RAMP_DELAY_323MS       0x10
+#define TWL4030_RAMP_DELAY_645MS       0x14
+#define TWL4030_RAMP_DELAY_1291MS      0x18
+#define TWL4030_RAMP_DELAY_2581MS      0x1C
+#define TWL4030_RAMP_EN                        0x02
+
+/* HFL_CTL (0x29, 0x2A) Fields */
+#define TWL4030_HF_CTL_HB_EN           0x04
+#define TWL4030_HF_CTL_LOOP_EN         0x08
+#define TWL4030_HF_CTL_RAMP_EN         0x10
+#define TWL4030_HF_CTL_REF_EN          0x20
+
+/* APLL_CTL (0x3A) Fields */
+
+#define TWL4030_APLL_EN                        0x10
+#define TWL4030_APLL_INFREQ            0x0F
+#define TWL4030_APLL_INFREQ_19200KHZ   0x05
+#define TWL4030_APLL_INFREQ_26000KHZ   0x06
+#define TWL4030_APLL_INFREQ_38400KHZ   0x0F
+
+/* REG_MISC_SET_1 (0x3E) Fields */
+
+#define TWL4030_CLK64_EN               0x80
+#define TWL4030_SCRAMBLE_EN            0x40
+#define TWL4030_FMLOOP_EN              0x20
+#define TWL4030_SMOOTH_ANAVOL_EN       0x02
+#define TWL4030_DIGMIC_LR_SWAP_EN      0x01
+
+extern struct snd_soc_dai twl4030_dai;
+extern struct snd_soc_codec_device soc_codec_dev_twl4030;
+
+#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
new file mode 100644 (file)
index 0000000..a2c5064
--- /dev/null
@@ -0,0 +1,668 @@
+/*
+ * uda134x.c  --  UDA134X ALSA SoC Codec driver
+ *
+ * Modifications by Christian Pellegrin <chripell@evolware.org>
+ *
+ * Copyright 2007 Dension Audio Systems Ltd.
+ * Author: Zoltan Devai
+ *
+ * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+
+#include <sound/uda134x.h>
+#include <sound/l3.h>
+
+#include "uda134x.h"
+
+
+#define POWER_OFF_ON_STANDBY 1
+/*
+  ALSA SOC usually puts the device in standby mode when it's not used
+  for sometime. If you define POWER_OFF_ON_STANDBY the driver will
+  turn off the ADC/DAC when this callback is invoked and turn it back
+  on when needed. Unfortunately this will result in a very light bump
+  (it can be audible only with good earphones). If this bothers you
+  just comment this line, you will have slightly higher power
+  consumption . Please note that sending the L3 command for ADC is
+  enough to make the bump, so it doesn't make difference if you
+  completely take off power from the codec.
+ */
+
+#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
+#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
+               SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
+
+struct uda134x_priv {
+       int sysclk;
+       int dai_fmt;
+
+       struct snd_pcm_substream *master_substream;
+       struct snd_pcm_substream *slave_substream;
+};
+
+/* In-data addresses are hard-coded into the reg-cache values */
+static const char uda134x_reg[UDA134X_REGS_NUM] = {
+       /* Extended address registers */
+       0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+       /* Status, data regs */
+       0x00, 0x83, 0x00, 0x40, 0x80, 0x00,
+};
+
+/*
+ * The codec has no support for reading its registers except for peak level...
+ */
+static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
+       unsigned int reg)
+{
+       u8 *cache = codec->reg_cache;
+
+       if (reg >= UDA134X_REGS_NUM)
+               return -1;
+       return cache[reg];
+}
+
+/*
+ * Write the register cache
+ */
+static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
+       u8 reg, unsigned int value)
+{
+       u8 *cache = codec->reg_cache;
+
+       if (reg >= UDA134X_REGS_NUM)
+               return;
+       cache[reg] = value;
+}
+
+/*
+ * Write to the uda134x registers
+ *
+ */
+static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
+       unsigned int value)
+{
+       int ret;
+       u8 addr;
+       u8 data = value;
+       struct uda134x_platform_data *pd = codec->control_data;
+
+       pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
+
+       if (reg >= UDA134X_REGS_NUM) {
+               printk(KERN_ERR "%s unkown register: reg: %d",
+                      __func__, reg);
+               return -EINVAL;
+       }
+
+       uda134x_write_reg_cache(codec, reg, value);
+
+       switch (reg) {
+       case UDA134X_STATUS0:
+       case UDA134X_STATUS1:
+               addr = UDA134X_STATUS_ADDR;
+               break;
+       case UDA134X_DATA000:
+       case UDA134X_DATA001:
+       case UDA134X_DATA010:
+               addr = UDA134X_DATA0_ADDR;
+               break;
+       case UDA134X_DATA1:
+               addr = UDA134X_DATA1_ADDR;
+               break;
+       default:
+               /* It's an extended address register */
+               addr =  (reg | UDA134X_EXTADDR_PREFIX);
+
+               ret = l3_write(&pd->l3,
+                              UDA134X_DATA0_ADDR, &addr, 1);
+               if (ret != 1)
+                       return -EIO;
+
+               addr = UDA134X_DATA0_ADDR;
+               data = (value | UDA134X_EXTDATA_PREFIX);
+               break;
+       }
+
+       ret = l3_write(&pd->l3,
+                      addr, &data, 1);
+       if (ret != 1)
+               return -EIO;
+
+       return 0;
+}
+
+static inline void uda134x_reset(struct snd_soc_codec *codec)
+{
+       u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
+       uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
+       msleep(1);
+       uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
+}
+
+static int uda134x_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
+
+       pr_debug("%s mute: %d\n", __func__, mute);
+
+       if (mute)
+               mute_reg |= (1<<2);
+       else
+               mute_reg &= ~(1<<2);
+
+       uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
+
+       return 0;
+}
+
+static int uda134x_startup(struct snd_pcm_substream *substream,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct uda134x_priv *uda134x = codec->private_data;
+       struct snd_pcm_runtime *master_runtime;
+
+       if (uda134x->master_substream) {
+               master_runtime = uda134x->master_substream->runtime;
+
+               pr_debug("%s constraining to %d bits at %d\n", __func__,
+                        master_runtime->sample_bits,
+                        master_runtime->rate);
+
+               snd_pcm_hw_constraint_minmax(substream->runtime,
+                                            SNDRV_PCM_HW_PARAM_RATE,
+                                            master_runtime->rate,
+                                            master_runtime->rate);
+
+               snd_pcm_hw_constraint_minmax(substream->runtime,
+                                            SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+                                            master_runtime->sample_bits,
+                                            master_runtime->sample_bits);
+
+               uda134x->slave_substream = substream;
+       } else
+               uda134x->master_substream = substream;
+
+       return 0;
+}
+
+static void uda134x_shutdown(struct snd_pcm_substream *substream,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct uda134x_priv *uda134x = codec->private_data;
+
+       if (uda134x->master_substream == substream)
+               uda134x->master_substream = uda134x->slave_substream;
+
+       uda134x->slave_substream = NULL;
+}
+
+static int uda134x_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       struct uda134x_priv *uda134x = codec->private_data;
+       u8 hw_params;
+
+       if (substream == uda134x->slave_substream) {
+               pr_debug("%s ignoring hw_params for slave substream\n",
+                        __func__);
+               return 0;
+       }
+
+       hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
+       hw_params &= STATUS0_SYSCLK_MASK;
+       hw_params &= STATUS0_DAIFMT_MASK;
+
+       pr_debug("%s sysclk: %d, rate:%d\n", __func__,
+                uda134x->sysclk, params_rate(params));
+
+       /* set SYSCLK / fs ratio */
+       switch (uda134x->sysclk / params_rate(params)) {
+       case 512:
+               break;
+       case 384:
+               hw_params |= (1<<4);
+               break;
+       case 256:
+               hw_params |= (1<<5);
+               break;
+       default:
+               printk(KERN_ERR "%s unsupported fs\n", __func__);
+               return -EINVAL;
+       }
+
+       pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
+                uda134x->dai_fmt, params_format(params));
+
+       /* set DAI format and word length */
+       switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               switch (params_format(params)) {
+               case SNDRV_PCM_FORMAT_S16_LE:
+                       hw_params |= (1<<1);
+                       break;
+               case SNDRV_PCM_FORMAT_S18_3LE:
+                       hw_params |= (1<<2);
+                       break;
+               case SNDRV_PCM_FORMAT_S20_3LE:
+                       hw_params |= ((1<<2) | (1<<1));
+                       break;
+               default:
+                       printk(KERN_ERR "%s unsupported format (right)\n",
+                              __func__);
+                       return -EINVAL;
+               }
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               hw_params |= (1<<3);
+               break;
+       default:
+               printk(KERN_ERR "%s unsupported format\n", __func__);
+               return -EINVAL;
+       }
+
+       uda134x_write(codec, UDA134X_STATUS0, hw_params);
+
+       return 0;
+}
+
+static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+                                 int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct uda134x_priv *uda134x = codec->private_data;
+
+       pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
+                clk_id, freq, dir);
+
+       /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
+          because the codec is slave. Of course limitations of the clock
+          master (the IIS controller) apply.
+          We'll error out on set_hw_params if it's not OK */
+       if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
+               uda134x->sysclk = freq;
+               return 0;
+       }
+
+       printk(KERN_ERR "%s unsupported sysclk\n", __func__);
+       return -EINVAL;
+}
+
+static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
+                              unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct uda134x_priv *uda134x = codec->private_data;
+
+       pr_debug("%s fmt: %08X\n", __func__, fmt);
+
+       /* codec supports only full slave mode */
+       if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
+               printk(KERN_ERR "%s unsupported slave mode\n", __func__);
+               return -EINVAL;
+       }
+
+       /* no support for clock inversion */
+       if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
+               printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
+               return -EINVAL;
+       }
+
+       /* We can't setup DAI format here as it depends on the word bit num */
+       /* so let's just store the value for later */
+       uda134x->dai_fmt = fmt;
+
+       return 0;
+}
+
+static int uda134x_set_bias_level(struct snd_soc_codec *codec,
+                                 enum snd_soc_bias_level level)
+{
+       u8 reg;
+       struct uda134x_platform_data *pd = codec->control_data;
+       int i;
+       u8 *cache = codec->reg_cache;
+
+       pr_debug("%s bias level %d\n", __func__, level);
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               /* ADC, DAC on */
+               reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
+               uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
+               break;
+       case SND_SOC_BIAS_PREPARE:
+               /* power on */
+               if (pd->power) {
+                       pd->power(1);
+                       /* Sync reg_cache with the hardware */
+                       for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
+                               codec->write(codec, i, *cache++);
+               }
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               /* ADC, DAC power off */
+               reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
+               uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
+               break;
+       case SND_SOC_BIAS_OFF:
+               /* power off */
+               if (pd->power)
+                       pd->power(0);
+               break;
+       }
+       codec->bias_level = level;
+       return 0;
+}
+
+static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
+                                           "Minimum2", "Maximum"};
+static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
+static const char *uda134x_mixmode[] = {"Differential", "Analog1",
+                                       "Analog2", "Both"};
+
+static const struct soc_enum uda134x_mixer_enum[] = {
+SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
+SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
+SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
+};
+
+static const struct snd_kcontrol_new uda1341_snd_controls[] = {
+SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
+SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
+SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
+SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
+
+SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
+SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
+
+SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
+SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
+
+SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
+SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
+SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
+
+SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
+SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
+SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
+
+SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
+SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
+SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
+SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
+SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
+SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new uda1340_snd_controls[] = {
+SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
+
+SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
+SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
+
+SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
+SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
+
+SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
+};
+
+static int uda134x_add_controls(struct snd_soc_codec *codec)
+{
+       int err, i, n;
+       const struct snd_kcontrol_new *ctrls;
+       struct uda134x_platform_data *pd = codec->control_data;
+
+       switch (pd->model) {
+       case UDA134X_UDA1340:
+       case UDA134X_UDA1344:
+               n = ARRAY_SIZE(uda1340_snd_controls);
+               ctrls = uda1340_snd_controls;
+               break;
+       case UDA134X_UDA1341:
+               n = ARRAY_SIZE(uda1341_snd_controls);
+               ctrls = uda1341_snd_controls;
+               break;
+       default:
+               printk(KERN_ERR "%s unkown codec type: %d",
+                      __func__, pd->model);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < n; i++) {
+               err = snd_ctl_add(codec->card,
+                                 snd_soc_cnew(&ctrls[i],
+                                              codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+struct snd_soc_dai uda134x_dai = {
+       .name = "UDA134X",
+       /* playback capabilities */
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = UDA134X_RATES,
+               .formats = UDA134X_FORMATS,
+       },
+       /* capture capabilities */
+       .capture = {
+               .stream_name = "Capture",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = UDA134X_RATES,
+               .formats = UDA134X_FORMATS,
+       },
+       /* pcm operations */
+       .ops = {
+               .startup = uda134x_startup,
+               .shutdown = uda134x_shutdown,
+               .hw_params = uda134x_hw_params,
+               .digital_mute = uda134x_mute,
+               .set_sysclk = uda134x_set_dai_sysclk,
+               .set_fmt = uda134x_set_dai_fmt,
+       }
+};
+EXPORT_SYMBOL(uda134x_dai);
+
+
+static int uda134x_soc_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec;
+       struct uda134x_priv *uda134x;
+       void *codec_setup_data = socdev->codec_data;
+       int ret = -ENOMEM;
+       struct uda134x_platform_data *pd;
+
+       printk(KERN_INFO "UDA134X SoC Audio Codec\n");
+
+       if (!codec_setup_data) {
+               printk(KERN_ERR "UDA134X SoC codec: "
+                      "missing L3 bitbang function\n");
+               return -ENODEV;
+       }
+
+       pd = codec_setup_data;
+       switch (pd->model) {
+       case UDA134X_UDA1340:
+       case UDA134X_UDA1341:
+       case UDA134X_UDA1344:
+               break;
+       default:
+               printk(KERN_ERR "UDA134X SoC codec: "
+                      "unsupported model %d\n",
+                       pd->model);
+               return -EINVAL;
+       }
+
+       socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+       if (socdev->codec == NULL)
+               return ret;
+
+       codec = socdev->codec;
+
+       uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
+       if (uda134x == NULL)
+               goto priv_err;
+       codec->private_data = uda134x;
+
+       codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
+                                  GFP_KERNEL);
+       if (codec->reg_cache == NULL)
+               goto reg_err;
+
+       mutex_init(&codec->mutex);
+
+       codec->reg_cache_size = sizeof(uda134x_reg);
+       codec->reg_cache_step = 1;
+
+       codec->name = "UDA134X";
+       codec->owner = THIS_MODULE;
+       codec->dai = &uda134x_dai;
+       codec->num_dai = 1;
+       codec->read = uda134x_read_reg_cache;
+       codec->write = uda134x_write;
+#ifdef POWER_OFF_ON_STANDBY
+       codec->set_bias_level = uda134x_set_bias_level;
+#endif
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+
+       codec->control_data = codec_setup_data;
+
+       if (pd->power)
+               pd->power(1);
+
+       uda134x_reset(codec);
+
+       /* register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               printk(KERN_ERR "UDA134X: failed to register pcms\n");
+               goto pcm_err;
+       }
+
+       ret = uda134x_add_controls(codec);
+       if (ret < 0) {
+               printk(KERN_ERR "UDA134X: failed to register controls\n");
+               goto pcm_err;
+       }
+
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               printk(KERN_ERR "UDA134X: failed to register card\n");
+               goto card_err;
+       }
+
+       return 0;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+pcm_err:
+       kfree(codec->reg_cache);
+reg_err:
+       kfree(codec->private_data);
+priv_err:
+       kfree(codec);
+       return ret;
+}
+
+/* power down chip */
+static int uda134x_soc_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+
+       kfree(codec->private_data);
+       kfree(codec->reg_cache);
+       kfree(codec);
+
+       return 0;
+}
+
+#if defined(CONFIG_PM)
+static int uda134x_soc_suspend(struct platform_device *pdev,
+                                               pm_message_t state)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int uda134x_soc_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
+       uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
+       return 0;
+}
+#else
+#define uda134x_soc_suspend NULL
+#define uda134x_soc_resume NULL
+#endif /* CONFIG_PM */
+
+struct snd_soc_codec_device soc_codec_dev_uda134x = {
+       .probe =        uda134x_soc_probe,
+       .remove =       uda134x_soc_remove,
+       .suspend =      uda134x_soc_suspend,
+       .resume =       uda134x_soc_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
+
+static int __init uda134x_init(void)
+{
+       return snd_soc_register_dai(&uda134x_dai);
+}
+module_init(uda134x_init);
+
+static void __exit uda134x_exit(void)
+{
+       snd_soc_unregister_dai(&uda134x_dai);
+}
+module_exit(uda134x_exit);
+
+MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
+MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
new file mode 100644 (file)
index 0000000..94f4404
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _UDA134X_CODEC_H
+#define _UDA134X_CODEC_H
+
+#define UDA134X_L3ADDR 5
+#define UDA134X_DATA0_ADDR     ((UDA134X_L3ADDR << 2) | 0)
+#define UDA134X_DATA1_ADDR     ((UDA134X_L3ADDR << 2) | 1)
+#define UDA134X_STATUS_ADDR    ((UDA134X_L3ADDR << 2) | 2)
+
+#define UDA134X_EXTADDR_PREFIX 0xC0
+#define UDA134X_EXTDATA_PREFIX 0xE0
+
+/* UDA134X registers */
+#define UDA134X_EA000  0
+#define UDA134X_EA001  1
+#define UDA134X_EA010  2
+#define UDA134X_EA011  3
+#define UDA134X_EA100  4
+#define UDA134X_EA101  5
+#define UDA134X_EA110  6
+#define UDA134X_EA111  7
+#define UDA134X_STATUS0 8
+#define UDA134X_STATUS1 9
+#define UDA134X_DATA000 10
+#define UDA134X_DATA001 11
+#define UDA134X_DATA010 12
+#define UDA134X_DATA1  13
+
+#define UDA134X_REGS_NUM 14
+
+#define STATUS0_DAIFMT_MASK (~(7<<1))
+#define STATUS0_SYSCLK_MASK (~(3<<4))
+
+extern struct snd_soc_dai uda134x_dai;
+extern struct snd_soc_codec_device soc_codec_dev_uda134x;
+
+#endif
index a69ee72a7af553ca3f36d03d2c63288d97914232..e6bf0844fbf3e4dd770b293bf01673f1be78c86d 100644 (file)
@@ -407,7 +407,8 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
  * when the DAI is being clocked by the CPU DAI. It's up to the
  * machine and cpu DAI driver to do this before we are called.
  */
-static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
+static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -439,7 +440,8 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
 }
 
 static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -477,7 +479,8 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream)
+static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -560,8 +563,6 @@ struct snd_soc_dai uda1380_dai[] = {
                .hw_params = uda1380_pcm_hw_params,
                .shutdown = uda1380_pcm_shutdown,
                .prepare = uda1380_pcm_prepare,
-       },
-       .dai_ops = {
                .digital_mute = uda1380_mute,
                .set_fmt = uda1380_set_dai_fmt,
        },
@@ -579,8 +580,6 @@ struct snd_soc_dai uda1380_dai[] = {
                .hw_params = uda1380_pcm_hw_params,
                .shutdown = uda1380_pcm_shutdown,
                .prepare = uda1380_pcm_prepare,
-       },
-       .dai_ops = {
                .digital_mute = uda1380_mute,
                .set_fmt = uda1380_set_dai_fmt,
        },
@@ -598,8 +597,6 @@ struct snd_soc_dai uda1380_dai[] = {
                .hw_params = uda1380_pcm_hw_params,
                .shutdown = uda1380_pcm_shutdown,
                .prepare = uda1380_pcm_prepare,
-       },
-       .dai_ops = {
                .set_fmt = uda1380_set_dai_fmt,
        },
 },
@@ -680,7 +677,7 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
        /* uda1380 init */
        uda1380_add_controls(codec);
        uda1380_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                pr_err("uda1380: failed to register card\n");
                goto card_err;
@@ -844,6 +841,18 @@ struct snd_soc_codec_device soc_codec_dev_uda1380 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
 
+static int __init uda1380_modinit(void)
+{
+       return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
+}
+module_init(uda1380_modinit);
+
+static void __exit uda1380_exit(void)
+{
+       snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
+}
+module_exit(uda1380_exit);
+
 MODULE_AUTHOR("Giorgio Padrin");
 MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
new file mode 100644 (file)
index 0000000..4bbfb5a
--- /dev/null
@@ -0,0 +1,1583 @@
+/*
+ * wm8350.c -- WM8350 ALSA SoC audio driver
+ *
+ * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
+ *
+ * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/wm8350/audio.h>
+#include <linux/mfd/wm8350/core.h>
+#include <linux/regulator/consumer.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8350.h"
+
+#define WM8350_OUTn_0dB 0x39
+
+#define WM8350_RAMP_NONE       0
+#define WM8350_RAMP_UP         1
+#define WM8350_RAMP_DOWN       2
+
+/* We only include the analogue supplies here; the digital supplies
+ * need to be available well before this driver can be probed.
+ */
+static const char *supply_names[] = {
+       "AVDD",
+       "HPVDD",
+};
+
+struct wm8350_output {
+       u16 active;
+       u16 left_vol;
+       u16 right_vol;
+       u16 ramp;
+       u16 mute;
+};
+
+struct wm8350_data {
+       struct snd_soc_codec codec;
+       struct wm8350_output out1;
+       struct wm8350_output out2;
+       struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
+};
+
+static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
+                                           unsigned int reg)
+{
+       struct wm8350 *wm8350 = codec->control_data;
+       return wm8350->reg_cache[reg];
+}
+
+static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
+                                     unsigned int reg)
+{
+       struct wm8350 *wm8350 = codec->control_data;
+       return wm8350_reg_read(wm8350, reg);
+}
+
+static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
+                             unsigned int value)
+{
+       struct wm8350 *wm8350 = codec->control_data;
+       return wm8350_reg_write(wm8350, reg, value);
+}
+
+/*
+ * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
+ */
+static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
+{
+       struct wm8350_data *wm8350_data = codec->private_data;
+       struct wm8350_output *out1 = &wm8350_data->out1;
+       struct wm8350 *wm8350 = codec->control_data;
+       int left_complete = 0, right_complete = 0;
+       u16 reg, val;
+
+       /* left channel */
+       reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
+       val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
+
+       if (out1->ramp == WM8350_RAMP_UP) {
+               /* ramp step up */
+               if (val < out1->left_vol) {
+                       val++;
+                       reg &= ~WM8350_OUT1L_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
+                                        reg | (val << WM8350_OUT1L_VOL_SHIFT));
+               } else
+                       left_complete = 1;
+       } else if (out1->ramp == WM8350_RAMP_DOWN) {
+               /* ramp step down */
+               if (val > 0) {
+                       val--;
+                       reg &= ~WM8350_OUT1L_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
+                                        reg | (val << WM8350_OUT1L_VOL_SHIFT));
+               } else
+                       left_complete = 1;
+       } else
+               return 1;
+
+       /* right channel */
+       reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
+       val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
+       if (out1->ramp == WM8350_RAMP_UP) {
+               /* ramp step up */
+               if (val < out1->right_vol) {
+                       val++;
+                       reg &= ~WM8350_OUT1R_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
+                                        reg | (val << WM8350_OUT1R_VOL_SHIFT));
+               } else
+                       right_complete = 1;
+       } else if (out1->ramp == WM8350_RAMP_DOWN) {
+               /* ramp step down */
+               if (val > 0) {
+                       val--;
+                       reg &= ~WM8350_OUT1R_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
+                                        reg | (val << WM8350_OUT1R_VOL_SHIFT));
+               } else
+                       right_complete = 1;
+       }
+
+       /* only hit the update bit if either volume has changed this step */
+       if (!left_complete || !right_complete)
+               wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
+
+       return left_complete & right_complete;
+}
+
+/*
+ * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
+ */
+static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
+{
+       struct wm8350_data *wm8350_data = codec->private_data;
+       struct wm8350_output *out2 = &wm8350_data->out2;
+       struct wm8350 *wm8350 = codec->control_data;
+       int left_complete = 0, right_complete = 0;
+       u16 reg, val;
+
+       /* left channel */
+       reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
+       val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
+       if (out2->ramp == WM8350_RAMP_UP) {
+               /* ramp step up */
+               if (val < out2->left_vol) {
+                       val++;
+                       reg &= ~WM8350_OUT2L_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
+                                        reg | (val << WM8350_OUT1L_VOL_SHIFT));
+               } else
+                       left_complete = 1;
+       } else if (out2->ramp == WM8350_RAMP_DOWN) {
+               /* ramp step down */
+               if (val > 0) {
+                       val--;
+                       reg &= ~WM8350_OUT2L_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
+                                        reg | (val << WM8350_OUT1L_VOL_SHIFT));
+               } else
+                       left_complete = 1;
+       } else
+               return 1;
+
+       /* right channel */
+       reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
+       val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
+       if (out2->ramp == WM8350_RAMP_UP) {
+               /* ramp step up */
+               if (val < out2->right_vol) {
+                       val++;
+                       reg &= ~WM8350_OUT2R_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
+                                        reg | (val << WM8350_OUT1R_VOL_SHIFT));
+               } else
+                       right_complete = 1;
+       } else if (out2->ramp == WM8350_RAMP_DOWN) {
+               /* ramp step down */
+               if (val > 0) {
+                       val--;
+                       reg &= ~WM8350_OUT2R_VOL_MASK;
+                       wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
+                                        reg | (val << WM8350_OUT1R_VOL_SHIFT));
+               } else
+                       right_complete = 1;
+       }
+
+       /* only hit the update bit if either volume has changed this step */
+       if (!left_complete || !right_complete)
+               wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
+
+       return left_complete & right_complete;
+}
+
+/*
+ * This work ramps both output PGAs at stream start/stop time to
+ * minimise pop associated with DAPM power switching.
+ * It's best to enable Zero Cross when ramping occurs to minimise any
+ * zipper noises.
+ */
+static void wm8350_pga_work(struct work_struct *work)
+{
+       struct snd_soc_codec *codec =
+           container_of(work, struct snd_soc_codec, delayed_work.work);
+       struct wm8350_data *wm8350_data = codec->private_data;
+       struct wm8350_output *out1 = &wm8350_data->out1,
+           *out2 = &wm8350_data->out2;
+       int i, out1_complete, out2_complete;
+
+       /* do we need to ramp at all ? */
+       if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
+               return;
+
+       /* PGA volumes have 6 bits of resolution to ramp */
+       for (i = 0; i <= 63; i++) {
+               out1_complete = 1, out2_complete = 1;
+               if (out1->ramp != WM8350_RAMP_NONE)
+                       out1_complete = wm8350_out1_ramp_step(codec);
+               if (out2->ramp != WM8350_RAMP_NONE)
+                       out2_complete = wm8350_out2_ramp_step(codec);
+
+               /* ramp finished ? */
+               if (out1_complete && out2_complete)
+                       break;
+
+               /* we need to delay longer on the up ramp */
+               if (out1->ramp == WM8350_RAMP_UP ||
+                   out2->ramp == WM8350_RAMP_UP) {
+                       /* delay is longer over 0dB as increases are larger */
+                       if (i >= WM8350_OUTn_0dB)
+                               schedule_timeout_interruptible(msecs_to_jiffies
+                                                              (2));
+                       else
+                               schedule_timeout_interruptible(msecs_to_jiffies
+                                                              (1));
+               } else
+                       udelay(50);     /* doesn't matter if we delay longer */
+       }
+
+       out1->ramp = WM8350_RAMP_NONE;
+       out2->ramp = WM8350_RAMP_NONE;
+}
+
+/*
+ * WM8350 Controls
+ */
+
+static int pga_event(struct snd_soc_dapm_widget *w,
+                    struct snd_kcontrol *kcontrol, int event)
+{
+       struct snd_soc_codec *codec = w->codec;
+       struct wm8350_data *wm8350_data = codec->private_data;
+       struct wm8350_output *out;
+
+       switch (w->shift) {
+       case 0:
+       case 1:
+               out = &wm8350_data->out1;
+               break;
+       case 2:
+       case 3:
+               out = &wm8350_data->out2;
+               break;
+
+       default:
+               BUG();
+               return -1;
+       }
+
+       switch (event) {
+       case SND_SOC_DAPM_POST_PMU:
+               out->ramp = WM8350_RAMP_UP;
+               out->active = 1;
+
+               if (!delayed_work_pending(&codec->delayed_work))
+                       schedule_delayed_work(&codec->delayed_work,
+                                             msecs_to_jiffies(1));
+               break;
+
+       case SND_SOC_DAPM_PRE_PMD:
+               out->ramp = WM8350_RAMP_DOWN;
+               out->active = 0;
+
+               if (!delayed_work_pending(&codec->delayed_work))
+                       schedule_delayed_work(&codec->delayed_work,
+                                             msecs_to_jiffies(1));
+               break;
+       }
+
+       return 0;
+}
+
+static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
+                                 struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8350_data *wm8350_priv = codec->private_data;
+       struct wm8350_output *out = NULL;
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       int ret;
+       unsigned int reg = mc->reg;
+       u16 val;
+
+       /* For OUT1 and OUT2 we shadow the values and only actually write
+        * them out when active in order to ensure the amplifier comes on
+        * as quietly as possible. */
+       switch (reg) {
+       case WM8350_LOUT1_VOLUME:
+               out = &wm8350_priv->out1;
+               break;
+       case WM8350_LOUT2_VOLUME:
+               out = &wm8350_priv->out2;
+               break;
+       default:
+               break;
+       }
+
+       if (out) {
+               out->left_vol = ucontrol->value.integer.value[0];
+               out->right_vol = ucontrol->value.integer.value[1];
+               if (!out->active)
+                       return 1;
+       }
+
+       ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
+       if (ret < 0)
+               return ret;
+
+       /* now hit the volume update bits (always bit 8) */
+       val = wm8350_codec_read(codec, reg);
+       wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
+       return 1;
+}
+
+static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
+                              struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+       struct wm8350_data *wm8350_priv = codec->private_data;
+       struct wm8350_output *out1 = &wm8350_priv->out1;
+       struct wm8350_output *out2 = &wm8350_priv->out2;
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+
+       /* If these are cached registers use the cache */
+       switch (reg) {
+       case WM8350_LOUT1_VOLUME:
+               ucontrol->value.integer.value[0] = out1->left_vol;
+               ucontrol->value.integer.value[1] = out1->right_vol;
+               return 0;
+
+       case WM8350_LOUT2_VOLUME:
+               ucontrol->value.integer.value[0] = out2->left_vol;
+               ucontrol->value.integer.value[1] = out2->right_vol;
+               return 0;
+
+       default:
+               break;
+       }
+
+       return snd_soc_get_volsw_2r(kcontrol, ucontrol);
+}
+
+/* double control with volume update */
+#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
+                               xinvert, tlv_array) \
+{      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+       .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+               SNDRV_CTL_ELEM_ACCESS_READWRITE | \
+               SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
+       .tlv.p = (tlv_array), \
+       .info = snd_soc_info_volsw_2r, \
+       .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
+       .private_value = (unsigned long)&(struct soc_mixer_control) \
+               {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
+                .rshift = xshift, .max = xmax, .invert = xinvert}, }
+
+static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
+static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
+static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
+static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
+static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
+static const char *wm8350_adcfilter[] = { "None", "High Pass" };
+static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
+static const char *wm8350_lr[] = { "Left", "Right" };
+
+static const struct soc_enum wm8350_enum[] = {
+       SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
+       SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
+       SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
+       SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
+       SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
+       SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
+       SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
+       SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
+       SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
+};
+
+static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525);
+static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600);
+static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
+static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
+static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
+
+static const unsigned int capture_sd_tlv[] = {
+       TLV_DB_RANGE_HEAD(2),
+       0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
+       13, 15, TLV_DB_SCALE_ITEM(0, 0, 0),
+};
+
+static const struct snd_kcontrol_new wm8350_snd_controls[] = {
+       SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
+       SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
+       SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume",
+                               WM8350_DAC_DIGITAL_VOLUME_L,
+                               WM8350_DAC_DIGITAL_VOLUME_R,
+                               0, 255, 0, dac_pcm_tlv),
+       SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
+       SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
+       SOC_ENUM("Playback PCM Filter", wm8350_enum[4]),
+       SOC_ENUM("Capture PCM Filter", wm8350_enum[5]),
+       SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]),
+       SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
+       SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
+                               WM8350_ADC_DIGITAL_VOLUME_L,
+                               WM8350_ADC_DIGITAL_VOLUME_R,
+                               0, 255, 0, adc_pcm_tlv),
+       SOC_DOUBLE_TLV("Capture Sidetone Volume",
+                      WM8350_ADC_DIVIDER,
+                      8, 4, 15, 1, capture_sd_tlv),
+       SOC_WM8350_DOUBLE_R_TLV("Capture Volume",
+                               WM8350_LEFT_INPUT_VOLUME,
+                               WM8350_RIGHT_INPUT_VOLUME,
+                               2, 63, 0, pre_amp_tlv),
+       SOC_DOUBLE_R("Capture ZC Switch",
+                    WM8350_LEFT_INPUT_VOLUME,
+                    WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
+       SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
+                      WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
+       SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
+                      WM8350_OUTPUT_LEFT_MIXER_VOLUME,
+                      5, 7, 0, out_mix_tlv),
+       SOC_SINGLE_TLV("Left Input Bypass Volume",
+                      WM8350_OUTPUT_LEFT_MIXER_VOLUME,
+                      9, 7, 0, out_mix_tlv),
+       SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
+                      WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
+                      1, 7, 0, out_mix_tlv),
+       SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
+                      WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
+                      5, 7, 0, out_mix_tlv),
+       SOC_SINGLE_TLV("Right Input Bypass Volume",
+                      WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
+                      13, 7, 0, out_mix_tlv),
+       SOC_SINGLE("Left Input Mixer +20dB Switch",
+                  WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
+       SOC_SINGLE("Right Input Mixer +20dB Switch",
+                  WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
+       SOC_SINGLE_TLV("Out4 Capture Volume",
+                      WM8350_INPUT_MIXER_VOLUME,
+                      1, 7, 0, out_mix_tlv),
+       SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume",
+                               WM8350_LOUT1_VOLUME,
+                               WM8350_ROUT1_VOLUME,
+                               2, 63, 0, out_pga_tlv),
+       SOC_DOUBLE_R("Out1 Playback ZC Switch",
+                    WM8350_LOUT1_VOLUME,
+                    WM8350_ROUT1_VOLUME, 13, 1, 0),
+       SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume",
+                               WM8350_LOUT2_VOLUME,
+                               WM8350_ROUT2_VOLUME,
+                               2, 63, 0, out_pga_tlv),
+       SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
+                    WM8350_ROUT2_VOLUME, 13, 1, 0),
+       SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
+       SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
+                      5, 7, 0, out_mix_tlv),
+
+       SOC_DOUBLE_R("Out1 Playback Switch",
+                    WM8350_LOUT1_VOLUME,
+                    WM8350_ROUT1_VOLUME,
+                    14, 1, 1),
+       SOC_DOUBLE_R("Out2 Playback Switch",
+                    WM8350_LOUT2_VOLUME,
+                    WM8350_ROUT2_VOLUME,
+                    14, 1, 1),
+};
+
+/*
+ * DAPM Controls
+ */
+
+/* Left Playback Mixer */
+static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Playback Switch",
+                       WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
+       SOC_DAPM_SINGLE("Left Bypass Switch",
+                       WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
+       SOC_DAPM_SINGLE("Right Playback Switch",
+                       WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
+       SOC_DAPM_SINGLE("Left Sidetone Switch",
+                       WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
+       SOC_DAPM_SINGLE("Right Sidetone Switch",
+                       WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
+};
+
+/* Right Playback Mixer */
+static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Playback Switch",
+                       WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
+       SOC_DAPM_SINGLE("Right Bypass Switch",
+                       WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
+       SOC_DAPM_SINGLE("Left Playback Switch",
+                       WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
+       SOC_DAPM_SINGLE("Left Sidetone Switch",
+                       WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
+       SOC_DAPM_SINGLE("Right Sidetone Switch",
+                       WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
+};
+
+/* Out4 Mixer */
+static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Right Playback Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
+       SOC_DAPM_SINGLE("Left Playback Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
+       SOC_DAPM_SINGLE("Right Capture Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
+       SOC_DAPM_SINGLE("Out3 Playback Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
+       SOC_DAPM_SINGLE("Right Mixer Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
+       SOC_DAPM_SINGLE("Left Mixer Switch",
+                       WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
+};
+
+/* Out3 Mixer */
+static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
+       SOC_DAPM_SINGLE("Left Playback Switch",
+                       WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
+       SOC_DAPM_SINGLE("Left Capture Switch",
+                       WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
+       SOC_DAPM_SINGLE("Out4 Playback Switch",
+                       WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
+       SOC_DAPM_SINGLE("Left Mixer Switch",
+                       WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
+};
+
+/* Left Input Mixer */
+static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
+       SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
+                           WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
+       SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
+                           WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
+       SOC_DAPM_SINGLE("PGA Capture Switch",
+                       WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
+};
+
+/* Right Input Mixer */
+static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
+       SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
+                           WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
+       SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
+                           WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
+       SOC_DAPM_SINGLE("PGA Capture Switch",
+                       WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
+};
+
+/* Left Mic Mixer */
+static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
+       SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
+       SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
+       SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
+};
+
+/* Right Mic Mixer */
+static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
+       SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
+       SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
+       SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
+};
+
+/* Beep Switch */
+static const struct snd_kcontrol_new wm8350_beep_switch_controls =
+SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
+
+/* Out4 Capture Mux */
+static const struct snd_kcontrol_new wm8350_out4_capture_controls =
+SOC_DAPM_ENUM("Route", wm8350_enum[8]);
+
+static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
+
+       SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
+       SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
+       SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
+                          0, pga_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
+                          pga_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
+                          0, pga_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
+                          pga_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+       SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
+                          7, 0, &wm8350_right_capt_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
+                          6, 0, &wm8350_left_capt_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
+                          &wm8350_out4_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_out4_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
+                          &wm8350_out3_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_out3_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
+                          &wm8350_right_play_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_right_play_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
+                          &wm8350_left_play_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_left_play_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
+                          &wm8350_left_mic_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
+
+       SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
+                          &wm8350_right_mic_mixer_controls[0],
+                          ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
+
+       /* virtual mixer for Beep and Out2R */
+       SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+       SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
+                           &wm8350_beep_switch_controls),
+
+       SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
+                        WM8350_POWER_MGMT_4, 3, 0),
+       SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
+                        WM8350_POWER_MGMT_4, 2, 0),
+       SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
+                        WM8350_POWER_MGMT_4, 5, 0),
+       SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
+                        WM8350_POWER_MGMT_4, 4, 0),
+
+       SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
+
+       SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
+                        &wm8350_out4_capture_controls),
+
+       SND_SOC_DAPM_OUTPUT("OUT1R"),
+       SND_SOC_DAPM_OUTPUT("OUT1L"),
+       SND_SOC_DAPM_OUTPUT("OUT2R"),
+       SND_SOC_DAPM_OUTPUT("OUT2L"),
+       SND_SOC_DAPM_OUTPUT("OUT3"),
+       SND_SOC_DAPM_OUTPUT("OUT4"),
+
+       SND_SOC_DAPM_INPUT("IN1RN"),
+       SND_SOC_DAPM_INPUT("IN1RP"),
+       SND_SOC_DAPM_INPUT("IN2R"),
+       SND_SOC_DAPM_INPUT("IN1LP"),
+       SND_SOC_DAPM_INPUT("IN1LN"),
+       SND_SOC_DAPM_INPUT("IN2L"),
+       SND_SOC_DAPM_INPUT("IN3R"),
+       SND_SOC_DAPM_INPUT("IN3L"),
+};
+
+static const struct snd_soc_dapm_route audio_map[] = {
+
+       /* left playback mixer */
+       {"Left Playback Mixer", "Playback Switch", "Left DAC"},
+       {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
+       {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
+       {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
+       {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
+
+       /* right playback mixer */
+       {"Right Playback Mixer", "Playback Switch", "Right DAC"},
+       {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
+       {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
+       {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
+       {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
+
+       /* out4 playback mixer */
+       {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
+       {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
+       {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
+       {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
+       {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
+       {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
+       {"OUT4", NULL, "Out4 Mixer"},
+
+       /* out3 playback mixer */
+       {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
+       {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
+       {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
+       {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
+       {"OUT3", NULL, "Out3 Mixer"},
+
+       /* out2 */
+       {"Right Out2 PGA", NULL, "Right Playback Mixer"},
+       {"Left Out2 PGA", NULL, "Left Playback Mixer"},
+       {"OUT2L", NULL, "Left Out2 PGA"},
+       {"OUT2R", NULL, "Right Out2 PGA"},
+
+       /* out1 */
+       {"Right Out1 PGA", NULL, "Right Playback Mixer"},
+       {"Left Out1 PGA", NULL, "Left Playback Mixer"},
+       {"OUT1L", NULL, "Left Out1 PGA"},
+       {"OUT1R", NULL, "Right Out1 PGA"},
+
+       /* ADCs */
+       {"Left ADC", NULL, "Left Capture Mixer"},
+       {"Right ADC", NULL, "Right Capture Mixer"},
+
+       /* Left capture mixer */
+       {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
+       {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
+       {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
+       {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
+
+       /* Right capture mixer */
+       {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
+       {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
+       {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
+       {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
+
+       /* L3 Inputs */
+       {"IN3L PGA", NULL, "IN3L"},
+       {"IN3R PGA", NULL, "IN3R"},
+
+       /* Left Mic mixer */
+       {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
+       {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
+       {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
+
+       /* Right Mic mixer */
+       {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
+       {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
+       {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
+
+       /* out 4 capture */
+       {"Out4 Capture Channel", NULL, "Out4 Mixer"},
+
+       /* Beep */
+       {"Beep", NULL, "IN3R PGA"},
+};
+
+static int wm8350_add_controls(struct snd_soc_codec *codec)
+{
+       int err, i;
+
+       for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) {
+               err = snd_ctl_add(codec->card,
+                                 snd_soc_cnew(&wm8350_snd_controls[i],
+                                              codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int wm8350_add_widgets(struct snd_soc_codec *codec)
+{
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(codec,
+                                       wm8350_dapm_widgets,
+                                       ARRAY_SIZE(wm8350_dapm_widgets));
+       if (ret != 0) {
+               dev_err(codec->dev, "dapm control register failed\n");
+               return ret;
+       }
+
+       /* set up audio paths */
+       ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+       if (ret != 0) {
+               dev_err(codec->dev, "DAPM route register failed\n");
+               return ret;
+       }
+
+       return snd_soc_dapm_new_widgets(codec);
+}
+
+static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+                                int clk_id, unsigned int freq, int dir)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct wm8350 *wm8350 = codec->control_data;
+       u16 fll_4;
+
+       switch (clk_id) {
+       case WM8350_MCLK_SEL_MCLK:
+               wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
+                                 WM8350_MCLK_SEL);
+               break;
+       case WM8350_MCLK_SEL_PLL_MCLK:
+       case WM8350_MCLK_SEL_PLL_DAC:
+       case WM8350_MCLK_SEL_PLL_ADC:
+       case WM8350_MCLK_SEL_PLL_32K:
+               wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
+                               WM8350_MCLK_SEL);
+               fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
+                   ~WM8350_FLL_CLK_SRC_MASK;
+               wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
+               break;
+       }
+
+       /* MCLK direction */
+       if (dir == WM8350_MCLK_DIR_OUT)
+               wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
+                               WM8350_MCLK_DIR);
+       else
+               wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
+                                 WM8350_MCLK_DIR);
+
+       return 0;
+}
+
+static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 val;
+
+       switch (div_id) {
+       case WM8350_ADC_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) &
+                   ~WM8350_ADC_CLKDIV_MASK;
+               wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div);
+               break;
+       case WM8350_DAC_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) &
+                   ~WM8350_DAC_CLKDIV_MASK;
+               wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
+               break;
+       case WM8350_BCLK_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
+                   ~WM8350_BCLK_DIV_MASK;
+               wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               break;
+       case WM8350_OPCLK_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
+                   ~WM8350_OPCLK_DIV_MASK;
+               wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               break;
+       case WM8350_SYS_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
+                   ~WM8350_MCLK_DIV_MASK;
+               wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
+               break;
+       case WM8350_DACLR_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
+                   ~WM8350_DACLRC_RATE_MASK;
+               wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div);
+               break;
+       case WM8350_ADCLR_CLKDIV:
+               val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
+                   ~WM8350_ADCLRC_RATE_MASK;
+               wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
+           ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
+       u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) &
+           ~WM8350_BCLK_MSTR;
+       u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
+           ~WM8350_DACLRC_ENA;
+       u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
+           ~WM8350_ADCLRC_ENA;
+
+       /* set master/slave audio interface */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               master |= WM8350_BCLK_MSTR;
+               dac_lrc |= WM8350_DACLRC_ENA;
+               adc_lrc |= WM8350_ADCLRC_ENA;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* interface format */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               iface |= 0x2 << 8;
+               break;
+       case SND_SOC_DAIFMT_RIGHT_J:
+               break;
+       case SND_SOC_DAIFMT_LEFT_J:
+               iface |= 0x1 << 8;
+               break;
+       case SND_SOC_DAIFMT_DSP_A:
+               iface |= 0x3 << 8;
+               break;
+       case SND_SOC_DAIFMT_DSP_B:
+               iface |= 0x3 << 8;      /* lg not sure which mode */
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* clock inversion */
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               iface |= WM8350_AIF_BCLK_INV;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               iface |= WM8350_AIF_LRCLK_INV;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
+       wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master);
+       wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
+       wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
+       return 0;
+}
+
+static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
+                             int cmd, struct snd_soc_dai *codec_dai)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
+           WM8350_BCLK_MSTR;
+       int enabled = 0;
+
+       /* Check that the DACs or ADCs are enabled since they are
+        * required for LRC in master mode. The DACs or ADCs need a
+        * valid audio path i.e. pin -> ADC or DAC -> pin before
+        * the LRC will be enabled in master mode. */
+       if (!master && cmd != SNDRV_PCM_TRIGGER_START)
+               return 0;
+
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+               enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
+                   (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
+       } else {
+               enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
+                   (WM8350_DACR_ENA | WM8350_DACL_ENA);
+       }
+
+       if (!enabled) {
+               dev_err(codec->dev,
+                      "%s: invalid audio path - no clocks available\n",
+                      __func__);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *codec_dai)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
+           ~WM8350_AIF_WL_MASK;
+
+       /* bit size */
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               iface |= 0x1 << 10;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               iface |= 0x2 << 10;
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               iface |= 0x3 << 10;
+               break;
+       }
+
+       wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
+       return 0;
+}
+
+static int wm8350_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       struct wm8350 *wm8350 = codec->control_data;
+
+       if (mute)
+               wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
+       else
+               wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
+       return 0;
+}
+
+/* FLL divisors */
+struct _fll_div {
+       int div;                /* FLL_OUTDIV */
+       int n;
+       int k;
+       int ratio;              /* FLL_FRATIO */
+};
+
+/* The size in bits of the fll divide multiplied by 10
+ * to allow rounding later */
+#define FIXED_FLL_SIZE ((1 << 16) * 10)
+
+static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
+                             unsigned int output)
+{
+       u64 Kpart;
+       unsigned int t1, t2, K, Nmod;
+
+       if (output >= 2815250 && output <= 3125000)
+               fll_div->div = 0x4;
+       else if (output >= 5625000 && output <= 6250000)
+               fll_div->div = 0x3;
+       else if (output >= 11250000 && output <= 12500000)
+               fll_div->div = 0x2;
+       else if (output >= 22500000 && output <= 25000000)
+               fll_div->div = 0x1;
+       else {
+               printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
+               return -EINVAL;
+       }
+
+       if (input > 48000)
+               fll_div->ratio = 1;
+       else
+               fll_div->ratio = 8;
+
+       t1 = output * (1 << (fll_div->div + 1));
+       t2 = input * fll_div->ratio;
+
+       fll_div->n = t1 / t2;
+       Nmod = t1 % t2;
+
+       if (Nmod) {
+               Kpart = FIXED_FLL_SIZE * (long long)Nmod;
+               do_div(Kpart, t2);
+               K = Kpart & 0xFFFFFFFF;
+
+               /* Check if we need to round */
+               if ((K % 10) >= 5)
+                       K += 5;
+
+               /* Move down to proper range now rounding is done */
+               K /= 10;
+               fll_div->k = K;
+       } else
+               fll_div->k = 0;
+
+       return 0;
+}
+
+static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
+                         int pll_id, unsigned int freq_in,
+                         unsigned int freq_out)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       struct wm8350 *wm8350 = codec->control_data;
+       struct _fll_div fll_div;
+       int ret = 0;
+       u16 fll_1, fll_4;
+
+       /* power down FLL - we need to do this for reconfiguration */
+       wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
+                         WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
+
+       if (freq_out == 0 || freq_in == 0)
+               return ret;
+
+       ret = fll_factors(&fll_div, freq_in, freq_out);
+       if (ret < 0)
+               return ret;
+       dev_dbg(wm8350->dev,
+               "FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
+               freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
+               fll_div.ratio);
+
+       /* set up N.K & dividers */
+       fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) &
+           ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
+       wm8350_codec_write(codec, WM8350_FLL_CONTROL_1,
+                          fll_1 | (fll_div.div << 8) | 0x50);
+       wm8350_codec_write(codec, WM8350_FLL_CONTROL_2,
+                          (fll_div.ratio << 11) | (fll_div.
+                                                   n & WM8350_FLL_N_MASK));
+       wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
+       fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
+           ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
+       wm8350_codec_write(codec, WM8350_FLL_CONTROL_4,
+                          fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
+                          (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
+
+       /* power FLL on */
+       wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
+       wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
+
+       return 0;
+}
+
+static int wm8350_set_bias_level(struct snd_soc_codec *codec,
+                                enum snd_soc_bias_level level)
+{
+       struct wm8350 *wm8350 = codec->control_data;
+       struct wm8350_data *priv = codec->private_data;
+       struct wm8350_audio_platform_data *platform =
+               wm8350->codec.platform_data;
+       u16 pm1;
+       int ret;
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+               pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
+                   ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
+               wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                pm1 | WM8350_VMID_50K |
+                                platform->codec_current_on << 14);
+               break;
+
+       case SND_SOC_BIAS_PREPARE:
+               pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
+               pm1 &= ~WM8350_VMID_MASK;
+               wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                pm1 | WM8350_VMID_50K);
+               break;
+
+       case SND_SOC_BIAS_STANDBY:
+               if (codec->bias_level == SND_SOC_BIAS_OFF) {
+                       ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
+                                                   priv->supplies);
+                       if (ret != 0)
+                               return ret;
+
+                       /* Enable the system clock */
+                       wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
+                                       WM8350_SYSCLK_ENA);
+
+                       /* mute DAC & outputs */
+                       wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
+                                       WM8350_DAC_MUTE_ENA);
+
+                       /* discharge cap memory */
+                       wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
+                                        platform->dis_out1 |
+                                        (platform->dis_out2 << 2) |
+                                        (platform->dis_out3 << 4) |
+                                        (platform->dis_out4 << 6));
+
+                       /* wait for discharge */
+                       schedule_timeout_interruptible(msecs_to_jiffies
+                                                      (platform->
+                                                       cap_discharge_msecs));
+
+                       /* enable antipop */
+                       wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
+                                        (platform->vmid_s_curve << 8));
+
+                       /* ramp up vmid */
+                       wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                        (platform->
+                                         codec_current_charge << 14) |
+                                        WM8350_VMID_5K | WM8350_VMIDEN |
+                                        WM8350_VBUFEN);
+
+                       /* wait for vmid */
+                       schedule_timeout_interruptible(msecs_to_jiffies
+                                                      (platform->
+                                                       vmid_charge_msecs));
+
+                       /* turn on vmid 300k  */
+                       pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
+                           ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
+                       pm1 |= WM8350_VMID_300K |
+                               (platform->codec_current_standby << 14);
+                       wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                        pm1);
+
+
+                       /* enable analogue bias */
+                       pm1 |= WM8350_BIASEN;
+                       wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
+
+                       /* disable antipop */
+                       wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
+
+               } else {
+                       /* turn on vmid 300k and reduce current */
+                       pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
+                           ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
+                       wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                        pm1 | WM8350_VMID_300K |
+                                        (platform->
+                                         codec_current_standby << 14));
+
+               }
+               break;
+
+       case SND_SOC_BIAS_OFF:
+
+               /* mute DAC & enable outputs */
+               wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
+
+               wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
+                               WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
+                               WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
+
+               /* enable anti pop S curve */
+               wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
+                                (platform->vmid_s_curve << 8));
+
+               /* turn off vmid  */
+               pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
+                   ~WM8350_VMIDEN;
+               wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
+
+               /* wait */
+               schedule_timeout_interruptible(msecs_to_jiffies
+                                              (platform->
+                                               vmid_discharge_msecs));
+
+               wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
+                                (platform->vmid_s_curve << 8) |
+                                platform->dis_out1 |
+                                (platform->dis_out2 << 2) |
+                                (platform->dis_out3 << 4) |
+                                (platform->dis_out4 << 6));
+
+               /* turn off VBuf and drain */
+               pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
+                   ~(WM8350_VBUFEN | WM8350_VMID_MASK);
+               wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
+                                pm1 | WM8350_OUTPUT_DRAIN_EN);
+
+               /* wait */
+               schedule_timeout_interruptible(msecs_to_jiffies
+                                              (platform->drain_msecs));
+
+               pm1 &= ~WM8350_BIASEN;
+               wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
+
+               /* disable anti-pop */
+               wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
+
+               wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
+                                 WM8350_OUT1L_ENA);
+               wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
+                                 WM8350_OUT1R_ENA);
+               wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
+                                 WM8350_OUT2L_ENA);
+               wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
+                                 WM8350_OUT2R_ENA);
+
+               /* disable clock gen */
+               wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
+                                 WM8350_SYSCLK_ENA);
+
+               regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
+                                      priv->supplies);
+               break;
+       }
+       codec->bias_level = level;
+       return 0;
+}
+
+static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
+       return 0;
+}
+
+static int wm8350_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
+               wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
+
+       return 0;
+}
+
+static struct snd_soc_codec *wm8350_codec;
+
+static int wm8350_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec;
+       struct wm8350 *wm8350;
+       struct wm8350_data *priv;
+       int ret;
+       struct wm8350_output *out1;
+       struct wm8350_output *out2;
+
+       BUG_ON(!wm8350_codec);
+
+       socdev->codec = wm8350_codec;
+       codec = socdev->codec;
+       wm8350 = codec->control_data;
+       priv = codec->private_data;
+
+       /* Enable the codec */
+       wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
+
+       /* Enable robust clocking mode in ADC */
+       wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
+       wm8350_codec_write(codec, 0xde, 0x13);
+       wm8350_codec_write(codec, WM8350_SECURITY, 0);
+
+       /* read OUT1 & OUT2 volumes */
+       out1 = &priv->out1;
+       out2 = &priv->out2;
+       out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
+                         WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
+       out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
+                          WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
+       out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
+                         WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
+       out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
+                          WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
+       wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
+       wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
+       wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
+       wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
+
+       /* Latch VU bits & mute */
+       wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
+                       WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
+       wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
+                       WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
+       wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
+                       WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
+       wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
+                       WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
+
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to create pcms\n");
+               return ret;
+       }
+
+       wm8350_add_controls(codec);
+       wm8350_add_widgets(codec);
+
+       wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to register card\n");
+               goto card_err;
+       }
+
+       return 0;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+       return ret;
+}
+
+static int wm8350_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+       struct wm8350 *wm8350 = codec->control_data;
+       int ret;
+
+       /* cancel any work waiting to be queued. */
+       ret = cancel_delayed_work(&codec->delayed_work);
+
+       /* if there was any work waiting then we run it now and
+        * wait for its completion */
+       if (ret) {
+               schedule_delayed_work(&codec->delayed_work, 0);
+               flush_scheduled_work();
+       }
+
+       wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
+
+       return 0;
+}
+
+#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
+
+#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+                       SNDRV_PCM_FMTBIT_S20_3LE |\
+                       SNDRV_PCM_FMTBIT_S24_LE)
+
+struct snd_soc_dai wm8350_dai = {
+       .name = "WM8350",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 1,
+               .channels_max = 2,
+               .rates = WM8350_RATES,
+               .formats = WM8350_FORMATS,
+       },
+       .capture = {
+                .stream_name = "Capture",
+                .channels_min = 1,
+                .channels_max = 2,
+                .rates = WM8350_RATES,
+                .formats = WM8350_FORMATS,
+        },
+       .ops = {
+                .hw_params = wm8350_pcm_hw_params,
+                .digital_mute = wm8350_mute,
+                .trigger = wm8350_pcm_trigger,
+                .set_fmt = wm8350_set_dai_fmt,
+                .set_sysclk = wm8350_set_dai_sysclk,
+                .set_pll = wm8350_set_fll,
+                .set_clkdiv = wm8350_set_clkdiv,
+        },
+};
+EXPORT_SYMBOL_GPL(wm8350_dai);
+
+struct snd_soc_codec_device soc_codec_dev_wm8350 = {
+       .probe =        wm8350_probe,
+       .remove =       wm8350_remove,
+       .suspend =      wm8350_suspend,
+       .resume =       wm8350_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
+
+static int wm8350_codec_probe(struct platform_device *pdev)
+{
+       struct wm8350 *wm8350 = platform_get_drvdata(pdev);
+       struct wm8350_data *priv;
+       struct snd_soc_codec *codec;
+       int ret, i;
+
+       if (wm8350->codec.platform_data == NULL) {
+               dev_err(&pdev->dev, "No audio platform data supplied\n");
+               return -EINVAL;
+       }
+
+       priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
+       if (priv == NULL)
+               return -ENOMEM;
+
+       for (i = 0; i < ARRAY_SIZE(supply_names); i++)
+               priv->supplies[i].supply = supply_names[i];
+
+       ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
+                                priv->supplies);
+       if (ret != 0)
+               goto err_priv;
+
+       codec = &priv->codec;
+       wm8350->codec.codec = codec;
+
+       wm8350_dai.dev = &pdev->dev;
+
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+       codec->dev = &pdev->dev;
+       codec->name = "WM8350";
+       codec->owner = THIS_MODULE;
+       codec->read = wm8350_codec_read;
+       codec->write = wm8350_codec_write;
+       codec->bias_level = SND_SOC_BIAS_OFF;
+       codec->set_bias_level = wm8350_set_bias_level;
+       codec->dai = &wm8350_dai;
+       codec->num_dai = 1;
+       codec->reg_cache_size = WM8350_MAX_REGISTER;
+       codec->private_data = priv;
+       codec->control_data = wm8350;
+
+       /* Put the codec into reset if it wasn't already */
+       wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
+
+       INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
+       ret = snd_soc_register_codec(codec);
+       if (ret != 0)
+               goto err_supply;
+
+       wm8350_codec = codec;
+
+       ret = snd_soc_register_dai(&wm8350_dai);
+       if (ret != 0)
+               goto err_codec;
+       return 0;
+
+err_codec:
+       snd_soc_unregister_codec(codec);
+err_supply:
+       regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
+err_priv:
+       kfree(priv);
+       wm8350_codec = NULL;
+       return ret;
+}
+
+static int wm8350_codec_remove(struct platform_device *pdev)
+{
+       struct wm8350 *wm8350 = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = wm8350->codec.codec;
+       struct wm8350_data *priv = codec->private_data;
+
+       snd_soc_unregister_dai(&wm8350_dai);
+       snd_soc_unregister_codec(codec);
+       regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
+       kfree(priv);
+       wm8350_codec = NULL;
+       return 0;
+}
+
+static struct platform_driver wm8350_codec_driver = {
+       .driver = {
+                  .name = "wm8350-codec",
+                  .owner = THIS_MODULE,
+                  },
+       .probe = wm8350_codec_probe,
+       .remove = __devexit_p(wm8350_codec_remove),
+};
+
+static __init int wm8350_init(void)
+{
+       return platform_driver_register(&wm8350_codec_driver);
+}
+module_init(wm8350_init);
+
+static __exit void wm8350_exit(void)
+{
+       platform_driver_unregister(&wm8350_codec_driver);
+}
+module_exit(wm8350_exit);
+
+MODULE_DESCRIPTION("ASoC WM8350 driver");
+MODULE_AUTHOR("Liam Girdwood");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-codec");
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
new file mode 100644 (file)
index 0000000..cc2887a
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * wm8350.h - WM8903 audio codec interface
+ *
+ * Copyright 2008 Wolfson Microelectronics PLC.
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ */
+
+#ifndef _WM8350_H
+#define _WM8350_H
+
+#include <sound/soc.h>
+
+extern struct snd_soc_dai wm8350_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8350;
+
+#endif
index d8ca2da8d634e5e2a827339f3f3939d196d89941..40f8238df7174d65b6c306fbd23e51d505a85d1c 100644 (file)
@@ -463,7 +463,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
 }
 
 static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -585,8 +586,6 @@ struct snd_soc_dai wm8510_dai = {
                .formats = WM8510_FORMATS,},
        .ops = {
                .hw_params = wm8510_pcm_hw_params,
-       },
-       .dai_ops = {
                .digital_mute = wm8510_mute,
                .set_fmt = wm8510_set_dai_fmt,
                .set_clkdiv = wm8510_set_dai_clkdiv,
@@ -659,7 +658,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
        wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        wm8510_add_controls(codec);
        wm8510_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8510: failed to register card\n");
                goto card_err;
@@ -890,6 +889,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8510 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
 
+static int __init wm8510_modinit(void)
+{
+       return snd_soc_register_dai(&wm8510_dai);
+}
+module_init(wm8510_modinit);
+
+static void __exit wm8510_exit(void)
+{
+       snd_soc_unregister_dai(&wm8510_dai);
+}
+module_exit(wm8510_exit);
+
 MODULE_DESCRIPTION("ASoC WM8510 driver");
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_LICENSE("GPL");
index 627ebfb4209b72b786ad66f992b0659491f8f74d..d004e5845298d2b8e6f4871629b75c78702e8724 100644 (file)
@@ -548,13 +548,13 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
  * Set PCM DAI bit size and sample rate.
  */
 static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_dai_link *dai = rtd->dai;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id);
+       u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
 
        paifb &= ~WM8580_AIF_LENGTH_MASK;
        /* bit size */
@@ -574,7 +574,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb);
+       wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
        return 0;
 }
 
@@ -798,8 +798,6 @@ struct snd_soc_dai wm8580_dai[] = {
                },
                .ops = {
                         .hw_params = wm8580_paif_hw_params,
-                },
-               .dai_ops = {
                         .set_fmt = wm8580_set_paif_dai_fmt,
                         .set_clkdiv = wm8580_set_dai_clkdiv,
                         .set_pll = wm8580_set_dai_pll,
@@ -818,8 +816,6 @@ struct snd_soc_dai wm8580_dai[] = {
                },
                .ops = {
                         .hw_params = wm8580_paif_hw_params,
-                },
-               .dai_ops = {
                         .set_fmt = wm8580_set_paif_dai_fmt,
                         .set_clkdiv = wm8580_set_dai_clkdiv,
                         .set_pll = wm8580_set_dai_pll,
@@ -873,7 +869,7 @@ static int wm8580_init(struct snd_soc_device *socdev)
        wm8580_add_controls(codec);
        wm8580_add_widgets(codec);
 
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8580: failed to register card\n");
                goto card_err;
@@ -900,85 +896,85 @@ static struct snd_soc_device *wm8580_socdev;
  *    low  = 0x1a
  *    high = 0x1b
  */
-static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
-
-/* Magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
 
-static struct i2c_driver wm8580_i2c_driver;
-static struct i2c_client client_template;
-
-static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
+static int wm8580_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = wm8580_socdev;
-       struct wm8580_setup_data *setup = socdev->codec_data;
        struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c;
        int ret;
 
-       if (addr != setup->i2c_address)
-               return -ENODEV;
-
-       client_template.adapter = adap;
-       client_template.addr = addr;
-
-       i2c =  kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
-               return -ENOMEM;
-       }
        i2c_set_clientdata(i2c, codec);
        codec->control_data = i2c;
 
-       ret = i2c_attach_client(i2c);
-       if (ret < 0) {
-               dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
-               goto err;
-       }
-
        ret = wm8580_init(socdev);
-       if (ret < 0) {
+       if (ret < 0)
                dev_err(&i2c->dev, "failed to initialise WM8580\n");
-               goto err;
-       }
-
-       return ret;
-
-err:
-       kfree(codec);
-       kfree(i2c);
        return ret;
 }
 
-static int wm8580_i2c_detach(struct i2c_client *client)
+static int wm8580_i2c_remove(struct i2c_client *client)
 {
        struct snd_soc_codec *codec = i2c_get_clientdata(client);
-       i2c_detach_client(client);
        kfree(codec->reg_cache);
-       kfree(client);
        return 0;
 }
 
-static int wm8580_i2c_attach(struct i2c_adapter *adap)
-{
-       return i2c_probe(adap, &addr_data, wm8580_codec_probe);
-}
+static const struct i2c_device_id wm8580_i2c_id[] = {
+       { "wm8580", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
 
-/* corgi i2c codec control layer */
 static struct i2c_driver wm8580_i2c_driver = {
        .driver = {
                .name = "WM8580 I2C Codec",
                .owner = THIS_MODULE,
        },
-       .attach_adapter = wm8580_i2c_attach,
-       .detach_client =  wm8580_i2c_detach,
-       .command =        NULL,
+       .probe =    wm8580_i2c_probe,
+       .remove =   wm8580_i2c_remove,
+       .id_table = wm8580_i2c_id,
 };
 
-static struct i2c_client client_template = {
-       .name =   "WM8580",
-       .driver = &wm8580_i2c_driver,
-};
+static int wm8580_add_i2c_device(struct platform_device *pdev,
+                                const struct wm8580_setup_data *setup)
+{
+       struct i2c_board_info info;
+       struct i2c_adapter *adapter;
+       struct i2c_client *client;
+       int ret;
+
+       ret = i2c_add_driver(&wm8580_i2c_driver);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "can't add i2c driver\n");
+               return ret;
+       }
+
+       memset(&info, 0, sizeof(struct i2c_board_info));
+       info.addr = setup->i2c_address;
+       strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
+
+       adapter = i2c_get_adapter(setup->i2c_bus);
+       if (!adapter) {
+               dev_err(&pdev->dev, "can't get i2c adapter %d\n",
+                       setup->i2c_bus);
+               goto err_driver;
+       }
+
+       client = i2c_new_device(adapter, &info);
+       i2c_put_adapter(adapter);
+       if (!client) {
+               dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
+                       (unsigned int)info.addr);
+               goto err_driver;
+       }
+
+       return 0;
+
+err_driver:
+       i2c_del_driver(&wm8580_i2c_driver);
+       return -ENODEV;
+}
 #endif
 
 static int wm8580_probe(struct platform_device *pdev)
@@ -1011,11 +1007,8 @@ static int wm8580_probe(struct platform_device *pdev)
 
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
        if (setup->i2c_address) {
-               normal_i2c[0] = setup->i2c_address;
                codec->hw_write = (hw_write_t)i2c_master_send;
-               ret = i2c_add_driver(&wm8580_i2c_driver);
-               if (ret != 0)
-                       printk(KERN_ERR "can't add i2c driver");
+               ret = wm8580_add_i2c_device(pdev, setup);
        }
 #else
                /* Add other interfaces here */
@@ -1034,6 +1027,7 @@ static int wm8580_remove(struct platform_device *pdev)
        snd_soc_free_pcms(socdev);
        snd_soc_dapm_free(socdev);
 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+       i2c_unregister_device(codec->control_data);
        i2c_del_driver(&wm8580_i2c_driver);
 #endif
        kfree(codec->private_data);
@@ -1048,6 +1042,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
 
+static int __init wm8580_modinit(void)
+{
+       return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
+}
+module_init(wm8580_modinit);
+
+static void __exit wm8580_exit(void)
+{
+       snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
+}
+module_exit(wm8580_exit);
+
 MODULE_DESCRIPTION("ASoC WM8580 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_LICENSE("GPL");
index 589ddaba21d777515545cc8a5f4b70ce3b366eea..09e4422f6f2fbfeda01f4d068b5eb13532a69a84 100644 (file)
@@ -29,6 +29,7 @@
 #define WM8580_CLKSRC_NONE 5
 
 struct wm8580_setup_data {
+       int i2c_bus;
        unsigned short i2c_address;
 };
 
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
new file mode 100644 (file)
index 0000000..80b1198
--- /dev/null
@@ -0,0 +1,585 @@
+/*
+ * wm8728.c  --  WM8728 ALSA SoC Audio driver
+ *
+ * Copyright 2008 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+
+#include "wm8728.h"
+
+struct snd_soc_codec_device soc_codec_dev_wm8728;
+
+/*
+ * We can't read the WM8728 register space so we cache them instead.
+ * Note that the defaults here aren't the physical defaults, we latch
+ * the volume update bits, mute the output and enable infinite zero
+ * detect.
+ */
+static const u16 wm8728_reg_defaults[] = {
+       0x1ff,
+       0x1ff,
+       0x001,
+       0x100,
+};
+
+static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
+       unsigned int reg)
+{
+       u16 *cache = codec->reg_cache;
+       BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
+       return cache[reg];
+}
+
+static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
+       u16 reg, unsigned int value)
+{
+       u16 *cache = codec->reg_cache;
+       BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
+       cache[reg] = value;
+}
+
+/*
+ * write to the WM8728 register space
+ */
+static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
+       unsigned int value)
+{
+       u8 data[2];
+
+       /* data is
+        *   D15..D9 WM8728 register offset
+        *   D8...D0 register data
+        */
+       data[0] = (reg << 1) | ((value >> 8) & 0x0001);
+       data[1] = value & 0x00ff;
+
+       wm8728_write_reg_cache(codec, reg, value);
+
+       if (codec->hw_write(codec->control_data, data, 2) == 2)
+               return 0;
+       else
+               return -EIO;
+}
+
+static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
+
+static const struct snd_kcontrol_new wm8728_snd_controls[] = {
+
+SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
+                0, 255, 0, wm8728_tlv),
+
+SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
+};
+
+static int wm8728_add_controls(struct snd_soc_codec *codec)
+{
+       int err, i;
+
+       for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) {
+               err = snd_ctl_add(codec->card,
+                                 snd_soc_cnew(&wm8728_snd_controls[i],
+                                               codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+/*
+ * DAPM controls.
+ */
+static const struct snd_soc_dapm_widget wm8728_dapm_widgets[] = {
+SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
+SND_SOC_DAPM_OUTPUT("VOUTL"),
+SND_SOC_DAPM_OUTPUT("VOUTR"),
+};
+
+static const struct snd_soc_dapm_route intercon[] = {
+       {"VOUTL", NULL, "DAC"},
+       {"VOUTR", NULL, "DAC"},
+};
+
+static int wm8728_add_widgets(struct snd_soc_codec *codec)
+{
+       snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
+                                 ARRAY_SIZE(wm8728_dapm_widgets));
+
+       snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
+
+       snd_soc_dapm_new_widgets(codec);
+
+       return 0;
+}
+
+static int wm8728_mute(struct snd_soc_dai *dai, int mute)
+{
+       struct snd_soc_codec *codec = dai->codec;
+       u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+
+       if (mute)
+               wm8728_write(codec, WM8728_DACCTL, mute_reg | 1);
+       else
+               wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1);
+
+       return 0;
+}
+
+static int wm8728_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+
+       dac &= ~0x18;
+
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+               break;
+       case SNDRV_PCM_FORMAT_S20_3LE:
+               dac |= 0x10;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               dac |= 0x08;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8728_write(codec, WM8728_DACCTL, dac);
+
+       return 0;
+}
+
+static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
+               unsigned int fmt)
+{
+       struct snd_soc_codec *codec = codec_dai->codec;
+       u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL);
+
+       /* Currently only I2S is supported by the driver, though the
+        * hardware is more flexible.
+        */
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               iface |= 1;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* The hardware only support full slave mode */
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+       case SND_SOC_DAIFMT_NB_NF:
+               iface &= ~0x22;
+               break;
+       case SND_SOC_DAIFMT_IB_NF:
+               iface |=  0x20;
+               iface &= ~0x02;
+               break;
+       case SND_SOC_DAIFMT_NB_IF:
+               iface |= 0x02;
+               iface &= ~0x20;
+               break;
+       case SND_SOC_DAIFMT_IB_IF:
+               iface |= 0x22;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       wm8728_write(codec, WM8728_IFCTL, iface);
+       return 0;
+}
+
+static int wm8728_set_bias_level(struct snd_soc_codec *codec,
+                                enum snd_soc_bias_level level)
+{
+       u16 reg;
+       int i;
+
+       switch (level) {
+       case SND_SOC_BIAS_ON:
+       case SND_SOC_BIAS_PREPARE:
+       case SND_SOC_BIAS_STANDBY:
+               if (codec->bias_level == SND_SOC_BIAS_OFF) {
+                       /* Power everything up... */
+                       reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+                       wm8728_write(codec, WM8728_DACCTL, reg & ~0x4);
+
+                       /* ..then sync in the register cache. */
+                       for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
+                               wm8728_write(codec, i,
+                                            wm8728_read_reg_cache(codec, i));
+               }
+               break;
+
+       case SND_SOC_BIAS_OFF:
+               reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
+               wm8728_write(codec, WM8728_DACCTL, reg | 0x4);
+               break;
+       }
+       codec->bias_level = level;
+       return 0;
+}
+
+#define WM8728_RATES (SNDRV_PCM_RATE_8000_192000)
+
+#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
+       SNDRV_PCM_FMTBIT_S24_LE)
+
+struct snd_soc_dai wm8728_dai = {
+       .name = "WM8728",
+       .playback = {
+               .stream_name = "Playback",
+               .channels_min = 2,
+               .channels_max = 2,
+               .rates = WM8728_RATES,
+               .formats = WM8728_FORMATS,
+       },
+       .ops = {
+                .hw_params = wm8728_hw_params,
+                .digital_mute = wm8728_mute,
+                .set_fmt = wm8728_set_dai_fmt,
+       }
+};
+EXPORT_SYMBOL_GPL(wm8728_dai);
+
+static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       return 0;
+}
+
+static int wm8728_resume(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       wm8728_set_bias_level(codec, codec->suspend_bias_level);
+
+       return 0;
+}
+
+/*
+ * initialise the WM8728 driver
+ * register the mixer and dsp interfaces with the kernel
+ */
+static int wm8728_init(struct snd_soc_device *socdev)
+{
+       struct snd_soc_codec *codec = socdev->codec;
+       int ret = 0;
+
+       codec->name = "WM8728";
+       codec->owner = THIS_MODULE;
+       codec->read = wm8728_read_reg_cache;
+       codec->write = wm8728_write;
+       codec->set_bias_level = wm8728_set_bias_level;
+       codec->dai = &wm8728_dai;
+       codec->num_dai = 1;
+       codec->bias_level = SND_SOC_BIAS_OFF;
+       codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
+       codec->reg_cache = kmemdup(wm8728_reg_defaults,
+                                  sizeof(wm8728_reg_defaults),
+                                  GFP_KERNEL);
+       if (codec->reg_cache == NULL)
+               return -ENOMEM;
+
+       /* register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               printk(KERN_ERR "wm8728: failed to create pcms\n");
+               goto pcm_err;
+       }
+
+       /* power on device */
+       wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
+       wm8728_add_controls(codec);
+       wm8728_add_widgets(codec);
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               printk(KERN_ERR "wm8728: failed to register card\n");
+               goto card_err;
+       }
+
+       return ret;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+pcm_err:
+       kfree(codec->reg_cache);
+       return ret;
+}
+
+static struct snd_soc_device *wm8728_socdev;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+
+/*
+ * WM8728 2 wire address is determined by GPIO5
+ * state during powerup.
+ *    low  = 0x1a
+ *    high = 0x1b
+ */
+
+static int wm8728_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+{
+       struct snd_soc_device *socdev = wm8728_socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       int ret;
+
+       i2c_set_clientdata(i2c, codec);
+       codec->control_data = i2c;
+
+       ret = wm8728_init(socdev);
+       if (ret < 0)
+               pr_err("failed to initialise WM8728\n");
+
+       return ret;
+}
+
+static int wm8728_i2c_remove(struct i2c_client *client)
+{
+       struct snd_soc_codec *codec = i2c_get_clientdata(client);
+       kfree(codec->reg_cache);
+       return 0;
+}
+
+static const struct i2c_device_id wm8728_i2c_id[] = {
+       { "wm8728", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
+
+static struct i2c_driver wm8728_i2c_driver = {
+       .driver = {
+               .name = "WM8728 I2C Codec",
+               .owner = THIS_MODULE,
+       },
+       .probe =    wm8728_i2c_probe,
+       .remove =   wm8728_i2c_remove,
+       .id_table = wm8728_i2c_id,
+};
+
+static int wm8728_add_i2c_device(struct platform_device *pdev,
+                                const struct wm8728_setup_data *setup)
+{
+       struct i2c_board_info info;
+       struct i2c_adapter *adapter;
+       struct i2c_client *client;
+       int ret;
+
+       ret = i2c_add_driver(&wm8728_i2c_driver);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "can't add i2c driver\n");
+               return ret;
+       }
+
+       memset(&info, 0, sizeof(struct i2c_board_info));
+       info.addr = setup->i2c_address;
+       strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
+
+       adapter = i2c_get_adapter(setup->i2c_bus);
+       if (!adapter) {
+               dev_err(&pdev->dev, "can't get i2c adapter %d\n",
+                       setup->i2c_bus);
+               goto err_driver;
+       }
+
+       client = i2c_new_device(adapter, &info);
+       i2c_put_adapter(adapter);
+       if (!client) {
+               dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
+                       (unsigned int)info.addr);
+               goto err_driver;
+       }
+
+       return 0;
+
+err_driver:
+       i2c_del_driver(&wm8728_i2c_driver);
+       return -ENODEV;
+}
+#endif
+
+#if defined(CONFIG_SPI_MASTER)
+static int __devinit wm8728_spi_probe(struct spi_device *spi)
+{
+       struct snd_soc_device *socdev = wm8728_socdev;
+       struct snd_soc_codec *codec = socdev->codec;
+       int ret;
+
+       codec->control_data = spi;
+
+       ret = wm8728_init(socdev);
+       if (ret < 0)
+               dev_err(&spi->dev, "failed to initialise WM8728\n");
+
+       return ret;
+}
+
+static int __devexit wm8728_spi_remove(struct spi_device *spi)
+{
+       return 0;
+}
+
+static struct spi_driver wm8728_spi_driver = {
+       .driver = {
+               .name   = "wm8728",
+               .bus    = &spi_bus_type,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = wm8728_spi_probe,
+       .remove         = __devexit_p(wm8728_spi_remove),
+};
+
+static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
+{
+       struct spi_transfer t;
+       struct spi_message m;
+       u8 msg[2];
+
+       if (len <= 0)
+               return 0;
+
+       msg[0] = data[0];
+       msg[1] = data[1];
+
+       spi_message_init(&m);
+       memset(&t, 0, (sizeof t));
+
+       t.tx_buf = &msg[0];
+       t.len = len;
+
+       spi_message_add_tail(&t, &m);
+       spi_sync(spi, &m);
+
+       return len;
+}
+#endif /* CONFIG_SPI_MASTER */
+
+static int wm8728_probe(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct wm8728_setup_data *setup;
+       struct snd_soc_codec *codec;
+       int ret = 0;
+
+       setup = socdev->codec_data;
+       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
+       if (codec == NULL)
+               return -ENOMEM;
+
+       socdev->codec = codec;
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+
+       wm8728_socdev = socdev;
+       ret = -ENODEV;
+
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+       if (setup->i2c_address) {
+               codec->hw_write = (hw_write_t)i2c_master_send;
+               ret = wm8728_add_i2c_device(pdev, setup);
+       }
+#endif
+#if defined(CONFIG_SPI_MASTER)
+       if (setup->spi) {
+               codec->hw_write = (hw_write_t)wm8728_spi_write;
+               ret = spi_register_driver(&wm8728_spi_driver);
+               if (ret != 0)
+                       printk(KERN_ERR "can't add spi driver");
+       }
+#endif
+
+       if (ret != 0)
+               kfree(codec);
+
+       return ret;
+}
+
+/* power down chip */
+static int wm8728_remove(struct platform_device *pdev)
+{
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_codec *codec = socdev->codec;
+
+       if (codec->control_data)
+               wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
+
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
+       i2c_unregister_device(codec->control_data);
+       i2c_del_driver(&wm8728_i2c_driver);
+#endif
+#if defined(CONFIG_SPI_MASTER)
+       spi_unregister_driver(&wm8728_spi_driver);
+#endif
+       kfree(codec);
+
+       return 0;
+}
+
+struct snd_soc_codec_device soc_codec_dev_wm8728 = {
+       .probe =        wm8728_probe,
+       .remove =       wm8728_remove,
+       .suspend =      wm8728_suspend,
+       .resume =       wm8728_resume,
+};
+EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
+
+static int __init wm8728_modinit(void)
+{
+       return snd_soc_register_dai(&wm8728_dai);
+}
+module_init(wm8728_modinit);
+
+static void __exit wm8728_exit(void)
+{
+       snd_soc_unregister_dai(&wm8728_dai);
+}
+module_exit(wm8728_exit);
+
+MODULE_DESCRIPTION("ASoC WM8728 driver");
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
new file mode 100644 (file)
index 0000000..d269c13
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * wm8728.h  --  WM8728 ASoC codec driver
+ *
+ * Copyright 2008 Wolfson Microelectronics plc
+ *
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _WM8728_H
+#define _WM8728_H
+
+#define WM8728_DACLVOL   0x00
+#define WM8728_DACRVOL   0x01
+#define WM8728_DACCTL    0x02
+#define WM8728_IFCTL     0x03
+
+struct wm8728_setup_data {
+       int            spi;
+       int            i2c_bus;
+       unsigned short i2c_address;
+};
+
+extern struct snd_soc_dai wm8728_dai;
+extern struct snd_soc_codec_device soc_codec_dev_wm8728;
+
+#endif
index 7f8a7e36b33e9124d0c3d924301d9cccb6cb9c5f..c444b9f2701ed7625baa550cc0030bf35d6d6712 100644 (file)
@@ -264,7 +264,8 @@ static inline int get_coeff(int mclk, int rate)
 }
 
 static int wm8731_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -293,7 +294,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
+static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
+                             struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -305,7 +307,8 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static void wm8731_shutdown(struct snd_pcm_substream *substream)
+static void wm8731_shutdown(struct snd_pcm_substream *substream,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -461,8 +464,6 @@ struct snd_soc_dai wm8731_dai = {
                .prepare = wm8731_pcm_prepare,
                .hw_params = wm8731_hw_params,
                .shutdown = wm8731_shutdown,
-       },
-       .dai_ops = {
                .digital_mute = wm8731_mute,
                .set_sysclk = wm8731_set_dai_sysclk,
                .set_fmt = wm8731_set_dai_fmt,
@@ -544,7 +545,7 @@ static int wm8731_init(struct snd_soc_device *socdev)
 
        wm8731_add_controls(codec);
        wm8731_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8731: failed to register card\n");
                goto card_err;
@@ -792,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
 
+static int __init wm8731_modinit(void)
+{
+       return snd_soc_register_dai(&wm8731_dai);
+}
+module_init(wm8731_modinit);
+
+static void __exit wm8731_exit(void)
+{
+       snd_soc_unregister_dai(&wm8731_dai);
+}
+module_exit(wm8731_exit);
+
 MODULE_DESCRIPTION("ASoC WM8731 driver");
 MODULE_AUTHOR("Richard Purdie");
 MODULE_LICENSE("GPL");
index 9b7296ee5b08fa541c6dfdbc44f9b5b8b31f92d6..5997fa68e0d58f08c1fb5af468e953bbb2a64ded 100644 (file)
@@ -614,7 +614,8 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
 }
 
 static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -709,8 +710,6 @@ struct snd_soc_dai wm8750_dai = {
                .formats = WM8750_FORMATS,},
        .ops = {
                .hw_params = wm8750_pcm_hw_params,
-       },
-       .dai_ops = {
                .digital_mute = wm8750_mute,
                .set_fmt = wm8750_set_dai_fmt,
                .set_sysclk = wm8750_set_dai_sysclk,
@@ -819,7 +818,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
 
        wm8750_add_controls(codec);
        wm8750_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8750: failed to register card\n");
                goto card_err;
@@ -1086,6 +1085,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8750 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
 
+static int __init wm8750_modinit(void)
+{
+       return snd_soc_register_dai(&wm8750_dai);
+}
+module_init(wm8750_modinit);
+
+static void __exit wm8750_exit(void)
+{
+       snd_soc_unregister_dai(&wm8750_dai);
+}
+module_exit(wm8750_exit);
+
 MODULE_DESCRIPTION("ASoC WM8750 driver");
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_LICENSE("GPL");
index d426eaa2218575b75004a48f86cfe9079d84fa21..6c21b50c93758f28c7aea6d59ae396405d232530 100644 (file)
@@ -922,7 +922,8 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
  * Set PCM DAI bit size and sample rate.
  */
 static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1155,7 +1156,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
  * Set PCM DAI bit size and sample rate.
  */
 static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1323,16 +1325,15 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
                .channels_min = 1,
                .channels_max = 2,
                .rates = WM8753_RATES,
-               .formats = WM8753_FORMATS,},
+               .formats = WM8753_FORMATS},
        .capture = { /* dummy for fast DAI switching */
                .stream_name = "Capture",
                .channels_min = 1,
                .channels_max = 2,
                .rates = WM8753_RATES,
-               .formats = WM8753_FORMATS,},
+               .formats = WM8753_FORMATS},
        .ops = {
-               .hw_params = wm8753_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8753_i2s_hw_params,
                .digital_mute = wm8753_mute,
                .set_fmt = wm8753_mode1h_set_dai_fmt,
                .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1356,8 +1357,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
                .rates = WM8753_RATES,
                .formats = WM8753_FORMATS,},
        .ops = {
-               .hw_params = wm8753_pcm_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8753_pcm_hw_params,
                .digital_mute = wm8753_mute,
                .set_fmt = wm8753_mode1v_set_dai_fmt,
                .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1385,8 +1385,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
                .rates = WM8753_RATES,
                .formats = WM8753_FORMATS,},
        .ops = {
-               .hw_params = wm8753_pcm_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8753_pcm_hw_params,
                .digital_mute = wm8753_mute,
                .set_fmt = wm8753_mode2_set_dai_fmt,
                .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1410,8 +1409,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
                .rates = WM8753_RATES,
                .formats = WM8753_FORMATS,},
        .ops = {
-               .hw_params = wm8753_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8753_i2s_hw_params,
                .digital_mute = wm8753_mute,
                .set_fmt = wm8753_mode3_4_set_dai_fmt,
                .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1439,8 +1437,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
                .rates = WM8753_RATES,
                .formats = WM8753_FORMATS,},
        .ops = {
-               .hw_params = wm8753_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8753_i2s_hw_params,
                .digital_mute = wm8753_mute,
                .set_fmt = wm8753_mode3_4_set_dai_fmt,
                .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1608,7 +1605,7 @@ static int wm8753_init(struct snd_soc_device *socdev)
 
        wm8753_add_controls(codec);
        wm8753_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8753: failed to register card\n");
                goto card_err;
@@ -1877,6 +1874,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8753 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
 
+static int __init wm8753_modinit(void)
+{
+       return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
+}
+module_init(wm8753_modinit);
+
+static void __exit wm8753_exit(void)
+{
+       snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
+}
+module_exit(wm8753_exit);
+
 MODULE_DESCRIPTION("ASoC WM8753 driver");
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_LICENSE("GPL");
index 3b326c9b55866bba7a81c1421329026bed290247..6767de10ded0a64ff008e7c1d039d42569b9a4e4 100644 (file)
 struct snd_soc_codec_device soc_codec_dev_wm8900;
 
 struct wm8900_priv {
+       struct snd_soc_codec codec;
+
+       u16 reg_cache[WM8900_MAXREG];
+
        u32 fll_in; /* FLL input frequency */
        u32 fll_out; /* FLL output frequency */
 };
@@ -727,7 +731,8 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
 }
 
 static int wm8900_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1117,8 +1122,6 @@ struct snd_soc_dai wm8900_dai = {
         },
        .ops = {
                .hw_params = wm8900_hw_params,
-        },
-       .dai_ops = {
                 .set_clkdiv = wm8900_set_dai_clkdiv,
                 .set_pll = wm8900_set_dai_pll,
                 .set_fmt = wm8900_set_dai_fmt,
@@ -1283,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
        return 0;
 }
 
-/*
- * initialise the WM8900 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8900_init(struct snd_soc_device *socdev)
+static struct snd_soc_codec *wm8900_codec;
+
+static int wm8900_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
 {
-       struct snd_soc_codec *codec = socdev->codec;
-       int ret = 0;
+       struct wm8900_priv *wm8900;
+       struct snd_soc_codec *codec;
        unsigned int reg;
-       struct i2c_client *i2c_client = socdev->codec->control_data;
+       int ret;
+
+       wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
+       if (wm8900 == NULL)
+               return -ENOMEM;
+
+       codec = &wm8900->codec;
+       codec->private_data = wm8900;
+       codec->reg_cache = &wm8900->reg_cache[0];
+       codec->reg_cache_size = WM8900_MAXREG;
+
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
 
        codec->name = "WM8900";
        codec->owner = THIS_MODULE;
@@ -1300,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
        codec->write = wm8900_write;
        codec->dai = &wm8900_dai;
        codec->num_dai = 1;
-       codec->reg_cache_size = WM8900_MAXREG;
-       codec->reg_cache = kmemdup(wm8900_reg_defaults,
-                                  sizeof(wm8900_reg_defaults), GFP_KERNEL);
-
-       if (codec->reg_cache == NULL)
-               return -ENOMEM;
+       codec->hw_write = (hw_write_t)i2c_master_send;
+       codec->control_data = i2c;
+       codec->set_bias_level = wm8900_set_bias_level;
+       codec->dev = &i2c->dev;
 
        reg = wm8900_read(codec, WM8900_REG_ID);
        if (reg != 0x8900) {
-               dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n",
-                       reg);
-               return -ENODEV;
-       }
-
-       codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
-       if (codec->private_data == NULL) {
-               ret = -ENOMEM;
-               goto priv_err;
+               dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
+               ret = -ENODEV;
+               goto err;
        }
 
        /* Read back from the chip */
        reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
        reg = (reg >> 12) & 0xf;
-       dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg);
+       dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
 
        wm8900_reset(codec);
 
+       /* Turn the chip on */
+       wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
+
        /* Latch the volume update bits */
        wm8900_write(codec, WM8900_REG_LINVOL,
                     wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1352,160 +1362,98 @@ static int wm8900_init(struct snd_soc_device *socdev)
        /* Set the DAC and mixer output bias */
        wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
 
-       /* Register pcms */
-       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
-       if (ret < 0) {
-               dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
-               goto pcm_err;
-       }
-
-       /* Turn the chip on */
-       codec->bias_level = SND_SOC_BIAS_OFF;
-       wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
-
-       wm8900_add_controls(codec);
-       wm8900_add_widgets(codec);
-
-       ret = snd_soc_register_card(socdev);
-       if (ret < 0) {
-               dev_err(&i2c_client->dev, "Failed to register card\n");
-               goto card_err;
-       }
-       return ret;
-
-card_err:
-       snd_soc_free_pcms(socdev);
-       snd_soc_dapm_free(socdev);
-pcm_err:
-       kfree(codec->reg_cache);
-priv_err:
-       kfree(codec->private_data);
-       return ret;
-}
+       wm8900_dai.dev = &i2c->dev;
 
-static struct snd_soc_device *wm8900_socdev;
+       wm8900_codec = codec;
 
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-
-static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
-
-/* Magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
-
-static struct i2c_driver wm8900_i2c_driver;
-static struct i2c_client client_template;
-
-/* If the i2c layer weren't so broken, we could pass this kind of data
-   around */
-static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
-{
-       struct snd_soc_device *socdev = wm8900_socdev;
-       struct wm8900_setup_data *setup = socdev->codec_data;
-       struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c;
-       int ret;
-
-       if (addr != setup->i2c_address)
-               return -ENODEV;
-
-       dev_err(&adap->dev, "Probe on %x\n", addr);
-
-       client_template.adapter = adap;
-       client_template.addr = addr;
-
-       i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
-       if (i2c == NULL) {
-               kfree(codec);
-               return -ENOMEM;
-       }
-       i2c_set_clientdata(i2c, codec);
-       codec->control_data = i2c;
-
-       ret = i2c_attach_client(i2c);
-       if (ret < 0) {
-               dev_err(&adap->dev,
-                       "failed to attach codec at addr %x\n", addr);
+       ret = snd_soc_register_codec(codec);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
                goto err;
        }
 
-       ret = wm8900_init(socdev);
-       if (ret < 0) {
-               dev_err(&adap->dev, "failed to initialise WM8900\n");
-               goto err;
+       ret = snd_soc_register_dai(&wm8900_dai);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
+               goto err_codec;
        }
+
        return ret;
 
+err_codec:
+       snd_soc_unregister_codec(codec);
 err:
-       kfree(codec);
-       kfree(i2c);
+       kfree(wm8900);
+       wm8900_codec = NULL;
        return ret;
 }
 
-static int wm8900_i2c_detach(struct i2c_client *client)
+static int wm8900_i2c_remove(struct i2c_client *client)
 {
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-       i2c_detach_client(client);
-       kfree(codec->reg_cache);
-       kfree(client);
+       snd_soc_unregister_dai(&wm8900_dai);
+       snd_soc_unregister_codec(wm8900_codec);
+
+       wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
+
+       wm8900_dai.dev = NULL;
+       kfree(wm8900_codec->private_data);
+       wm8900_codec = NULL;
+
        return 0;
 }
 
-static int wm8900_i2c_attach(struct i2c_adapter *adap)
-{
-       return i2c_probe(adap, &addr_data, wm8900_codec_probe);
-}
+static const struct i2c_device_id wm8900_i2c_id[] = {
+       { "wm8900", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
 
-/* corgi i2c codec control layer */
 static struct i2c_driver wm8900_i2c_driver = {
        .driver = {
-               .name = "WM8900 I2C codec",
+               .name = "WM8900",
                .owner = THIS_MODULE,
        },
-       .attach_adapter = wm8900_i2c_attach,
-       .detach_client =  wm8900_i2c_detach,
-       .command =        NULL,
-};
-
-static struct i2c_client client_template = {
-       .name =   "WM8900",
-       .driver = &wm8900_i2c_driver,
+       .probe = wm8900_i2c_probe,
+       .remove = wm8900_i2c_remove,
+       .id_table = wm8900_i2c_id,
 };
-#endif
 
 static int wm8900_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct wm8900_setup_data *setup;
        struct snd_soc_codec *codec;
        int ret = 0;
 
-       dev_info(&pdev->dev, "WM8900 Audio Codec\n");
-
-       setup = socdev->codec_data;
-       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-       if (codec == NULL)
-               return -ENOMEM;
-
-       mutex_init(&codec->mutex);
-       INIT_LIST_HEAD(&codec->dapm_widgets);
-       INIT_LIST_HEAD(&codec->dapm_paths);
+       if (!wm8900_codec) {
+               dev_err(&pdev->dev, "I2C client not yet instantiated\n");
+               return -ENODEV;
+       }
 
+       codec = wm8900_codec;
        socdev->codec = codec;
 
-       codec->set_bias_level = wm8900_set_bias_level;
+       /* Register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to register new PCMs\n");
+               goto pcm_err;
+       }
 
-       wm8900_socdev = socdev;
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-       if (setup->i2c_address) {
-               normal_i2c[0] = setup->i2c_address;
-               codec->hw_write = (hw_write_t)i2c_master_send;
-               ret = i2c_add_driver(&wm8900_i2c_driver);
-               if (ret != 0)
-                       printk(KERN_ERR "can't add i2c driver");
+       wm8900_add_controls(codec);
+       wm8900_add_widgets(codec);
+
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Failed to register card\n");
+               goto card_err;
        }
-#else
-#error Non-I2C interfaces not yet supported
-#endif
+
+       return ret;
+
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+pcm_err:
        return ret;
 }
 
@@ -1513,17 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
 static int wm8900_remove(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_codec *codec = socdev->codec;
-
-       if (codec->control_data)
-               wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
        snd_soc_free_pcms(socdev);
        snd_soc_dapm_free(socdev);
-#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
-       i2c_del_driver(&wm8900_i2c_driver);
-#endif
-       kfree(codec);
 
        return 0;
 }
@@ -1536,6 +1476,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8900 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
 
+static int __init wm8900_modinit(void)
+{
+       return i2c_add_driver(&wm8900_i2c_driver);
+}
+module_init(wm8900_modinit);
+
+static void __exit wm8900_exit(void)
+{
+       i2c_del_driver(&wm8900_i2c_driver);
+}
+module_exit(wm8900_exit);
+
 MODULE_DESCRIPTION("ASoC WM8900 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
 MODULE_LICENSE("GPL");
index ba450d99e9026c1114d90c402f3b3a6d37e13e0d..fd15007d10c7ec22950174758a9b688247eede08 100644 (file)
 #define WM8900_DAC_CLKDIV_5_5 0x14
 #define WM8900_DAC_CLKDIV_6   0x18
 
-#define WM8900_
-
-struct wm8900_setup_data {
-       unsigned short i2c_address;
-};
-
 extern struct snd_soc_dai wm8900_dai;
 extern struct snd_soc_codec_device soc_codec_dev_wm8900;
 
index ce40d78776058456782f5d723152250bfc79e681..bde74546db4a7050ee28e1617dc190390822fcc1 100644 (file)
 
 #include "wm8903.h"
 
-struct wm8903_priv {
-       int sysclk;
-
-       /* Reference counts */
-       int charge_pump_users;
-       int class_w_users;
-       int playback_active;
-       int capture_active;
-
-       struct snd_pcm_substream *master_substream;
-       struct snd_pcm_substream *slave_substream;
-};
-
 /* Register defaults at reset */
 static u16 wm8903_reg_defaults[] = {
        0x8903,     /* R0   - SW Reset and ID */
@@ -223,6 +210,23 @@ static u16 wm8903_reg_defaults[] = {
        0x0000,     /* R172 - Analogue Output Bias 0 */
 };
 
+struct wm8903_priv {
+       struct snd_soc_codec codec;
+       u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
+
+       int sysclk;
+
+       /* Reference counts */
+       int charge_pump_users;
+       int class_w_users;
+       int playback_active;
+       int capture_active;
+
+       struct snd_pcm_substream *master_substream;
+       struct snd_pcm_substream *slave_substream;
+};
+
+
 static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
                                                 unsigned int reg)
 {
@@ -360,6 +364,8 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
 static void wm8903_reset(struct snd_soc_codec *codec)
 {
        wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
+       memcpy(codec->reg_cache, wm8903_reg_defaults,
+              sizeof(wm8903_reg_defaults));
 }
 
 #define WM8903_OUTPUT_SHORT 0x8
@@ -392,6 +398,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
                break;
        default:
                BUG();
+               return -EINVAL;  /* Spurious warning from some compilers */
        }
 
        switch (w->shift) {
@@ -403,6 +410,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
                break;
        default:
                BUG();
+               return -EINVAL;  /* Spurious warning from some compilers */
        }
 
        if (event & SND_SOC_DAPM_PRE_PMU) {
@@ -773,14 +781,14 @@ static const struct snd_kcontrol_new left_output_mixer[] = {
 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
 SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
-SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
+SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0),
 };
 
 static const struct snd_kcontrol_new right_output_mixer[] = {
 SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
 SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
-SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
+SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 0, 1, 0),
 };
 
 static const struct snd_kcontrol_new left_speaker_mixer[] = {
@@ -788,7 +796,7 @@ SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
 SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
 SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
 SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
-               1, 1, 0),
+               0, 1, 0),
 };
 
 static const struct snd_kcontrol_new right_speaker_mixer[] = {
@@ -797,7 +805,7 @@ SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
 SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
                1, 1, 0),
 SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
-               1, 1, 0),
+               0, 1, 0),
 };
 
 static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
@@ -989,6 +997,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_STANDBY:
                if (codec->bias_level == SND_SOC_BIAS_OFF) {
+                       wm8903_write(codec, WM8903_CLOCK_RATES_2,
+                                    WM8903_CLK_SYS_ENA);
+
                        wm8903_run_sequence(codec, 0);
                        wm8903_sync_reg_cache(codec, codec->reg_cache);
 
@@ -1019,6 +1030,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
 
        case SND_SOC_BIAS_OFF:
                wm8903_run_sequence(codec, 32);
+               reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
+               reg &= ~WM8903_CLK_SYS_ENA;
+               wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
                break;
        }
 
@@ -1257,7 +1271,8 @@ static struct {
        { 0,      0 },
 };
 
-static int wm8903_startup(struct snd_pcm_substream *substream)
+static int wm8903_startup(struct snd_pcm_substream *substream,
+                         struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1298,7 +1313,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static void wm8903_shutdown(struct snd_pcm_substream *substream)
+static void wm8903_shutdown(struct snd_pcm_substream *substream,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1317,7 +1333,8 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream)
 }
 
 static int wm8903_hw_params(struct snd_pcm_substream *substream,
-                           struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1515,8 +1532,6 @@ struct snd_soc_dai wm8903_dai = {
                 .startup = wm8903_startup,
                 .shutdown = wm8903_shutdown,
                 .hw_params = wm8903_hw_params,
-       },
-       .dai_ops = {
                 .digital_mute = wm8903_digital_mute,
                 .set_fmt = wm8903_set_dai_fmt,
                 .set_sysclk = wm8903_set_dai_sysclk
@@ -1560,39 +1575,48 @@ static int wm8903_resume(struct platform_device *pdev)
        return 0;
 }
 
-/*
- * initialise the WM8903 driver
- * register the mixer and dsp interfaces with the kernel
- */
-static int wm8903_init(struct snd_soc_device *socdev)
+static struct snd_soc_codec *wm8903_codec;
+
+static int wm8903_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
 {
-       struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c = codec->control_data;
-       int ret = 0;
+       struct wm8903_priv *wm8903;
+       struct snd_soc_codec *codec;
+       int ret;
        u16 val;
 
-       val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
-       if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
-               dev_err(&i2c->dev,
-                       "Device with ID register %x is not a WM8903\n", val);
-               return -ENODEV;
-       }
+       wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
+       if (wm8903 == NULL)
+               return -ENOMEM;
+
+       codec = &wm8903->codec;
 
+       mutex_init(&codec->mutex);
+       INIT_LIST_HEAD(&codec->dapm_widgets);
+       INIT_LIST_HEAD(&codec->dapm_paths);
+
+       codec->dev = &i2c->dev;
        codec->name = "WM8903";
        codec->owner = THIS_MODULE;
        codec->read = wm8903_read;
        codec->write = wm8903_write;
+       codec->hw_write = (hw_write_t)i2c_master_send;
        codec->bias_level = SND_SOC_BIAS_OFF;
        codec->set_bias_level = wm8903_set_bias_level;
        codec->dai = &wm8903_dai;
        codec->num_dai = 1;
-       codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults);
-       codec->reg_cache = kmemdup(wm8903_reg_defaults,
-                                  sizeof(wm8903_reg_defaults),
-                                  GFP_KERNEL);
-       if (codec->reg_cache == NULL) {
-               dev_err(&i2c->dev, "Failed to allocate register cache\n");
-               return -ENOMEM;
+       codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
+       codec->reg_cache = &wm8903->reg_cache[0];
+       codec->private_data = wm8903;
+
+       i2c_set_clientdata(i2c, codec);
+       codec->control_data = i2c;
+
+       val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
+       if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
+               dev_err(&i2c->dev,
+                       "Device with ID register %x is not a WM8903\n", val);
+               return -ENODEV;
        }
 
        val = wm8903_read(codec, WM8903_REVISION_NUMBER);
@@ -1601,16 +1625,6 @@ static int wm8903_init(struct snd_soc_device *socdev)
 
        wm8903_reset(codec);
 
-       /* register pcms */
-       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
-       if (ret < 0) {
-               dev_err(&i2c->dev, "failed to create pcms\n");
-               goto pcm_err;
-       }
-
-       /* SYSCLK is required for pretty much anything */
-       wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
-
        /* power on device */
        wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
@@ -1645,47 +1659,45 @@ static int wm8903_init(struct snd_soc_device *socdev)
        val |= WM8903_DAC_MUTEMODE;
        wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
 
-       wm8903_add_controls(codec);
-       wm8903_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
-       if (ret < 0) {
-               dev_err(&i2c->dev, "wm8903: failed to register card\n");
-               goto card_err;
+       wm8903_dai.dev = &i2c->dev;
+       wm8903_codec = codec;
+
+       ret = snd_soc_register_codec(codec);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
+               goto err;
+       }
+
+       ret = snd_soc_register_dai(&wm8903_dai);
+       if (ret != 0) {
+               dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
+               goto err_codec;
        }
 
        return ret;
 
-card_err:
-       snd_soc_free_pcms(socdev);
-       snd_soc_dapm_free(socdev);
-pcm_err:
-       kfree(codec->reg_cache);
+err_codec:
+       snd_soc_unregister_codec(codec);
+err:
+       wm8903_codec = NULL;
+       kfree(wm8903);
        return ret;
 }
 
-static struct snd_soc_device *wm8903_socdev;
-
-static int wm8903_i2c_probe(struct i2c_client *i2c,
-                           const struct i2c_device_id *id)
+static int wm8903_i2c_remove(struct i2c_client *client)
 {
-       struct snd_soc_device *socdev = wm8903_socdev;
-       struct snd_soc_codec *codec = socdev->codec;
-       int ret;
+       struct snd_soc_codec *codec = i2c_get_clientdata(client);
 
-       i2c_set_clientdata(i2c, codec);
-       codec->control_data = i2c;
+       snd_soc_unregister_dai(&wm8903_dai);
+       snd_soc_unregister_codec(codec);
 
-       ret = wm8903_init(socdev);
-       if (ret < 0)
-               dev_err(&i2c->dev, "Device initialisation failed\n");
+       wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
 
-       return ret;
-}
+       kfree(codec->private_data);
+
+       wm8903_codec = NULL;
+       wm8903_dai.dev = NULL;
 
-static int wm8903_i2c_remove(struct i2c_client *client)
-{
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-       kfree(codec->reg_cache);
        return 0;
 }
 
@@ -1709,75 +1721,37 @@ static struct i2c_driver wm8903_i2c_driver = {
 static int wm8903_probe(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct wm8903_setup_data *setup;
-       struct snd_soc_codec *codec;
-       struct wm8903_priv *wm8903;
-       struct i2c_board_info board_info;
-       struct i2c_adapter *adapter;
-       struct i2c_client *i2c_client;
        int ret = 0;
 
-       setup = socdev->codec_data;
-
-       if (!setup->i2c_address) {
-               dev_err(&pdev->dev, "No codec address provided\n");
-               return -ENODEV;
+       if (!wm8903_codec) {
+               dev_err(&pdev->dev, "I2C device not yet probed\n");
+               goto err;
        }
 
-       codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
-       if (codec == NULL)
-               return -ENOMEM;
+       socdev->codec = wm8903_codec;
 
-       wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
-       if (wm8903 == NULL) {
-               ret = -ENOMEM;
-               goto err_codec;
+       /* register pcms */
+       ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "failed to create pcms\n");
+               goto err;
        }
 
-       codec->private_data = wm8903;
-       socdev->codec = codec;
-       mutex_init(&codec->mutex);
-       INIT_LIST_HEAD(&codec->dapm_widgets);
-       INIT_LIST_HEAD(&codec->dapm_paths);
-
-       wm8903_socdev = socdev;
+       wm8903_add_controls(socdev->codec);
+       wm8903_add_widgets(socdev->codec);
 
-       codec->hw_write = (hw_write_t)i2c_master_send;
-       ret = i2c_add_driver(&wm8903_i2c_driver);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "can't add i2c driver\n");
-               goto err_priv;
-       } else {
-               memset(&board_info, 0, sizeof(board_info));
-               strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
-               board_info.addr = setup->i2c_address;
-
-               adapter = i2c_get_adapter(setup->i2c_bus);
-               if (!adapter) {
-                       dev_err(&pdev->dev, "Can't get I2C bus %d\n",
-                               setup->i2c_bus);
-                       ret = -ENODEV;
-                       goto err_adapter;
-               }
-
-               i2c_client = i2c_new_device(adapter, &board_info);
-               i2c_put_adapter(adapter);
-               if (i2c_client == NULL) {
-                       dev_err(&pdev->dev,
-                               "I2C driver registration failed\n");
-                       ret = -ENODEV;
-                       goto err_adapter;
-               }
+       ret = snd_soc_init_card(socdev);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "wm8903: failed to register card\n");
+               goto card_err;
        }
 
        return ret;
 
-err_adapter:
-       i2c_del_driver(&wm8903_i2c_driver);
-err_priv:
-       kfree(codec->private_data);
-err_codec:
-       kfree(codec);
+card_err:
+       snd_soc_free_pcms(socdev);
+       snd_soc_dapm_free(socdev);
+err:
        return ret;
 }
 
@@ -1792,10 +1766,6 @@ static int wm8903_remove(struct platform_device *pdev)
 
        snd_soc_free_pcms(socdev);
        snd_soc_dapm_free(socdev);
-       i2c_unregister_device(socdev->codec->control_data);
-       i2c_del_driver(&wm8903_i2c_driver);
-       kfree(codec->private_data);
-       kfree(codec);
 
        return 0;
 }
@@ -1808,6 +1778,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8903 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
 
+static int __init wm8903_modinit(void)
+{
+       return i2c_add_driver(&wm8903_i2c_driver);
+}
+module_init(wm8903_modinit);
+
+static void __exit wm8903_exit(void)
+{
+       i2c_del_driver(&wm8903_i2c_driver);
+}
+module_exit(wm8903_exit);
+
 MODULE_DESCRIPTION("ASoC WM8903 driver");
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
 MODULE_LICENSE("GPL");
index cec622f2f66020c3a41923b440baad33fe6df225..0ea27e2b9963922b4da5899773f256c9b76813ce 100644 (file)
 extern struct snd_soc_dai wm8903_dai;
 extern struct snd_soc_codec_device soc_codec_dev_wm8903;
 
-struct wm8903_setup_data {
-       int i2c_bus;
-       int i2c_address;
-};
-
 #define WM8903_MCLK_DIV_2 1
 #define WM8903_CLK_SYS    2
 #define WM8903_BCLK       3
index f41a578ddd4fabe908053cee4b273a43155b0e77..88ead7f8dd98007cf4b909a06b30679ff65721d3 100644 (file)
@@ -541,7 +541,8 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
 }
 
 static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -634,8 +635,6 @@ struct snd_soc_dai wm8971_dai = {
                .formats = WM8971_FORMATS,},
        .ops = {
                .hw_params = wm8971_pcm_hw_params,
-       },
-       .dai_ops = {
                .digital_mute = wm8971_mute,
                .set_fmt = wm8971_set_dai_fmt,
                .set_sysclk = wm8971_set_dai_sysclk,
@@ -748,7 +747,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
 
        wm8971_add_controls(codec);
        wm8971_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8971: failed to register card\n");
                goto card_err;
@@ -936,6 +935,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8971 = {
 
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
 
+static int __init wm8971_modinit(void)
+{
+       return snd_soc_register_dai(&wm8971_dai);
+}
+module_init(wm8971_modinit);
+
+static void __exit wm8971_exit(void)
+{
+       snd_soc_unregister_dai(&wm8971_dai);
+}
+module_exit(wm8971_exit);
+
 MODULE_DESCRIPTION("ASoC WM8971 driver");
 MODULE_AUTHOR("Lab126");
 MODULE_LICENSE("GPL");
index 572d22b0880b5b1f1033e244cee6269831cd9216..5b5afc14447817ede31e23807af451f4def6e989 100644 (file)
@@ -106,6 +106,7 @@ static const u16 wm8990_reg[] = {
        0x0008,     /* R60 - PLL1 */
        0x0031,     /* R61 - PLL2 */
        0x0026,     /* R62 - PLL3 */
+       0x0000,     /* R63 - Driver internal */
 };
 
 /*
@@ -126,10 +127,9 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
        unsigned int reg, unsigned int value)
 {
        u16 *cache = codec->reg_cache;
-       BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
 
-       /* Reset register is uncached */
-       if (reg == 0)
+       /* Reset register and reserved registers are uncached */
+       if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1)
                return;
 
        cache[reg] = value;
@@ -1172,7 +1172,8 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
  * Set PCM DAI bit size and sample rate.
  */
 static int wm8990_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
@@ -1222,8 +1223,14 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
        switch (level) {
        case SND_SOC_BIAS_ON:
                break;
+
        case SND_SOC_BIAS_PREPARE:
+               /* VMID=2*50k */
+               val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
+                       ~WM8990_VMID_MODE_MASK;
+               wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
                break;
+
        case SND_SOC_BIAS_STANDBY:
                if (codec->bias_level == SND_SOC_BIAS_OFF) {
                        /* Enable all output discharge bits */
@@ -1272,10 +1279,17 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
 
                        /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
                        wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
-               } else {
-                       /* ON -> standby */
 
+                       /* Enable workaround for ADC clocking issue. */
+                       wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
+                       wm8990_write(codec, WM8990_EXT_CTL1, 0xa003);
+                       wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0);
                }
+
+               /* VMID=2*250k */
+               val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
+                       ~WM8990_VMID_MODE_MASK;
+               wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
                break;
 
        case SND_SOC_BIAS_OFF:
@@ -1349,8 +1363,7 @@ struct snd_soc_dai wm8990_dai = {
                .rates = WM8990_RATES,
                .formats = WM8990_FORMATS,},
        .ops = {
-               .hw_params = wm8990_hw_params,},
-       .dai_ops = {
+               .hw_params = wm8990_hw_params,
                .digital_mute = wm8990_mute,
                .set_fmt = wm8990_set_dai_fmt,
                .set_clkdiv = wm8990_set_dai_clkdiv,
@@ -1449,7 +1462,7 @@ static int wm8990_init(struct snd_soc_device *socdev)
 
        wm8990_add_controls(codec);
        wm8990_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm8990: failed to register card\n");
                goto card_err;
@@ -1630,6 +1643,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8990 = {
 };
 EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
 
+static int __init wm8990_modinit(void)
+{
+       return snd_soc_register_dai(&wm8990_dai);
+}
+module_init(wm8990_modinit);
+
+static void __exit wm8990_exit(void)
+{
+       snd_soc_unregister_dai(&wm8990_dai);
+}
+module_exit(wm8990_exit);
+
 MODULE_DESCRIPTION("ASoC WM8990 driver");
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_LICENSE("GPL");
index 0e192f3b07882a44cb7950486c3f8bacafa4a09f..7114ddc88b4ba5fb6c2dff17712b7b05c36ac39c 100644 (file)
@@ -80,8 +80,8 @@
 #define WM8990_PLL3                             0x3E
 #define WM8990_INTDRIVBITS                     0x3F
 
-#define WM8990_REGISTER_COUNT                   60
-#define WM8990_MAX_REGISTER                     0x3F
+#define WM8990_EXT_ACCESS_ENA                  0x75
+#define WM8990_EXT_CTL1                                0x7a
 
 /*
  * Field Definitions.
index ffb471e420e2e76718f931420135c8b99cf21864..af83d629078a47f2dbaac75d6d47036086b57ce1 100644 (file)
@@ -487,7 +487,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
        return 0;
 }
 
-static int ac97_prepare(struct snd_pcm_substream *substream)
+static int ac97_prepare(struct snd_pcm_substream *substream,
+                       struct snd_soc_dai *dai)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -507,7 +508,8 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
        return ac97_write(codec, reg, runtime->rate);
 }
 
-static int ac97_aux_prepare(struct snd_pcm_substream *substream)
+static int ac97_aux_prepare(struct snd_pcm_substream *substream,
+                           struct snd_soc_dai *dai)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -533,7 +535,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
 struct snd_soc_dai wm9712_dai[] = {
 {
        .name = "AC97 HiFi",
-       .type = SND_SOC_DAI_AC97_BUS,
+       .ac97_control = 1,
        .playback = {
                .stream_name = "HiFi Playback",
                .channels_min = 1,
@@ -688,7 +690,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
 
        ret = wm9712_reset(codec, 0);
        if (ret < 0) {
-               printk(KERN_ERR "AC97 link error\n");
+               printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
                goto reset_err;
        }
 
@@ -698,7 +700,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
        wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
        wm9712_add_controls(codec);
        wm9712_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0) {
                printk(KERN_ERR "wm9712: failed to register card\n");
                goto reset_err;
index 945b32ed98840039a93289c108c27fd69656a927..f3ca8aaf013944a33a9516f9c7fd9bbc690e17f0 100644 (file)
@@ -928,11 +928,10 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
 }
 
 static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = dai->codec;
        u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
 
        switch (params_format(params)) {
@@ -954,11 +953,10 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
+static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
+                                struct snd_soc_dai *dai)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_codec *codec = dai->codec;
        u16 status;
 
        /* Gracefully shut down the voice interface. */
@@ -969,12 +967,11 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
        ac97_write(codec, AC97_EXTENDED_MID, status);
 }
 
-static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
+static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
 {
+       struct snd_soc_codec *codec = dai->codec;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->codec;
        int reg;
        u16 vra;
 
@@ -989,12 +986,11 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
        return ac97_write(codec, reg, runtime->rate);
 }
 
-static int ac97_aux_prepare(struct snd_pcm_substream *substream)
+static int ac97_aux_prepare(struct snd_pcm_substream *substream,
+                           struct snd_soc_dai *dai)
 {
+       struct snd_soc_codec *codec = dai->codec;
        struct snd_pcm_runtime *runtime = substream->runtime;
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_device *socdev = rtd->socdev;
-       struct snd_soc_codec *codec = socdev->codec;
        u16 vra, xsle;
 
        vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -1028,7 +1024,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
 struct snd_soc_dai wm9713_dai[] = {
 {
        .name = "AC97 HiFi",
-       .type = SND_SOC_DAI_AC97_BUS,
+       .ac97_control = 1,
        .playback = {
                .stream_name = "HiFi Playback",
                .channels_min = 1,
@@ -1042,8 +1038,7 @@ struct snd_soc_dai wm9713_dai[] = {
                .rates = WM9713_RATES,
                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
        .ops = {
-               .prepare = ac97_hifi_prepare,},
-       .dai_ops = {
+               .prepare = ac97_hifi_prepare,
                .set_clkdiv = wm9713_set_dai_clkdiv,
                .set_pll = wm9713_set_dai_pll,},
        },
@@ -1056,8 +1051,7 @@ struct snd_soc_dai wm9713_dai[] = {
                .rates = WM9713_RATES,
                .formats = SNDRV_PCM_FMTBIT_S16_LE,},
        .ops = {
-               .prepare = ac97_aux_prepare,},
-       .dai_ops = {
+               .prepare = ac97_aux_prepare,
                .set_clkdiv = wm9713_set_dai_clkdiv,
                .set_pll = wm9713_set_dai_pll,},
        },
@@ -1077,8 +1071,7 @@ struct snd_soc_dai wm9713_dai[] = {
                .formats = WM9713_PCM_FORMATS,},
        .ops = {
                .hw_params = wm9713_pcm_hw_params,
-               .shutdown = wm9713_voiceshutdown,},
-       .dai_ops = {
+               .shutdown = wm9713_voiceshutdown,
                .set_clkdiv = wm9713_set_dai_clkdiv,
                .set_pll = wm9713_set_dai_pll,
                .set_fmt = wm9713_set_dai_fmt,
@@ -1097,6 +1090,8 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
        }
 
        soc_ac97_ops.reset(codec->ac97);
+       if (soc_ac97_ops.warm_reset)
+               soc_ac97_ops.warm_reset(codec->ac97);
        if (ac97_read(codec, 0) != wm9713_reg[0])
                return -EIO;
        return 0;
@@ -1240,7 +1235,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
        wm9713_reset(codec, 0);
        ret = wm9713_reset(codec, 1);
        if (ret < 0) {
-               printk(KERN_ERR "AC97 link error\n");
+               printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n");
                goto reset_err;
        }
 
@@ -1252,7 +1247,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
 
        wm9713_add_controls(codec);
        wm9713_add_widgets(codec);
-       ret = snd_soc_register_card(socdev);
+       ret = snd_soc_init_card(socdev);
        if (ret < 0)
                goto reset_err;
        return 0;
@@ -1288,7 +1283,6 @@ static int wm9713_soc_remove(struct platform_device *pdev)
        snd_soc_free_ac97_codec(codec);
        kfree(codec->private_data);
        kfree(codec->reg_cache);
-       kfree(codec->dai);
        kfree(codec);
        return 0;
 }
index 8f7e3383490246e81c66c4dc7b92849d768b804e..b502741692d6ba866047917046c04d267a3ac89f 100644 (file)
@@ -17,3 +17,13 @@ config SND_DAVINCI_SOC_EVM
        help
          Say Y if you want to add support for SoC audio on TI
          DaVinci EVM platform.
+
+config SND_DAVINCI_SOC_SFFSDR
+       tristate "SoC Audio support for SFFSDR"
+       depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR
+       select SND_DAVINCI_SOC_I2S
+       select SND_SOC_PCM3008
+       select SFFSDR_FPGA
+       help
+         Say Y if you want to add support for SoC audio on
+         Lyrtech SFFSDR board.
index ca772e5b463727b1a7bb32d22e845fdf634b7d17..ca8bae1fc3f6ff00b062dd42094bd4c7035fe619 100644 (file)
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
 
 # DAVINCI Machine Support
 snd-soc-evm-objs := davinci-evm.o
+snd-soc-sffsdr-objs := davinci-sffsdr.o
 
 obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
+obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
index 9e6062cd6b59957f6df964470a52b8756f7f9398..d87b91179cc882f5369169d47f2c2b88d1cd98b8 100644 (file)
@@ -128,8 +128,9 @@ static struct snd_soc_dai_link evm_dai = {
 };
 
 /* davinci-evm audio machine driver */
-static struct snd_soc_machine snd_soc_machine_evm = {
+static struct snd_soc_card snd_soc_card_evm = {
        .name = "DaVinci EVM",
+       .platform = &davinci_soc_platform,
        .dai_link = &evm_dai,
        .num_links = 1,
 };
@@ -142,8 +143,7 @@ static struct aic3x_setup_data evm_aic3x_setup = {
 
 /* evm audio subsystem */
 static struct snd_soc_device evm_snd_devdata = {
-       .machine = &snd_soc_machine_evm,
-       .platform = &davinci_soc_platform,
+       .card = &snd_soc_card_evm,
        .codec_dev = &soc_codec_dev_aic3x,
        .codec_data = &evm_aic3x_setup,
 };
index abb5fedb0b1e0952ecb17fedb7592ab966c0ffda..81ff5c37ab56df34e3ea044da920a632079fe122 100644 (file)
@@ -59,6 +59,7 @@
 #define DAVINCI_MCBSP_PCR_CLKXP                (1 << 1)
 #define DAVINCI_MCBSP_PCR_FSRP         (1 << 2)
 #define DAVINCI_MCBSP_PCR_FSXP         (1 << 3)
+#define DAVINCI_MCBSP_PCR_SCLKME       (1 << 7)
 #define DAVINCI_MCBSP_PCR_CLKRM                (1 << 8)
 #define DAVINCI_MCBSP_PCR_CLKXM                (1 << 9)
 #define DAVINCI_MCBSP_PCR_FSRM         (1 << 10)
@@ -110,16 +111,59 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
+       struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_platform *platform = socdev->card->platform;
        u32 w;
+       int ret;
 
        /* Start the sample generator and enable transmitter/receiver */
        w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
        MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               /* Stop the DMA to avoid data loss */
+               /* while the transmitter is out of reset to handle XSYNCERR */
+               if (platform->pcm_ops->trigger) {
+                       ret = platform->pcm_ops->trigger(substream,
+                               SNDRV_PCM_TRIGGER_STOP);
+                       if (ret < 0)
+                               printk(KERN_DEBUG "Playback DMA stop failed\n");
+               }
+
+               /* Enable the transmitter */
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
                MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
-       else
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+
+               /* wait for any unexpected frame sync error to occur */
+               udelay(100);
+
+               /* Disable the transmitter to clear any outstanding XSYNCERR */
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+               MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+
+               /* Restart the DMA */
+               if (platform->pcm_ops->trigger) {
+                       ret = platform->pcm_ops->trigger(substream,
+                               SNDRV_PCM_TRIGGER_START);
+                       if (ret < 0)
+                               printk(KERN_DEBUG "Playback DMA start failed\n");
+               }
+               /* Enable the transmitter */
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+               MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+
+       } else {
+
+               /* Enable the reciever */
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
                MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+       }
+
 
        /* Start frame sync */
        w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -144,7 +188,8 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
        davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
 }
 
-static int davinci_i2s_startup(struct snd_pcm_substream *substream)
+static int davinci_i2s_startup(struct snd_pcm_substream *substream,
+                              struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -171,6 +216,16 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG,
                                        DAVINCI_MCBSP_SRGR_FSGM);
                break;
+       case SND_SOC_DAIFMT_CBM_CFS:
+               /* McBSP CLKR pin is the input for the Sample Rate Generator.
+                * McBSP FSR and FSX are driven by the Sample Rate Generator. */
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG,
+                                       DAVINCI_MCBSP_PCR_SCLKME |
+                                       DAVINCI_MCBSP_PCR_FSXM |
+                                       DAVINCI_MCBSP_PCR_FSRM);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG,
+                                       DAVINCI_MCBSP_SRGR_FSGM);
+               break;
        case SND_SOC_DAIFMT_CBM_CFM:
                davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 0);
                break;
@@ -205,11 +260,34 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
                return -EINVAL;
        }
 
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_RIGHT_J:
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG,
+                                       DAVINCI_MCBSP_RCR_RFRLEN1(1) |
+                                       DAVINCI_MCBSP_RCR_RDATDLY(0));
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG,
+                                       DAVINCI_MCBSP_XCR_XFRLEN1(1) |
+                                       DAVINCI_MCBSP_XCR_XDATDLY(0) |
+                                       DAVINCI_MCBSP_XCR_XFIG);
+               break;
+       case SND_SOC_DAIFMT_I2S:
+       default:
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG,
+                                       DAVINCI_MCBSP_RCR_RFRLEN1(1) |
+                                       DAVINCI_MCBSP_RCR_RDATDLY(1));
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG,
+                                       DAVINCI_MCBSP_XCR_XFRLEN1(1) |
+                                       DAVINCI_MCBSP_XCR_XDATDLY(1) |
+                                       DAVINCI_MCBSP_XCR_XFIG);
+               break;
+       }
+
        return 0;
 }
 
 static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
@@ -219,17 +297,14 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
        u32 w;
 
        /* general line settings */
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG,
-                               DAVINCI_MCBSP_SPCR_RINTM(3) |
-                               DAVINCI_MCBSP_SPCR_XINTM(3) |
-                               DAVINCI_MCBSP_SPCR_FREE);
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG,
-                               DAVINCI_MCBSP_RCR_RFRLEN1(1) |
-                               DAVINCI_MCBSP_RCR_RDATDLY(1));
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG,
-                               DAVINCI_MCBSP_XCR_XFRLEN1(1) |
-                               DAVINCI_MCBSP_XCR_XDATDLY(1) |
-                               DAVINCI_MCBSP_XCR_XFIG);
+       w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+               w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+       } else {
+               w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
+       }
 
        i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
        w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG);
@@ -260,20 +335,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG);
-       MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
-                      DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
+       if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG);
+               MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
+                              DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
 
-       w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG);
-       MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
-                      DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1);
-       davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
+       } else {
+               w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG);
+               MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
+                              DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1);
+               davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
 
+       }
        return 0;
 }
 
-static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *dai)
 {
        int ret = 0;
 
@@ -299,8 +378,8 @@ static int davinci_i2s_probe(struct platform_device *pdev,
                             struct snd_soc_dai *dai)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
        struct davinci_mcbsp_dev *dev;
        struct resource *mem, *ioarea;
        struct evm_snd_platform_data *pdata;
@@ -361,8 +440,8 @@ static void davinci_i2s_remove(struct platform_device *pdev,
                               struct snd_soc_dai *dai)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
        struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
        struct resource *mem;
 
@@ -381,7 +460,6 @@ static void davinci_i2s_remove(struct platform_device *pdev,
 struct snd_soc_dai davinci_i2s_dai = {
        .name = "davinci-i2s",
        .id = 0,
-       .type = SND_SOC_DAI_I2S,
        .probe = davinci_i2s_probe,
        .remove = davinci_i2s_remove,
        .playback = {
@@ -397,13 +475,24 @@ struct snd_soc_dai davinci_i2s_dai = {
        .ops = {
                .startup = davinci_i2s_startup,
                .trigger = davinci_i2s_trigger,
-               .hw_params = davinci_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = davinci_i2s_hw_params,
                .set_fmt = davinci_i2s_set_dai_fmt,
        },
 };
 EXPORT_SYMBOL_GPL(davinci_i2s_dai);
 
+static int __init davinci_i2s_init(void)
+{
+       return snd_soc_register_dai(&davinci_i2s_dai);
+}
+module_init(davinci_i2s_init);
+
+static void __exit davinci_i2s_exit(void)
+{
+       snd_soc_unregister_dai(&davinci_i2s_dai);
+}
+module_exit(davinci_i2s_exit);
+
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
 MODULE_LICENSE("GPL");
index 76feaa657375e3579cee33db8528a3d6e57f4da6..74abc9b4f1ccd6e9277166873047499bb39c8380 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/dma-mapping.h>
+#include <linux/kernel.h>
 
 #include <sound/core.h>
 #include <sound/pcm.h>
 
 #include "davinci-pcm.h"
 
-#define DAVINCI_PCM_DEBUG 0
-#if DAVINCI_PCM_DEBUG
-#define DPRINTK(x...) printk(KERN_DEBUG x)
-#else
-#define DPRINTK(x...)
-#endif
-
 static struct snd_pcm_hardware davinci_pcm_hardware = {
        .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
                 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
@@ -78,8 +72,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
        dma_offset = prtd->period * period_size;
        dma_pos = runtime->dma_addr + dma_offset;
 
-       DPRINTK("audio_set_dma_params_play channel = %d dma_ptr = %x "
-               "period_size=%x\n", lch, dma_pos, period_size);
+       pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
+               "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size);
 
        data_type = prtd->params->data_type;
        count = period_size / data_type;
@@ -112,7 +106,7 @@ static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
        struct snd_pcm_substream *substream = data;
        struct davinci_runtime_data *prtd = substream->runtime->private_data;
 
-       DPRINTK("lch=%d, status=0x%x\n", lch, ch_status);
+       pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status);
 
        if (unlikely(ch_status != DMA_COMPLETE))
                return;
@@ -316,8 +310,8 @@ static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
        buf->area = dma_alloc_writecombine(pcm->card->dev, size,
                                           &buf->addr, GFP_KERNEL);
 
-       DPRINTK("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
-               (void *) buf->area, (void *) buf->addr, size);
+       pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
+               "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
 
        if (!buf->area)
                return -ENOMEM;
@@ -384,6 +378,18 @@ struct snd_soc_platform davinci_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(davinci_soc_platform);
 
+static int __init davinci_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&davinci_soc_platform);
+}
+module_init(davinci_soc_platform_init);
+
+static void __exit davinci_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&davinci_soc_platform);
+}
+module_exit(davinci_soc_platform_exit);
+
 MODULE_AUTHOR("Vladimir Barinov");
 MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
new file mode 100644 (file)
index 0000000..f67579d
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * ASoC driver for Lyrtech SFFSDR board.
+ *
+ * Author:     Hugo Villeneuve
+ * Copyright (C) 2008 Lyrtech inc
+ *
+ * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
+ * Copyright:   (C) 2007 MontaVista Software, Inc., <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/dma.h>
+#include <asm/plat-sffsdr/sffsdr-fpga.h>
+
+#include <mach/mcbsp.h>
+#include <mach/edma.h>
+
+#include "../codecs/pcm3008.h"
+#include "davinci-pcm.h"
+#include "davinci-i2s.h"
+
+static int sffsdr_hw_params(struct snd_pcm_substream *substream,
+                           struct snd_pcm_hw_params *params,
+                           struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int fs;
+       int ret = 0;
+
+       /* Set cpu DAI configuration:
+        * CLKX and CLKR are the inputs for the Sample Rate Generator.
+        * FSX and FSR are outputs, driven by the sample Rate Generator. */
+       ret = snd_soc_dai_set_fmt(cpu_dai,
+                                 SND_SOC_DAIFMT_RIGHT_J |
+                                 SND_SOC_DAIFMT_CBM_CFS |
+                                 SND_SOC_DAIFMT_IB_NF);
+       if (ret < 0)
+               return ret;
+
+       /* Fsref can be 32000, 44100 or 48000. */
+       fs = params_rate(params);
+
+       pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
+
+       return sffsdr_fpga_set_codec_fs(fs);
+}
+
+static struct snd_soc_ops sffsdr_ops = {
+       .hw_params = sffsdr_hw_params,
+};
+
+/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link sffsdr_dai = {
+       .name = "PCM3008", /* Codec name */
+       .stream_name = "PCM3008 HiFi",
+       .cpu_dai = &davinci_i2s_dai,
+       .codec_dai = &pcm3008_dai,
+       .ops = &sffsdr_ops,
+};
+
+/* davinci-sffsdr audio machine driver */
+static struct snd_soc_card snd_soc_sffsdr = {
+       .name = "DaVinci SFFSDR",
+       .platform = &davinci_soc_platform,
+       .dai_link = &sffsdr_dai,
+       .num_links = 1,
+};
+
+/* sffsdr audio private data */
+static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
+       .dem0_pin = GPIO(45),
+       .dem1_pin = GPIO(46),
+       .pdad_pin = GPIO(47),
+       .pdda_pin = GPIO(38),
+};
+
+/* sffsdr audio subsystem */
+static struct snd_soc_device sffsdr_snd_devdata = {
+       .card = &snd_soc_sffsdr,
+       .codec_dev = &soc_codec_dev_pcm3008,
+       .codec_data = &sffsdr_pcm3008_setup,
+};
+
+static struct resource sffsdr_snd_resources[] = {
+       {
+               .start = DAVINCI_MCBSP_BASE,
+               .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+static struct evm_snd_platform_data sffsdr_snd_data = {
+       .tx_dma_ch      = DAVINCI_DMA_MCBSP_TX,
+       .rx_dma_ch      = DAVINCI_DMA_MCBSP_RX,
+};
+
+static struct platform_device *sffsdr_snd_device;
+
+static int __init sffsdr_init(void)
+{
+       int ret;
+
+       sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
+       if (!sffsdr_snd_device) {
+               printk(KERN_ERR "platform device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata);
+       sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
+       sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data;
+
+       ret = platform_device_add_resources(sffsdr_snd_device,
+                                           sffsdr_snd_resources,
+                                           ARRAY_SIZE(sffsdr_snd_resources));
+       if (ret) {
+               printk(KERN_ERR "platform device add ressources failed\n");
+               goto error;
+       }
+
+       ret = platform_device_add(sffsdr_snd_device);
+       if (ret)
+               goto error;
+
+       return ret;
+
+error:
+       platform_device_put(sffsdr_snd_device);
+       return ret;
+}
+
+static void __exit sffsdr_exit(void)
+{
+       platform_device_unregister(sffsdr_snd_device);
+}
+
+module_init(sffsdr_init);
+module_exit(sffsdr_exit);
+
+MODULE_AUTHOR("Hugo Villeneuve");
+MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
+MODULE_LICENSE("GPL");
index bba9546ba5f5c30d076cb7962359d9405f1cc0fa..95c12b26fe37c0a3acfdb1ba070facdf02ca4067 100644 (file)
@@ -20,7 +20,8 @@ config SND_SOC_MPC8610_HPCD
 
 config SND_SOC_MPC5200_I2S
        tristate "Freescale MPC5200 PSC in I2S mode driver"
+       depends on PPC_MPC52xx && PPC_BESTCOMM
        select SND_SOC_OF_SIMPLE
-       depends on SND_SOC && PPC_MPC52xx
+       select PPC_BESTCOMM_GEN_BD
        help
          Say Y here to support the MPC5200 PSCs in I2S mode.
index d2d3da9729f25f56d7563fefabe3f7d94b51f2fa..64993eda5679ebce0cd582afe2fc48f74b7f0605 100644 (file)
@@ -284,7 +284,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
  * fsl_dma_new: initialize this PCM driver.
  *
  * This function is called when the codec driver calls snd_soc_new_pcms(),
- * once for each .dai_link in the machine driver's snd_soc_machine
+ * once for each .dai_link in the machine driver's snd_soc_card
  * structure.
  */
 static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
@@ -853,6 +853,18 @@ int fsl_dma_configure(struct fsl_dma_info *dma_info)
 }
 EXPORT_SYMBOL_GPL(fsl_dma_configure);
 
+static int __init fsl_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&fsl_soc_platform);
+}
+module_init(fsl_soc_platform_init);
+
+static void __exit fsl_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&fsl_soc_platform);
+}
+module_exit(fsl_soc_platform_exit);
+
 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
 MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module");
 MODULE_LICENSE("GPL");
index 157a7895ffa1befbb2427b121f0bb493c0190b3d..c6d6eb71dc1d9635d7c109531f9b0a653c687d6c 100644 (file)
@@ -266,7 +266,8 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
  * If this is the first stream open, then grab the IRQ and program most of
  * the SSI registers.
  */
-static int fsl_ssi_startup(struct snd_pcm_substream *substream)
+static int fsl_ssi_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -411,7 +412,8 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream)
  * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
  * clock master.
  */
-static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
+static int fsl_ssi_prepare(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -441,7 +443,8 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
  * The DMA channel is in external master start and pause mode, which
  * means the SSI completely controls the flow of data.
  */
-static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
+static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -490,7 +493,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
  *
  * Shutdown the SSI if there are no other substreams open.
  */
-static void fsl_ssi_shutdown(struct snd_pcm_substream *substream)
+static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -578,8 +582,6 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
                .prepare = fsl_ssi_prepare,
                .shutdown = fsl_ssi_shutdown,
                .trigger = fsl_ssi_trigger,
-       },
-       .dai_ops = {
                .set_sysclk = fsl_ssi_set_sysclk,
                .set_fmt = fsl_ssi_set_fmt,
        },
@@ -671,6 +673,14 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
        fsl_ssi_dai->private_data = ssi_private;
        fsl_ssi_dai->name = ssi_private->name;
        fsl_ssi_dai->id = ssi_info->id;
+       fsl_ssi_dai->dev = ssi_info->dev;
+
+       ret = snd_soc_register_dai(fsl_ssi_dai);
+       if (ret != 0) {
+               dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
+               kfree(fsl_ssi_dai);
+               return NULL;
+       }
 
        return fsl_ssi_dai;
 }
@@ -688,6 +698,8 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
 
        device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
 
+       snd_soc_unregister_dai(&ssi_private->cpu_dai);
+
        kfree(ssi_private);
 }
 EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
index 94a02eaa4825a0ef1494c0f8e3798c2daef69504..9eb1ce185bd0cbd11e0e3e8744499ff7085fa624 100644 (file)
@@ -187,7 +187,8 @@ static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
  * If this is the first stream open, then grab the IRQ and program most of
  * the PSC registers.
  */
-static int psc_i2s_startup(struct snd_pcm_substream *substream)
+static int psc_i2s_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -220,7 +221,8 @@ static int psc_i2s_startup(struct snd_pcm_substream *substream)
 }
 
 static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -256,7 +258,8 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
+static int psc_i2s_hw_free(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
 {
        snd_pcm_set_runtime_buffer(substream, NULL);
        return 0;
@@ -268,7 +271,8 @@ static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
  * This function is called by ALSA to start, stop, pause, and resume the DMA
  * transfer of data.
  */
-static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                          struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -383,7 +387,8 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
  *
  * Shutdown the PSC if there are no other substreams open.
  */
-static void psc_i2s_shutdown(struct snd_pcm_substream *substream)
+static void psc_i2s_shutdown(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -464,7 +469,6 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
  * psc_i2s_dai_template: template CPU Digital Audio Interface
  */
 static struct snd_soc_dai psc_i2s_dai_template = {
-       .type = SND_SOC_DAI_I2S,
        .playback = {
                .channels_min = 2,
                .channels_max = 2,
@@ -483,8 +487,6 @@ static struct snd_soc_dai psc_i2s_dai_template = {
                .hw_free = psc_i2s_hw_free,
                .shutdown = psc_i2s_shutdown,
                .trigger = psc_i2s_trigger,
-       },
-       .dai_ops = {
                .set_sysclk = psc_i2s_set_sysclk,
                .set_fmt = psc_i2s_set_fmt,
        },
@@ -826,6 +828,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
        if (rc)
                dev_info(psc_i2s->dev, "error creating sysfs files\n");
 
+       snd_soc_register_platform(&psc_i2s_pcm_soc_platform);
+
        /* Tell the ASoC OF helpers about it */
        of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
                                     &psc_i2s->dai);
@@ -839,6 +843,8 @@ static int __devexit psc_i2s_of_remove(struct of_device *op)
 
        dev_dbg(&op->dev, "psc_i2s_remove()\n");
 
+       snd_soc_unregister_platform(&psc_i2s_pcm_soc_platform);
+
        bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
        bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
 
index 94f89debde1fa463a043741b022040bad7971b3e..bcec3f60bad99d8e5e885ebe9646ed942ebd1ec4 100644 (file)
@@ -29,7 +29,7 @@
 struct mpc8610_hpcd_data {
        struct snd_soc_device sound_devdata;
        struct snd_soc_dai_link dai;
-       struct snd_soc_machine machine;
+       struct snd_soc_card machine;
        unsigned int dai_format;
        unsigned int codec_clk_direction;
        unsigned int cpu_clk_direction;
@@ -185,7 +185,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
 /**
  * mpc8610_hpcd_machine: ASoC machine data
  */
-static struct snd_soc_machine mpc8610_hpcd_machine = {
+static struct snd_soc_card mpc8610_hpcd_machine = {
        .probe = mpc8610_hpcd_machine_probe,
        .remove = mpc8610_hpcd_machine_remove,
        .name = "MPC8610 HPCD",
@@ -465,9 +465,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
                goto error;
        }
 
-       machine_data->sound_devdata.machine = &mpc8610_hpcd_machine;
+       machine_data->sound_devdata.card = &mpc8610_hpcd_machine;
        machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270;
-       machine_data->sound_devdata.platform = &fsl_soc_platform;
+       machine_data->machine.platform = &fsl_soc_platform;
 
        sound_device->dev.platform_data = machine_data;
 
index 0382fdac51cd44d615ea0cae24ecff239eb4bcc7..8bc5cd9e972fc89a2223dc32f01c42cbffd15fea 100644 (file)
@@ -31,7 +31,7 @@ struct of_snd_soc_device {
        int id;
        struct list_head list;
        struct snd_soc_device device;
-       struct snd_soc_machine machine;
+       struct snd_soc_card card;
        struct snd_soc_dai_link dai_link;
        struct platform_device *pdev;
        struct device_node *platform_node;
@@ -58,9 +58,9 @@ of_snd_soc_get_device(struct device_node *codec_node)
        /* Initialize the structure and add it to the global list */
        of_soc->codec_node = codec_node;
        of_soc->id = of_snd_soc_next_index++;
-       of_soc->machine.dai_link = &of_soc->dai_link;
-       of_soc->machine.num_links = 1;
-       of_soc->device.machine = &of_soc->machine;
+       of_soc->card.dai_link = &of_soc->dai_link;
+       of_soc->card.num_links = 1;
+       of_soc->device.card = &of_soc->card;
        of_soc->dai_link.ops = &of_snd_soc_ops;
        list_add(&of_soc->list, &of_snd_soc_device_list);
 
@@ -158,8 +158,8 @@ int of_snd_soc_register_platform(struct snd_soc_platform *platform,
 
        of_soc->platform_node = node;
        of_soc->dai_link.cpu_dai = cpu_dai;
-       of_soc->device.platform = platform;
-       of_soc->machine.name = of_soc->dai_link.cpu_dai->name;
+       of_soc->card.platform = platform;
+       of_soc->card.name = of_soc->dai_link.cpu_dai->name;
 
        /* Now try to register the SoC device */
        of_snd_soc_register_device(of_soc);
index 8b7766b998d7de431bd30d18d32569019a116d28..a7b1d77b2105ec6e722e11301b822fe270c30e60 100644 (file)
@@ -1,6 +1,6 @@
 config SND_OMAP_SOC
        tristate "SoC Audio for the Texas Instruments OMAP chips"
-       depends on ARCH_OMAP && SND_SOC
+       depends on ARCH_OMAP
 
 config SND_OMAP_SOC_MCBSP
        tristate
@@ -21,3 +21,36 @@ config SND_OMAP_SOC_OSK5912
        select SND_SOC_TLV320AIC23
        help
          Say Y if you want to add support for SoC audio on osk5912.
+
+config SND_OMAP_SOC_OVERO
+       tristate "SoC Audio support for Gumstix Overo"
+       depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO
+       select SND_OMAP_SOC_MCBSP
+       select SND_SOC_TWL4030
+       help
+         Say Y if you want to add support for SoC audio on the Gumstix Overo.
+
+config SND_OMAP_SOC_OMAP2EVM
+       tristate "SoC Audio support for OMAP2EVM board"
+       depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM
+       select SND_OMAP_SOC_MCBSP
+       select SND_SOC_TWL4030
+       help
+         Say Y if you want to add support for SoC audio on the omap2evm board.
+
+config SND_OMAP_SOC_SDP3430
+       tristate "SoC Audio support for Texas Instruments SDP3430"
+       depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
+       select SND_OMAP_SOC_MCBSP
+       select SND_SOC_TWL4030
+       help
+         Say Y if you want to add support for SoC audio on Texas Instruments
+         SDP3430.
+
+config SND_OMAP_SOC_OMAP3_PANDORA
+       tristate "SoC Audio support for OMAP3 Pandora"
+       depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
+       select SND_OMAP_SOC_MCBSP
+       select SND_SOC_TWL4030
+       help
+         Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
index e09d1f297f644c856c16250dc7cdc407bd6f7e6f..76fedd96e3657b8c4e52b9d0695d3fb47f8ae70c 100644 (file)
@@ -8,6 +8,14 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
 # OMAP Machine Support
 snd-soc-n810-objs := n810.o
 snd-soc-osk5912-objs := osk5912.o
+snd-soc-overo-objs := overo.o
+snd-soc-omap2evm-objs := omap2evm.o
+snd-soc-sdp3430-objs := sdp3430.o
+snd-soc-omap3pandora-objs := omap3pandora.o
 
 obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
 obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
+obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
+obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
+obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
+obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
index fae3ad36e0bfc3e03606561c48c0c54bb7d192b6..25593fee9121e22df808bd88ac5f2048ea2f2fae 100644 (file)
@@ -70,9 +70,13 @@ static void n810_ext_control(struct snd_soc_codec *codec)
 
 static int n810_startup(struct snd_pcm_substream *substream)
 {
+       struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_codec *codec = rtd->socdev->codec;
 
+       snd_pcm_hw_constraint_minmax(runtime,
+                                    SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
+
        n810_ext_control(codec);
        return clk_enable(sys_clkout2);
 }
@@ -282,8 +286,9 @@ static struct snd_soc_dai_link n810_dai = {
 };
 
 /* Audio machine driver */
-static struct snd_soc_machine snd_soc_machine_n810 = {
+static struct snd_soc_card snd_soc_n810 = {
        .name = "N810",
+       .platform = &omap_soc_platform,
        .dai_link = &n810_dai,
        .num_links = 1,
 };
@@ -298,8 +303,7 @@ static struct aic3x_setup_data n810_aic33_setup = {
 
 /* Audio subsystem */
 static struct snd_soc_device n810_snd_devdata = {
-       .machine = &snd_soc_machine_n810,
-       .platform = &omap_soc_platform,
+       .card = &snd_soc_n810,
        .codec_dev = &soc_codec_dev_aic3x,
        .codec_data = &n810_aic33_setup,
 };
index 8485a8a9d0ff0e89687eb73a62755d064c8177e6..7b86373007ca2f66fb9282a668813e2c5da2d07d 100644 (file)
@@ -36,9 +36,7 @@
 #include "omap-mcbsp.h"
 #include "omap-pcm.h"
 
-#define OMAP_MCBSP_RATES       (SNDRV_PCM_RATE_44100 | \
-                                SNDRV_PCM_RATE_48000 | \
-                                SNDRV_PCM_RATE_KNOT)
+#define OMAP_MCBSP_RATES       (SNDRV_PCM_RATE_8000_96000)
 
 struct omap_mcbsp_data {
        unsigned int                    bus_id;
@@ -140,7 +138,8 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
 static const unsigned long omap34xx_mcbsp_port[][2] = {};
 #endif
 
-static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
+static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
+                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -153,7 +152,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
        return err;
 }
 
-static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
+static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
+                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -165,7 +165,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
        }
 }
 
-static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
+static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
+                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -194,14 +195,15 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
 }
 
 static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
-                                   struct snd_pcm_hw_params *params)
+                                   struct snd_pcm_hw_params *params,
+                                   struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
        struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
        struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
        int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
-       int wlen;
+       int wlen, channels;
        unsigned long port;
 
        if (cpu_class_is_omap1()) {
@@ -230,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
                return 0;
        }
 
-       switch (params_channels(params)) {
+       channels = params_channels(params);
+       switch (channels) {
        case 2:
-               /* Set 1 word per (McBPSP) frame and use dual-phase frames */
-               regs->rcr2      |= RFRLEN2(1 - 1) | RPHASE;
+               /* Use dual-phase frames */
+               regs->rcr2      |= RPHASE;
+               regs->xcr2      |= XPHASE;
+       case 1:
+               /* Set 1 word per (McBSP) frame */
+               regs->rcr2      |= RFRLEN2(1 - 1);
                regs->rcr1      |= RFRLEN1(1 - 1);
-               regs->xcr2      |= XFRLEN2(1 - 1) | XPHASE;
+               regs->xcr2      |= XFRLEN2(1 - 1);
                regs->xcr1      |= XFRLEN1(1 - 1);
                break;
        default:
@@ -264,8 +271,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
                regs->srgr1     |= FWID(wlen - 1);
                break;
        case SND_SOC_DAIFMT_DSP_A:
-               regs->srgr2     |= FPER(wlen * 2 - 1);
-               regs->srgr1     |= FWID(wlen * 2 - 2);
+               regs->srgr2     |= FPER(wlen * channels - 1);
+               regs->srgr1     |= FWID(wlen * channels - 2);
                break;
        }
 
@@ -452,17 +459,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 
 #define OMAP_MCBSP_DAI_BUILDER(link_id)                                \
 {                                                              \
-       .name = "omap-mcbsp-dai-(link_id)",                     \
+       .name = "omap-mcbsp-dai-"#link_id,                      \
        .id = (link_id),                                        \
-       .type = SND_SOC_DAI_I2S,                                \
        .playback = {                                           \
-               .channels_min = 2,                              \
+               .channels_min = 1,                              \
                .channels_max = 2,                              \
                .rates = OMAP_MCBSP_RATES,                      \
                .formats = SNDRV_PCM_FMTBIT_S16_LE,             \
        },                                                      \
        .capture = {                                            \
-               .channels_min = 2,                              \
+               .channels_min = 1,                              \
                .channels_max = 2,                              \
                .rates = OMAP_MCBSP_RATES,                      \
                .formats = SNDRV_PCM_FMTBIT_S16_LE,             \
@@ -472,8 +478,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
                .shutdown = omap_mcbsp_dai_shutdown,            \
                .trigger = omap_mcbsp_dai_trigger,              \
                .hw_params = omap_mcbsp_dai_hw_params,          \
-       },                                                      \
-       .dai_ops = {                                            \
                .set_fmt = omap_mcbsp_dai_set_dai_fmt,          \
                .set_clkdiv = omap_mcbsp_dai_set_clkdiv,        \
                .set_sysclk = omap_mcbsp_dai_set_dai_sysclk,    \
@@ -495,6 +499,19 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
 
 EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
 
+static int __init snd_omap_mcbsp_init(void)
+{
+       return snd_soc_register_dais(omap_mcbsp_dai,
+                                    ARRAY_SIZE(omap_mcbsp_dai));
+}
+module_init(snd_omap_mcbsp_init);
+
+static void __exit snd_omap_mcbsp_exit(void)
+{
+       snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai));
+}
+module_exit(snd_omap_mcbsp_exit);
+
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
 MODULE_DESCRIPTION("OMAP I2S SoC Interface");
 MODULE_LICENSE("GPL");
index acd68efb2b758dc59692036d4bd6f445854dc985..803581c9280d7d9d53b00b35c39d2a5e68b1a72e 100644 (file)
@@ -354,6 +354,18 @@ struct snd_soc_platform omap_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(omap_soc_platform);
 
+static int __init omap_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&omap_soc_platform);
+}
+module_init(omap_soc_platform_init);
+
+static void __exit omap_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&omap_soc_platform);
+}
+module_exit(omap_soc_platform_exit);
+
 MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
 MODULE_DESCRIPTION("OMAP PCM DMA module");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
new file mode 100644 (file)
index 0000000..0c2322d
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * omap2evm.c  --  SoC audio machine driver for omap2evm board
+ *
+ * Author: Arun KS <arunks@mistralsolutions.com>
+ *
+ * Based on sound/soc/omap/overo.c by Steve Sakoman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/mcbsp.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+static int omap2evm_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params,
+       struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int ret;
+
+       /* Set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec DAI configuration\n");
+               return ret;
+       }
+
+       /* Set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set cpu DAI configuration\n");
+               return ret;
+       }
+
+       /* Set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+                                           SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec system clock\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops omap2evm_ops = {
+       .hw_params = omap2evm_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap2evm_dai = {
+       .name = "TWL4030",
+       .stream_name = "TWL4030",
+       .cpu_dai = &omap_mcbsp_dai[0],
+       .codec_dai = &twl4030_dai,
+       .ops = &omap2evm_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_card snd_soc_omap2evm = {
+       .name = "omap2evm",
+       .platform = &omap_soc_platform,
+       .dai_link = &omap2evm_dai,
+       .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device omap2evm_snd_devdata = {
+       .card = &snd_soc_omap2evm,
+       .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *omap2evm_snd_device;
+
+static int __init omap2evm_soc_init(void)
+{
+       int ret;
+
+       if (!machine_is_omap2evm()) {
+               pr_debug("Not omap2evm!\n");
+               return -ENODEV;
+       }
+       printk(KERN_INFO "omap2evm SoC init\n");
+
+       omap2evm_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!omap2evm_snd_device) {
+               printk(KERN_ERR "Platform device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(omap2evm_snd_device, &omap2evm_snd_devdata);
+       omap2evm_snd_devdata.dev = &omap2evm_snd_device->dev;
+       *(unsigned int *)omap2evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
+
+       ret = platform_device_add(omap2evm_snd_device);
+       if (ret)
+               goto err1;
+
+       return 0;
+
+err1:
+       printk(KERN_ERR "Unable to add platform device\n");
+       platform_device_put(omap2evm_snd_device);
+
+       return ret;
+}
+module_init(omap2evm_soc_init);
+
+static void __exit omap2evm_soc_exit(void)
+{
+       platform_device_unregister(omap2evm_snd_device);
+}
+module_exit(omap2evm_soc_exit);
+
+MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
+MODULE_DESCRIPTION("ALSA SoC omap2evm");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
new file mode 100644 (file)
index 0000000..fd24a4a
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * omap3beagle.c  --  SoC audio for OMAP3 Beagle
+ *
+ * Author: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/mcbsp.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+static int omap3beagle_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int ret;
+
+       /* Set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec DAI configuration\n");
+               return ret;
+       }
+
+       /* Set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set cpu DAI configuration\n");
+               return ret;
+       }
+
+       /* Set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+                                    SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec system clock\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops omap3beagle_ops = {
+       .hw_params = omap3beagle_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap3beagle_dai = {
+       .name = "TWL4030",
+       .stream_name = "TWL4030",
+       .cpu_dai = &omap_mcbsp_dai[0],
+       .codec_dai = &twl4030_dai,
+       .ops = &omap3beagle_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_card snd_soc_omap3beagle = {
+       .name = "omap3beagle",
+       .platform = &omap_soc_platform,
+       .dai_link = &omap3beagle_dai,
+       .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device omap3beagle_snd_devdata = {
+       .card = &snd_soc_omap3beagle,
+       .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *omap3beagle_snd_device;
+
+static int __init omap3beagle_soc_init(void)
+{
+       int ret;
+
+       if (!machine_is_omap3_beagle()) {
+               pr_debug("Not OMAP3 Beagle!\n");
+               return -ENODEV;
+       }
+       pr_info("OMAP3 Beagle SoC init\n");
+
+       omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!omap3beagle_snd_device) {
+               printk(KERN_ERR "Platform device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata);
+       omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
+       *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
+
+       ret = platform_device_add(omap3beagle_snd_device);
+       if (ret)
+               goto err1;
+
+       return 0;
+
+err1:
+       printk(KERN_ERR "Unable to add platform device\n");
+       platform_device_put(omap3beagle_snd_device);
+
+       return ret;
+}
+
+static void __exit omap3beagle_soc_exit(void)
+{
+       platform_device_unregister(omap3beagle_snd_device);
+}
+
+module_init(omap3beagle_soc_init);
+module_exit(omap3beagle_soc_exit);
+
+MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
+MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
new file mode 100644 (file)
index 0000000..bd91594
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * omap3pandora.c  --  SoC audio for Pandora Handheld Console
+ *
+ * Author: Gražvydas Ignotas <notasas@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+#define OMAP3_PANDORA_DAC_POWER_GPIO   118
+#define OMAP3_PANDORA_AMP_POWER_GPIO   14
+
+#define PREFIX "ASoC omap3pandora: "
+
+static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
+       struct snd_soc_dai *cpu_dai, unsigned int fmt)
+{
+       int ret;
+
+       /* Set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai, fmt);
+       if (ret < 0) {
+               pr_err(PREFIX "can't set codec DAI configuration\n");
+               return ret;
+       }
+
+       /* Set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+       if (ret < 0) {
+               pr_err(PREFIX "can't set cpu DAI configuration\n");
+               return ret;
+       }
+
+       /* Set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+                                           SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               pr_err(PREFIX "can't set codec system clock\n");
+               return ret;
+       }
+
+       /* Set McBSP clock to external */
+       ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0,
+                                           SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               pr_err(PREFIX "can't set cpu system clock\n");
+               return ret;
+       }
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 8);
+       if (ret < 0) {
+               pr_err(PREFIX "can't set SRG clock divider\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+
+       return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
+                                         SND_SOC_DAIFMT_I2S |
+                                         SND_SOC_DAIFMT_IB_NF |
+                                         SND_SOC_DAIFMT_CBS_CFS);
+}
+
+static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+
+       return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
+                                         SND_SOC_DAIFMT_I2S |
+                                         SND_SOC_DAIFMT_NB_NF |
+                                         SND_SOC_DAIFMT_CBS_CFS);
+}
+
+static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
+       struct snd_kcontrol *k, int event)
+{
+       if (SND_SOC_DAPM_EVENT_ON(event)) {
+               gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
+               gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
+       } else {
+               gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
+               mdelay(1);
+               gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
+       }
+
+       return 0;
+}
+
+/*
+ * Audio paths on Pandora board:
+ *
+ *  |O| ---> PCM DAC +-> AMP -> Headphone Jack
+ *  |M|         A    +--------> Line Out
+ *  |A| <~~clk~~+
+ *  |P| <--- TWL4030 <--------- Line In and MICs
+ */
+static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
+       SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
+       SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
+                          0, 0, NULL, 0, omap3pandora_hp_event,
+                          SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_LINE("Line Out", NULL),
+};
+
+static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
+       SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
+       SND_SOC_DAPM_MIC("Mic (external)", NULL),
+       SND_SOC_DAPM_LINE("Line In", NULL),
+};
+
+static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
+       {"Headphone Amplifier", NULL, "PCM DAC"},
+       {"Line Out", NULL, "PCM DAC"},
+       {"Headphone Jack", NULL, "Headphone Amplifier"},
+};
+
+static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
+       {"INL", NULL, "Line In"},
+       {"INR", NULL, "Line In"},
+       {"INL", NULL, "Mic (Internal)"},
+       {"INR", NULL, "Mic (external)"},
+};
+
+static int omap3pandora_out_init(struct snd_soc_codec *codec)
+{
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
+                               ARRAY_SIZE(omap3pandora_out_dapm_widgets));
+       if (ret < 0)
+               return ret;
+
+       snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
+               ARRAY_SIZE(omap3pandora_out_map));
+
+       return snd_soc_dapm_sync(codec);
+}
+
+static int omap3pandora_in_init(struct snd_soc_codec *codec)
+{
+       int ret;
+
+       ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
+                               ARRAY_SIZE(omap3pandora_in_dapm_widgets));
+       if (ret < 0)
+               return ret;
+
+       snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
+               ARRAY_SIZE(omap3pandora_in_map));
+
+       return snd_soc_dapm_sync(codec);
+}
+
+static struct snd_soc_ops omap3pandora_out_ops = {
+       .hw_params = omap3pandora_out_hw_params,
+};
+
+static struct snd_soc_ops omap3pandora_in_ops = {
+       .hw_params = omap3pandora_in_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap3pandora_dai[] = {
+       {
+               .name = "PCM1773",
+               .stream_name = "HiFi Out",
+               .cpu_dai = &omap_mcbsp_dai[0],
+               .codec_dai = &twl4030_dai,
+               .ops = &omap3pandora_out_ops,
+               .init = omap3pandora_out_init,
+       }, {
+               .name = "TWL4030",
+               .stream_name = "Line/Mic In",
+               .cpu_dai = &omap_mcbsp_dai[1],
+               .codec_dai = &twl4030_dai,
+               .ops = &omap3pandora_in_ops,
+               .init = omap3pandora_in_init,
+       }
+};
+
+/* SoC card */
+static struct snd_soc_card snd_soc_card_omap3pandora = {
+       .name = "omap3pandora",
+       .platform = &omap_soc_platform,
+       .dai_link = omap3pandora_dai,
+       .num_links = ARRAY_SIZE(omap3pandora_dai),
+};
+
+/* Audio subsystem */
+static struct snd_soc_device omap3pandora_snd_data = {
+       .card = &snd_soc_card_omap3pandora,
+       .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *omap3pandora_snd_device;
+
+static int __init omap3pandora_soc_init(void)
+{
+       int ret;
+
+       if (!machine_is_omap3_pandora()) {
+               pr_debug(PREFIX "Not OMAP3 Pandora\n");
+               return -ENODEV;
+       }
+       pr_info("OMAP3 Pandora SoC init\n");
+
+       ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
+       if (ret) {
+               pr_err(PREFIX "Failed to get DAC power GPIO\n");
+               return ret;
+       }
+
+       ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
+       if (ret) {
+               pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
+               goto fail0;
+       }
+
+       ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
+       if (ret) {
+               pr_err(PREFIX "Failed to get amp power GPIO\n");
+               goto fail0;
+       }
+
+       ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
+       if (ret) {
+               pr_err(PREFIX "Failed to set amp power GPIO direction\n");
+               goto fail1;
+       }
+
+       omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
+       if (omap3pandora_snd_device == NULL) {
+               pr_err(PREFIX "Platform device allocation failed\n");
+               ret = -ENOMEM;
+               goto fail1;
+       }
+
+       platform_set_drvdata(omap3pandora_snd_device, &omap3pandora_snd_data);
+       omap3pandora_snd_data.dev = &omap3pandora_snd_device->dev;
+       *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */
+       *(unsigned int *)omap_mcbsp_dai[1].private_data = 3; /* McBSP4 */
+
+       ret = platform_device_add(omap3pandora_snd_device);
+       if (ret) {
+               pr_err(PREFIX "Unable to add platform device\n");
+               goto fail2;
+       }
+
+       return 0;
+
+fail2:
+       platform_device_put(omap3pandora_snd_device);
+fail1:
+       gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
+fail0:
+       gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
+       return ret;
+}
+module_init(omap3pandora_soc_init);
+
+static void __exit omap3pandora_soc_exit(void)
+{
+       platform_device_unregister(omap3pandora_snd_device);
+       gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
+       gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
+}
+module_exit(omap3pandora_soc_exit);
+
+MODULE_AUTHOR("Grazvydas Ignotas <notasas@gmail.com>");
+MODULE_DESCRIPTION("ALSA SoC OMAP3 Pandora");
+MODULE_LICENSE("GPL");
index 0fe733796898149471013ba47db2d6394343921d..845bf41335b93db0fe31e95c3ff3fa4d67aaad73 100644 (file)
@@ -143,16 +143,16 @@ static struct snd_soc_dai_link osk_dai = {
 };
 
 /* Audio machine driver */
-static struct snd_soc_machine snd_soc_machine_osk = {
+static struct snd_soc_card snd_soc_card_osk = {
        .name = "OSK5912",
+       .platform = &omap_soc_platform,
        .dai_link = &osk_dai,
        .num_links = 1,
 };
 
 /* Audio subsystem */
 static struct snd_soc_device osk_snd_devdata = {
-       .machine = &snd_soc_machine_osk,
-       .platform = &omap_soc_platform,
+       .card = &snd_soc_card_osk,
        .codec_dev = &soc_codec_dev_tlv320aic23,
 };
 
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
new file mode 100644 (file)
index 0000000..a72dc4e
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * overo.c  --  SoC audio for Gumstix Overo
+ *
+ * Author: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/mcbsp.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+static int overo_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int ret;
+
+       /* Set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec DAI configuration\n");
+               return ret;
+       }
+
+       /* Set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set cpu DAI configuration\n");
+               return ret;
+       }
+
+       /* Set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+                                           SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec system clock\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops overo_ops = {
+       .hw_params = overo_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link overo_dai = {
+       .name = "TWL4030",
+       .stream_name = "TWL4030",
+       .cpu_dai = &omap_mcbsp_dai[0],
+       .codec_dai = &twl4030_dai,
+       .ops = &overo_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_card snd_soc_card_overo = {
+       .name = "overo",
+       .platform = &omap_soc_platform,
+       .dai_link = &overo_dai,
+       .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device overo_snd_devdata = {
+       .card = &snd_soc_card_overo,
+       .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *overo_snd_device;
+
+static int __init overo_soc_init(void)
+{
+       int ret;
+
+       if (!machine_is_overo()) {
+               pr_debug("Not Overo!\n");
+               return -ENODEV;
+       }
+       printk(KERN_INFO "overo SoC init\n");
+
+       overo_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!overo_snd_device) {
+               printk(KERN_ERR "Platform device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(overo_snd_device, &overo_snd_devdata);
+       overo_snd_devdata.dev = &overo_snd_device->dev;
+       *(unsigned int *)overo_dai.cpu_dai->private_data = 1; /* McBSP2 */
+
+       ret = platform_device_add(overo_snd_device);
+       if (ret)
+               goto err1;
+
+       return 0;
+
+err1:
+       printk(KERN_ERR "Unable to add platform device\n");
+       platform_device_put(overo_snd_device);
+
+       return ret;
+}
+module_init(overo_soc_init);
+
+static void __exit overo_soc_exit(void)
+{
+       platform_device_unregister(overo_snd_device);
+}
+module_exit(overo_soc_exit);
+
+MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
+MODULE_DESCRIPTION("ALSA SoC overo");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
new file mode 100644 (file)
index 0000000..ad97836
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * sdp3430.c  --  SoC audio for TI OMAP3430 SDP
+ *
+ * Author: Misael Lopez Cruz <x0052729@ti.com>
+ *
+ * Based on:
+ * Author: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/mcbsp.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+static int sdp3430_hw_params(struct snd_pcm_substream *substream,
+       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int ret;
+
+       /* Set codec DAI configuration */
+       ret = snd_soc_dai_set_fmt(codec_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec DAI configuration\n");
+               return ret;
+       }
+
+       /* Set cpu DAI configuration */
+       ret = snd_soc_dai_set_fmt(cpu_dai,
+                                 SND_SOC_DAIFMT_I2S |
+                                 SND_SOC_DAIFMT_NB_NF |
+                                 SND_SOC_DAIFMT_CBM_CFM);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set cpu DAI configuration\n");
+               return ret;
+       }
+
+       /* Set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+                                           SND_SOC_CLOCK_IN);
+       if (ret < 0) {
+               printk(KERN_ERR "can't set codec system clock\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static struct snd_soc_ops sdp3430_ops = {
+       .hw_params = sdp3430_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link sdp3430_dai = {
+       .name = "TWL4030",
+       .stream_name = "TWL4030",
+       .cpu_dai = &omap_mcbsp_dai[0],
+       .codec_dai = &twl4030_dai,
+       .ops = &sdp3430_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_machine snd_soc_machine_sdp3430 = {
+       .name = "SDP3430",
+       .platform = &omap_soc_platform,
+       .dai_link = &sdp3430_dai,
+       .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device sdp3430_snd_devdata = {
+       .machine = &snd_soc_machine_sdp3430,
+       .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *sdp3430_snd_device;
+
+static int __init sdp3430_soc_init(void)
+{
+       int ret;
+
+       if (!machine_is_omap_3430sdp()) {
+               pr_debug("Not SDP3430!\n");
+               return -ENODEV;
+       }
+       printk(KERN_INFO "SDP3430 SoC init\n");
+
+       sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!sdp3430_snd_device) {
+               printk(KERN_ERR "Platform device allocation failed\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata);
+       sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
+       *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */
+
+       ret = platform_device_add(sdp3430_snd_device);
+       if (ret)
+               goto err1;
+
+       return 0;
+
+err1:
+       printk(KERN_ERR "Unable to add platform device\n");
+       platform_device_put(sdp3430_snd_device);
+
+       return ret;
+}
+module_init(sdp3430_soc_init);
+
+static void __exit sdp3430_soc_exit(void)
+{
+       platform_device_unregister(sdp3430_snd_device);
+}
+module_exit(sdp3430_soc_exit);
+
+MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
+MODULE_DESCRIPTION("ALSA SoC SDP3430");
+MODULE_LICENSE("GPL");
+
index f8c1cdd940acf54330c05fed9c69a3f4f7c7b0e6..f82e106994717da3c561515e0ba027f1ff32a965 100644 (file)
@@ -21,6 +21,9 @@ config SND_PXA2XX_SOC_AC97
 config SND_PXA2XX_SOC_I2S
        tristate
 
+config SND_PXA_SOC_SSP
+       tristate
+
 config SND_PXA2XX_SOC_CORGI
        tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
        depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -75,3 +78,22 @@ config SND_PXA2XX_SOC_EM_X270
        help
          Say Y if you want to add support for SoC audio on
          CompuLab EM-x270.
+
+config SND_PXA2XX_SOC_PALM27X
+       bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
+       depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
+       select SND_PXA2XX_SOC_AC97
+       select SND_SOC_WM9712
+       help
+         Say Y if you want to add support for SoC audio on
+         Palm T|X, T5 or LifeDrive handheld computer.
+
+config SND_SOC_ZYLONITE
+       tristate "SoC Audio support for Marvell Zylonite"
+       depends on SND_PXA2XX_SOC && MACH_ZYLONITE
+       select SND_PXA2XX_SOC_AC97
+       select SND_PXA_SOC_SSP
+       select SND_SOC_WM9713
+       help
+         Say Y if you want to add support for SoC audio on the
+         Marvell Zylonite reference platform.
index 5bc8edf9dca9ec8532ec6e56e1c7e7ea88f463fc..08a9f279772991f76adbe8f307aee987b8f8351c 100644 (file)
@@ -2,10 +2,12 @@
 snd-soc-pxa2xx-objs := pxa2xx-pcm.o
 snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
 snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
+snd-soc-pxa-ssp-objs := pxa-ssp.o
 
 obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
 obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
 obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
+obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
 
 # PXA Machine Support
 snd-soc-corgi-objs := corgi.o
@@ -14,6 +16,8 @@ snd-soc-tosa-objs := tosa.o
 snd-soc-e800-objs := e800_wm9712.o
 snd-soc-spitz-objs := spitz.o
 snd-soc-em-x270-objs := em-x270.o
+snd-soc-palm27x-objs := palm27x.o
+snd-soc-zylonite-objs := zylonite.o
 
 obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
 obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -21,3 +25,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
 obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
 obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
 obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
+obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
+obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
index 2718eaf7895f39d4db2e5d93e4227400b995b1a7..1ba25a559524296217824f188ac8f4de081a72ec 100644 (file)
@@ -108,15 +108,11 @@ static int corgi_startup(struct snd_pcm_substream *substream)
 }
 
 /* we need to unmute the HP at shutdown as the mute burns power on corgi */
-static int corgi_shutdown(struct snd_pcm_substream *substream)
+static void corgi_shutdown(struct snd_pcm_substream *substream)
 {
-       struct snd_soc_pcm_runtime *rtd = substream->private_data;
-       struct snd_soc_codec *codec = rtd->socdev->codec;
-
        /* set = unmute headphone */
        gpio_set_value(CORGI_GPIO_MUTE_L, 1);
        gpio_set_value(CORGI_GPIO_MUTE_R, 1);
-       return 0;
 }
 
 static int corgi_hw_params(struct snd_pcm_substream *substream,
@@ -314,8 +310,9 @@ static struct snd_soc_dai_link corgi_dai = {
 };
 
 /* corgi audio machine driver */
-static struct snd_soc_machine snd_soc_machine_corgi = {
+static struct snd_soc_card snd_soc_corgi = {
        .name = "Corgi",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = &corgi_dai,
        .num_links = 1,
 };
@@ -328,8 +325,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
 
 /* corgi audio subsystem */
 static struct snd_soc_device corgi_snd_devdata = {
-       .machine = &snd_soc_machine_corgi,
-       .platform = &pxa2xx_soc_platform,
+       .card = &snd_soc_corgi,
        .codec_dev = &soc_codec_dev_wm8731,
        .codec_data = &corgi_wm8731_setup,
 };
index 6781c5be242fb75e3716eaa5bdbc3de3baf4c336..2e3386dfa0f0ed0604568b0b98d4a4b0f19105f8 100644 (file)
@@ -29,7 +29,7 @@
 #include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
-static struct snd_soc_machine e800;
+static struct snd_soc_card e800;
 
 static struct snd_soc_dai_link e800_dai[] = {
 {
@@ -40,15 +40,15 @@ static struct snd_soc_dai_link e800_dai[] = {
 },
 };
 
-static struct snd_soc_machine e800 = {
+static struct snd_soc_card e800 = {
        .name = "Toshiba e800",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = e800_dai,
        .num_links = ARRAY_SIZE(e800_dai),
 };
 
 static struct snd_soc_device e800_snd_devdata = {
-       .machine = &e800,
-       .platform = &pxa2xx_soc_platform,
+       .card = &e800,
        .codec_dev = &soc_codec_dev_wm9712,
 };
 
index e6ff6929ab4b799f7b9875144681469c15e6d8fe..fe4a729ea6487653881c2bda3b4c627ff58b2110 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/moduleparam.h>
 #include <linux/device.h>
 
-#include <sound/driver.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc.h>
@@ -53,15 +52,15 @@ static struct snd_soc_dai_link em_x270_dai[] = {
        },
 };
 
-static struct snd_soc_machine em_x270 = {
+static struct snd_soc_card em_x270 = {
        .name = "EM-X270",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = em_x270_dai,
        .num_links = ARRAY_SIZE(em_x270_dai),
 };
 
 static struct snd_soc_device em_x270_snd_devdata = {
-       .machine = &em_x270,
-       .platform = &pxa2xx_soc_platform,
+       .card = &em_x270,
        .codec_dev = &soc_codec_dev_wm9712,
 };
 
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
new file mode 100644 (file)
index 0000000..4a9cf30
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * linux/sound/soc/pxa/palm27x.c
+ *
+ * SoC Audio driver for Palm T|X, T5 and LifeDrive
+ *
+ * based on tosa.c
+ *
+ * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/audio.h>
+#include <mach/palmasoc.h>
+
+#include "../codecs/wm9712.h"
+#include "pxa2xx-pcm.h"
+#include "pxa2xx-ac97.h"
+
+static int palm27x_jack_func = 1;
+static int palm27x_spk_func = 1;
+static int palm27x_ep_gpio = -1;
+
+static void palm27x_ext_control(struct snd_soc_codec *codec)
+{
+       if (!palm27x_spk_func)
+               snd_soc_dapm_enable_pin(codec, "Speaker");
+       else
+               snd_soc_dapm_disable_pin(codec, "Speaker");
+
+       if (!palm27x_jack_func)
+               snd_soc_dapm_enable_pin(codec, "Headphone Jack");
+       else
+               snd_soc_dapm_disable_pin(codec, "Headphone Jack");
+
+       snd_soc_dapm_sync(codec);
+}
+
+static int palm27x_startup(struct snd_pcm_substream *substream)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_codec *codec = rtd->socdev->codec;
+
+       /* check the jack status at stream startup */
+       palm27x_ext_control(codec);
+       return 0;
+}
+
+static struct snd_soc_ops palm27x_ops = {
+       .startup = palm27x_startup,
+};
+
+static irqreturn_t palm27x_interrupt(int irq, void *v)
+{
+       palm27x_spk_func = gpio_get_value(palm27x_ep_gpio);
+       palm27x_jack_func = !palm27x_spk_func;
+       return IRQ_HANDLED;
+}
+
+static int palm27x_get_jack(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.integer.value[0] = palm27x_jack_func;
+       return 0;
+}
+
+static int palm27x_set_jack(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+
+       if (palm27x_jack_func == ucontrol->value.integer.value[0])
+               return 0;
+
+       palm27x_jack_func = ucontrol->value.integer.value[0];
+       palm27x_ext_control(codec);
+       return 1;
+}
+
+static int palm27x_get_spk(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.integer.value[0] = palm27x_spk_func;
+       return 0;
+}
+
+static int palm27x_set_spk(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_codec *codec =  snd_kcontrol_chip(kcontrol);
+
+       if (palm27x_spk_func == ucontrol->value.integer.value[0])
+               return 0;
+
+       palm27x_spk_func = ucontrol->value.integer.value[0];
+       palm27x_ext_control(codec);
+       return 1;
+}
+
+/* PalmTX machine dapm widgets */
+static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone Jack", NULL),
+       SND_SOC_DAPM_SPK("Speaker", NULL),
+};
+
+/* PalmTX audio map */
+static const struct snd_soc_dapm_route audio_map[] = {
+       /* headphone connected to HPOUTL, HPOUTR */
+       {"Headphone Jack", NULL, "HPOUTL"},
+       {"Headphone Jack", NULL, "HPOUTR"},
+
+       /* ext speaker connected to ROUT2, LOUT2 */
+       {"Speaker", NULL, "LOUT2"},
+       {"Speaker", NULL, "ROUT2"},
+};
+
+static const char *jack_function[] = {"Headphone", "Off"};
+static const char *spk_function[] = {"On", "Off"};
+static const struct soc_enum palm27x_enum[] = {
+       SOC_ENUM_SINGLE_EXT(2, jack_function),
+       SOC_ENUM_SINGLE_EXT(2, spk_function),
+};
+
+static const struct snd_kcontrol_new palm27x_controls[] = {
+       SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack,
+               palm27x_set_jack),
+       SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk,
+               palm27x_set_spk),
+};
+
+static int palm27x_ac97_init(struct snd_soc_codec *codec)
+{
+       int i, err;
+
+       snd_soc_dapm_nc_pin(codec, "OUT3");
+       snd_soc_dapm_nc_pin(codec, "MONOOUT");
+
+       /* add palm27x specific controls */
+       for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) {
+               err = snd_ctl_add(codec->card,
+                               snd_soc_cnew(&palm27x_controls[i],
+                                               codec, NULL));
+               if (err < 0)
+                       return err;
+       }
+
+       /* add palm27x specific widgets */
+       snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
+                               ARRAY_SIZE(palm27x_dapm_widgets));
+
+       /* set up palm27x specific audio path audio_map */
+       snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+       snd_soc_dapm_sync(codec);
+       return 0;
+}
+
+static struct snd_soc_dai_link palm27x_dai[] = {
+{
+       .name = "AC97 HiFi",
+       .stream_name = "AC97 HiFi",
+       .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
+       .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
+       .init = palm27x_ac97_init,
+       .ops = &palm27x_ops,
+},
+{
+       .name = "AC97 Aux",
+       .stream_name = "AC97 Aux",
+       .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
+       .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
+       .ops = &palm27x_ops,
+},
+};
+
+static struct snd_soc_card palm27x_asoc = {
+       .name = "Palm/PXA27x",
+       .platform = &pxa2xx_soc_platform,
+       .dai_link = palm27x_dai,
+       .num_links = ARRAY_SIZE(palm27x_dai),
+};
+
+static struct snd_soc_device palm27x_snd_devdata = {
+       .card = &palm27x_asoc,
+       .codec_dev = &soc_codec_dev_wm9712,
+};
+
+static struct platform_device *palm27x_snd_device;
+
+static int __init palm27x_asoc_init(void)
+{
+       int ret;
+
+       if (!(machine_is_palmtx() || machine_is_palmt5() ||
+               machine_is_palmld()))
+               return -ENODEV;
+
+       ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
+       if (ret)
+               return ret;
+       ret = gpio_direction_input(palm27x_ep_gpio);
+       if (ret)
+               goto err_alloc;
+
+       if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt,
+                       IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+                       "Headphone jack", NULL))
+               goto err_alloc;
+
+       palm27x_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!palm27x_snd_device) {
+               ret = -ENOMEM;
+               goto err_dev;
+       }
+
+       platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
+       palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
+       ret = platform_device_add(palm27x_snd_device);
+
+       if (ret != 0)
+               goto put_device;
+
+       return 0;
+
+put_device:
+       platform_device_put(palm27x_snd_device);
+err_dev:
+       free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
+err_alloc:
+       gpio_free(palm27x_ep_gpio);
+
+       return ret;
+}
+
+static void __exit palm27x_asoc_exit(void)
+{
+       free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
+       gpio_free(palm27x_ep_gpio);
+       platform_device_unregister(palm27x_snd_device);
+}
+
+void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data)
+{
+       palm27x_ep_gpio = data->jack_gpio;
+}
+
+module_init(palm27x_asoc_init);
+module_exit(palm27x_asoc_exit);
+
+/* Module information */
+MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
+MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
+MODULE_LICENSE("GPL");
index 4d9930c52789989313a8a1189bbc99b26160d8b2..6e9827189fffdca01b79b9c38bb212ee4998ce17 100644 (file)
@@ -276,8 +276,9 @@ static struct snd_soc_dai_link poodle_dai = {
 };
 
 /* poodle audio machine driver */
-static struct snd_soc_machine snd_soc_machine_poodle = {
+static struct snd_soc_card snd_soc_poodle = {
        .name = "Poodle",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = &poodle_dai,
        .num_links = 1,
 };
@@ -290,8 +291,7 @@ static struct wm8731_setup_data poodle_wm8731_setup = {
 
 /* poodle audio subsystem */
 static struct snd_soc_device poodle_snd_devdata = {
-       .machine = &snd_soc_machine_poodle,
-       .platform = &pxa2xx_soc_platform,
+       .card = &snd_soc_poodle,
        .codec_dev = &soc_codec_dev_wm8731,
        .codec_data = &poodle_wm8731_setup,
 };
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
new file mode 100644 (file)
index 0000000..73cb6b4
--- /dev/null
@@ -0,0 +1,931 @@
+#define DEBUG
+/*
+ * pxa-ssp.c  --  ALSA Soc Audio Layer
+ *
+ * Copyright 2005,2008 Wolfson Microelectronics PLC.
+ * Author: Liam Girdwood
+ *         Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ * TODO:
+ *  o Test network mode for > 16bit sample size
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/initval.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/pxa2xx-lib.h>
+
+#include <mach/hardware.h>
+#include <mach/pxa-regs.h>
+#include <mach/regs-ssp.h>
+#include <mach/audio.h>
+#include <mach/ssp.h>
+
+#include "pxa2xx-pcm.h"
+#include "pxa-ssp.h"
+
+/*
+ * SSP audio private data
+ */
+struct ssp_priv {
+       struct ssp_dev dev;
+       unsigned int sysclk;
+       int dai_fmt;
+#ifdef CONFIG_PM
+       struct ssp_state state;
+#endif
+};
+
+#define PXA2xx_SSP1_BASE       0x41000000
+#define PXA27x_SSP2_BASE       0x41700000
+#define PXA27x_SSP3_BASE       0x41900000
+#define PXA3xx_SSP4_BASE       0x41a00000
+
+static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
+       .name                   = "SSP1 PCM Mono out",
+       .dev_addr               = PXA2xx_SSP1_BASE + SSDR,
+       .drcmr                  = &DRCMR(14),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
+       .name                   = "SSP1 PCM Mono in",
+       .dev_addr               = PXA2xx_SSP1_BASE + SSDR,
+       .drcmr                  = &DRCMR(13),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
+       .name                   = "SSP1 PCM Stereo out",
+       .dev_addr               = PXA2xx_SSP1_BASE + SSDR,
+       .drcmr                  = &DRCMR(14),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
+       .name                   = "SSP1 PCM Stereo in",
+       .dev_addr               = PXA2xx_SSP1_BASE + SSDR,
+       .drcmr                  = &DRCMR(13),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
+       .name                   = "SSP2 PCM Mono out",
+       .dev_addr               = PXA27x_SSP2_BASE + SSDR,
+       .drcmr                  = &DRCMR(16),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
+       .name                   = "SSP2 PCM Mono in",
+       .dev_addr               = PXA27x_SSP2_BASE + SSDR,
+       .drcmr                  = &DRCMR(15),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
+       .name                   = "SSP2 PCM Stereo out",
+       .dev_addr               = PXA27x_SSP2_BASE + SSDR,
+       .drcmr                  = &DRCMR(16),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
+       .name                   = "SSP2 PCM Stereo in",
+       .dev_addr               = PXA27x_SSP2_BASE + SSDR,
+       .drcmr                  = &DRCMR(15),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
+       .name                   = "SSP3 PCM Mono out",
+       .dev_addr               = PXA27x_SSP3_BASE + SSDR,
+       .drcmr                  = &DRCMR(67),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
+       .name                   = "SSP3 PCM Mono in",
+       .dev_addr               = PXA27x_SSP3_BASE + SSDR,
+       .drcmr                  = &DRCMR(66),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
+       .name                   = "SSP3 PCM Stereo out",
+       .dev_addr               = PXA27x_SSP3_BASE + SSDR,
+       .drcmr                  = &DRCMR(67),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
+       .name                   = "SSP3 PCM Stereo in",
+       .dev_addr               = PXA27x_SSP3_BASE + SSDR,
+       .drcmr                  = &DRCMR(66),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
+       .name                   = "SSP4 PCM Mono out",
+       .dev_addr               = PXA3xx_SSP4_BASE + SSDR,
+       .drcmr                  = &DRCMR(67),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
+       .name                   = "SSP4 PCM Mono in",
+       .dev_addr               = PXA3xx_SSP4_BASE + SSDR,
+       .drcmr                  = &DRCMR(66),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH2,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
+       .name                   = "SSP4 PCM Stereo out",
+       .dev_addr               = PXA3xx_SSP4_BASE + SSDR,
+       .drcmr                  = &DRCMR(67),
+       .dcmd                   = DCMD_INCSRCADDR | DCMD_FLOWTRG |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
+       .name                   = "SSP4 PCM Stereo in",
+       .dev_addr               = PXA3xx_SSP4_BASE + SSDR,
+       .drcmr                  = &DRCMR(66),
+       .dcmd                   = DCMD_INCTRGADDR | DCMD_FLOWSRC |
+                                 DCMD_BURST16 | DCMD_WIDTH4,
+};
+
+static void dump_registers(struct ssp_device *ssp)
+{
+       dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
+                ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
+                ssp_read_reg(ssp, SSTO));
+
+       dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
+                ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
+                ssp_read_reg(ssp, SSACD));
+}
+
+static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = {
+       {
+               &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in,
+               &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
+       },
+       {
+               &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
+               &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
+       },
+       {
+               &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
+               &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
+       },
+       {
+               &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
+               &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
+       },
+};
+
+static int pxa_ssp_startup(struct snd_pcm_substream *substream,
+                          struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct ssp_priv *priv = cpu_dai->private_data;
+       int ret = 0;
+
+       if (!cpu_dai->active) {
+               ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ);
+               if (ret < 0)
+                       return ret;
+               ssp_disable(&priv->dev);
+       }
+       return ret;
+}
+
+static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
+                            struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct ssp_priv *priv = cpu_dai->private_data;
+
+       if (!cpu_dai->active) {
+               ssp_disable(&priv->dev);
+               ssp_exit(&priv->dev);
+       }
+}
+
+#ifdef CONFIG_PM
+
+static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+
+       if (!cpu_dai->active)
+               return 0;
+
+       ssp_save_state(&priv->dev, &priv->state);
+       clk_disable(priv->dev.ssp->clk);
+       return 0;
+}
+
+static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+
+       if (!cpu_dai->active)
+               return 0;
+
+       clk_enable(priv->dev.ssp->clk);
+       ssp_restore_state(&priv->dev, &priv->state);
+       ssp_enable(&priv->dev);
+
+       return 0;
+}
+
+#else
+#define pxa_ssp_suspend        NULL
+#define pxa_ssp_resume NULL
+#endif
+
+/**
+ * ssp_set_clkdiv - set SSP clock divider
+ * @div: serial clock rate divider
+ */
+static void ssp_set_scr(struct ssp_dev *dev, u32 div)
+{
+       struct ssp_device *ssp = dev->ssp;
+       u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR;
+
+       ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div)));
+}
+
+/*
+ * Set the SSP ports SYSCLK.
+ */
+static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
+       int clk_id, unsigned int freq, int dir)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       int val;
+
+       u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
+               ~(SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
+
+       dev_dbg(&ssp->pdev->dev,
+               "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n",
+               cpu_dai->id, clk_id, freq);
+
+       switch (clk_id) {
+       case PXA_SSP_CLK_NET_PLL:
+               sscr0 |= SSCR0_MOD;
+               break;
+       case PXA_SSP_CLK_PLL:
+               /* Internal PLL is fixed */
+               if (cpu_is_pxa25x())
+                       priv->sysclk = 1843200;
+               else
+                       priv->sysclk = 13000000;
+               break;
+       case PXA_SSP_CLK_EXT:
+               priv->sysclk = freq;
+               sscr0 |= SSCR0_ECS;
+               break;
+       case PXA_SSP_CLK_NET:
+               priv->sysclk = freq;
+               sscr0 |= SSCR0_NCS | SSCR0_MOD;
+               break;
+       case PXA_SSP_CLK_AUDIO:
+               priv->sysclk = 0;
+               ssp_set_scr(&priv->dev, 1);
+               sscr0 |= SSCR0_ADC;
+               break;
+       default:
+               return -ENODEV;
+       }
+
+       /* The SSP clock must be disabled when changing SSP clock mode
+        * on PXA2xx.  On PXA3xx it must be enabled when doing so. */
+       if (!cpu_is_pxa3xx())
+               clk_disable(priv->dev.ssp->clk);
+       val = ssp_read_reg(ssp, SSCR0) | sscr0;
+       ssp_write_reg(ssp, SSCR0, val);
+       if (!cpu_is_pxa3xx())
+               clk_enable(priv->dev.ssp->clk);
+
+       return 0;
+}
+
+/*
+ * Set the SSP clock dividers.
+ */
+static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
+       int div_id, int div)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       int val;
+
+       switch (div_id) {
+       case PXA_SSP_AUDIO_DIV_ACDS:
+               val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
+               ssp_write_reg(ssp, SSACD, val);
+               break;
+       case PXA_SSP_AUDIO_DIV_SCDB:
+               val = ssp_read_reg(ssp, SSACD);
+               val &= ~SSACD_SCDB;
+#if defined(CONFIG_PXA3xx)
+               if (cpu_is_pxa3xx())
+                       val &= ~SSACD_SCDX8;
+#endif
+               switch (div) {
+               case PXA_SSP_CLK_SCDB_1:
+                       val |= SSACD_SCDB;
+                       break;
+               case PXA_SSP_CLK_SCDB_4:
+                       break;
+#if defined(CONFIG_PXA3xx)
+               case PXA_SSP_CLK_SCDB_8:
+                       if (cpu_is_pxa3xx())
+                               val |= SSACD_SCDX8;
+                       else
+                               return -EINVAL;
+                       break;
+#endif
+               default:
+                       return -EINVAL;
+               }
+               ssp_write_reg(ssp, SSACD, val);
+               break;
+       case PXA_SSP_DIV_SCR:
+               ssp_set_scr(&priv->dev, div);
+               break;
+       default:
+               return -ENODEV;
+       }
+
+       return 0;
+}
+
+/*
+ * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
+ */
+static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
+       int pll_id, unsigned int freq_in, unsigned int freq_out)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
+
+#if defined(CONFIG_PXA3xx)
+       if (cpu_is_pxa3xx())
+               ssp_write_reg(ssp, SSACDD, 0);
+#endif
+
+       switch (freq_out) {
+       case 5622000:
+               break;
+       case 11345000:
+               ssacd |= (0x1 << 4);
+               break;
+       case 12235000:
+               ssacd |= (0x2 << 4);
+               break;
+       case 14857000:
+               ssacd |= (0x3 << 4);
+               break;
+       case 32842000:
+               ssacd |= (0x4 << 4);
+               break;
+       case 48000000:
+               ssacd |= (0x5 << 4);
+               break;
+       case 0:
+               /* Disable */
+               break;
+
+       default:
+#ifdef CONFIG_PXA3xx
+               /* PXA3xx has a clock ditherer which can be used to generate
+                * a wider range of frequencies - calculate a value for it.
+                */
+               if (cpu_is_pxa3xx()) {
+                       u32 val;
+                       u64 tmp = 19968;
+                       tmp *= 1000000;
+                       do_div(tmp, freq_out);
+                       val = tmp;
+
+                       val = (val << 16) | 64;;
+                       ssp_write_reg(ssp, SSACDD, val);
+
+                       ssacd |= (0x6 << 4);
+
+                       dev_dbg(&ssp->pdev->dev,
+                               "Using SSACDD %x to supply %dHz\n",
+                               val, freq_out);
+                       break;
+               }
+#endif
+
+               return -EINVAL;
+       }
+
+       ssp_write_reg(ssp, SSACD, ssacd);
+
+       return 0;
+}
+
+/*
+ * Set the active slots in TDM/Network mode
+ */
+static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
+       unsigned int mask, int slots)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       u32 sscr0;
+
+       sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7);
+
+       /* set number of active slots */
+       sscr0 |= SSCR0_SlotsPerFrm(slots);
+       ssp_write_reg(ssp, SSCR0, sscr0);
+
+       /* set active slot mask */
+       ssp_write_reg(ssp, SSTSA, mask);
+       ssp_write_reg(ssp, SSRSA, mask);
+       return 0;
+}
+
+/*
+ * Tristate the SSP DAI lines
+ */
+static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
+       int tristate)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       u32 sscr1;
+
+       sscr1 = ssp_read_reg(ssp, SSCR1);
+       if (tristate)
+               sscr1 &= ~SSCR1_TTE;
+       else
+               sscr1 |= SSCR1_TTE;
+       ssp_write_reg(ssp, SSCR1, sscr1);
+
+       return 0;
+}
+
+/*
+ * Set up the SSP DAI format.
+ * The SSP Port must be inactive before calling this function as the
+ * physical interface format is changed.
+ */
+static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
+               unsigned int fmt)
+{
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       u32 sscr0;
+       u32 sscr1;
+       u32 sspsp;
+
+       /* reset port settings */
+       sscr0 = ssp_read_reg(ssp, SSCR0) &
+               (SSCR0_ECS |  SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
+       sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
+       sspsp = 0;
+
+       switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+       case SND_SOC_DAIFMT_CBM_CFM:
+               sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
+               break;
+       case SND_SOC_DAIFMT_CBM_CFS:
+               sscr1 |= SSCR1_SCLKDIR;
+               break;
+       case SND_SOC_DAIFMT_CBS_CFS:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ssp_write_reg(ssp, SSCR0, sscr0);
+       ssp_write_reg(ssp, SSCR1, sscr1);
+       ssp_write_reg(ssp, SSPSP, sspsp);
+
+       switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               sscr0 |= SSCR0_MOD | SSCR0_PSP;
+               sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
+
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       sspsp |= SSPSP_FSRT;
+                       break;
+               case SND_SOC_DAIFMT_NB_IF:
+                       sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
+                       break;
+               case SND_SOC_DAIFMT_IB_IF:
+                       sspsp |= SSPSP_SFRMP;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+
+       case SND_SOC_DAIFMT_DSP_A:
+               sspsp |= SSPSP_FSRT;
+       case SND_SOC_DAIFMT_DSP_B:
+               sscr0 |= SSCR0_MOD | SSCR0_PSP;
+               sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
+
+               switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+               case SND_SOC_DAIFMT_NB_NF:
+                       sspsp |= SSPSP_SFRMP;
+                       break;
+               case SND_SOC_DAIFMT_IB_IF:
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       ssp_write_reg(ssp, SSCR0, sscr0);
+       ssp_write_reg(ssp, SSCR1, sscr1);
+       ssp_write_reg(ssp, SSPSP, sspsp);
+
+       dump_registers(ssp);
+
+       /* Since we are configuring the timings for the format by hand
+        * we have to defer some things until hw_params() where we
+        * know parameters like the sample size.
+        */
+       priv->dai_fmt = fmt;
+
+       return 0;
+}
+
+/*
+ * Set the SSP audio DMA parameters and sample size.
+ * Can be called multiple times by oss emulation.
+ */
+static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       int dma = 0, chn = params_channels(params);
+       u32 sscr0;
+       u32 sspsp;
+       int width = snd_pcm_format_physical_width(params_format(params));
+
+       /* select correct DMA params */
+       if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
+               dma = 1; /* capture DMA offset is 1,3 */
+       if (chn == 2)
+               dma += 2; /* stereo DMA offset is 2, mono is 0 */
+       cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
+
+       dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
+
+       /* we can only change the settings if the port is not in use */
+       if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
+               return 0;
+
+       /* clear selected SSP bits */
+       sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
+       ssp_write_reg(ssp, SSCR0, sscr0);
+
+       /* bit size */
+       sscr0 = ssp_read_reg(ssp, SSCR0);
+       switch (params_format(params)) {
+       case SNDRV_PCM_FORMAT_S16_LE:
+#ifdef CONFIG_PXA3xx
+               if (cpu_is_pxa3xx())
+                       sscr0 |= SSCR0_FPCKE;
+#endif
+               sscr0 |= SSCR0_DataSize(16);
+               if (params_channels(params) > 1)
+                       sscr0 |= SSCR0_EDSS;
+               break;
+       case SNDRV_PCM_FORMAT_S24_LE:
+               sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
+               /* we must be in network mode (2 slots) for 24 bit stereo */
+               break;
+       case SNDRV_PCM_FORMAT_S32_LE:
+               sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
+               /* we must be in network mode (2 slots) for 32 bit stereo */
+               break;
+       }
+       ssp_write_reg(ssp, SSCR0, sscr0);
+
+       switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+       case SND_SOC_DAIFMT_I2S:
+               /* Cleared when the DAI format is set */
+               sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width);
+               ssp_write_reg(ssp, SSPSP, sspsp);
+               break;
+       default:
+               break;
+       }
+
+       /* We always use a network mode so we always require TDM slots
+        * - complain loudly and fail if they've not been set up yet.
+        */
+       if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) {
+               dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
+               return -EINVAL;
+       }
+
+       dump_registers(ssp);
+
+       return 0;
+}
+
+static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
+                          struct snd_soc_dai *dai)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       int ret = 0;
+       struct ssp_priv *priv = cpu_dai->private_data;
+       struct ssp_device *ssp = priv->dev.ssp;
+       int val;
+
+       switch (cmd) {
+       case SNDRV_PCM_TRIGGER_RESUME:
+               ssp_enable(&priv->dev);
+               break;
+       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+               val = ssp_read_reg(ssp, SSCR1);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       val |= SSCR1_TSRE;
+               else
+                       val |= SSCR1_RSRE;
+               ssp_write_reg(ssp, SSCR1, val);
+               val = ssp_read_reg(ssp, SSSR);
+               ssp_write_reg(ssp, SSSR, val);
+               break;
+       case SNDRV_PCM_TRIGGER_START:
+               val = ssp_read_reg(ssp, SSCR1);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       val |= SSCR1_TSRE;
+               else
+                       val |= SSCR1_RSRE;
+               ssp_write_reg(ssp, SSCR1, val);
+               ssp_enable(&priv->dev);
+               break;
+       case SNDRV_PCM_TRIGGER_STOP:
+               val = ssp_read_reg(ssp, SSCR1);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       val &= ~SSCR1_TSRE;
+               else
+                       val &= ~SSCR1_RSRE;
+               ssp_write_reg(ssp, SSCR1, val);
+               break;
+       case SNDRV_PCM_TRIGGER_SUSPEND:
+               ssp_disable(&priv->dev);
+               break;
+       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+               val = ssp_read_reg(ssp, SSCR1);
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       val &= ~SSCR1_TSRE;
+               else
+                       val &= ~SSCR1_RSRE;
+               ssp_write_reg(ssp, SSCR1, val);
+               break;
+
+       default:
+               ret = -EINVAL;
+       }
+
+       dump_registers(ssp);
+
+       return ret;
+}
+
+static int pxa_ssp_probe(struct platform_device *pdev,
+                           struct snd_soc_dai *dai)
+{
+       struct ssp_priv *priv;
+       int ret;
+
+       priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       priv->dev.ssp = ssp_request(dai->id, "SoC audio");
+       if (priv->dev.ssp == NULL) {
+               ret = -ENODEV;
+               goto err_priv;
+       }
+
+       dai->private_data = priv;
+
+       return 0;
+
+err_priv:
+       kfree(priv);
+       return ret;
+}
+
+static void pxa_ssp_remove(struct platform_device *pdev,
+                             struct snd_soc_dai *dai)
+{
+       struct ssp_priv *priv = dai->private_data;
+       ssp_free(priv->dev.ssp);
+}
+
+#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
+                         SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
+                         SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
+                         SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
+
+#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+                           SNDRV_PCM_FMTBIT_S24_LE |   \
+                           SNDRV_PCM_FMTBIT_S32_LE)
+
+struct snd_soc_dai pxa_ssp_dai[] = {
+       {
+               .name = "pxa2xx-ssp1",
+               .id = 0,
+               .probe = pxa_ssp_probe,
+               .remove = pxa_ssp_remove,
+               .suspend = pxa_ssp_suspend,
+               .resume = pxa_ssp_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+               },
+               .capture = {
+                        .channels_min = 1,
+                        .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+                },
+               .ops = {
+                       .startup = pxa_ssp_startup,
+                       .shutdown = pxa_ssp_shutdown,
+                       .trigger = pxa_ssp_trigger,
+                       .hw_params = pxa_ssp_hw_params,
+                       .set_sysclk = pxa_ssp_set_dai_sysclk,
+                       .set_clkdiv = pxa_ssp_set_dai_clkdiv,
+                       .set_pll = pxa_ssp_set_dai_pll,
+                       .set_fmt = pxa_ssp_set_dai_fmt,
+                       .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
+                       .set_tristate = pxa_ssp_set_dai_tristate,
+               },
+       },
+       {       .name = "pxa2xx-ssp2",
+               .id = 1,
+               .probe = pxa_ssp_probe,
+               .remove = pxa_ssp_remove,
+               .suspend = pxa_ssp_suspend,
+               .resume = pxa_ssp_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+               },
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+                },
+               .ops = {
+                       .startup = pxa_ssp_startup,
+                       .shutdown = pxa_ssp_shutdown,
+                       .trigger = pxa_ssp_trigger,
+                       .hw_params = pxa_ssp_hw_params,
+                       .set_sysclk = pxa_ssp_set_dai_sysclk,
+                       .set_clkdiv = pxa_ssp_set_dai_clkdiv,
+                       .set_pll = pxa_ssp_set_dai_pll,
+                       .set_fmt = pxa_ssp_set_dai_fmt,
+                       .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
+                       .set_tristate = pxa_ssp_set_dai_tristate,
+               },
+       },
+       {
+               .name = "pxa2xx-ssp3",
+               .id = 2,
+               .probe = pxa_ssp_probe,
+               .remove = pxa_ssp_remove,
+               .suspend = pxa_ssp_suspend,
+               .resume = pxa_ssp_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+               },
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+                },
+               .ops = {
+                       .startup = pxa_ssp_startup,
+                       .shutdown = pxa_ssp_shutdown,
+                       .trigger = pxa_ssp_trigger,
+                       .hw_params = pxa_ssp_hw_params,
+                       .set_sysclk = pxa_ssp_set_dai_sysclk,
+                       .set_clkdiv = pxa_ssp_set_dai_clkdiv,
+                       .set_pll = pxa_ssp_set_dai_pll,
+                       .set_fmt = pxa_ssp_set_dai_fmt,
+                       .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
+                       .set_tristate = pxa_ssp_set_dai_tristate,
+               },
+       },
+       {
+               .name = "pxa2xx-ssp4",
+               .id = 3,
+               .probe = pxa_ssp_probe,
+               .remove = pxa_ssp_remove,
+               .suspend = pxa_ssp_suspend,
+               .resume = pxa_ssp_resume,
+               .playback = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+               },
+               .capture = {
+                       .channels_min = 1,
+                       .channels_max = 2,
+                       .rates = PXA_SSP_RATES,
+                       .formats = PXA_SSP_FORMATS,
+                },
+               .ops = {
+                       .startup = pxa_ssp_startup,
+                       .shutdown = pxa_ssp_shutdown,
+                       .trigger = pxa_ssp_trigger,
+                       .hw_params = pxa_ssp_hw_params,
+                       .set_sysclk = pxa_ssp_set_dai_sysclk,
+                       .set_clkdiv = pxa_ssp_set_dai_clkdiv,
+                       .set_pll = pxa_ssp_set_dai_pll,
+                       .set_fmt = pxa_ssp_set_dai_fmt,
+                       .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
+                       .set_tristate = pxa_ssp_set_dai_tristate,
+               },
+       },
+};
+EXPORT_SYMBOL_GPL(pxa_ssp_dai);
+
+static int __init pxa_ssp_init(void)
+{
+       return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+}
+module_init(pxa_ssp_init);
+
+static void __exit pxa_ssp_exit(void)
+{
+       snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
+}
+module_exit(pxa_ssp_exit);
+
+/* Module information */
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
+MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
new file mode 100644 (file)
index 0000000..91deadd
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * ASoC PXA SSP port support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef _PXA_SSP_H
+#define _PXA_SSP_H
+
+/* pxa DAI SSP IDs */
+#define PXA_DAI_SSP1                   0
+#define PXA_DAI_SSP2                   1
+#define PXA_DAI_SSP3                   2
+#define PXA_DAI_SSP4                   3
+
+/* SSP clock sources */
+#define PXA_SSP_CLK_PLL        0
+#define PXA_SSP_CLK_EXT        1
+#define PXA_SSP_CLK_NET        2
+#define PXA_SSP_CLK_AUDIO      3
+#define PXA_SSP_CLK_NET_PLL    4
+
+/* SSP audio dividers */
+#define PXA_SSP_AUDIO_DIV_ACDS         0
+#define PXA_SSP_AUDIO_DIV_SCDB         1
+#define PXA_SSP_DIV_SCR                                2
+
+/* SSP ACDS audio dividers values */
+#define PXA_SSP_CLK_AUDIO_DIV_1                0
+#define PXA_SSP_CLK_AUDIO_DIV_2                1
+#define PXA_SSP_CLK_AUDIO_DIV_4                2
+#define PXA_SSP_CLK_AUDIO_DIV_8                3
+#define PXA_SSP_CLK_AUDIO_DIV_16       4
+#define PXA_SSP_CLK_AUDIO_DIV_32       5
+
+/* SSP divider bypass */
+#define PXA_SSP_CLK_SCDB_4             0
+#define PXA_SSP_CLK_SCDB_1             1
+#define PXA_SSP_CLK_SCDB_8             2
+
+#define PXA_SSP_PLL_OUT  0
+
+extern struct snd_soc_dai pxa_ssp_dai[4];
+
+#endif
index a7a3a9c5c6ff41c6eee5ce690106de63823eb458..780db6757ad2ee4990887a78cc4485493ecab2b6 100644 (file)
@@ -87,14 +87,12 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
 };
 
 #ifdef CONFIG_PM
-static int pxa2xx_ac97_suspend(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
+static int pxa2xx_ac97_suspend(struct snd_soc_dai *dai)
 {
        return pxa2xx_ac97_hw_suspend();
 }
 
-static int pxa2xx_ac97_resume(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
+static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
 {
        return pxa2xx_ac97_hw_resume();
 }
@@ -117,7 +115,8 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev,
 }
 
 static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -131,7 +130,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
 }
 
 static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                                    struct snd_pcm_hw_params *params,
+                                    struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -145,7 +145,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
 }
 
 static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                                    struct snd_pcm_hw_params *params,
+                                    struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -170,7 +171,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
 {
        .name = "pxa2xx-ac97",
        .id = 0,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .probe = pxa2xx_ac97_probe,
        .remove = pxa2xx_ac97_remove,
        .suspend = pxa2xx_ac97_suspend,
@@ -193,7 +194,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
 {
        .name = "pxa2xx-ac97-aux",
        .id = 1,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .playback = {
                .stream_name = "AC97 Aux Playback",
                .channels_min = 1,
@@ -212,7 +213,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
 {
        .name = "pxa2xx-ac97-mic",
        .id = 2,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .capture = {
                .stream_name = "AC97 Mic Capture",
                .channels_min = 1,
@@ -227,6 +228,18 @@ struct snd_soc_dai pxa_ac97_dai[] = {
 EXPORT_SYMBOL_GPL(pxa_ac97_dai);
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
+static int __init pxa_ac97_init(void)
+{
+       return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
+}
+module_init(pxa_ac97_init);
+
+static void __exit pxa_ac97_exit(void)
+{
+       snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
+}
+module_exit(pxa_ac97_exit);
+
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
 MODULE_LICENSE("GPL");
index e758034db5c3ba38422e07592b2a933dc3e50b81..517991fb10993f16cdbdc758479885da69a840d4 100644 (file)
@@ -121,7 +121,8 @@ static struct pxa2xx_gpio gpio_bus[] = {
        },
 };
 
-static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream)
+static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
+                             struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -187,7 +188,8 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
 }
 
 static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+                               struct snd_pcm_hw_params *params,
+                               struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -248,7 +250,8 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                             struct snd_soc_dai *dai)
 {
        int ret = 0;
 
@@ -269,7 +272,8 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
        return ret;
 }
 
-static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
+static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
+                               struct snd_soc_dai *dai)
 {
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                SACR1 |= SACR1_DRPL;
@@ -289,8 +293,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
 }
 
 #ifdef CONFIG_PM
-static int pxa2xx_i2s_suspend(struct platform_device *dev,
-       struct snd_soc_dai *dai)
+static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
 {
        if (!dai->active)
                return 0;
@@ -307,8 +310,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev,
        return 0;
 }
 
-static int pxa2xx_i2s_resume(struct platform_device *pdev,
-       struct snd_soc_dai *dai)
+static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
 {
        if (!dai->active)
                return 0;
@@ -336,7 +338,6 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev,
 struct snd_soc_dai pxa_i2s_dai = {
        .name = "pxa2xx-i2s",
        .id = 0,
-       .type = SND_SOC_DAI_I2S,
        .suspend = pxa2xx_i2s_suspend,
        .resume = pxa2xx_i2s_resume,
        .playback = {
@@ -353,8 +354,7 @@ struct snd_soc_dai pxa_i2s_dai = {
                .startup = pxa2xx_i2s_startup,
                .shutdown = pxa2xx_i2s_shutdown,
                .trigger = pxa2xx_i2s_trigger,
-               .hw_params = pxa2xx_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = pxa2xx_i2s_hw_params,
                .set_fmt = pxa2xx_i2s_set_dai_fmt,
                .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
        },
@@ -364,12 +364,23 @@ EXPORT_SYMBOL_GPL(pxa_i2s_dai);
 
 static int pxa2xx_i2s_probe(struct platform_device *dev)
 {
+       int ret;
+
        clk_i2s = clk_get(&dev->dev, "I2SCLK");
-       return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0;
+       if (IS_ERR(clk_i2s))
+               return PTR_ERR(clk_i2s);
+
+       pxa_i2s_dai.dev = &dev->dev;
+       ret = snd_soc_register_dai(&pxa_i2s_dai);
+       if (ret != 0)
+               clk_put(clk_i2s);
+
+       return ret;
 }
 
 static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
 {
+       snd_soc_unregister_dai(&pxa_i2s_dai);
        clk_put(clk_i2s);
        clk_i2s = ERR_PTR(-ENOENT);
        return 0;
index afcd892cd2fa42f0526defd607bd58db9f5722ec..c670d08e7c9ede6223b24b4ef78e8c2465859b89 100644 (file)
@@ -69,7 +69,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
        return 0;
 }
 
-struct snd_pcm_ops pxa2xx_pcm_ops = {
+static struct snd_pcm_ops pxa2xx_pcm_ops = {
        .open           = __pxa2xx_pcm_open,
        .close          = __pxa2xx_pcm_close,
        .ioctl          = snd_pcm_lib_ioctl,
@@ -118,6 +118,18 @@ struct snd_soc_platform pxa2xx_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
 
+static int __init pxa2xx_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&pxa2xx_soc_platform);
+}
+module_init(pxa2xx_soc_platform_init);
+
+static void __exit pxa2xx_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&pxa2xx_soc_platform);
+}
+module_exit(pxa2xx_soc_platform_exit);
+
 MODULE_AUTHOR("Nicolas Pitre");
 MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
 MODULE_LICENSE("GPL");
index d307b6757e9550646b565a4cffaac5abc0a02007..a3b9e6bdf9794cb1350d34448efeddbee1989591 100644 (file)
@@ -319,8 +319,9 @@ static struct snd_soc_dai_link spitz_dai = {
 };
 
 /* spitz audio machine driver */
-static struct snd_soc_machine snd_soc_machine_spitz = {
+static struct snd_soc_card snd_soc_spitz = {
        .name = "Spitz",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = &spitz_dai,
        .num_links = 1,
 };
@@ -333,8 +334,7 @@ static struct wm8750_setup_data spitz_wm8750_setup = {
 
 /* spitz audio subsystem */
 static struct snd_soc_device spitz_snd_devdata = {
-       .machine = &snd_soc_machine_spitz,
-       .platform = &pxa2xx_soc_platform,
+       .card = &snd_soc_spitz,
        .codec_dev = &soc_codec_dev_wm8750,
        .codec_data = &spitz_wm8750_setup,
 };
index afefe41b8c46c9f47ae255b14ec1ebed56e3522e..c77194f74c9b56eea9438db006c0d4b37b7912b5 100644 (file)
@@ -38,7 +38,7 @@
 #include "pxa2xx-pcm.h"
 #include "pxa2xx-ac97.h"
 
-static struct snd_soc_machine tosa;
+static struct snd_soc_card tosa;
 
 #define TOSA_HP        0
 #define TOSA_MIC_INT   1
@@ -230,15 +230,37 @@ static struct snd_soc_dai_link tosa_dai[] = {
 },
 };
 
-static struct snd_soc_machine tosa = {
+static int tosa_probe(struct platform_device *dev)
+{
+       int ret;
+
+       ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
+       if (ret)
+               return ret;
+       ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
+       if (ret)
+               gpio_free(TOSA_GPIO_L_MUTE);
+
+       return ret;
+}
+
+static int tosa_remove(struct platform_device *dev)
+{
+       gpio_free(TOSA_GPIO_L_MUTE);
+       return 0;
+}
+
+static struct snd_soc_card tosa = {
        .name = "Tosa",
+       .platform = &pxa2xx_soc_platform,
        .dai_link = tosa_dai,
        .num_links = ARRAY_SIZE(tosa_dai),
+       .probe = tosa_probe,
+       .remove = tosa_remove,
 };
 
 static struct snd_soc_device tosa_snd_devdata = {
-       .machine = &tosa,
-       .platform = &pxa2xx_soc_platform,
+       .card = &tosa,
        .codec_dev = &soc_codec_dev_wm9712,
 };
 
@@ -251,11 +273,6 @@ static int __init tosa_init(void)
        if (!machine_is_tosa())
                return -ENODEV;
 
-       ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
-       if (ret)
-               return ret;
-       gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
-
        tosa_snd_device = platform_device_alloc("soc-audio", -1);
        if (!tosa_snd_device) {
                ret = -ENOMEM;
@@ -272,15 +289,12 @@ static int __init tosa_init(void)
        platform_device_put(tosa_snd_device);
 
 err_alloc:
-       gpio_free(TOSA_GPIO_L_MUTE);
-
        return ret;
 }
 
 static void __exit tosa_exit(void)
 {
        platform_device_unregister(tosa_snd_device);
-       gpio_free(TOSA_GPIO_L_MUTE);
 }
 
 module_init(tosa_init);
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
new file mode 100644 (file)
index 0000000..f8e9ecd
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * zylonite.c  --  SoC audio for Zylonite
+ *
+ * Copyright 2008 Wolfson Microelectronics PLC.
+ * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include "../codecs/wm9713.h"
+#include "pxa2xx-pcm.h"
+#include "pxa2xx-ac97.h"
+#include "pxa-ssp.h"
+
+static struct snd_soc_card zylonite;
+
+static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
+       SND_SOC_DAPM_HP("Headphone", NULL),
+       SND_SOC_DAPM_MIC("Headset Microphone", NULL),
+       SND_SOC_DAPM_MIC("Handset Microphone", NULL),
+       SND_SOC_DAPM_SPK("Multiactor", NULL),
+       SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
+};
+
+/* Currently supported audio map */
+static const struct snd_soc_dapm_route audio_map[] = {
+
+       /* Headphone output connected to HPL/HPR */
+       { "Headphone", NULL,  "HPL" },
+       { "Headphone", NULL,  "HPR" },
+
+       /* On-board earpiece */
+       { "Headset Earpiece", NULL, "OUT3" },
+
+       /* Headphone mic */
+       { "MIC2A", NULL, "Mic Bias" },
+       { "Mic Bias", NULL, "Headset Microphone" },
+
+       /* On-board mic */
+       { "MIC1", NULL, "Mic Bias" },
+       { "Mic Bias", NULL, "Handset Microphone" },
+
+       /* Multiactor differentially connected over SPKL/SPKR */
+       { "Multiactor", NULL, "SPKL" },
+       { "Multiactor", NULL, "SPKR" },
+};
+
+static int zylonite_wm9713_init(struct snd_soc_codec *codec)
+{
+       /* Currently we only support use of the AC97 clock here.  If
+        * CLK_POUT is selected by SW15 then the clock API will need
+        * to be used to request and enable it here.
+        */
+
+       snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
+                                 ARRAY_SIZE(zylonite_dapm_widgets));
+
+       snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
+
+       /* Static setup for now */
+       snd_soc_dapm_enable_pin(codec, "Headphone");
+       snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
+
+       snd_soc_dapm_sync(codec);
+       return 0;
+}
+
+static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
+                                   struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       unsigned int pll_out = 0;
+       unsigned int acds = 0;
+       unsigned int wm9713_div = 0;
+       int ret = 0;
+
+       switch (params_rate(params)) {
+       case 8000:
+               wm9713_div = 12;
+               pll_out = 2048000;
+               break;
+       case 16000:
+               wm9713_div = 6;
+               pll_out = 4096000;
+               break;
+       case 48000:
+       default:
+               wm9713_div = 2;
+               pll_out = 12288000;
+               acds = 1;
+               break;
+       }
+
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+               SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_tdm_slot(cpu_dai,
+                                      params_channels(params),
+                                      params_channels(params));
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
+       if (ret < 0)
+               return ret;
+
+       /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs
+        * to be set instead.
+        */
+       ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
+                                    WM9713_PCMDIV(wm9713_div));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops zylonite_voice_ops = {
+       .hw_params = zylonite_voice_hw_params,
+};
+
+static struct snd_soc_dai_link zylonite_dai[] = {
+{
+       .name = "AC97",
+       .stream_name = "AC97 HiFi",
+       .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
+       .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
+       .init = zylonite_wm9713_init,
+},
+{
+       .name = "AC97 Aux",
+       .stream_name = "AC97 Aux",
+       .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
+       .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
+},
+{
+       .name = "WM9713 Voice",
+       .stream_name = "WM9713 Voice",
+       .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
+       .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
+       .ops = &zylonite_voice_ops,
+},
+};
+
+static struct snd_soc_card zylonite = {
+       .name = "Zylonite",
+       .platform = &pxa2xx_soc_platform,
+       .dai_link = zylonite_dai,
+       .num_links = ARRAY_SIZE(zylonite_dai),
+};
+
+static struct snd_soc_device zylonite_snd_ac97_devdata = {
+       .card = &zylonite,
+       .codec_dev = &soc_codec_dev_wm9713,
+};
+
+static struct platform_device *zylonite_snd_ac97_device;
+
+static int __init zylonite_init(void)
+{
+       int ret;
+
+       zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
+       if (!zylonite_snd_ac97_device)
+               return -ENOMEM;
+
+       platform_set_drvdata(zylonite_snd_ac97_device,
+                            &zylonite_snd_ac97_devdata);
+       zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
+
+       ret = platform_device_add(zylonite_snd_ac97_device);
+       if (ret != 0)
+               platform_device_put(zylonite_snd_ac97_device);
+
+       return ret;
+}
+
+static void __exit zylonite_exit(void)
+{
+       platform_device_unregister(zylonite_snd_ac97_device);
+}
+
+module_init(zylonite_init);
+module_exit(zylonite_exit);
+
+MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
+MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
+MODULE_LICENSE("GPL");
index b9f2353effebfba49cf5010c10bcf5b2794781c6..fcd03acf10f6cd4a51d504c12ed4bf4c49d84eb8 100644 (file)
@@ -44,3 +44,8 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
          Say Y if you want to add support for SoC audio on ln2440sbc
          with the ALC650.
 
+config SND_S3C24XX_SOC_S3C24XX_UDA134X
+       tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
+               depends on SND_S3C24XX_SOC
+               select SND_S3C24XX_SOC_I2S
+               select SND_SOC_UDA134X
index 0aa5fb0b9700ae5d4db9ff3704da92aa18c7bfa9..96b3f3f617d4280dddb8fa03c5d0aa95ec9a1e11 100644 (file)
@@ -13,7 +13,9 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
 snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
 snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
 snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
+snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
 
 obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
 obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
 obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
+obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
index 4eab2c19c454dbda65a62a4e000f05841332c0c5..12c71482d258b35c70d22ecf9e9c18441b57a575 100644 (file)
@@ -27,7 +27,7 @@
 #include "s3c24xx-pcm.h"
 #include "s3c24xx-ac97.h"
 
-static struct snd_soc_machine ln2440sbc;
+static struct snd_soc_card ln2440sbc;
 
 static struct snd_soc_dai_link ln2440sbc_dai[] = {
 {
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
 },
 };
 
-static struct snd_soc_machine ln2440sbc = {
+static struct snd_soc_card ln2440sbc = {
        .name = "LN2440SBC",
+       .platform = &s3c24xx_soc_platform,
        .dai_link = ln2440sbc_dai,
        .num_links = ARRAY_SIZE(ln2440sbc_dai),
 };
 
 static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
-       .machine = &ln2440sbc,
-       .platform = &s3c24xx_soc_platform,
+       .card = &ln2440sbc,
        .codec_dev = &soc_codec_dev_ac97,
 };
 
index 87ddfefcc2fba18b821f3b154fbe03d86e1bf3e7..45bb12e8ea447df922a5f99c02d9479569bd632d 100644 (file)
@@ -59,7 +59,7 @@
 #define NEO_CAPTURE_HEADSET            7
 #define NEO_CAPTURE_BLUETOOTH          8
 
-static struct snd_soc_machine neo1973;
+static struct snd_soc_card neo1973;
 static struct i2c_client *i2c;
 
 static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
@@ -548,7 +548,6 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
 static struct snd_soc_dai bt_dai = {
        .name = "Bluetooth",
        .id = 0,
-       .type = SND_SOC_DAI_PCM,
        .playback = {
                .channels_min = 1,
                .channels_max = 1,
@@ -579,8 +578,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
 },
 };
 
-static struct snd_soc_machine neo1973 = {
+static struct snd_soc_card neo1973 = {
        .name = "neo1973",
+       .platform = &s3c24xx_soc_platform,
        .dai_link = neo1973_dai,
        .num_links = ARRAY_SIZE(neo1973_dai),
 };
@@ -591,8 +591,7 @@ static struct wm8753_setup_data neo1973_wm8753_setup = {
 };
 
 static struct snd_soc_device neo1973_snd_devdata = {
-       .machine = &neo1973,
-       .platform = &s3c24xx_soc_platform,
+       .card = &neo1973,
        .codec_dev = &soc_codec_dev_wm8753,
        .codec_data = &neo1973_wm8753_setup,
 };
index ded7d995a9228a5f0d9080cbc4575cfd2216cd32..f3fc0aba0aaf78755d2e0170eeabcc82d575f31b 100644 (file)
@@ -343,7 +343,8 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 }
 
 static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
-                                struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        u32 iismod;
@@ -373,7 +374,8 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *dai)
 {
        int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
        unsigned long irqs;
@@ -647,8 +649,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
 }
 
 #ifdef CONFIG_PM
-static int s3c2412_i2s_suspend(struct platform_device *dev,
-                             struct snd_soc_dai *dai)
+static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
 {
        struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
        u32 iismod;
@@ -663,25 +664,24 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
                iismod = readl(i2s->regs + S3C2412_IISMOD);
 
                if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
-                       dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__);
+                       pr_warning("%s: RXDMA active?\n", __func__);
 
                if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
-                       dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__);
+                       pr_warning("%s: TXDMA active?\n", __func__);
 
                if (iismod & S3C2412_IISCON_IIS_ACTIVE)
-                       dev_warn(&dev->dev, "%s: IIS active\n", __func__);
+                       pr_warning("%s: IIS active\n", __func__);
        }
 
        return 0;
 }
 
-static int s3c2412_i2s_resume(struct platform_device *pdev,
-                             struct snd_soc_dai *dai)
+static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
 {
        struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
 
-       dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n",
-                dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
+       pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
+               dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
 
        if (dai->active) {
                writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
@@ -711,7 +711,6 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
 struct snd_soc_dai s3c2412_i2s_dai = {
        .name   = "s3c2412-i2s",
        .id     = 0,
-       .type   = SND_SOC_DAI_I2S,
        .probe  = s3c2412_i2s_probe,
        .suspend = s3c2412_i2s_suspend,
        .resume = s3c2412_i2s_resume,
@@ -730,8 +729,6 @@ struct snd_soc_dai s3c2412_i2s_dai = {
        .ops = {
                .trigger        = s3c2412_i2s_trigger,
                .hw_params      = s3c2412_i2s_hw_params,
-       },
-       .dai_ops = {
                .set_fmt        = s3c2412_i2s_set_fmt,
                .set_clkdiv     = s3c2412_i2s_set_clkdiv,
                .set_sysclk     = s3c2412_i2s_set_sysclk,
@@ -739,6 +736,19 @@ struct snd_soc_dai s3c2412_i2s_dai = {
 };
 EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
 
+static int __init s3c2412_i2s_init(void)
+{
+       return snd_soc_register_dai(&s3c2412_i2s_dai);
+}
+module_init(s3c2412_i2s_init);
+
+static void __exit s3c2412_i2s_exit(void)
+{
+       snd_soc_unregister_dai(&s3c2412_i2s_dai);
+}
+module_exit(s3c2412_i2s_exit);
+
+
 /* Module information */
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
index 19c5c3cf5d8c64138e31d9b70b489768309159a1..1bfce40bb2e457a56eea42ec6d78a2ad15cffd6a 100644 (file)
@@ -271,7 +271,8 @@ static void s3c2443_ac97_remove(struct platform_device *pdev,
 }
 
 static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+                                 struct snd_pcm_hw_params *params,
+                                 struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -284,7 +285,8 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
+static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
+                               struct snd_soc_dai *dai)
 {
        u32 ac_glbctrl;
 
@@ -313,7 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
 }
 
 static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
-       struct snd_pcm_hw_params *params)
+                                     struct snd_pcm_hw_params *params,
+                                     struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -327,7 +330,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
 }
 
 static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
-       int cmd)
+                                   int cmd, struct snd_soc_dai *dai)
 {
        u32 ac_glbctrl;
 
@@ -356,7 +359,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
 {
        .name = "s3c2443-ac97",
        .id = 0,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .probe = s3c2443_ac97_probe,
        .remove = s3c2443_ac97_remove,
        .playback = {
@@ -378,7 +381,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
 {
        .name = "pxa2xx-ac97-mic",
        .id = 1,
-       .type = SND_SOC_DAI_AC97,
+       .ac97_control = 1,
        .capture = {
                .stream_name = "AC97 Mic Capture",
                .channels_min = 1,
@@ -393,6 +396,21 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
 EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
+static int __init s3c2443_ac97_init(void)
+{
+       return snd_soc_register_dais(s3c2443_ac97_dai,
+                                    ARRAY_SIZE(s3c2443_ac97_dai));
+}
+module_init(s3c2443_ac97_init);
+
+static void __exit s3c2443_ac97_exit(void)
+{
+       snd_soc_unregister_dais(s3c2443_ac97_dai,
+                               ARRAY_SIZE(s3c2443_ac97_dai));
+}
+module_exit(s3c2443_ac97_exit);
+
+
 MODULE_AUTHOR("Graeme Gregory");
 MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
 MODULE_LICENSE("GPL");
index ba4476b55fbcc1f0e67f1311418fd015b1f3bef4..6f4d439b57aaecf4a388d8a2ce80c3caa9301ace 100644 (file)
@@ -243,7 +243,8 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
 }
 
 static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
-                               struct snd_pcm_hw_params *params)
+                                struct snd_pcm_hw_params *params,
+                                struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        u32 iismod;
@@ -261,10 +262,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
 
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S8:
+               iismod &= ~S3C2410_IISMOD_16BIT;
+               ((struct s3c24xx_pcm_dma_params *)
+                 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
                break;
        case SNDRV_PCM_FORMAT_S16_LE:
                iismod |= S3C2410_IISMOD_16BIT;
+               ((struct s3c24xx_pcm_dma_params *)
+                 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
                break;
+       default:
+               return -EINVAL;
        }
 
        writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -272,7 +280,8 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
+static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
+                              struct snd_soc_dai *dai)
 {
        int ret = 0;
 
@@ -410,8 +419,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
 }
 
 #ifdef CONFIG_PM
-static int s3c24xx_i2s_suspend(struct platform_device *pdev,
-               struct snd_soc_dai *cpu_dai)
+static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
 {
        DBG("Entered %s\n", __func__);
 
@@ -425,8 +433,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
        return 0;
 }
 
-static int s3c24xx_i2s_resume(struct platform_device *pdev,
-               struct snd_soc_dai *cpu_dai)
+static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
 {
        DBG("Entered %s\n", __func__);
        clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +459,6 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
 struct snd_soc_dai s3c24xx_i2s_dai = {
        .name = "s3c24xx-i2s",
        .id = 0,
-       .type = SND_SOC_DAI_I2S,
        .probe = s3c24xx_i2s_probe,
        .suspend = s3c24xx_i2s_suspend,
        .resume = s3c24xx_i2s_resume,
@@ -468,8 +474,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
                .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
        .ops = {
                .trigger = s3c24xx_i2s_trigger,
-               .hw_params = s3c24xx_i2s_hw_params,},
-       .dai_ops = {
+               .hw_params = s3c24xx_i2s_hw_params,
                .set_fmt = s3c24xx_i2s_set_fmt,
                .set_clkdiv = s3c24xx_i2s_set_clkdiv,
                .set_sysclk = s3c24xx_i2s_set_sysclk,
@@ -477,6 +482,18 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
 };
 EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
 
+static int __init s3c24xx_i2s_init(void)
+{
+       return snd_soc_register_dai(&s3c24xx_i2s_dai);
+}
+module_init(s3c24xx_i2s_init);
+
+static void __exit s3c24xx_i2s_exit(void)
+{
+       snd_soc_unregister_dai(&s3c24xx_i2s_dai);
+}
+module_exit(s3c24xx_i2s_exit);
+
 /* Module information */
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
index e13e614bada9aca7beeaecd85b8eb3f14f92a2a8..7c64d31d067e7283714c070001cf4c7f99764f84 100644 (file)
@@ -465,6 +465,18 @@ struct snd_soc_platform s3c24xx_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
 
+static int __init s3c24xx_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&s3c24xx_soc_platform);
+}
+module_init(s3c24xx_soc_platform_init);
+
+static void __exit s3c24xx_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&s3c24xx_soc_platform);
+}
+module_exit(s3c24xx_soc_platform_exit);
+
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
 MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
new file mode 100644 (file)
index 0000000..a0a4d18
--- /dev/null
@@ -0,0 +1,373 @@
+/*
+ * Modifications by Christian Pellegrin <chripell@evolware.org>
+ *
+ * s3c24xx_uda134x.c  --  S3C24XX_UDA134X ALSA SoC Audio board driver
+ *
+ * Copyright 2007 Dension Audio Systems Ltd.
+ * Author: Zoltan Devai
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/s3c24xx_uda134x.h>
+#include <sound/uda134x.h>
+
+#include <asm/plat-s3c24xx/regs-iis.h>
+
+#include "s3c24xx-pcm.h"
+#include "s3c24xx-i2s.h"
+#include "../codecs/uda134x.h"
+
+
+/* #define ENFORCE_RATES 1 */
+/*
+  Unfortunately the S3C24XX in master mode has a limited capacity of
+  generating the clock for the codec. If you define this only rates
+  that are really available will be enforced. But be careful, most
+  user level application just want the usual sampling frequencies (8,
+  11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
+  operation for embedded systems. So if you aren't very lucky or your
+  hardware engineer wasn't very forward-looking it's better to leave
+  this undefined. If you do so an approximate value for the requested
+  sampling rate in the range -/+ 5% will be chosen. If this in not
+  possible an error will be returned.
+*/
+
+static struct clk *xtal;
+static struct clk *pclk;
+/* this is need because we don't have a place where to keep the
+ * pointers to the clocks in each substream. We get the clocks only
+ * when we are actually using them so we don't block stuff like
+ * frequency change or oscillator power-off */
+static int clk_users;
+static DEFINE_MUTEX(clk_lock);
+
+static unsigned int rates[33 * 2];
+#ifdef ENFORCE_RATES
+static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
+       .count  = ARRAY_SIZE(rates),
+       .list   = rates,
+       .mask   = 0,
+};
+#endif
+
+static struct platform_device *s3c24xx_uda134x_snd_device;
+
+static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
+{
+       int ret = 0;
+#ifdef ENFORCE_RATES
+       struct snd_pcm_runtime *runtime = substream->runtime;;
+#endif
+
+       mutex_lock(&clk_lock);
+       pr_debug("%s %d\n", __func__, clk_users);
+       if (clk_users == 0) {
+               xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
+               if (!xtal) {
+                       printk(KERN_ERR "%s cannot get xtal\n", __func__);
+                       ret = -EBUSY;
+               } else {
+                       pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
+                                      "pclk");
+                       if (!pclk) {
+                               printk(KERN_ERR "%s cannot get pclk\n",
+                                      __func__);
+                               clk_put(xtal);
+                               ret = -EBUSY;
+                       }
+               }
+               if (!ret) {
+                       int i, j;
+
+                       for (i = 0; i < 2; i++) {
+                               int fs = i ? 256 : 384;
+
+                               rates[i*33] = clk_get_rate(xtal) / fs;
+                               for (j = 1; j < 33; j++)
+                                       rates[i*33 + j] = clk_get_rate(pclk) /
+                                               (j * fs);
+                       }
+               }
+       }
+       clk_users += 1;
+       mutex_unlock(&clk_lock);
+       if (!ret) {
+#ifdef ENFORCE_RATES
+               ret = snd_pcm_hw_constraint_list(runtime, 0,
+                                                SNDRV_PCM_HW_PARAM_RATE,
+                                                &hw_constraints_rates);
+               if (ret < 0)
+                       printk(KERN_ERR "%s cannot set constraints\n",
+                              __func__);
+#endif
+       }
+       return ret;
+}
+
+static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
+{
+       mutex_lock(&clk_lock);
+       pr_debug("%s %d\n", __func__, clk_users);
+       clk_users -= 1;
+       if (clk_users == 0) {
+               clk_put(xtal);
+               xtal = NULL;
+               clk_put(pclk);
+               pclk = NULL;
+       }
+       mutex_unlock(&clk_lock);
+}
+
+static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
+                                       struct snd_pcm_hw_params *params)
+{
+       struct snd_soc_pcm_runtime *rtd = substream->private_data;
+       struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+       struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+       unsigned int clk = 0;
+       int ret = 0;
+       int clk_source, fs_mode;
+       unsigned long rate = params_rate(params);
+       long err, cerr;
+       unsigned int div;
+       int i, bi;
+
+       err = 999999;
+       bi = 0;
+       for (i = 0; i < 2*33; i++) {
+               cerr = rates[i] - rate;
+               if (cerr < 0)
+                       cerr = -cerr;
+               if (cerr < err) {
+                       err = cerr;
+                       bi = i;
+               }
+       }
+       if (bi / 33 == 1)
+               fs_mode = S3C2410_IISMOD_256FS;
+       else
+               fs_mode = S3C2410_IISMOD_384FS;
+       if (bi % 33 == 0) {
+               clk_source = S3C24XX_CLKSRC_MPLL;
+               div = 1;
+       } else {
+               clk_source = S3C24XX_CLKSRC_PCLK;
+               div = bi % 33;
+       }
+       pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
+
+       clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
+       pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
+                fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
+                clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
+                div, clk, err);
+
+       if ((err * 100 / rate) > 5) {
+               printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
+                      "too different from desired (%ld%%)\n",
+                      err * 100 / rate);
+               return -EINVAL;
+       }
+
+       ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
+                       SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
+                       SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
+                       SND_SOC_CLOCK_IN);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
+                       S3C2410_IISMOD_32FS);
+       if (ret < 0)
+               return ret;
+
+       ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
+                       S3C24XX_PRESCALE(div, div));
+       if (ret < 0)
+               return ret;
+
+       /* set the codec system clock for DAC and ADC */
+       ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
+                       SND_SOC_CLOCK_OUT);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static struct snd_soc_ops s3c24xx_uda134x_ops = {
+       .startup = s3c24xx_uda134x_startup,
+       .shutdown = s3c24xx_uda134x_shutdown,
+       .hw_params = s3c24xx_uda134x_hw_params,
+};
+
+static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
+       .name = "UDA134X",
+       .stream_name = "UDA134X",
+       .codec_dai = &uda134x_dai,
+       .cpu_dai = &s3c24xx_i2s_dai,
+       .ops = &s3c24xx_uda134x_ops,
+};
+
+static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
+       .name = "S3C24XX_UDA134X",
+       .platform = &s3c24xx_soc_platform,
+       .dai_link = &s3c24xx_uda134x_dai_link,
+       .num_links = 1,
+};
+
+static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
+
+static void setdat(int v)
+{
+       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
+}
+
+static void setclk(int v)
+{
+       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
+}
+
+static void setmode(int v)
+{
+       gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
+}
+
+static struct uda134x_platform_data s3c24xx_uda134x = {
+       .l3 = {
+               .setdat = setdat,
+               .setclk = setclk,
+               .setmode = setmode,
+               .data_hold = 1,
+               .data_setup = 1,
+               .clock_high = 1,
+               .mode_hold = 1,
+               .mode = 1,
+               .mode_setup = 1,
+       },
+};
+
+static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
+       .card = &snd_soc_s3c24xx_uda134x,
+       .codec_dev = &soc_codec_dev_uda134x,
+       .codec_data = &s3c24xx_uda134x,
+};
+
+static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
+{
+       if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
+               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
+                      "l3 %s pin already in use", fun);
+               return -EBUSY;
+       }
+       gpio_direction_output(pin, 0);
+       return 0;
+}
+
+static int s3c24xx_uda134x_probe(struct platform_device *pdev)
+{
+       int ret;
+
+       printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
+
+       s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
+       if (s3c24xx_uda134x_l3_pins == NULL) {
+               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
+                      "unable to find platform data\n");
+               return -ENODEV;
+       }
+       s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
+       s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
+
+       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
+                                     "data") < 0)
+               return -EBUSY;
+       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
+                                     "clk") < 0) {
+               gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
+               return -EBUSY;
+       }
+       if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
+                                     "mode") < 0) {
+               gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
+               gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
+               return -EBUSY;
+       }
+
+       s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
+       if (!s3c24xx_uda134x_snd_device) {
+               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
+                      "Unable to register\n");
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(s3c24xx_uda134x_snd_device,
+                            &s3c24xx_uda134x_snd_devdata);
+       s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
+       ret = platform_device_add(s3c24xx_uda134x_snd_device);
+       if (ret) {
+               printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
+               platform_device_put(s3c24xx_uda134x_snd_device);
+       }
+
+       return ret;
+}
+
+static int s3c24xx_uda134x_remove(struct platform_device *pdev)
+{
+       platform_device_unregister(s3c24xx_uda134x_snd_device);
+       gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
+       gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
+       gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
+       return 0;
+}
+
+static struct platform_driver s3c24xx_uda134x_driver = {
+       .probe  = s3c24xx_uda134x_probe,
+       .remove = s3c24xx_uda134x_remove,
+       .driver = {
+               .name = "s3c24xx_uda134x",
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init s3c24xx_uda134x_init(void)
+{
+       return platform_driver_register(&s3c24xx_uda134x_driver);
+}
+
+static void __exit s3c24xx_uda134x_exit(void)
+{
+       platform_driver_unregister(&s3c24xx_uda134x_driver);
+}
+
+
+module_init(s3c24xx_uda134x_init);
+module_exit(s3c24xx_uda134x_exit);
+
+MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
+MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
+MODULE_LICENSE("GPL");
index 8515d6ff03f2c50c5220f8a39cf9ec7a0389693d..a2a4f5323c177b83e600a8271640407170556aa3 100644 (file)
@@ -23,7 +23,7 @@
 #include "s3c24xx-pcm.h"
 #include "s3c24xx-ac97.h"
 
-static struct snd_soc_machine smdk2443;
+static struct snd_soc_card smdk2443;
 
 static struct snd_soc_dai_link smdk2443_dai[] = {
 {
@@ -34,15 +34,15 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
 },
 };
 
-static struct snd_soc_machine smdk2443 = {
+static struct snd_soc_card smdk2443 = {
        .name = "SMDK2443",
+       .platform = &s3c24xx_soc_platform,
        .dai_link = smdk2443_dai,
        .num_links = ARRAY_SIZE(smdk2443_dai),
 };
 
 static struct snd_soc_device smdk2443_snd_ac97_devdata = {
-       .machine = &smdk2443,
-       .platform = &s3c24xx_soc_platform,
+       .card = &smdk2443,
        .codec_dev = &soc_codec_dev_ac97,
 };
 
index 9faa12622d09c07895c48cdf5d96ff6cfd47e38e..0dad3a0bb92018751b9101d5020cf32f1f0d2db2 100644 (file)
@@ -348,6 +348,18 @@ struct snd_soc_platform sh7760_soc_platform = {
 };
 EXPORT_SYMBOL_GPL(sh7760_soc_platform);
 
+static int __init sh7760_soc_platform_init(void)
+{
+       return snd_soc_register_platform(&sh7760_soc_platform);
+}
+module_init(sh7760_soc_platform_init);
+
+static void __exit sh7760_soc_platform_exit(void)
+{
+       snd_soc_unregister_platform(&sh7760_soc_platform);
+}
+module_exit(sh7760_soc_platform_exit);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
 MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
index df7bc345c3205cc0ae069322f6243e1027b71492..eab31838badfed9515a93a97a8eb020d50e4688e 100644 (file)
@@ -236,7 +236,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
 EXPORT_SYMBOL_GPL(soc_ac97_ops);
 
 static int hac_hw_params(struct snd_pcm_substream *substream,
-                        struct snd_pcm_hw_params *params)
+                        struct snd_pcm_hw_params *params,
+                        struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
@@ -270,7 +271,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
 {
        .name                   = "HAC0",
        .id                     = 0,
-       .type                   = SND_SOC_DAI_AC97,
+       .ac97_control           = 1,
        .playback = {
                .rates          = AC97_RATES,
                .formats        = AC97_FMTS,
@@ -290,8 +291,8 @@ struct snd_soc_dai sh4_hac_dai[] = {
 #ifdef CONFIG_CPU_SUBTYPE_SH7760
 {
        .name                   = "HAC1",
+       .ac97_control           = 1,
        .id                     = 1,
-       .type                   = SND_SOC_DAI_AC97,
        .playback = {
                .rates          = AC97_RATES,
                .formats        = AC97_FMTS,
@@ -313,6 +314,18 @@ struct snd_soc_dai sh4_hac_dai[] = {
 };
 EXPORT_SYMBOL_GPL(sh4_hac_dai);
 
+static int __init sh4_hac_init(void)
+{
+       return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
+}
+module_init(sh4_hac_init);
+
+static void __exit sh4_hac_exit(void)
+{
+       snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
+}
+module_exit(sh4_hac_exit);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
 MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
index 92bfaf4774a7d05fec84bf270539c8be09a6b05d..ce7f95b59de32aa3efe58bd46389ecb1d0b98c5e 100644 (file)
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
        .ops = NULL,
 };
 
-static struct snd_soc_machine sh7760_ac97_soc_machine  = {
+static struct snd_soc_card sh7760_ac97_soc_machine  = {
        .name = "SH7760 AC97",
+       .platform = &sh7760_soc_platform,
        .dai_link = &sh7760_ac97_dai,
        .num_links = 1,
 };
 
 static struct snd_soc_device sh7760_ac97_snd_devdata = {
-       .machine = &sh7760_ac97_soc_machine,
-       .platform = &sh7760_soc_platform,
+       .card = &sh7760_ac97_soc_machine,
        .codec_dev = &soc_codec_dev_ac97,
 };
 
index 55c3464163ab45b50b7c359ef50b138c994bfcd1..d1e5390fddeb7ff82c999aac717ca281e966864e 100644 (file)
@@ -89,7 +89,8 @@ struct ssi_priv {
  * track usage of the SSI; it is simplex-only so prevent attempts of
  * concurrent playback + capture. FIXME: any locking required?
  */
-static int ssi_startup(struct snd_pcm_substream *substream)
+static int ssi_startup(struct snd_pcm_substream *substream,
+                      struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -101,7 +102,8 @@ static int ssi_startup(struct snd_pcm_substream *substream)
        return 0;
 }
 
-static void ssi_shutdown(struct snd_pcm_substream *substream)
+static void ssi_shutdown(struct snd_pcm_substream *substream,
+                        struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -109,7 +111,8 @@ static void ssi_shutdown(struct snd_pcm_substream *substream)
        ssi->inuse = 0;
 }
 
-static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
+static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
+                      struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -129,7 +132,8 @@ static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
 }
 
 static int ssi_hw_params(struct snd_pcm_substream *substream,
-                        struct snd_pcm_hw_params *params)
+                        struct snd_pcm_hw_params *params,
+                        struct snd_soc_dai *dai)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -336,7 +340,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
 {
        .name                   = "SSI0",
        .id                     = 0,
-       .type                   = SND_SOC_DAI_I2S,
        .playback = {
                .rates          = SSI_RATES,
                .formats        = SSI_FMTS,
@@ -354,8 +357,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
                .shutdown       = ssi_shutdown,
                .trigger        = ssi_trigger,
                .hw_params      = ssi_hw_params,
-       },
-       .dai_ops = {
                .set_sysclk     = ssi_set_sysclk,
                .set_clkdiv     = ssi_set_clkdiv,
                .set_fmt        = ssi_set_fmt,
@@ -365,7 +366,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
 {
        .name                   = "SSI1",
        .id                     = 1,
-       .type                   = SND_SOC_DAI_I2S,
        .playback = {
                .rates          = SSI_RATES,
                .formats        = SSI_FMTS,
@@ -383,8 +383,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
                .shutdown       = ssi_shutdown,
                .trigger        = ssi_trigger,
                .hw_params      = ssi_hw_params,
-       },
-       .dai_ops = {
                .set_sysclk     = ssi_set_sysclk,
                .set_clkdiv     = ssi_set_clkdiv,
                .set_fmt        = ssi_set_fmt,
@@ -394,6 +392,18 @@ struct snd_soc_dai sh4_ssi_dai[] = {
 };
 EXPORT_SYMBOL_GPL(sh4_ssi_dai);
 
+static int __init sh4_ssi_init(void)
+{
+       return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
+}
+module_init(sh4_ssi_init);
+
+static void __exit sh4_ssi_exit(void)
+{
+       snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
+}
+module_exit(sh4_ssi_exit);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
 MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
index 16c7453f494691cd3f75b6d6fe4ef5b45c339c84..b098c0b4c584ea8b5a441c3f626ecf02290caeee 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/delay.h>
 #include <linux/pm.h>
 #include <linux/bitops.h>
+#include <linux/debugfs.h>
 #include <linux/platform_device.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/soc-dapm.h>
 #include <sound/initval.h>
 
-/* debug */
-#define SOC_DEBUG 0
-#if SOC_DEBUG
-#define dbg(format, arg...) printk(format, ## arg)
-#else
-#define dbg(format, arg...)
-#endif
-
 static DEFINE_MUTEX(pcm_mutex);
 static DEFINE_MUTEX(io_mutex);
 static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
 
+#ifdef CONFIG_DEBUG_FS
+static struct dentry *debugfs_root;
+#endif
+
+static DEFINE_MUTEX(client_mutex);
+static LIST_HEAD(card_list);
+static LIST_HEAD(dai_list);
+static LIST_HEAD(platform_list);
+static LIST_HEAD(codec_list);
+
+static int snd_soc_register_card(struct snd_soc_card *card);
+static int snd_soc_unregister_card(struct snd_soc_card *card);
+
 /*
  * This is a timeout to do a DAPM powerdown after a stream is closed().
  * It can be used to eliminate pops between different playback streams, e.g.
@@ -107,20 +113,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
 }
 #endif
 
-static inline const char *get_dai_name(int type)
-{
-       switch (type) {
-       case SND_SOC_DAI_AC97_BUS:
-       case SND_SOC_DAI_AC97:
-               return "AC97";
-       case SND_SOC_DAI_I2S:
-               return "I2S";
-       case SND_SOC_DAI_PCM:
-               return "PCM";
-       }
-       return NULL;
-}
-
 /*
  * Called by ALSA when a PCM substream is opened, the runtime->hw record is
  * then initialized and any private data can be allocated. This also calls
@@ -130,9 +122,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_card *card = socdev->card;
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        int ret = 0;
@@ -141,7 +134,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
 
        /* startup the audio subsystem */
        if (cpu_dai->ops.startup) {
-               ret = cpu_dai->ops.startup(substream);
+               ret = cpu_dai->ops.startup(substream, cpu_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: can't open interface %s\n",
                                cpu_dai->name);
@@ -158,7 +151,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
        }
 
        if (codec_dai->ops.startup) {
-               ret = codec_dai->ops.startup(substream);
+               ret = codec_dai->ops.startup(substream, codec_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: can't open codec %s\n",
                                codec_dai->name);
@@ -228,12 +221,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
                goto machine_err;
        }
 
-       dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
-       dbg("asoc: rate mask 0x%x\n", runtime->hw.rates);
-       dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
-               runtime->hw.channels_max);
-       dbg("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
-               runtime->hw.rate_max);
+       pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
+       pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
+       pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
+                runtime->hw.channels_max);
+       pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
+                runtime->hw.rate_max);
 
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                cpu_dai->playback.active = codec_dai->playback.active = 1;
@@ -255,7 +248,7 @@ codec_dai_err:
 
 platform_err:
        if (cpu_dai->ops.shutdown)
-               cpu_dai->ops.shutdown(substream);
+               cpu_dai->ops.shutdown(substream, cpu_dai);
 out:
        mutex_unlock(&pcm_mutex);
        return ret;
@@ -268,8 +261,9 @@ out:
  */
 static void close_delayed_work(struct work_struct *work)
 {
-       struct snd_soc_device *socdev =
-               container_of(work, struct snd_soc_device, delayed_work.work);
+       struct snd_soc_card *card = container_of(work, struct snd_soc_card,
+                                                delayed_work.work);
+       struct snd_soc_device *socdev = card->socdev;
        struct snd_soc_codec *codec = socdev->codec;
        struct snd_soc_dai *codec_dai;
        int i;
@@ -278,18 +272,18 @@ static void close_delayed_work(struct work_struct *work)
        for (i = 0; i < codec->num_dai; i++) {
                codec_dai = &codec->dai[i];
 
-               dbg("pop wq checking: %s status: %s waiting: %s\n",
-                       codec_dai->playback.stream_name,
-                       codec_dai->playback.active ? "active" : "inactive",
-                       codec_dai->pop_wait ? "yes" : "no");
+               pr_debug("pop wq checking: %s status: %s waiting: %s\n",
+                        codec_dai->playback.stream_name,
+                        codec_dai->playback.active ? "active" : "inactive",
+                        codec_dai->pop_wait ? "yes" : "no");
 
                /* are we waiting on this codec DAI stream */
                if (codec_dai->pop_wait == 1) {
 
                        /* Reduce power if no longer active */
                        if (codec->active == 0) {
-                               dbg("pop wq D1 %s %s\n", codec->name,
-                                       codec_dai->playback.stream_name);
+                               pr_debug("pop wq D1 %s %s\n", codec->name,
+                                        codec_dai->playback.stream_name);
                                snd_soc_dapm_set_bias_level(socdev,
                                        SND_SOC_BIAS_PREPARE);
                        }
@@ -301,8 +295,8 @@ static void close_delayed_work(struct work_struct *work)
 
                        /* Fall into standby if no longer active */
                        if (codec->active == 0) {
-                               dbg("pop wq D3 %s %s\n", codec->name,
-                                       codec_dai->playback.stream_name);
+                               pr_debug("pop wq D3 %s %s\n", codec->name,
+                                        codec_dai->playback.stream_name);
                                snd_soc_dapm_set_bias_level(socdev,
                                        SND_SOC_BIAS_STANDBY);
                        }
@@ -320,8 +314,9 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_card *card = socdev->card;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        struct snd_soc_codec *codec = socdev->codec;
@@ -346,10 +341,10 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
                snd_soc_dai_digital_mute(codec_dai, 1);
 
        if (cpu_dai->ops.shutdown)
-               cpu_dai->ops.shutdown(substream);
+               cpu_dai->ops.shutdown(substream, cpu_dai);
 
        if (codec_dai->ops.shutdown)
-               codec_dai->ops.shutdown(substream);
+               codec_dai->ops.shutdown(substream, codec_dai);
 
        if (machine->ops && machine->ops->shutdown)
                machine->ops->shutdown(substream);
@@ -361,7 +356,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
                /* start delayed pop wq here for playback streams */
                codec_dai->pop_wait = 1;
-               schedule_delayed_work(&socdev->delayed_work,
+               schedule_delayed_work(&card->delayed_work,
                        msecs_to_jiffies(pmdown_time));
        } else {
                /* capture streams can be powered down now */
@@ -387,8 +382,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_card *card = socdev->card;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        struct snd_soc_codec *codec = socdev->codec;
@@ -413,7 +409,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
        }
 
        if (codec_dai->ops.prepare) {
-               ret = codec_dai->ops.prepare(substream);
+               ret = codec_dai->ops.prepare(substream, codec_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: codec DAI prepare error\n");
                        goto out;
@@ -421,58 +417,49 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
        }
 
        if (cpu_dai->ops.prepare) {
-               ret = cpu_dai->ops.prepare(substream);
+               ret = cpu_dai->ops.prepare(substream, cpu_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: cpu DAI prepare error\n");
                        goto out;
                }
        }
 
-       /* we only want to start a DAPM playback stream if we are not waiting
-        * on an existing one stopping */
-       if (codec_dai->pop_wait) {
-               /* we are waiting for the delayed work to start */
-               if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
-                               snd_soc_dapm_stream_event(socdev->codec,
-                                       codec_dai->capture.stream_name,
-                                       SND_SOC_DAPM_STREAM_START);
-               else {
-                       codec_dai->pop_wait = 0;
-                       cancel_delayed_work(&socdev->delayed_work);
-                       snd_soc_dai_digital_mute(codec_dai, 0);
-               }
-       } else {
-               /* no delayed work - do we need to power up codec */
-               if (codec->bias_level != SND_SOC_BIAS_ON) {
+       /* cancel any delayed stream shutdown that is pending */
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
+           codec_dai->pop_wait) {
+               codec_dai->pop_wait = 0;
+               cancel_delayed_work(&card->delayed_work);
+       }
 
-                       snd_soc_dapm_set_bias_level(socdev,
-                                                   SND_SOC_BIAS_PREPARE);
+       /* do we need to power up codec */
+       if (codec->bias_level != SND_SOC_BIAS_ON) {
+               snd_soc_dapm_set_bias_level(socdev,
+                                           SND_SOC_BIAS_PREPARE);
 
-                       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               snd_soc_dapm_stream_event(codec,
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       snd_soc_dapm_stream_event(codec,
                                        codec_dai->playback.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
-                       else
-                               snd_soc_dapm_stream_event(codec,
+               else
+                       snd_soc_dapm_stream_event(codec,
                                        codec_dai->capture.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
 
-                       snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
-                       snd_soc_dai_digital_mute(codec_dai, 0);
+               snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
+               snd_soc_dai_digital_mute(codec_dai, 0);
 
-               } else {
-                       /* codec already powered - power on widgets */
-                       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
-                               snd_soc_dapm_stream_event(codec,
+       } else {
+               /* codec already powered - power on widgets */
+               if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+                       snd_soc_dapm_stream_event(codec,
                                        codec_dai->playback.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
-                       else
-                               snd_soc_dapm_stream_event(codec,
+               else
+                       snd_soc_dapm_stream_event(codec,
                                        codec_dai->capture.stream_name,
                                        SND_SOC_DAPM_STREAM_START);
 
-                       snd_soc_dai_digital_mute(codec_dai, 0);
-               }
+               snd_soc_dai_digital_mute(codec_dai, 0);
        }
 
 out:
@@ -491,7 +478,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        int ret = 0;
@@ -507,7 +495,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (codec_dai->ops.hw_params) {
-               ret = codec_dai->ops.hw_params(substream, params);
+               ret = codec_dai->ops.hw_params(substream, params, codec_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: can't set codec %s hw params\n",
                                codec_dai->name);
@@ -516,7 +504,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (cpu_dai->ops.hw_params) {
-               ret = cpu_dai->ops.hw_params(substream, params);
+               ret = cpu_dai->ops.hw_params(substream, params, cpu_dai);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: interface %s hw params failed\n",
                                cpu_dai->name);
@@ -539,11 +527,11 @@ out:
 
 platform_err:
        if (cpu_dai->ops.hw_free)
-               cpu_dai->ops.hw_free(substream);
+               cpu_dai->ops.hw_free(substream, cpu_dai);
 
 interface_err:
        if (codec_dai->ops.hw_free)
-               codec_dai->ops.hw_free(substream);
+               codec_dai->ops.hw_free(substream, codec_dai);
 
 codec_err:
        if (machine->ops && machine->ops->hw_free)
@@ -561,7 +549,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        struct snd_soc_codec *codec = socdev->codec;
@@ -582,10 +571,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
 
        /* now free hw params for the DAI's  */
        if (codec_dai->ops.hw_free)
-               codec_dai->ops.hw_free(substream);
+               codec_dai->ops.hw_free(substream, codec_dai);
 
        if (cpu_dai->ops.hw_free)
-               cpu_dai->ops.hw_free(substream);
+               cpu_dai->ops.hw_free(substream, cpu_dai);
 
        mutex_unlock(&pcm_mutex);
        return 0;
@@ -595,14 +584,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 {
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
+       struct snd_soc_card *card= socdev->card;
        struct snd_soc_dai_link *machine = rtd->dai;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *cpu_dai = machine->cpu_dai;
        struct snd_soc_dai *codec_dai = machine->codec_dai;
        int ret;
 
        if (codec_dai->ops.trigger) {
-               ret = codec_dai->ops.trigger(substream, cmd);
+               ret = codec_dai->ops.trigger(substream, cmd, codec_dai);
                if (ret < 0)
                        return ret;
        }
@@ -614,7 +604,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
        }
 
        if (cpu_dai->ops.trigger) {
-               ret = cpu_dai->ops.trigger(substream, cmd);
+               ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai);
                if (ret < 0)
                        return ret;
        }
@@ -636,8 +626,8 @@ static struct snd_pcm_ops soc_pcm_ops = {
 static int soc_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
        struct snd_soc_codec *codec = socdev->codec;
        int i;
@@ -653,29 +643,29 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
        snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot);
 
        /* mute any active DAC's */
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *dai = machine->dai_link[i].codec_dai;
-               if (dai->dai_ops.digital_mute && dai->playback.active)
-                       dai->dai_ops.digital_mute(dai, 1);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
+               if (dai->ops.digital_mute && dai->playback.active)
+                       dai->ops.digital_mute(dai, 1);
        }
 
        /* suspend all pcms */
-       for (i = 0; i < machine->num_links; i++)
-               snd_pcm_suspend_all(machine->dai_link[i].pcm);
+       for (i = 0; i < card->num_links; i++)
+               snd_pcm_suspend_all(card->dai_link[i].pcm);
 
-       if (machine->suspend_pre)
-               machine->suspend_pre(pdev, state);
+       if (card->suspend_pre)
+               card->suspend_pre(pdev, state);
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai  *cpu_dai = machine->dai_link[i].cpu_dai;
-               if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97)
-                       cpu_dai->suspend(pdev, cpu_dai);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai  *cpu_dai = card->dai_link[i].cpu_dai;
+               if (cpu_dai->suspend && !cpu_dai->ac97_control)
+                       cpu_dai->suspend(cpu_dai);
                if (platform->suspend)
-                       platform->suspend(pdev, cpu_dai);
+                       platform->suspend(cpu_dai);
        }
 
        /* close any waiting streams and save state */
-       run_delayed_work(&socdev->delayed_work);
+       run_delayed_work(&card->delayed_work);
        codec->suspend_bias_level = codec->bias_level;
 
        for (i = 0; i < codec->num_dai; i++) {
@@ -692,14 +682,14 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
        if (codec_dev->suspend)
                codec_dev->suspend(pdev, state);
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
-               if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97)
-                       cpu_dai->suspend(pdev, cpu_dai);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+               if (cpu_dai->suspend && cpu_dai->ac97_control)
+                       cpu_dai->suspend(cpu_dai);
        }
 
-       if (machine->suspend_post)
-               machine->suspend_post(pdev, state);
+       if (card->suspend_post)
+               card->suspend_post(pdev, state);
 
        return 0;
 }
@@ -709,11 +699,11 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
  */
 static void soc_resume_deferred(struct work_struct *work)
 {
-       struct snd_soc_device *socdev = container_of(work,
-                                                    struct snd_soc_device,
-                                                    deferred_resume_work);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_card *card = container_of(work,
+                                                struct snd_soc_card,
+                                                deferred_resume_work);
+       struct snd_soc_device *socdev = card->socdev;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
        struct snd_soc_codec *codec = socdev->codec;
        struct platform_device *pdev = to_platform_device(socdev->dev);
@@ -723,15 +713,15 @@ static void soc_resume_deferred(struct work_struct *work)
         * so userspace apps are blocked from touching us
         */
 
-       dev_info(socdev->dev, "starting resume work\n");
+       dev_dbg(socdev->dev, "starting resume work\n");
 
-       if (machine->resume_pre)
-               machine->resume_pre(pdev);
+       if (card->resume_pre)
+               card->resume_pre(pdev);
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
-               if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97)
-                       cpu_dai->resume(pdev, cpu_dai);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+               if (cpu_dai->resume && cpu_dai->ac97_control)
+                       cpu_dai->resume(cpu_dai);
        }
 
        if (codec_dev->resume)
@@ -749,24 +739,24 @@ static void soc_resume_deferred(struct work_struct *work)
        }
 
        /* unmute any active DACs */
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *dai = machine->dai_link[i].codec_dai;
-               if (dai->dai_ops.digital_mute && dai->playback.active)
-                       dai->dai_ops.digital_mute(dai, 0);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
+               if (dai->ops.digital_mute && dai->playback.active)
+                       dai->ops.digital_mute(dai, 0);
        }
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
-               if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97)
-                       cpu_dai->resume(pdev, cpu_dai);
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
+               if (cpu_dai->resume && !cpu_dai->ac97_control)
+                       cpu_dai->resume(cpu_dai);
                if (platform->resume)
-                       platform->resume(pdev, cpu_dai);
+                       platform->resume(cpu_dai);
        }
 
-       if (machine->resume_post)
-               machine->resume_post(pdev);
+       if (card->resume_post)
+               card->resume_post(pdev);
 
-       dev_info(socdev->dev, "resume work completed\n");
+       dev_dbg(socdev->dev, "resume work completed\n");
 
        /* userspace can access us now we are back as we were before */
        snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0);
@@ -776,11 +766,12 @@ static void soc_resume_deferred(struct work_struct *work)
 static int soc_resume(struct platform_device *pdev)
 {
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_card *card = socdev->card;
 
-       dev_info(socdev->dev, "scheduling resume work\n");
+       dev_dbg(socdev->dev, "scheduling resume work\n");
 
-       if (!schedule_work(&socdev->deferred_resume_work))
-               dev_err(socdev->dev, "work item may be lost\n");
+       if (!schedule_work(&card->deferred_resume_work))
+               dev_err(socdev->dev, "resume work item may be lost\n");
 
        return 0;
 }
@@ -790,23 +781,83 @@ static int soc_resume(struct platform_device *pdev)
 #define soc_resume     NULL
 #endif
 
-/* probes a new socdev */
-static int soc_probe(struct platform_device *pdev)
+static void snd_soc_instantiate_card(struct snd_soc_card *card)
 {
-       int ret = 0, i;
-       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_platform *platform = socdev->platform;
-       struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
+       struct platform_device *pdev = container_of(card->dev,
+                                                   struct platform_device,
+                                                   dev);
+       struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
+       struct snd_soc_platform *platform;
+       struct snd_soc_dai *dai;
+       int i, found, ret, ac97;
+
+       if (card->instantiated)
+               return;
+
+       found = 0;
+       list_for_each_entry(platform, &platform_list, list)
+               if (card->platform == platform) {
+                       found = 1;
+                       break;
+               }
+       if (!found) {
+               dev_dbg(card->dev, "Platform %s not registered\n",
+                       card->platform->name);
+               return;
+       }
+
+       ac97 = 0;
+       for (i = 0; i < card->num_links; i++) {
+               found = 0;
+               list_for_each_entry(dai, &dai_list, list)
+                       if (card->dai_link[i].cpu_dai == dai) {
+                               found = 1;
+                               break;
+                       }
+               if (!found) {
+                       dev_dbg(card->dev, "DAI %s not registered\n",
+                               card->dai_link[i].cpu_dai->name);
+                       return;
+               }
 
-       if (machine->probe) {
-               ret = machine->probe(pdev);
+               if (card->dai_link[i].cpu_dai->ac97_control)
+                       ac97 = 1;
+       }
+
+       /* If we have AC97 in the system then don't wait for the
+        * codec.  This will need revisiting if we have to handle
+        * systems with mixed AC97 and non-AC97 parts.  Only check for
+        * DAIs currently; we can't do this per link since some AC97
+        * codecs have non-AC97 DAIs.
+        */
+       if (!ac97)
+               for (i = 0; i < card->num_links; i++) {
+                       found = 0;
+                       list_for_each_entry(dai, &dai_list, list)
+                               if (card->dai_link[i].codec_dai == dai) {
+                                       found = 1;
+                                       break;
+                               }
+                       if (!found) {
+                               dev_dbg(card->dev, "DAI %s not registered\n",
+                                       card->dai_link[i].codec_dai->name);
+                               return;
+                       }
+               }
+
+       /* Note that we do not current check for codec components */
+
+       dev_dbg(card->dev, "All components present, instantiating\n");
+
+       /* Found everything, bring it up */
+       if (card->probe) {
+               ret = card->probe(pdev);
                if (ret < 0)
-                       return ret;
+                       return;
        }
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
                if (cpu_dai->probe) {
                        ret = cpu_dai->probe(pdev, cpu_dai);
                        if (ret < 0)
@@ -827,13 +878,15 @@ static int soc_probe(struct platform_device *pdev)
        }
 
        /* DAPM stream work */
-       INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work);
+       INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);
 #ifdef CONFIG_PM
        /* deferred resume work */
-       INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred);
+       INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
 #endif
 
-       return 0;
+       card->instantiated = 1;
+
+       return;
 
 platform_err:
        if (codec_dev->remove)
@@ -841,15 +894,45 @@ platform_err:
 
 cpu_dai_err:
        for (i--; i >= 0; i--) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
                if (cpu_dai->remove)
                        cpu_dai->remove(pdev, cpu_dai);
        }
 
-       if (machine->remove)
-               machine->remove(pdev);
+       if (card->remove)
+               card->remove(pdev);
+}
 
-       return ret;
+/*
+ * Attempt to initialise any uninitalised cards.  Must be called with
+ * client_mutex.
+ */
+static void snd_soc_instantiate_cards(void)
+{
+       struct snd_soc_card *card;
+       list_for_each_entry(card, &card_list, list)
+               snd_soc_instantiate_card(card);
+}
+
+/* probes a new socdev */
+static int soc_probe(struct platform_device *pdev)
+{
+       int ret = 0;
+       struct snd_soc_device *socdev = platform_get_drvdata(pdev);
+       struct snd_soc_card *card = socdev->card;
+
+       /* Bodge while we push things out of socdev */
+       card->socdev = socdev;
+
+       /* Bodge while we unpick instantiation */
+       card->dev = &pdev->dev;
+       ret = snd_soc_register_card(card);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "Failed to register card\n");
+               return ret;
+       }
+
+       return 0;
 }
 
 /* removes a socdev */
@@ -857,11 +940,11 @@ static int soc_remove(struct platform_device *pdev)
 {
        int i;
        struct snd_soc_device *socdev = platform_get_drvdata(pdev);
-       struct snd_soc_machine *machine = socdev->machine;
-       struct snd_soc_platform *platform = socdev->platform;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
 
-       run_delayed_work(&socdev->delayed_work);
+       run_delayed_work(&card->delayed_work);
 
        if (platform->remove)
                platform->remove(pdev);
@@ -869,14 +952,16 @@ static int soc_remove(struct platform_device *pdev)
        if (codec_dev->remove)
                codec_dev->remove(pdev);
 
-       for (i = 0; i < machine->num_links; i++) {
-               struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai;
+       for (i = 0; i < card->num_links; i++) {
+               struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
                if (cpu_dai->remove)
                        cpu_dai->remove(pdev, cpu_dai);
        }
 
-       if (machine->remove)
-               machine->remove(pdev);
+       if (card->remove)
+               card->remove(pdev);
+
+       snd_soc_unregister_card(card);
 
        return 0;
 }
@@ -898,6 +983,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
        struct snd_soc_dai_link *dai_link, int num)
 {
        struct snd_soc_codec *codec = socdev->codec;
+       struct snd_soc_card *card = socdev->card;
+       struct snd_soc_platform *platform = card->platform;
        struct snd_soc_dai *codec_dai = dai_link->codec_dai;
        struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
        struct snd_soc_pcm_runtime *rtd;
@@ -914,8 +1001,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
        codec_dai->codec = socdev->codec;
 
        /* check client and interface hw capabilities */
-       sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name,
-               get_dai_name(cpu_dai->type), num);
+       sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
+               num);
 
        if (codec_dai->playback.channels_min)
                playback = 1;
@@ -933,13 +1020,13 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
 
        dai_link->pcm = pcm;
        pcm->private_data = rtd;
-       soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap;
-       soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer;
-       soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl;
-       soc_pcm_ops.copy = socdev->platform->pcm_ops->copy;
-       soc_pcm_ops.silence = socdev->platform->pcm_ops->silence;
-       soc_pcm_ops.ack = socdev->platform->pcm_ops->ack;
-       soc_pcm_ops.page = socdev->platform->pcm_ops->page;
+       soc_pcm_ops.mmap = platform->pcm_ops->mmap;
+       soc_pcm_ops.pointer = platform->pcm_ops->pointer;
+       soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
+       soc_pcm_ops.copy = platform->pcm_ops->copy;
+       soc_pcm_ops.silence = platform->pcm_ops->silence;
+       soc_pcm_ops.ack = platform->pcm_ops->ack;
+       soc_pcm_ops.page = platform->pcm_ops->page;
 
        if (playback)
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -947,24 +1034,22 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
        if (capture)
                snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
 
-       ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm);
+       ret = platform->pcm_new(codec->card, codec_dai, pcm);
        if (ret < 0) {
                printk(KERN_ERR "asoc: platform pcm constructor failed\n");
                kfree(rtd);
                return ret;
        }
 
-       pcm->private_free = socdev->platform->pcm_free;
+       pcm->private_free = platform->pcm_free;
        printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
                cpu_dai->name);
        return ret;
 }
 
 /* codec register dump */
-static ssize_t codec_reg_show(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf)
 {
-       struct snd_soc_device *devdata = dev_get_drvdata(dev);
        struct snd_soc_codec *codec = devdata->codec;
        int i, step = 1, count = 0;
 
@@ -1001,8 +1086,110 @@ static ssize_t codec_reg_show(struct device *dev,
 
        return count;
 }
+static ssize_t codec_reg_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct snd_soc_device *devdata = dev_get_drvdata(dev);
+       return soc_codec_reg_show(devdata, buf);
+}
+
 static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
 
+#ifdef CONFIG_DEBUG_FS
+static int codec_reg_open_file(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       ssize_t ret;
+       struct snd_soc_codec *codec = file->private_data;
+       struct device *card_dev = codec->card->dev;
+       struct snd_soc_device *devdata = card_dev->driver_data;
+       char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       ret = soc_codec_reg_show(devdata, buf);
+       if (ret >= 0)
+               ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+       kfree(buf);
+       return ret;
+}
+
+static ssize_t codec_reg_write_file(struct file *file,
+               const char __user *user_buf, size_t count, loff_t *ppos)
+{
+       char buf[32];
+       int buf_size;
+       char *start = buf;
+       unsigned long reg, value;
+       int step = 1;
+       struct snd_soc_codec *codec = file->private_data;
+
+       buf_size = min(count, (sizeof(buf)-1));
+       if (copy_from_user(buf, user_buf, buf_size))
+               return -EFAULT;
+       buf[buf_size] = 0;
+
+       if (codec->reg_cache_step)
+               step = codec->reg_cache_step;
+
+       while (*start == ' ')
+               start++;
+       reg = simple_strtoul(start, &start, 16);
+       if ((reg >= codec->reg_cache_size) || (reg % step))
+               return -EINVAL;
+       while (*start == ' ')
+               start++;
+       if (strict_strtoul(start, 16, &value))
+               return -EINVAL;
+       codec->write(codec, reg, value);
+       return buf_size;
+}
+
+static const struct file_operations codec_reg_fops = {
+       .open = codec_reg_open_file,
+       .read = codec_reg_read_file,
+       .write = codec_reg_write_file,
+};
+
+static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+{
+       codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
+                                                debugfs_root, codec,
+                                                &codec_reg_fops);
+       if (!codec->debugfs_reg)
+               printk(KERN_WARNING
+                      "ASoC: Failed to create codec register debugfs file\n");
+
+       codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
+                                                    debugfs_root,
+                                                    &codec->pop_time);
+       if (!codec->debugfs_pop_time)
+               printk(KERN_WARNING
+                      "Failed to create pop time debugfs file\n");
+}
+
+static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+{
+       debugfs_remove(codec->debugfs_pop_time);
+       debugfs_remove(codec->debugfs_reg);
+}
+
+#else
+
+static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+{
+}
+
+static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+{
+}
+#endif
+
 /**
  * snd_soc_new_ac97_codec - initailise AC97 device
  * @codec: audio codec
@@ -1121,7 +1308,7 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
 int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
 {
        struct snd_soc_codec *codec = socdev->codec;
-       struct snd_soc_machine *machine = socdev->machine;
+       struct snd_soc_card *card = socdev->card;
        int ret = 0, i;
 
        mutex_lock(&codec->mutex);
@@ -1140,11 +1327,11 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
        strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
 
        /* create the pcms */
-       for (i = 0; i < machine->num_links; i++) {
-               ret = soc_new_pcm(socdev, &machine->dai_link[i], i);
+       for (i = 0; i < card->num_links; i++) {
+               ret = soc_new_pcm(socdev, &card->dai_link[i], i);
                if (ret < 0) {
                        printk(KERN_ERR "asoc: can't create pcm %s\n",
-                               machine->dai_link[i].stream_name);
+                               card->dai_link[i].stream_name);
                        mutex_unlock(&codec->mutex);
                        return ret;
                }
@@ -1156,7 +1343,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
 EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
 
 /**
- * snd_soc_register_card - register sound card
+ * snd_soc_init_card - register sound card
  * @socdev: the SoC audio device
  *
  * Register a SoC sound card. Also registers an AC97 device if the
@@ -1164,29 +1351,28 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
  *
  * Returns 0 for success, else error.
  */
-int snd_soc_register_card(struct snd_soc_device *socdev)
+int snd_soc_init_card(struct snd_soc_device *socdev)
 {
        struct snd_soc_codec *codec = socdev->codec;
-       struct snd_soc_machine *machine = socdev->machine;
+       struct snd_soc_card *card = socdev->card;
        int ret = 0, i, ac97 = 0, err = 0;
 
-       for (i = 0; i < machine->num_links; i++) {
-               if (socdev->machine->dai_link[i].init) {
-                       err = socdev->machine->dai_link[i].init(codec);
+       for (i = 0; i < card->num_links; i++) {
+               if (card->dai_link[i].init) {
+                       err = card->dai_link[i].init(codec);
                        if (err < 0) {
                                printk(KERN_ERR "asoc: failed to init %s\n",
-                                       socdev->machine->dai_link[i].stream_name);
+                                       card->dai_link[i].stream_name);
                                continue;
                        }
                }
-               if (socdev->machine->dai_link[i].codec_dai->type ==
-                       SND_SOC_DAI_AC97_BUS)
+               if (card->dai_link[i].codec_dai->ac97_control)
                        ac97 = 1;
        }
        snprintf(codec->card->shortname, sizeof(codec->card->shortname),
-                "%s", machine->name);
+                "%s",  card->name);
        snprintf(codec->card->longname, sizeof(codec->card->longname),
-                "%s (%s)", machine->name, codec->name);
+                "%s (%s)", card->name, codec->name);
 
        ret = snd_card_register(codec->card);
        if (ret < 0) {
@@ -1216,12 +1402,13 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
        if (err < 0)
                printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
 
+       soc_init_codec_debugfs(socdev->codec);
        mutex_unlock(&codec->mutex);
 
 out:
        return ret;
 }
-EXPORT_SYMBOL_GPL(snd_soc_register_card);
+EXPORT_SYMBOL_GPL(snd_soc_init_card);
 
 /**
  * snd_soc_free_pcms - free sound card and pcms
@@ -1239,10 +1426,11 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
 #endif
 
        mutex_lock(&codec->mutex);
+       soc_cleanup_codec_debugfs(socdev->codec);
 #ifdef CONFIG_SND_SOC_AC97_BUS
        for (i = 0; i < codec->num_dai; i++) {
                codec_dai = &codec->dai[i];
-               if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) {
+               if (codec_dai->ac97_control && codec->ac97) {
                        soc_ac97_dev_unregister(codec);
                        goto free_card;
                }
@@ -1756,8 +1944,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
 int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
        unsigned int freq, int dir)
 {
-       if (dai->dai_ops.set_sysclk)
-               return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir);
+       if (dai->ops.set_sysclk)
+               return dai->ops.set_sysclk(dai, clk_id, freq, dir);
        else
                return -EINVAL;
 }
@@ -1776,8 +1964,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
 int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
        int div_id, int div)
 {
-       if (dai->dai_ops.set_clkdiv)
-               return dai->dai_ops.set_clkdiv(dai, div_id, div);
+       if (dai->ops.set_clkdiv)
+               return dai->ops.set_clkdiv(dai, div_id, div);
        else
                return -EINVAL;
 }
@@ -1795,8 +1983,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
 int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
        int pll_id, unsigned int freq_in, unsigned int freq_out)
 {
-       if (dai->dai_ops.set_pll)
-               return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out);
+       if (dai->ops.set_pll)
+               return dai->ops.set_pll(dai, pll_id, freq_in, freq_out);
        else
                return -EINVAL;
 }
@@ -1805,15 +1993,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
 /**
  * snd_soc_dai_set_fmt - configure DAI hardware audio format.
  * @dai: DAI
- * @clk_id: DAI specific clock ID
  * @fmt: SND_SOC_DAIFMT_ format value.
  *
  * Configures the DAI hardware format and clocking.
  */
 int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
-       if (dai->dai_ops.set_fmt)
-               return dai->dai_ops.set_fmt(dai, fmt);
+       if (dai->ops.set_fmt)
+               return dai->ops.set_fmt(dai, fmt);
        else
                return -EINVAL;
 }
@@ -1831,8 +2018,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
 int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
        unsigned int mask, int slots)
 {
-       if (dai->dai_ops.set_sysclk)
-               return dai->dai_ops.set_tdm_slot(dai, mask, slots);
+       if (dai->ops.set_sysclk)
+               return dai->ops.set_tdm_slot(dai, mask, slots);
        else
                return -EINVAL;
 }
@@ -1847,8 +2034,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
  */
 int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
 {
-       if (dai->dai_ops.set_sysclk)
-               return dai->dai_ops.set_tristate(dai, tristate);
+       if (dai->ops.set_sysclk)
+               return dai->ops.set_tristate(dai, tristate);
        else
                return -EINVAL;
 }
@@ -1863,21 +2050,242 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
  */
 int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
 {
-       if (dai->dai_ops.digital_mute)
-               return dai->dai_ops.digital_mute(dai, mute);
+       if (dai->ops.digital_mute)
+               return dai->ops.digital_mute(dai, mute);
        else
                return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
 
-static int __devinit snd_soc_init(void)
+/**
+ * snd_soc_register_card - Register a card with the ASoC core
+ *
+ * @param card Card to register
+ *
+ * Note that currently this is an internal only function: it will be
+ * exposed to machine drivers after further backporting of ASoC v2
+ * registration APIs.
+ */
+static int snd_soc_register_card(struct snd_soc_card *card)
+{
+       if (!card->name || !card->dev)
+               return -EINVAL;
+
+       INIT_LIST_HEAD(&card->list);
+       card->instantiated = 0;
+
+       mutex_lock(&client_mutex);
+       list_add(&card->list, &card_list);
+       snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
+
+       dev_dbg(card->dev, "Registered card '%s'\n", card->name);
+
+       return 0;
+}
+
+/**
+ * snd_soc_unregister_card - Unregister a card with the ASoC core
+ *
+ * @param card Card to unregister
+ *
+ * Note that currently this is an internal only function: it will be
+ * exposed to machine drivers after further backporting of ASoC v2
+ * registration APIs.
+ */
+static int snd_soc_unregister_card(struct snd_soc_card *card)
+{
+       mutex_lock(&client_mutex);
+       list_del(&card->list);
+       mutex_unlock(&client_mutex);
+
+       dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
+
+       return 0;
+}
+
+/**
+ * snd_soc_register_dai - Register a DAI with the ASoC core
+ *
+ * @param dai DAI to register
+ */
+int snd_soc_register_dai(struct snd_soc_dai *dai)
+{
+       if (!dai->name)
+               return -EINVAL;
+
+       /* The device should become mandatory over time */
+       if (!dai->dev)
+               printk(KERN_WARNING "No device for DAI %s\n", dai->name);
+
+       INIT_LIST_HEAD(&dai->list);
+
+       mutex_lock(&client_mutex);
+       list_add(&dai->list, &dai_list);
+       snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Registered DAI '%s'\n", dai->name);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_dai);
+
+/**
+ * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
+ *
+ * @param dai DAI to unregister
+ */
+void snd_soc_unregister_dai(struct snd_soc_dai *dai)
+{
+       mutex_lock(&client_mutex);
+       list_del(&dai->list);
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Unregistered DAI '%s'\n", dai->name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
+
+/**
+ * snd_soc_register_dais - Register multiple DAIs with the ASoC core
+ *
+ * @param dai Array of DAIs to register
+ * @param count Number of DAIs
+ */
+int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count)
+{
+       int i, ret;
+
+       for (i = 0; i < count; i++) {
+               ret = snd_soc_register_dai(&dai[i]);
+               if (ret != 0)
+                       goto err;
+       }
+
+       return 0;
+
+err:
+       for (i--; i >= 0; i--)
+               snd_soc_unregister_dai(&dai[i]);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_dais);
+
+/**
+ * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
+ *
+ * @param dai Array of DAIs to unregister
+ * @param count Number of DAIs
+ */
+void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count)
+{
+       int i;
+
+       for (i = 0; i < count; i++)
+               snd_soc_unregister_dai(&dai[i]);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
+
+/**
+ * snd_soc_register_platform - Register a platform with the ASoC core
+ *
+ * @param platform platform to register
+ */
+int snd_soc_register_platform(struct snd_soc_platform *platform)
+{
+       if (!platform->name)
+               return -EINVAL;
+
+       INIT_LIST_HEAD(&platform->list);
+
+       mutex_lock(&client_mutex);
+       list_add(&platform->list, &platform_list);
+       snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Registered platform '%s'\n", platform->name);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_platform);
+
+/**
+ * snd_soc_unregister_platform - Unregister a platform from the ASoC core
+ *
+ * @param platform platform to unregister
+ */
+void snd_soc_unregister_platform(struct snd_soc_platform *platform)
 {
-       printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);
+       mutex_lock(&client_mutex);
+       list_del(&platform->list);
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Unregistered platform '%s'\n", platform->name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
+
+/**
+ * snd_soc_register_codec - Register a codec with the ASoC core
+ *
+ * @param codec codec to register
+ */
+int snd_soc_register_codec(struct snd_soc_codec *codec)
+{
+       if (!codec->name)
+               return -EINVAL;
+
+       /* The device should become mandatory over time */
+       if (!codec->dev)
+               printk(KERN_WARNING "No device for codec %s\n", codec->name);
+
+       INIT_LIST_HEAD(&codec->list);
+
+       mutex_lock(&client_mutex);
+       list_add(&codec->list, &codec_list);
+       snd_soc_instantiate_cards();
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Registered codec '%s'\n", codec->name);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(snd_soc_register_codec);
+
+/**
+ * snd_soc_unregister_codec - Unregister a codec from the ASoC core
+ *
+ * @param codec codec to unregister
+ */
+void snd_soc_unregister_codec(struct snd_soc_codec *codec)
+{
+       mutex_lock(&client_mutex);
+       list_del(&codec->list);
+       mutex_unlock(&client_mutex);
+
+       pr_debug("Unregistered codec '%s'\n", codec->name);
+}
+EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
+
+static int __init snd_soc_init(void)
+{
+#ifdef CONFIG_DEBUG_FS
+       debugfs_root = debugfs_create_dir("asoc", NULL);
+       if (IS_ERR(debugfs_root) || !debugfs_root) {
+               printk(KERN_WARNING
+                      "ASoC: Failed to create debugfs directory\n");
+               debugfs_root = NULL;
+       }
+#endif
+
        return platform_driver_register(&soc_driver);
 }
 
-static void snd_soc_exit(void)
+static void __exit snd_soc_exit(void)
 {
+#ifdef CONFIG_DEBUG_FS
+       debugfs_remove_recursive(debugfs_root);
+#endif
        platform_driver_unregister(&soc_driver);
 }
 
index 7351db9606e48f3d11870671a4b9e71c37081e50..8863eddbac029975f9f7b4fefeac73b73bbcb6cf 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/bitops.h>
 #include <linux/platform_device.h>
 #include <linux/jiffies.h>
-#include <linux/debugfs.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -67,17 +66,13 @@ static int dapm_status = 1;
 module_param(dapm_status, int, 0);
 MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
 
-static struct dentry *asoc_debugfs;
-
-static u32 pop_time;
-
-static void pop_wait(void)
+static void pop_wait(u32 pop_time)
 {
        if (pop_time)
                schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
 }
 
-static void pop_dbg(const char *fmt, ...)
+static void pop_dbg(u32 pop_time, const char *fmt, ...)
 {
        va_list args;
 
@@ -85,7 +80,7 @@ static void pop_dbg(const char *fmt, ...)
 
        if (pop_time) {
                vprintk(fmt, args);
-               pop_wait();
+               pop_wait(pop_time);
        }
 
        va_end(args);
@@ -230,10 +225,11 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
 
        change = old != new;
        if (change) {
-               pop_dbg("pop test %s : %s in %d ms\n", widget->name,
-                       widget->power ? "on" : "off", pop_time);
+               pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
+                       widget->name, widget->power ? "on" : "off",
+                       codec->pop_time);
                snd_soc_write(codec, widget->reg, new);
-               pop_wait();
+               pop_wait(codec->pop_time);
        }
        pr_debug("reg %x old %x new %x change %d\n", widget->reg,
                 old, new, change);
@@ -293,7 +289,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
        struct snd_soc_dapm_widget *w)
 {
        int i, ret = 0;
-       char name[32];
+       size_t name_len;
        struct snd_soc_dapm_path *path;
 
        /* add kcontrol */
@@ -307,11 +303,16 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
                                continue;
 
                        /* add dapm control with long name */
-                       snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name);
-                       path->long_name = kstrdup (name, GFP_KERNEL);
+                       name_len = 2 + strlen(w->name)
+                               + strlen(w->kcontrols[i].name);
+                       path->long_name = kmalloc(name_len, GFP_KERNEL);
                        if (path->long_name == NULL)
                                return -ENOMEM;
 
+                       snprintf(path->long_name, name_len, "%s %s",
+                                w->name, w->kcontrols[i].name);
+                       path->long_name[name_len - 1] = '\0';
+
                        path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
                                path->long_name);
                        ret = snd_ctl_add(codec->card, path->kcontrol);
@@ -821,23 +822,9 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
 
 int snd_soc_dapm_sys_add(struct device *dev)
 {
-       int ret = 0;
-
        if (!dapm_status)
                return 0;
-
-       ret = device_create_file(dev, &dev_attr_dapm_widget);
-       if (ret != 0)
-               return ret;
-
-       asoc_debugfs = debugfs_create_dir("asoc", NULL);
-       if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
-               debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
-                                  &pop_time);
-       else
-               asoc_debugfs = NULL;
-
-       return 0;
+       return device_create_file(dev, &dev_attr_dapm_widget);
 }
 
 static void snd_soc_dapm_sys_remove(struct device *dev)
@@ -845,9 +832,6 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
        if (dapm_status) {
                device_remove_file(dev, &dev_attr_dapm_widget);
        }
-
-       if (asoc_debugfs)
-               debugfs_remove_recursive(asoc_debugfs);
 }
 
 /* free all dapm widgets and resources */
@@ -1006,28 +990,6 @@ err:
        return ret;
 }
 
-/**
- * snd_soc_dapm_connect_input - connect dapm widgets
- * @codec: audio codec
- * @sink: name of target widget
- * @control: mixer control name
- * @source: name of source name
- *
- * Connects 2 dapm widgets together via a named audio path. The sink is
- * the widget receiving the audio signal, whilst the source is the sender
- * of the audio signal.
- *
- * This function has been deprecated in favour of snd_soc_dapm_add_routes().
- *
- * Returns 0 for success else error.
- */
-int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
-       const char *control, const char *source)
-{
-       return snd_soc_dapm_add_route(codec, sink, control, source);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
-
 /**
  * snd_soc_dapm_add_routes - Add routes between DAPM widgets
  * @codec: codec
@@ -1358,8 +1320,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
 
        for (i = 0; i < num; i++) {
                ret = snd_soc_dapm_new_control(codec, widget);
-               if (ret < 0)
+               if (ret < 0) {
+                       printk(KERN_ERR
+                              "ASoC: Failed to create DAPM control %s: %d\n",
+                              widget->name, ret);
                        return ret;
+               }
                widget++;
        }
        return 0;
@@ -1440,11 +1406,11 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
                                enum snd_soc_bias_level level)
 {
        struct snd_soc_codec *codec = socdev->codec;
-       struct snd_soc_machine *machine = socdev->machine;
+       struct snd_soc_card *card = socdev->card;
        int ret = 0;
 
-       if (machine->set_bias_level)
-               ret = machine->set_bias_level(machine, level);
+       if (card->set_bias_level)
+               ret = card->set_bias_level(card, level);
        if (ret == 0 && codec->set_bias_level)
                ret = codec->set_bias_level(codec, level);
 
index a75b289a5d78465c25ccf2aab83958e3e8a0a67d..10ba4218161b04936892bd72e6ca15688f2e36ef 100644 (file)
@@ -457,7 +457,7 @@ EXPORT_SYMBOL(unregister_sound_mixer);
 
 void unregister_sound_midi(int unit)
 {
-       return sound_remove_unit(&chains[2], unit);
+       sound_remove_unit(&chains[2], unit);
 }
 
 EXPORT_SYMBOL(unregister_sound_midi);
@@ -474,7 +474,7 @@ EXPORT_SYMBOL(unregister_sound_midi);
 
 void unregister_sound_dsp(int unit)
 {
-       return sound_remove_unit(&chains[3], unit);
+       sound_remove_unit(&chains[3], unit);
 }
 
 
@@ -507,7 +507,7 @@ static struct sound_unit *__look_for_unit(int chain, int unit)
        return NULL;
 }
 
-int soundcore_open(struct inode *inode, struct file *file)
+static int soundcore_open(struct inode *inode, struct file *file)
 {
        int chain;
        int unit = iminor(inode);