diff --git a/[refs] b/[refs] index eefb1b08dc76..a5e417bae898 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ba252af8d60f543a2a2c03f5574f64007ae9c2f3 +refs/heads/master: 3fd43858c7937801134bd70ef1d411e44f9c0c1c diff --git a/trunk/Documentation/hwmon/sysfs-interface b/trunk/Documentation/hwmon/sysfs-interface index 004ee161721e..2f10ce6a879f 100644 --- a/trunk/Documentation/hwmon/sysfs-interface +++ b/trunk/Documentation/hwmon/sysfs-interface @@ -150,11 +150,6 @@ fan[1-*]_min Fan minimum value Unit: revolution/min (RPM) RW -fan[1-*]_max Fan maximum value - Unit: revolution/min (RPM) - Only rarely supported by the hardware. - RW - fan[1-*]_input Fan input value. Unit: revolution/min (RPM) RO @@ -395,7 +390,6 @@ OR in[0-*]_min_alarm in[0-*]_max_alarm fan[1-*]_min_alarm -fan[1-*]_max_alarm temp[1-*]_min_alarm temp[1-*]_max_alarm temp[1-*]_crit_alarm diff --git a/trunk/Documentation/input/multi-touch-protocol.txt b/trunk/Documentation/input/multi-touch-protocol.txt index a12ea3b586e6..9f09557aea39 100644 --- a/trunk/Documentation/input/multi-touch-protocol.txt +++ b/trunk/Documentation/input/multi-touch-protocol.txt @@ -18,12 +18,8 @@ Usage Anonymous finger details are sent sequentially as separate packets of ABS events. Only the ABS_MT events are recognized as part of a finger packet. The end of a packet is marked by calling the input_mt_sync() -function, which generates a SYN_MT_REPORT event. This instructs the -receiver to accept the data for the current finger and prepare to receive -another. The end of a multi-touch transfer is marked by calling the usual -input_sync() function. This instructs the receiver to act upon events -accumulated since last EV_SYN/SYN_REPORT and prepare to receive a new -set of events/packets. +function, which generates a SYN_MT_REPORT event. The end of multi-touch +transfer is marked by calling the usual input_sync() function. A set of ABS_MT events with the desired properties is defined. The events are divided into categories, to allow for partial implementation. The @@ -31,26 +27,11 @@ minimum set consists of ABS_MT_TOUCH_MAJOR, ABS_MT_POSITION_X and ABS_MT_POSITION_Y, which allows for multiple fingers to be tracked. If the device supports it, the ABS_MT_WIDTH_MAJOR may be used to provide the size of the approaching finger. Anisotropy and direction may be specified with -ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION. The -ABS_MT_TOOL_TYPE may be used to specify whether the touching tool is a -finger or a pen or something else. Devices with more granular information -may specify general shapes as blobs, i.e., as a sequence of rectangular -shapes grouped together by an ABS_MT_BLOB_ID. Finally, for the few devices -that currently support it, the ABS_MT_TRACKING_ID event may be used to -report finger tracking from hardware [5]. - -Here is what a minimal event sequence for a two-finger touch would look -like: - - ABS_MT_TOUCH_MAJOR - ABS_MT_POSITION_X - ABS_MT_POSITION_Y - SYN_MT_REPORT - ABS_MT_TOUCH_MAJOR - ABS_MT_POSITION_X - ABS_MT_POSITION_Y - SYN_MT_REPORT - SYN_REPORT +ABS_MT_TOUCH_MINOR, ABS_MT_WIDTH_MINOR and ABS_MT_ORIENTATION. Devices with +more granular information may specify general shapes as blobs, i.e., as a +sequence of rectangular shapes grouped together by an +ABS_MT_BLOB_ID. Finally, the ABS_MT_TOOL_TYPE may be used to specify +whether the touching tool is a finger or a pen or something else. Event Semantics @@ -63,24 +44,24 @@ ABS_MT_TOUCH_MAJOR The length of the major axis of the contact. The length should be given in surface units. If the surface has an X times Y resolution, the largest -possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal [4]. +possible value of ABS_MT_TOUCH_MAJOR is sqrt(X^2 + Y^2), the diagonal. ABS_MT_TOUCH_MINOR The length, in surface units, of the minor axis of the contact. If the -contact is circular, this event can be omitted [4]. +contact is circular, this event can be omitted. ABS_MT_WIDTH_MAJOR The length, in surface units, of the major axis of the approaching tool. This should be understood as the size of the tool itself. The orientation of the contact and the approaching tool are assumed to be the -same [4]. +same. ABS_MT_WIDTH_MINOR The length, in surface units, of the minor axis of the approaching -tool. Omit if circular [4]. +tool. Omit if circular. The above four values can be used to derive additional information about the contact. The ratio ABS_MT_TOUCH_MAJOR / ABS_MT_WIDTH_MAJOR approximates @@ -89,17 +70,14 @@ different characteristic widths [1]. ABS_MT_ORIENTATION -The orientation of the ellipse. The value should describe a signed quarter -of a revolution clockwise around the touch center. The signed value range -is arbitrary, but zero should be returned for a finger aligned along the Y -axis of the surface, a negative value when finger is turned to the left, and -a positive value when finger turned to the right. When completely aligned with -the X axis, the range max should be returned. Orientation can be omitted -if the touching object is circular, or if the information is not available -in the kernel driver. Partial orientation support is possible if the device -can distinguish between the two axis, but not (uniquely) any values in -between. In such cases, the range of ABS_MT_ORIENTATION should be [0, 1] -[4]. +The orientation of the ellipse. The value should describe half a revolution +clockwise around the touch center. The scale of the value is arbitrary, but +zero should be returned for an ellipse aligned along the Y axis of the +surface. As an example, an index finger placed straight onto the axis could +return zero orientation, something negative when twisted to the left, and +something positive when twisted to the right. This value can be omitted if +the touching object is circular, or if the information is not available in +the kernel driver. ABS_MT_POSITION_X @@ -120,35 +98,8 @@ ABS_MT_BLOB_ID The BLOB_ID groups several packets together into one arbitrarily shaped contact. This is a low-level anonymous grouping, and should not be confused -with the high-level trackingID [5]. Most kernel drivers will not have blob -capability, and can safely omit the event. - -ABS_MT_TRACKING_ID - -The TRACKING_ID identifies an initiated contact throughout its life cycle -[5]. There are currently only a few devices that support it, so this event -should normally be omitted. - - -Event Computation ------------------ - -The flora of different hardware unavoidably leads to some devices fitting -better to the MT protocol than others. To simplify and unify the mapping, -this section gives recipes for how to compute certain events. - -For devices reporting contacts as rectangular shapes, signed orientation -cannot be obtained. Assuming X and Y are the lengths of the sides of the -touching rectangle, here is a simple formula that retains the most -information possible: - - ABS_MT_TOUCH_MAJOR := max(X, Y) - ABS_MT_TOUCH_MINOR := min(X, Y) - ABS_MT_ORIENTATION := bool(X > Y) - -The range of ABS_MT_ORIENTATION should be set to [0, 1], to indicate that -the device can distinguish between a finger along the Y axis (0) and a -finger along the X axis (1). +with the high-level contactID, explained below. Most kernel drivers will +not have this capability, and can safely omit the event. Finger Tracking @@ -158,18 +109,14 @@ The kernel driver should generate an arbitrary enumeration of the set of anonymous contacts currently on the surface. The order in which the packets appear in the event stream is not important. -The process of finger tracking, i.e., to assign a unique trackingID to each +The process of finger tracking, i.e., to assign a unique contactID to each initiated contact on the surface, is left to user space; preferably the -multi-touch X driver [3]. In that driver, the trackingID stays the same and +multi-touch X driver [3]. In that driver, the contactID stays the same and unique until the contact vanishes (when the finger leaves the surface). The problem of assigning a set of anonymous fingers to a set of identified fingers is a euclidian bipartite matching problem at each event update, and relies on a sufficiently rapid update rate. -There are a few devices that support trackingID in hardware. User space can -make use of these native identifiers to reduce bandwidth and cpu usage. - - Notes ----- @@ -189,7 +136,5 @@ could be used to derive tilt. time of writing (April 2009), the MT protocol is not yet merged, and the prototype implements finger matching, basic mouse support and two-finger scrolling. The project aims at improving the quality of current multi-touch -functionality available in the Synaptics X driver, and in addition +functionality available in the synaptics X driver, and in addition implement more advanced gestures. -[4] See the section on event computation. -[5] See the section on finger tracking. diff --git a/trunk/Documentation/sound/alsa/Procfile.txt b/trunk/Documentation/sound/alsa/Procfile.txt index cfac20cf9e33..bba2dbb79d81 100644 --- a/trunk/Documentation/sound/alsa/Procfile.txt +++ b/trunk/Documentation/sound/alsa/Procfile.txt @@ -104,11 +104,6 @@ card*/pcm*/xrun_debug When this value is greater than 1, the driver will show the stack trace additionally. This may help the debugging. - Since 2.6.30, this option also enables the hwptr check using - jiffies. This detects spontaneous invalid pointer callback - values, but can be lead to too much corrections for a (mostly - buggy) hardware that doesn't give smooth pointer updates. - card*/pcm*/sub*/info The general information of this PCM sub-stream. diff --git a/trunk/Documentation/sound/alsa/soc/dapm.txt b/trunk/Documentation/sound/alsa/soc/dapm.txt index 9ac842be9b4f..9e6763264a2e 100644 --- a/trunk/Documentation/sound/alsa/soc/dapm.txt +++ b/trunk/Documentation/sound/alsa/soc/dapm.txt @@ -62,7 +62,6 @@ Audio DAPM widgets fall into a number of types:- o Mic - Mic (and optional Jack) o Line - Line Input/Output (and optional Jack) o Speaker - Speaker - o Supply - Power or clock supply widget used by other widgets. o Pre - Special PRE widget (exec before all others) o Post - Special POST widget (exec after all others) diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index e8cb115e33b8..77cbfb1a696c 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -434,7 +434,7 @@ F: arch/alpha/ AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER P: Thomas Dahlmann -M: dahlmann.thomas@arcor.de +M: thomas.dahlmann@amd.com L: linux-geode@lists.infradead.org (moderated for non-subscribers) S: Supported F: drivers/usb/gadget/amd5536udc.* @@ -624,7 +624,6 @@ M: paulius.zaleckas@teltonika.lt L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) T: git git://gitorious.org/linux-gemini/mainline.git S: Maintained -F: arch/arm/mach-gemini/ ARM/EBSA110 MACHINE SUPPORT P: Russell King @@ -651,7 +650,6 @@ P: Paulius Zaleckas M: paulius.zaleckas@teltonika.lt L: linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only) S: Maintained -F: arch/arm/mm/*-fa* ARM/FOOTBRIDGE ARCHITECTURE P: Russell King @@ -1134,17 +1132,17 @@ F: fs/bfs/ F: include/linux/bfs_fs.h BLACKFIN ARCHITECTURE -P: Mike Frysinger -M: vapier@gentoo.org +P: Bryan Wu +M: cooloney@kernel.org L: uclinux-dist-devel@blackfin.uclinux.org W: http://blackfin.uclinux.org S: Supported F: arch/blackfin/ BLACKFIN EMAC DRIVER -P: Michael Hennerich -M: michael.hennerich@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org +P: Bryan Wu +M: cooloney@kernel.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported F: drivers/net/bfin_mac.* @@ -1152,7 +1150,7 @@ F: drivers/net/bfin_mac.* BLACKFIN RTC DRIVER P: Mike Frysinger M: vapier.adi@gmail.com -L: uclinux-dist-devel@blackfin.uclinux.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported F: drivers/rtc/rtc-bfin.c @@ -1160,7 +1158,7 @@ F: drivers/rtc/rtc-bfin.c BLACKFIN SERIAL DRIVER P: Sonic Zhang M: sonic.zhang@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported F: drivers/serial/bfin_5xx.c @@ -1168,7 +1166,7 @@ F: drivers/serial/bfin_5xx.c BLACKFIN WATCHDOG DRIVER P: Mike Frysinger M: vapier.adi@gmail.com -L: uclinux-dist-devel@blackfin.uclinux.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org S: Supported F: drivers/watchdog/bfin_wdt.c @@ -1176,7 +1174,7 @@ F: drivers/watchdog/bfin_wdt.c BLACKFIN I2C TWI DRIVER P: Sonic Zhang M: sonic.zhang@analog.com -L: uclinux-dist-devel@blackfin.uclinux.org +L: uclinux-dist-devel@blackfin.uclinux.org (subscribers-only) W: http://blackfin.uclinux.org/ S: Supported F: drivers/i2c/busses/i2c-bfin-twi.c @@ -1542,13 +1540,6 @@ W: http://www.fi.muni.cz/~kas/cosa/ S: Maintained F: drivers/net/wan/cosa* -CPMAC ETHERNET DRIVER -P: Florian Fainelli -M: florian@openwrt.org -L: netdev@vger.kernel.org -S: Maintained -F: drivers/net/cpmac.c - CPU FREQUENCY DRIVERS P: Dave Jones M: davej@redhat.com @@ -1980,8 +1971,8 @@ F: include/linux/edac.h EDAC-E752X P: Mark Gross -M: mark.gross@intel.com P: Doug Thompson +M: mark.gross@intel.com M: dougthompson@xmission.com L: bluesmoke-devel@lists.sourceforge.net (moderated for non-subscribers) W: bluesmoke.sourceforge.net @@ -2258,7 +2249,7 @@ P: Li Yang M: leoli@freescale.com P: Zhang Wei M: zw@zh-kernel.org -L: linuxppc-dev@ozlabs.org +L: linuxppc-embedded@ozlabs.org L: linux-kernel@vger.kernel.org S: Maintained F: drivers/dma/fsldma.* @@ -4574,8 +4565,7 @@ F: drivers/pcmcia/pxa2xx* F: drivers/spi/pxa2xx* F: drivers/usb/gadget/pxa2* F: include/sound/pxa2xx-lib.h -F: sound/arm/pxa* -F: sound/soc/pxa +F: sound/soc/pxa/pxa2xx* PXA168 SUPPORT P: Eric Miao @@ -5303,12 +5293,11 @@ P: Liam Girdwood M: lrg@slimlogic.co.uk P: Mark Brown M: broonie@opensource.wolfsonmicro.com -T: git git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound-2.6.git +T: git git://opensource.wolfsonmicro.com/linux-2.6-asoc L: alsa-devel@alsa-project.org (subscribers-only) W: http://alsa-project.org/main/index.php/ASoC S: Supported F: sound/soc/ -F: include/sound/soc* SPARC + UltraSPARC (sparc/sparc64) P: David S. Miller diff --git a/trunk/Makefile b/trunk/Makefile index 03373bb703ca..739fd34a72a2 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 30 -EXTRAVERSION = +EXTRAVERSION = -rc7 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* @@ -533,7 +533,7 @@ endif include $(srctree)/arch/$(SRCARCH)/Makefile -ifneq ($(CONFIG_FRAME_WARN),0) +ifneq (CONFIG_FRAME_WARN,0) KBUILD_CFLAGS += $(call cc-option,-Wframe-larger-than=${CONFIG_FRAME_WARN}) endif diff --git a/trunk/arch/arm/include/asm/assembler.h b/trunk/arch/arm/include/asm/assembler.h index 15f8a092b700..6116e4893c0a 100644 --- a/trunk/arch/arm/include/asm/assembler.h +++ b/trunk/arch/arm/include/asm/assembler.h @@ -114,16 +114,3 @@ .align 3; \ .long 9999b,9001f; \ .previous - -/* - * SMP data memory barrier - */ - .macro smp_dmb -#ifdef CONFIG_SMP -#if __LINUX_ARM_ARCH__ >= 7 - dmb -#elif __LINUX_ARM_ARCH__ == 6 - mcr p15, 0, r0, c7, c10, 5 @ dmb -#endif -#endif - .endm diff --git a/trunk/arch/arm/include/asm/atomic.h b/trunk/arch/arm/include/asm/atomic.h index 16b52f397983..ee99723b3a6c 100644 --- a/trunk/arch/arm/include/asm/atomic.h +++ b/trunk/arch/arm/include/asm/atomic.h @@ -44,29 +44,11 @@ static inline void atomic_set(atomic_t *v, int i) : "cc"); } -static inline void atomic_add(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - __asm__ __volatile__("@ atomic_add\n" -"1: ldrex %0, [%2]\n" -" add %0, %0, %3\n" -" strex %1, %0, [%2]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp) - : "r" (&v->counter), "Ir" (i) - : "cc"); -} - static inline int atomic_add_return(int i, atomic_t *v) { unsigned long tmp; int result; - smp_mb(); - __asm__ __volatile__("@ atomic_add_return\n" "1: ldrex %0, [%2]\n" " add %0, %0, %3\n" @@ -77,34 +59,14 @@ static inline int atomic_add_return(int i, atomic_t *v) : "r" (&v->counter), "Ir" (i) : "cc"); - smp_mb(); - return result; } -static inline void atomic_sub(int i, atomic_t *v) -{ - unsigned long tmp; - int result; - - __asm__ __volatile__("@ atomic_sub\n" -"1: ldrex %0, [%2]\n" -" sub %0, %0, %3\n" -" strex %1, %0, [%2]\n" -" teq %1, #0\n" -" bne 1b" - : "=&r" (result), "=&r" (tmp) - : "r" (&v->counter), "Ir" (i) - : "cc"); -} - static inline int atomic_sub_return(int i, atomic_t *v) { unsigned long tmp; int result; - smp_mb(); - __asm__ __volatile__("@ atomic_sub_return\n" "1: ldrex %0, [%2]\n" " sub %0, %0, %3\n" @@ -115,8 +77,6 @@ static inline int atomic_sub_return(int i, atomic_t *v) : "r" (&v->counter), "Ir" (i) : "cc"); - smp_mb(); - return result; } @@ -124,8 +84,6 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) { unsigned long oldval, res; - smp_mb(); - do { __asm__ __volatile__("@ atomic_cmpxchg\n" "ldrex %1, [%2]\n" @@ -137,8 +95,6 @@ static inline int atomic_cmpxchg(atomic_t *ptr, int old, int new) : "cc"); } while (res); - smp_mb(); - return oldval; } @@ -179,7 +135,6 @@ static inline int atomic_add_return(int i, atomic_t *v) return val; } -#define atomic_add(i, v) (void) atomic_add_return(i, v) static inline int atomic_sub_return(int i, atomic_t *v) { @@ -193,7 +148,6 @@ static inline int atomic_sub_return(int i, atomic_t *v) return val; } -#define atomic_sub(i, v) (void) atomic_sub_return(i, v) static inline int atomic_cmpxchg(atomic_t *v, int old, int new) { @@ -233,8 +187,10 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) } #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) -#define atomic_inc(v) atomic_add(1, v) -#define atomic_dec(v) atomic_sub(1, v) +#define atomic_add(i, v) (void) atomic_add_return(i, v) +#define atomic_inc(v) (void) atomic_add_return(1, v) +#define atomic_sub(i, v) (void) atomic_sub_return(i, v) +#define atomic_dec(v) (void) atomic_sub_return(1, v) #define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) #define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) @@ -244,10 +200,11 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u) #define atomic_add_negative(i,v) (atomic_add_return(i, v) < 0) -#define smp_mb__before_atomic_dec() smp_mb() -#define smp_mb__after_atomic_dec() smp_mb() -#define smp_mb__before_atomic_inc() smp_mb() -#define smp_mb__after_atomic_inc() smp_mb() +/* Atomic operations are already serializing on ARM */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() #include #endif diff --git a/trunk/arch/arm/include/asm/cache.h b/trunk/arch/arm/include/asm/cache.h index feaa75f0013e..cb7a9e97fd7e 100644 --- a/trunk/arch/arm/include/asm/cache.h +++ b/trunk/arch/arm/include/asm/cache.h @@ -7,20 +7,4 @@ #define L1_CACHE_SHIFT 5 #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) -/* - * Memory returned by kmalloc() may be used for DMA, so we must make - * sure that all such allocations are cache aligned. Otherwise, - * unrelated code may cause parts of the buffer to be read into the - * cache before the transfer is done, causing old data to be seen by - * the CPU. - */ -#define ARCH_KMALLOC_MINALIGN L1_CACHE_BYTES - -/* - * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers. - */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) -#define ARCH_SLAB_MINALIGN 8 -#endif - #endif diff --git a/trunk/arch/arm/include/asm/flat.h b/trunk/arch/arm/include/asm/flat.h index 59426a4595c9..1d77e51907f6 100644 --- a/trunk/arch/arm/include/asm/flat.h +++ b/trunk/arch/arm/include/asm/flat.h @@ -5,6 +5,9 @@ #ifndef __ARM_FLAT_H__ #define __ARM_FLAT_H__ +/* An odd number of words will be pushed after this alignment, so + deliberately misalign the value. */ +#define flat_stack_align(sp) sp = (void *)(((unsigned long)(sp) - 4) | 4) #define flat_argvp_envp_on_stack() 1 #define flat_old_ram_flag(flags) (flags) #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) diff --git a/trunk/arch/arm/include/asm/page.h b/trunk/arch/arm/include/asm/page.h index 7b522770f29d..e6eb8a67b807 100644 --- a/trunk/arch/arm/include/asm/page.h +++ b/trunk/arch/arm/include/asm/page.h @@ -202,6 +202,13 @@ typedef struct page *pgtable_t; (((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \ VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) +/* + * With EABI on ARMv5 and above we must have 64-bit aligned slab pointers. + */ +#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) +#define ARCH_SLAB_MINALIGN 8 +#endif + #include #endif diff --git a/trunk/arch/arm/include/asm/system.h b/trunk/arch/arm/include/asm/system.h index d65b2f5bf41f..bd4dc8ed53d5 100644 --- a/trunk/arch/arm/include/asm/system.h +++ b/trunk/arch/arm/include/asm/system.h @@ -248,8 +248,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size unsigned int tmp; #endif - smp_mb(); - switch (size) { #if __LINUX_ARM_ARCH__ >= 6 case 1: @@ -309,7 +307,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size __bad_xchg(ptr, size), ret = 0; break; } - smp_mb(); return ret; } @@ -319,12 +316,6 @@ extern void enable_hlt(void); #include -#if __LINUX_ARM_ARCH__ < 6 - -#ifdef CONFIG_SMP -#error "SMP is not supported on this platform" -#endif - /* * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make * them available. @@ -338,173 +329,6 @@ extern void enable_hlt(void); #include #endif -#else /* __LINUX_ARM_ARCH__ >= 6 */ - -extern void __bad_cmpxchg(volatile void *ptr, int size); - -/* - * cmpxchg only support 32-bits operands on ARMv6. - */ - -static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long oldval, res; - - switch (size) { -#ifdef CONFIG_CPU_32v6K - case 1: - do { - asm volatile("@ __cmpxchg1\n" - " ldrexb %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexbeq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; - case 2: - do { - asm volatile("@ __cmpxchg1\n" - " ldrexh %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexheq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; -#endif /* CONFIG_CPU_32v6K */ - case 4: - do { - asm volatile("@ __cmpxchg4\n" - " ldrex %1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " strexeq %0, %4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (old), "r" (new) - : "memory", "cc"); - } while (res); - break; - default: - __bad_cmpxchg(ptr, size); - oldval = 0; - } - - return oldval; -} - -static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old, - unsigned long new, int size) -{ - unsigned long ret; - - smp_mb(); - ret = __cmpxchg(ptr, old, new, size); - smp_mb(); - - return ret; -} - -#define cmpxchg(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \ - (unsigned long)(o), \ - (unsigned long)(n), \ - sizeof(*(ptr)))) - -static inline unsigned long __cmpxchg_local(volatile void *ptr, - unsigned long old, - unsigned long new, int size) -{ - unsigned long ret; - - switch (size) { -#ifndef CONFIG_CPU_32v6K - case 1: - case 2: - ret = __cmpxchg_local_generic(ptr, old, new, size); - break; -#endif /* !CONFIG_CPU_32v6K */ - default: - ret = __cmpxchg(ptr, old, new, size); - } - - return ret; -} - -#define cmpxchg_local(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \ - (unsigned long)(o), \ - (unsigned long)(n), \ - sizeof(*(ptr)))) - -#ifdef CONFIG_CPU_32v6K - -/* - * Note : ARMv7-M (currently unsupported by Linux) does not support - * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should - * not be allowed to use __cmpxchg64. - */ -static inline unsigned long long __cmpxchg64(volatile void *ptr, - unsigned long long old, - unsigned long long new) -{ - register unsigned long long oldval asm("r0"); - register unsigned long long __old asm("r2") = old; - register unsigned long long __new asm("r4") = new; - unsigned long res; - - do { - asm volatile( - " @ __cmpxchg8\n" - " ldrexd %1, %H1, [%2]\n" - " mov %0, #0\n" - " teq %1, %3\n" - " teqeq %H1, %H3\n" - " strexdeq %0, %4, %H4, [%2]\n" - : "=&r" (res), "=&r" (oldval) - : "r" (ptr), "Ir" (__old), "r" (__new) - : "memory", "cc"); - } while (res); - - return oldval; -} - -static inline unsigned long long __cmpxchg64_mb(volatile void *ptr, - unsigned long long old, - unsigned long long new) -{ - unsigned long long ret; - - smp_mb(); - ret = __cmpxchg64(ptr, old, new); - smp_mb(); - - return ret; -} - -#define cmpxchg64(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) - -#define cmpxchg64_local(ptr,o,n) \ - ((__typeof__(*(ptr)))__cmpxchg64((ptr), \ - (unsigned long long)(o), \ - (unsigned long long)(n))) - -#else /* !CONFIG_CPU_32v6K */ - -#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) - -#endif /* CONFIG_CPU_32v6K */ - -#endif /* __LINUX_ARM_ARCH__ >= 6 */ - #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) diff --git a/trunk/arch/arm/kernel/elf.c b/trunk/arch/arm/kernel/elf.c index 950391f194c4..d4a0da1e48f4 100644 --- a/trunk/arch/arm/kernel/elf.c +++ b/trunk/arch/arm/kernel/elf.c @@ -78,15 +78,6 @@ int arm_elf_read_implies_exec(const struct elf32_hdr *x, int executable_stack) return 1; if (cpu_architecture() < CPU_ARCH_ARMv6) return 1; -#if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT) - /* - * If we have support for OABI programs, we can never allow NX - * support - our signal syscall restart mechanism relies upon - * being able to execute code placed on the user stack. - */ - return 1; -#else return 0; -#endif } EXPORT_SYMBOL(arm_elf_read_implies_exec); diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 83b1da6b7baa..d662a2f1fd85 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -815,7 +815,10 @@ __kuser_helper_start: */ __kuser_memory_barrier: @ 0xffff0fa0 - smp_dmb + +#if __LINUX_ARM_ARCH__ >= 6 && defined(CONFIG_SMP) + mcr p15, 0, r0, c7, c10, 5 @ dmb +#endif usr_ret lr .align 5 diff --git a/trunk/arch/arm/lib/bitops.h b/trunk/arch/arm/lib/bitops.h index c7f2627385e7..2e787d40d599 100644 --- a/trunk/arch/arm/lib/bitops.h +++ b/trunk/arch/arm/lib/bitops.h @@ -18,14 +18,12 @@ mov r2, #1 add r1, r1, r0, lsr #3 @ Get byte offset mov r3, r2, lsl r3 @ create mask - smp_dmb 1: ldrexb r2, [r1] ands r0, r2, r3 @ save old value of bit \instr r2, r2, r3 @ toggle bit strexb ip, r2, [r1] cmp ip, #0 bne 1b - smp_dmb cmp r0, #0 movne r0, #1 2: mov pc, lr diff --git a/trunk/arch/arm/mach-gemini/include/mach/hardware.h b/trunk/arch/arm/mach-gemini/include/mach/hardware.h index 213a4fcfeb1c..de6752674c05 100644 --- a/trunk/arch/arm/mach-gemini/include/mach/hardware.h +++ b/trunk/arch/arm/mach-gemini/include/mach/hardware.h @@ -15,9 +15,10 @@ /* * Memory Map definitions */ +/* FIXME: Does it really swap SRAM like this? */ #ifdef CONFIG_GEMINI_MEM_SWAP # define GEMINI_DRAM_BASE 0x00000000 -# define GEMINI_SRAM_BASE 0x70000000 +# define GEMINI_SRAM_BASE 0x20000000 #else # define GEMINI_SRAM_BASE 0x00000000 # define GEMINI_DRAM_BASE 0x10000000 diff --git a/trunk/arch/arm/mach-kirkwood/common.c b/trunk/arch/arm/mach-kirkwood/common.c index be1ca28fed3f..eeb00240d784 100644 --- a/trunk/arch/arm/mach-kirkwood/common.c +++ b/trunk/arch/arm/mach-kirkwood/common.c @@ -144,9 +144,6 @@ static struct platform_device kirkwood_ge00 = { .id = 0, .num_resources = 1, .resource = kirkwood_ge00_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) @@ -205,9 +202,6 @@ static struct platform_device kirkwood_ge01 = { .id = 1, .num_resources = 1, .resource = kirkwood_ge01_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) @@ -392,10 +386,12 @@ static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = { static struct resource kirkwood_i2c_resources[] = { { + .name = "i2c", .start = I2C_PHYS_BASE, .end = I2C_PHYS_BASE + 0x1f, .flags = IORESOURCE_MEM, }, { + .name = "i2c", .start = IRQ_KIRKWOOD_TWSI, .end = IRQ_KIRKWOOD_TWSI, .flags = IORESOURCE_IRQ, diff --git a/trunk/arch/arm/mach-kirkwood/ts219-setup.c b/trunk/arch/arm/mach-kirkwood/ts219-setup.c index 01aa213c0a6f..dda5743cf3e0 100644 --- a/trunk/arch/arm/mach-kirkwood/ts219-setup.c +++ b/trunk/arch/arm/mach-kirkwood/ts219-setup.c @@ -142,8 +142,6 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = { MPP1_SPI_MOSI, MPP2_SPI_SCK, MPP3_SPI_MISO, - MPP4_SATA1_ACTn, - MPP5_SATA0_ACTn, MPP8_TW_SDA, MPP9_TW_SCK, MPP10_UART0_TXD, @@ -152,6 +150,10 @@ static unsigned int qnap_ts219_mpp_config[] __initdata = { MPP14_UART1_RXD, /* PIC controller */ MPP15_GPIO, /* USB Copy button */ MPP16_GPIO, /* Reset button */ + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP22_SATA1_PRESENTn, + MPP23_SATA0_PRESENTn, 0 }; diff --git a/trunk/arch/arm/mach-loki/common.c b/trunk/arch/arm/mach-loki/common.c index 818f19d7ab1f..c0d2d9d12e74 100644 --- a/trunk/arch/arm/mach-loki/common.c +++ b/trunk/arch/arm/mach-loki/common.c @@ -82,9 +82,6 @@ static struct platform_device loki_ge0 = { .id = 0, .num_resources = 1, .resource = loki_ge0_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data) @@ -139,9 +136,6 @@ static struct platform_device loki_ge1 = { .id = 1, .num_resources = 1, .resource = loki_ge1_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data) diff --git a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index 2e914649b9e4..d0bdb6e3682b 100644 --- a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -3,11 +3,6 @@ #include -#define MFP_DRIVE_VERY_SLOW (0x0 << 13) -#define MFP_DRIVE_SLOW (0x1 << 13) -#define MFP_DRIVE_MEDIUM (0x2 << 13) -#define MFP_DRIVE_FAST (0x3 << 13) - /* GPIO */ #define GPIO0_GPIO MFP_CFG(GPIO0, AF5) #define GPIO1_GPIO MFP_CFG(GPIO1, AF5) diff --git a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa910.h b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa910.h index d97de36c50ad..48a1cbc7c56b 100644 --- a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa910.h +++ b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa910.h @@ -3,11 +3,6 @@ #include -#define MFP_DRIVE_VERY_SLOW (0x0 << 13) -#define MFP_DRIVE_SLOW (0x2 << 13) -#define MFP_DRIVE_MEDIUM (0x4 << 13) -#define MFP_DRIVE_FAST (0x8 << 13) - /* UART2 */ #define GPIO47_UART2_RXD MFP_CFG(GPIO47, AF6) #define GPIO48_UART2_TXD MFP_CFG(GPIO48, AF6) diff --git a/trunk/arch/arm/mach-mmp/include/mach/mfp.h b/trunk/arch/arm/mach-mmp/include/mach/mfp.h index 62e510e80a58..277ea4cd0f9f 100644 --- a/trunk/arch/arm/mach-mmp/include/mach/mfp.h +++ b/trunk/arch/arm/mach-mmp/include/mach/mfp.h @@ -12,13 +12,16 @@ * possible, we make the following compromise: * * 1. SLEEP_OE_N will always be programmed to '1' (by MFP_LPM_FLOAT) - * 2. DRIVE strength definitions redefined to include the reserved bit - * - the reserved bit differs between pxa168 and pxa910, and the - * MFP_DRIVE_* macros are individually defined in mfp-pxa{168,910}.h + * 2. DRIVE strength definitions redefined to include the reserved bit10 * 3. Override MFP_CFG() and MFP_CFG_DRV() * 4. Drop the use of MFP_CFG_LPM() and MFP_CFG_X() */ +#define MFP_DRIVE_VERY_SLOW (0x0 << 13) +#define MFP_DRIVE_SLOW (0x2 << 13) +#define MFP_DRIVE_MEDIUM (0x4 << 13) +#define MFP_DRIVE_FAST (0x8 << 13) + #undef MFP_CFG #undef MFP_CFG_DRV #undef MFP_CFG_LPM diff --git a/trunk/arch/arm/mach-mmp/time.c b/trunk/arch/arm/mach-mmp/time.c index a8400bb891e7..b03a6eda7419 100644 --- a/trunk/arch/arm/mach-mmp/time.c +++ b/trunk/arch/arm/mach-mmp/time.c @@ -136,7 +136,7 @@ static struct clock_event_device ckevt = { .set_mode = timer_set_mode, }; -static cycle_t clksrc_read(struct clocksource *cs) +static cycle_t clksrc_read(void) { return timer_read(); } diff --git a/trunk/arch/arm/mach-mv78xx0/common.c b/trunk/arch/arm/mach-mv78xx0/common.c index 1b22e4af8791..9ba595083dab 100644 --- a/trunk/arch/arm/mach-mv78xx0/common.c +++ b/trunk/arch/arm/mach-mv78xx0/common.c @@ -321,9 +321,6 @@ static struct platform_device mv78xx0_ge00 = { .id = 0, .num_resources = 1, .resource = mv78xx0_ge00_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data) @@ -378,9 +375,6 @@ static struct platform_device mv78xx0_ge01 = { .id = 1, .num_resources = 1, .resource = mv78xx0_ge01_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data) @@ -435,9 +429,6 @@ static struct platform_device mv78xx0_ge10 = { .id = 2, .num_resources = 1, .resource = mv78xx0_ge10_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data) @@ -505,9 +496,6 @@ static struct platform_device mv78xx0_ge11 = { .id = 3, .num_resources = 1, .resource = mv78xx0_ge11_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data) @@ -544,10 +532,12 @@ static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = { static struct resource mv78xx0_i2c_0_resources[] = { { + .name = "i2c 0 base", .start = I2C_0_PHYS_BASE, .end = I2C_0_PHYS_BASE + 0x1f, .flags = IORESOURCE_MEM, }, { + .name = "i2c 0 irq", .start = IRQ_MV78XX0_I2C_0, .end = IRQ_MV78XX0_I2C_0, .flags = IORESOURCE_IRQ, @@ -577,10 +567,12 @@ static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = { static struct resource mv78xx0_i2c_1_resources[] = { { + .name = "i2c 1 base", .start = I2C_1_PHYS_BASE, .end = I2C_1_PHYS_BASE + 0x1f, .flags = IORESOURCE_MEM, }, { + .name = "i2c 1 irq", .start = IRQ_MV78XX0_I2C_1, .end = IRQ_MV78XX0_I2C_1, .flags = IORESOURCE_IRQ, diff --git a/trunk/arch/arm/mach-mx2/clock_imx21.c b/trunk/arch/arm/mach-mx2/clock_imx21.c index e4b08ca804ea..999d013e06e3 100644 --- a/trunk/arch/arm/mach-mx2/clock_imx21.c +++ b/trunk/arch/arm/mach-mx2/clock_imx21.c @@ -890,7 +890,7 @@ static struct clk clko_clk = { .con_id = n, \ .clk = &c, \ }, -static struct clk_lookup lookups[] = { +static struct clk_lookup lookups[] __initdata = { /* It's unlikely that any driver wants one of them directly: _REGISTER_CLOCK(NULL, "ckih", ckih_clk) _REGISTER_CLOCK(NULL, "ckil", ckil_clk) diff --git a/trunk/arch/arm/mach-mx2/clock_imx27.c b/trunk/arch/arm/mach-mx2/clock_imx27.c index 2c971442f3f2..3f7280c490f0 100644 --- a/trunk/arch/arm/mach-mx2/clock_imx27.c +++ b/trunk/arch/arm/mach-mx2/clock_imx27.c @@ -621,7 +621,7 @@ DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk); .clk = &c, \ }, -static struct clk_lookup lookups[] = { +static struct clk_lookup lookups[] __initdata = { _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) diff --git a/trunk/arch/arm/mach-mx3/clock-imx35.c b/trunk/arch/arm/mach-mx3/clock-imx35.c index 3c1e06f56dd6..53a112d4e04a 100644 --- a/trunk/arch/arm/mach-mx3/clock-imx35.c +++ b/trunk/arch/arm/mach-mx3/clock-imx35.c @@ -404,7 +404,7 @@ DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); .clk = &c, \ }, -static struct clk_lookup lookups[] = { +static struct clk_lookup lookups[] __initdata = { _REGISTER_CLOCK(NULL, "asrc", asrc_clk) _REGISTER_CLOCK(NULL, "ata", ata_clk) _REGISTER_CLOCK(NULL, "audmux", audmux_clk) diff --git a/trunk/arch/arm/mach-mx3/clock.c b/trunk/arch/arm/mach-mx3/clock.c index a68fcf981edf..9957a11533a4 100644 --- a/trunk/arch/arm/mach-mx3/clock.c +++ b/trunk/arch/arm/mach-mx3/clock.c @@ -516,7 +516,7 @@ DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); .clk = &c, \ }, -static struct clk_lookup lookups[] = { +static struct clk_lookup lookups[] __initdata = { _REGISTER_CLOCK(NULL, "emi", emi_clk) _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) diff --git a/trunk/arch/arm/mach-orion5x/common.c b/trunk/arch/arm/mach-orion5x/common.c index b1c7778d9f96..6af99ddabdfb 100644 --- a/trunk/arch/arm/mach-orion5x/common.c +++ b/trunk/arch/arm/mach-orion5x/common.c @@ -188,9 +188,6 @@ static struct platform_device orion5x_eth = { .id = 0, .num_resources = 1, .resource = orion5x_eth_resources, - .dev = { - .coherent_dma_mask = 0xffffffff, - }, }; void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data) @@ -251,10 +248,12 @@ static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = { static struct resource orion5x_i2c_resources[] = { { + .name = "i2c base", .start = I2C_PHYS_BASE, .end = I2C_PHYS_BASE + 0x1f, .flags = IORESOURCE_MEM, }, { + .name = "i2c irq", .start = IRQ_ORION5X_I2C, .end = IRQ_ORION5X_I2C, .flags = IORESOURCE_IRQ, diff --git a/trunk/arch/arm/mach-pxa/devices.c b/trunk/arch/arm/mach-pxa/devices.c index 29970f703f3c..d245e59c51b1 100644 --- a/trunk/arch/arm/mach-pxa/devices.c +++ b/trunk/arch/arm/mach-pxa/devices.c @@ -72,10 +72,7 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info) } -static struct pxa2xx_udc_mach_info pxa_udc_info = { - .gpio_pullup = -1, - .gpio_vbus = -1, -}; +static struct pxa2xx_udc_mach_info pxa_udc_info; void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info) { diff --git a/trunk/arch/arm/mach-pxa/ezx.c b/trunk/arch/arm/mach-pxa/ezx.c index 7db966dc29ce..92ba16e1b6fc 100644 --- a/trunk/arch/arm/mach-pxa/ezx.c +++ b/trunk/arch/arm/mach-pxa/ezx.c @@ -111,9 +111,9 @@ static unsigned long ezx_pin_config[] __initdata = { GPIO25_SSP1_TXD, GPIO26_SSP1_RXD, GPIO24_GPIO, /* pcap chip select */ - GPIO1_GPIO | WAKEUP_ON_EDGE_RISE, /* pcap interrupt */ - GPIO4_GPIO | MFP_LPM_DRIVE_HIGH, /* WDI_AP */ - GPIO55_GPIO | MFP_LPM_DRIVE_HIGH, /* SYS_RESTART */ + GPIO1_GPIO, /* pcap interrupt */ + GPIO4_GPIO, /* WDI_AP */ + GPIO55_GPIO, /* SYS_RESTART */ /* MMC */ GPIO32_MMC_CLK, @@ -144,20 +144,20 @@ static unsigned long ezx_pin_config[] __initdata = { #if defined(CONFIG_MACH_EZX_A780) || defined(CONFIG_MACH_EZX_E680) static unsigned long gen1_pin_config[] __initdata = { /* flip / lockswitch */ - GPIO12_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO12_GPIO, /* bluetooth (bcm2035) */ - GPIO14_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */ + GPIO14_GPIO | WAKEUP_ON_LEVEL_HIGH, /* HOSTWAKE */ GPIO48_GPIO, /* RESET */ GPIO28_GPIO, /* WAKEUP */ /* Neptune handshake */ - GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */ - GPIO57_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */ - GPIO13_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI */ - GPIO3_GPIO | WAKEUP_ON_EDGE_BOTH, /* WDI2 */ - GPIO82_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */ - GPIO99_GPIO | MFP_LPM_DRIVE_HIGH, /* TC_MM_EN */ + GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* BP_RDY */ + GPIO57_GPIO, /* AP_RDY */ + GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH, /* WDI */ + GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH, /* WDI2 */ + GPIO82_GPIO, /* RESET */ + GPIO99_GPIO, /* TC_MM_EN */ /* sound */ GPIO52_SSP3_SCLK, @@ -199,21 +199,21 @@ static unsigned long gen1_pin_config[] __initdata = { defined(CONFIG_MACH_EZX_E2) || defined(CONFIG_MACH_EZX_E6) static unsigned long gen2_pin_config[] __initdata = { /* flip / lockswitch */ - GPIO15_GPIO | WAKEUP_ON_EDGE_BOTH, + GPIO15_GPIO, /* EOC */ - GPIO10_GPIO | WAKEUP_ON_EDGE_RISE, + GPIO10_GPIO, /* bluetooth (bcm2045) */ - GPIO13_GPIO | WAKEUP_ON_EDGE_RISE, /* HOSTWAKE */ + GPIO13_GPIO | WAKEUP_ON_LEVEL_HIGH, /* HOSTWAKE */ GPIO37_GPIO, /* RESET */ GPIO57_GPIO, /* WAKEUP */ /* Neptune handshake */ - GPIO0_GPIO | WAKEUP_ON_EDGE_FALL, /* BP_RDY */ - GPIO96_GPIO | MFP_LPM_DRIVE_HIGH, /* AP_RDY */ - GPIO3_GPIO | WAKEUP_ON_EDGE_FALL, /* WDI */ - GPIO116_GPIO | MFP_LPM_DRIVE_HIGH, /* RESET */ + GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* BP_RDY */ + GPIO96_GPIO, /* AP_RDY */ + GPIO3_GPIO | WAKEUP_ON_LEVEL_HIGH, /* WDI */ + GPIO116_GPIO, /* RESET */ GPIO41_GPIO, /* BP_FLASH */ /* sound */ diff --git a/trunk/arch/arm/mach-pxa/imote2.c b/trunk/arch/arm/mach-pxa/imote2.c index 2b27336c29f1..2121309b2474 100644 --- a/trunk/arch/arm/mach-pxa/imote2.c +++ b/trunk/arch/arm/mach-pxa/imote2.c @@ -412,7 +412,7 @@ static struct platform_device imote2_flash_device = { */ static struct i2c_board_info __initdata imote2_i2c_board_info[] = { { /* UCAM sensor board */ - .type = "max1239", + .type = "max1238", .addr = 0x35, }, { /* ITS400 Sensor board only */ .type = "max1363", diff --git a/trunk/arch/arm/mach-pxa/include/mach/reset.h b/trunk/arch/arm/mach-pxa/include/mach/reset.h index b6c10556fbc7..31e6a7b6ad80 100644 --- a/trunk/arch/arm/mach-pxa/include/mach/reset.h +++ b/trunk/arch/arm/mach-pxa/include/mach/reset.h @@ -13,9 +13,8 @@ extern void clear_reset_status(unsigned int mask); /** * init_gpio_reset() - register GPIO as reset generator * @gpio: gpio nr - * @output: set gpio as output instead of input during normal work - * @level: output level + * @output: set gpio as out/low instead of input during normal work */ -extern int init_gpio_reset(int gpio, int output, int level); +extern int init_gpio_reset(int gpio, int output); #endif /* __ASM_ARCH_RESET_H */ diff --git a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c index cf6b720c055f..7ffb91d64c39 100644 --- a/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/trunk/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -322,7 +322,6 @@ static inline void pxa27x_mfp_init(void) {} #ifdef CONFIG_PM static unsigned long saved_gafr[2][4]; static unsigned long saved_gpdr[4]; -static unsigned long saved_pgsr[4]; static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state) { @@ -333,7 +332,6 @@ static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state) saved_gafr[0][i] = GAFR_L(i); saved_gafr[1][i] = GAFR_U(i); saved_gpdr[i] = GPDR(i * 32); - saved_pgsr[i] = PGSR(i); GPDR(i * 32) = gpdr_lpm[i]; } @@ -348,7 +346,6 @@ static int pxa2xx_mfp_resume(struct sys_device *d) GAFR_L(i) = saved_gafr[0][i]; GAFR_U(i) = saved_gafr[1][i]; GPDR(i * 32) = saved_gpdr[i]; - PGSR(i) = saved_pgsr[i]; } PSSR = PSSR_RDH | PSSR_PH; return 0; @@ -377,9 +374,6 @@ static int __init pxa2xx_mfp_init(void) if (cpu_is_pxa27x()) pxa27x_mfp_init(); - /* clear RDH bit to enable GPIO receivers after reset/sleep exit */ - PSSR = PSSR_RDH; - /* initialize gafr_run[], pgsr_lpm[] from existing values */ for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++) gpdr_lpm[i] = GPDR(i * 32); diff --git a/trunk/arch/arm/mach-pxa/palmld.c b/trunk/arch/arm/mach-pxa/palmld.c index 471a853e548b..1cec1806f002 100644 --- a/trunk/arch/arm/mach-pxa/palmld.c +++ b/trunk/arch/arm/mach-pxa/palmld.c @@ -62,8 +62,6 @@ static unsigned long palmld_pin_config[] __initdata = { GPIO29_AC97_SDATA_IN_0, GPIO30_AC97_SDATA_OUT, GPIO31_AC97_SYNC, - GPIO89_AC97_SYSCLK, - GPIO95_AC97_nRESET, /* IrDA */ GPIO108_GPIO, /* ir disable */ diff --git a/trunk/arch/arm/mach-pxa/palmt5.c b/trunk/arch/arm/mach-pxa/palmt5.c index 05bf979b78a6..30662363907b 100644 --- a/trunk/arch/arm/mach-pxa/palmt5.c +++ b/trunk/arch/arm/mach-pxa/palmt5.c @@ -64,7 +64,6 @@ static unsigned long palmt5_pin_config[] __initdata = { GPIO29_AC97_SDATA_IN_0, GPIO30_AC97_SDATA_OUT, GPIO31_AC97_SYNC, - GPIO89_AC97_SYSCLK, GPIO95_AC97_nRESET, /* IrDA */ diff --git a/trunk/arch/arm/mach-pxa/palmtx.c b/trunk/arch/arm/mach-pxa/palmtx.c index e99a893c58a7..e2d44b1a8a9b 100644 --- a/trunk/arch/arm/mach-pxa/palmtx.c +++ b/trunk/arch/arm/mach-pxa/palmtx.c @@ -65,7 +65,6 @@ static unsigned long palmtx_pin_config[] __initdata = { GPIO29_AC97_SDATA_IN_0, GPIO30_AC97_SDATA_OUT, GPIO31_AC97_SYNC, - GPIO89_AC97_SYSCLK, GPIO95_AC97_nRESET, /* IrDA */ diff --git a/trunk/arch/arm/mach-pxa/reset.c b/trunk/arch/arm/mach-pxa/reset.c index 01e9d643394a..df29d45fb4e7 100644 --- a/trunk/arch/arm/mach-pxa/reset.c +++ b/trunk/arch/arm/mach-pxa/reset.c @@ -20,7 +20,7 @@ static void do_hw_reset(void); static int reset_gpio = -1; -int init_gpio_reset(int gpio, int output, int level) +int init_gpio_reset(int gpio, int output) { int rc; @@ -31,7 +31,7 @@ int init_gpio_reset(int gpio, int output, int level) } if (output) - rc = gpio_direction_output(gpio, level); + rc = gpio_direction_output(gpio, 0); else rc = gpio_direction_input(gpio); if (rc) { diff --git a/trunk/arch/arm/mach-pxa/spitz.c b/trunk/arch/arm/mach-pxa/spitz.c index 5a45fe340a10..c18e34acafcb 100644 --- a/trunk/arch/arm/mach-pxa/spitz.c +++ b/trunk/arch/arm/mach-pxa/spitz.c @@ -531,15 +531,9 @@ static int spitz_ohci_init(struct device *dev) return gpio_direction_output(SPITZ_GPIO_USB_HOST, 1); } -static void spitz_ohci_exit(struct device *dev) -{ - gpio_free(SPITZ_GPIO_USB_HOST); -} - static struct pxaohci_platform_data spitz_ohci_platform_data = { .port_mode = PMM_NPS_MODE, .init = spitz_ohci_init, - .exit = spitz_ohci_exit, .flags = ENABLE_PORT_ALL | NO_OC_PROTECTION, .power_budget = 150, }; @@ -737,7 +731,7 @@ static void spitz_restart(char mode, const char *cmd) static void __init common_init(void) { - init_gpio_reset(SPITZ_GPIO_ON_RESET, 1, 0); + init_gpio_reset(SPITZ_GPIO_ON_RESET, 1); pm_power_off = spitz_poweroff; arm_pm_restart = spitz_restart; diff --git a/trunk/arch/arm/mach-pxa/tosa.c b/trunk/arch/arm/mach-pxa/tosa.c index a0bd46ef5d30..afac5b6d3d78 100644 --- a/trunk/arch/arm/mach-pxa/tosa.c +++ b/trunk/arch/arm/mach-pxa/tosa.c @@ -897,7 +897,7 @@ static void __init tosa_init(void) gpio_set_wake(MFP_PIN_GPIO1, 1); /* We can't pass to gpio-keys since it will drop the Reset altfunc */ - init_gpio_reset(TOSA_GPIO_ON_RESET, 0, 0); + init_gpio_reset(TOSA_GPIO_ON_RESET, 0); pm_power_off = tosa_poweroff; arm_pm_restart = tosa_restart; diff --git a/trunk/arch/arm/mm/proc-v7.S b/trunk/arch/arm/mm/proc-v7.S index a08d9d2380d3..3397f1e64d76 100644 --- a/trunk/arch/arm/mm/proc-v7.S +++ b/trunk/arch/arm/mm/proc-v7.S @@ -184,37 +184,23 @@ __v7_setup: stmia r12, {r0-r5, r7, r9, r11, lr} bl v7_flush_dcache_all ldmia r12, {r0-r5, r7, r9, r11, lr} - - mrc p15, 0, r0, c0, c0, 0 @ read main ID register - and r10, r0, #0xff000000 @ ARM? - teq r10, #0x41000000 - bne 2f - and r5, r0, #0x00f00000 @ variant - and r6, r0, #0x0000000f @ revision - orr r0, r6, r5, lsr #20-4 @ combine variant and revision - #ifdef CONFIG_ARM_ERRATA_430973 - teq r5, #0x00100000 @ only present in r1p* - mrceq p15, 0, r10, c1, c0, 1 @ read aux control register - orreq r10, r10, #(1 << 6) @ set IBE to 1 - mcreq p15, 0, r10, c1, c0, 1 @ write aux control register + mrc p15, 0, r10, c1, c0, 1 @ read aux control register + orr r10, r10, #(1 << 6) @ set IBE to 1 + mcr p15, 0, r10, c1, c0, 1 @ write aux control register #endif #ifdef CONFIG_ARM_ERRATA_458693 - teq r0, #0x20 @ only present in r2p0 - mrceq p15, 0, r10, c1, c0, 1 @ read aux control register - orreq r10, r10, #(1 << 5) @ set L1NEON to 1 - orreq r10, r10, #(1 << 9) @ set PLDNOP to 1 - mcreq p15, 0, r10, c1, c0, 1 @ write aux control register + mrc p15, 0, r10, c1, c0, 1 @ read aux control register + orr r10, r10, #(1 << 5) @ set L1NEON to 1 + orr r10, r10, #(1 << 9) @ set PLDNOP to 1 + mcr p15, 0, r10, c1, c0, 1 @ write aux control register #endif #ifdef CONFIG_ARM_ERRATA_460075 - teq r0, #0x20 @ only present in r2p0 - mrceq p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register - tsteq r10, #1 << 22 - orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit - mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register + mrc p15, 1, r10, c9, c0, 2 @ read L2 cache aux ctrl register + orr r10, r10, #(1 << 22) @ set the Write Allocate disable bit + mcr p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register #endif - -2: mov r10, #0 + mov r10, #0 #ifdef HARVARD_CACHE mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate #endif diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index fec64678a63a..945e0d237a1d 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -12,7 +12,7 @@ # # http://www.arm.linux.org.uk/developer/machines/?action=new # -# Last update: Fri May 29 10:14:20 2009 +# Last update: Mon Mar 23 20:09:01 2009 # # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number # @@ -916,7 +916,7 @@ nxdb500 MACH_NXDB500 NXDB500 905 apf9328 MACH_APF9328 APF9328 906 omap_wipoq MACH_OMAP_WIPOQ OMAP_WIPOQ 907 omap_twip MACH_OMAP_TWIP OMAP_TWIP 908 -treo650 MACH_TREO650 TREO650 909 +palmt650 MACH_PALMT650 PALMT650 909 acumen MACH_ACUMEN ACUMEN 910 xp100 MACH_XP100 XP100 911 fs2410 MACH_FS2410 FS2410 912 @@ -1232,7 +1232,7 @@ ql202b MACH_QL202B QL202B 1226 vpac270 MACH_VPAC270 VPAC270 1227 rd129 MACH_RD129 RD129 1228 htcwizard MACH_HTCWIZARD HTCWIZARD 1229 -treo680 MACH_TREO680 TREO680 1230 +xscale_treo680 MACH_XSCALE_TREO680 XSCALE_TREO680 1230 tecon_tmezon MACH_TECON_TMEZON TECON_TMEZON 1231 zylonite MACH_ZYLONITE ZYLONITE 1233 gene1270 MACH_GENE1270 GENE1270 1234 @@ -1418,10 +1418,10 @@ looxc550 MACH_LOOXC550 LOOXC550 1417 cnty_titan MACH_CNTY_TITAN CNTY_TITAN 1418 app3xx MACH_APP3XX APP3XX 1419 sideoatsgrama MACH_SIDEOATSGRAMA SIDEOATSGRAMA 1420 -treo700p MACH_TREO700P TREO700P 1421 -treo700w MACH_TREO700W TREO700W 1422 -treo750 MACH_TREO750 TREO750 1423 -treo755p MACH_TREO755P TREO755P 1424 +palmtreo700p MACH_PALMTREO700P PALMTREO700P 1421 +palmtreo700w MACH_PALMTREO700W PALMTREO700W 1422 +palmtreo750 MACH_PALMTREO750 PALMTREO750 1423 +palmtreo755p MACH_PALMTREO755P PALMTREO755P 1424 ezreganut9200 MACH_EZREGANUT9200 EZREGANUT9200 1425 sarge MACH_SARGE SARGE 1426 a696 MACH_A696 A696 1427 @@ -1721,7 +1721,7 @@ sapphire MACH_SAPPHIRE SAPPHIRE 1729 csb637xo MACH_CSB637XO CSB637XO 1730 evisiong MACH_EVISIONG EVISIONG 1731 stmp37xx MACH_STMP37XX STMP37XX 1732 -stmp378x MACH_STMP378X STMP378X 1733 +stmp378x MACH_STMP38XX STMP38XX 1733 tnt MACH_TNT TNT 1734 tbxt MACH_TBXT TBXT 1735 playmate MACH_PLAYMATE PLAYMATE 1736 @@ -1817,7 +1817,7 @@ smdkc100 MACH_SMDKC100 SMDKC100 1826 tavorevb MACH_TAVOREVB TAVOREVB 1827 saar MACH_SAAR SAAR 1828 deister_eyecam MACH_DEISTER_EYECAM DEISTER_EYECAM 1829 -at91sam9m10g45ek MACH_AT91SAM9M10G45EK AT91SAM9M10G45EK 1830 +at91sam9m10ek MACH_AT91SAM9M10EK AT91SAM9M10EK 1830 linkstation_produo MACH_LINKSTATION_PRODUO LINKSTATION_PRODUO 1831 hit_b0 MACH_HIT_B0 HIT_B0 1832 adx_rmu MACH_ADX_RMU ADX_RMU 1833 @@ -2132,116 +2132,3 @@ apollo MACH_APOLLO APOLLO 2141 at91cap9stk MACH_AT91CAP9STK AT91CAP9STK 2142 spc300 MACH_SPC300 SPC300 2143 eko MACH_EKO EKO 2144 -ccw9m2443 MACH_CCW9M2443 CCW9M2443 2145 -ccw9m2443js MACH_CCW9M2443JS CCW9M2443JS 2146 -m2m_router_device MACH_M2M_ROUTER_DEVICE M2M_ROUTER_DEVICE 2147 -str9104nas MACH_STAR9104NAS STAR9104NAS 2148 -pca100 MACH_PCA100 PCA100 2149 -z3_dm365_mod_01 MACH_Z3_DM365_MOD_01 Z3_DM365_MOD_01 2150 -hipox MACH_HIPOX HIPOX 2151 -omap3_piteds MACH_OMAP3_PITEDS OMAP3_PITEDS 2152 -bm150r MACH_BM150R BM150R 2153 -tbone MACH_TBONE TBONE 2154 -merlin MACH_MERLIN MERLIN 2155 -falcon MACH_FALCON FALCON 2156 -davinci_da850_evm MACH_DAVINCI_DA850_EVM DAVINCI_DA850_EVM 2157 -s5p6440 MACH_S5P6440 S5P6440 2158 -at91sam9g10ek MACH_AT91SAM9G10EK AT91SAM9G10EK 2159 -omap_4430sdp MACH_OMAP_4430SDP OMAP_4430SDP 2160 -lpc313x MACH_LPC313X LPC313X 2161 -magx_zn5 MACH_MAGX_ZN5 MAGX_ZN5 2162 -magx_em30 MACH_MAGX_EM30 MAGX_EM30 2163 -magx_ve66 MACH_MAGX_VE66 MAGX_VE66 2164 -meesc MACH_MEESC MEESC 2165 -otc570 MACH_OTC570 OTC570 2166 -bcu2412 MACH_BCU2412 BCU2412 2167 -beacon MACH_BEACON BEACON 2168 -actia_tgw MACH_ACTIA_TGW ACTIA_TGW 2169 -e4430 MACH_E4430 E4430 2170 -ql300 MACH_QL300 QL300 2171 -btmavb101 MACH_BTMAVB101 BTMAVB101 2172 -btmawb101 MACH_BTMAWB101 BTMAWB101 2173 -sq201 MACH_SQ201 SQ201 2174 -quatro45xx MACH_QUATRO45XX QUATRO45XX 2175 -openpad MACH_OPENPAD OPENPAD 2176 -tx25 MACH_TX25 TX25 2177 -omap3_torpedo MACH_OMAP3_TORPEDO OMAP3_TORPEDO 2178 -htcraphael_k MACH_HTCRAPHAEL_K HTCRAPHAEL_K 2179 -lal43 MACH_LAL43 LAL43 2181 -htcraphael_cdma500 MACH_HTCRAPHAEL_CDMA500 HTCRAPHAEL_CDMA500 2182 -anw6410 MACH_ANW6410 ANW6410 2183 -htcprophet MACH_HTCPROPHET HTCPROPHET 2185 -cfa_10022 MACH_CFA_10022 CFA_10022 2186 -imx27_visstrim_m10 MACH_IMX27_VISSTRIM_M10 IMX27_VISSTRIM_M10 2187 -px2imx27 MACH_PX2IMX27 PX2IMX27 2188 -stm3210e_eval MACH_STM3210E_EVAL STM3210E_EVAL 2189 -dvs10 MACH_DVS10 DVS10 2190 -portuxg20 MACH_PORTUXG20 PORTUXG20 2191 -arm_spv MACH_ARM_SPV ARM_SPV 2192 -smdkc110 MACH_SMDKC110 SMDKC110 2193 -cabespresso MACH_CABESPRESSO CABESPRESSO 2194 -hmc800 MACH_HMC800 HMC800 2195 -sholes MACH_SHOLES SHOLES 2196 -btmxc31 MACH_BTMXC31 BTMXC31 2197 -dt501 MACH_DT501 DT501 2198 -ktx MACH_KTX KTX 2199 -omap3517evm MACH_OMAP3517EVM OMAP3517EVM 2200 -netspace_v2 MACH_NETSPACE_V2 NETSPACE_V2 2201 -netspace_max_v2 MACH_NETSPACE_MAX_V2 NETSPACE_MAX_V2 2202 -d2net_v2 MACH_D2NET_V2 D2NET_V2 2203 -net2big_v2 MACH_NET2BIG_V2 NET2BIG_V2 2204 -net4big_v2 MACH_NET4BIG_V2 NET4BIG_V2 2205 -net5big_v2 MACH_NET5BIG_V2 NET5BIG_V2 2206 -endb2443 MACH_ENDB2443 ENDB2443 2207 -inetspace_v2 MACH_INETSPACE_V2 INETSPACE_V2 2208 -tros MACH_TROS TROS 2209 -pelco_homer MACH_PELCO_HOMER PELCO_HOMER 2210 -ofsp8 MACH_OFSP8 OFSP8 2211 -at91sam9g45ekes MACH_AT91SAM9G45EKES AT91SAM9G45EKES 2212 -guf_cupid MACH_GUF_CUPID GUF_CUPID 2213 -eab1r MACH_EAB1R EAB1R 2214 -desirec MACH_DESIREC DESIREC 2215 -cordoba MACH_CORDOBA CORDOBA 2216 -irvine MACH_IRVINE IRVINE 2217 -sff772 MACH_SFF772 SFF772 2218 -pelco_milano MACH_PELCO_MILANO PELCO_MILANO 2219 -pc7302 MACH_PC7302 PC7302 2220 -bip6000 MACH_BIP6000 BIP6000 2221 -silvermoon MACH_SILVERMOON SILVERMOON 2222 -vc0830 MACH_VC0830 VC0830 2223 -dt430 MACH_DT430 DT430 2224 -ji42pf MACH_JI42PF JI42PF 2225 -gnet_ksm MACH_GNET_KSM GNET_KSM 2226 -gnet_sgm MACH_GNET_SGM GNET_SGM 2227 -gnet_sgr MACH_GNET_SGR GNET_SGR 2228 -omap3_icetekevm MACH_OMAP3_ICETEKEVM OMAP3_ICETEKEVM 2229 -pnp MACH_PNP PNP 2230 -ctera_2bay_k MACH_CTERA_2BAY_K CTERA_2BAY_K 2231 -ctera_2bay_u MACH_CTERA_2BAY_U CTERA_2BAY_U 2232 -sas_c MACH_SAS_C SAS_C 2233 -vma2315 MACH_VMA2315 VMA2315 2234 -vcs MACH_VCS VCS 2235 -spear600 MACH_SPEAR600 SPEAR600 2236 -spear300 MACH_SPEAR300 SPEAR300 2237 -spear1300 MACH_SPEAR1300 SPEAR1300 2238 -lilly1131 MACH_LILLY1131 LILLY1131 2239 -arvoo_ax301 MACH_ARVOO_AX301 ARVOO_AX301 2240 -mapphone MACH_MAPPHONE MAPPHONE 2241 -legend MACH_LEGEND LEGEND 2242 -salsa MACH_SALSA SALSA 2243 -lounge MACH_LOUNGE LOUNGE 2244 -vision MACH_VISION VISION 2245 -vmb20 MACH_VMB20 VMB20 2246 -hy2410 MACH_HY2410 HY2410 2247 -hy9315 MACH_HY9315 HY9315 2248 -bullwinkle MACH_BULLWINKLE BULLWINKLE 2249 -arm_ultimator2 MACH_ARM_ULTIMATOR2 ARM_ULTIMATOR2 2250 -vs_v210 MACH_VS_V210 VS_V210 2252 -vs_v212 MACH_VS_V212 VS_V212 2253 -hmt MACH_HMT HMT 2254 -suen3 MACH_SUEN3 SUEN3 2255 -vesper MACH_VESPER VESPER 2256 -str9 MACH_STR9 STR9 2257 -omap3_wl_ff MACH_OMAP3_WL_FF OMAP3_WL_FF 2258 -simcom MACH_SIMCOM SIMCOM 2259 -mcwebio MACH_MCWEBIO MCWEBIO 2260 diff --git a/trunk/arch/blackfin/include/asm/.gitignore b/trunk/arch/blackfin/include/asm/.gitignore new file mode 100644 index 000000000000..7858564a4466 --- /dev/null +++ b/trunk/arch/blackfin/include/asm/.gitignore @@ -0,0 +1 @@ ++mach diff --git a/trunk/arch/blackfin/include/asm/flat.h b/trunk/arch/blackfin/include/asm/flat.h index 733a178d782d..e70074e05f4e 100644 --- a/trunk/arch/blackfin/include/asm/flat.h +++ b/trunk/arch/blackfin/include/asm/flat.h @@ -10,6 +10,7 @@ #include +#define flat_stack_align(sp) /* nothing needed */ #define flat_argvp_envp_on_stack() 0 #define flat_old_ram_flag(flags) (flags) diff --git a/trunk/arch/blackfin/include/asm/unistd.h b/trunk/arch/blackfin/include/asm/unistd.h index cf5066d3efd2..1e57b636e0bc 100644 --- a/trunk/arch/blackfin/include/asm/unistd.h +++ b/trunk/arch/blackfin/include/asm/unistd.h @@ -378,10 +378,8 @@ #define __NR_dup3 363 #define __NR_pipe2 364 #define __NR_inotify_init1 365 -#define __NR_preadv 366 -#define __NR_pwritev 367 -#define __NR_syscall 368 +#define __NR_syscall 366 #define NR_syscalls __NR_syscall /* Old optional stuff no one actually uses */ diff --git a/trunk/arch/blackfin/kernel/.gitignore b/trunk/arch/blackfin/kernel/.gitignore deleted file mode 100644 index c5f676c3c224..000000000000 --- a/trunk/arch/blackfin/kernel/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vmlinux.lds diff --git a/trunk/arch/blackfin/lib/strncmp.c b/trunk/arch/blackfin/lib/strncmp.c index 46518b1d2983..2aaae78a68e0 100644 --- a/trunk/arch/blackfin/lib/strncmp.c +++ b/trunk/arch/blackfin/lib/strncmp.c @@ -8,9 +8,10 @@ #define strncmp __inline_strncmp #include -#include #undef strncmp +#include + int strncmp(const char *cs, const char *ct, size_t count) { return __inline_strncmp(cs, ct, count); diff --git a/trunk/arch/blackfin/mach-common/entry.S b/trunk/arch/blackfin/mach-common/entry.S index a063a434f7e3..21e65a339a22 100644 --- a/trunk/arch/blackfin/mach-common/entry.S +++ b/trunk/arch/blackfin/mach-common/entry.S @@ -1581,8 +1581,6 @@ ENTRY(_sys_call_table) .long _sys_dup3 .long _sys_pipe2 .long _sys_inotify_init1 /* 365 */ - .long _sys_preadv - .long _sys_pwritev .rept NR_syscalls-(.-_sys_call_table)/4 .long _sys_ni_syscall diff --git a/trunk/arch/h8300/include/asm/flat.h b/trunk/arch/h8300/include/asm/flat.h index bd12b31b90e6..2a873508a9a1 100644 --- a/trunk/arch/h8300/include/asm/flat.h +++ b/trunk/arch/h8300/include/asm/flat.h @@ -5,6 +5,7 @@ #ifndef __H8300_FLAT_H__ #define __H8300_FLAT_H__ +#define flat_stack_align(sp) /* nothing needed */ #define flat_argvp_envp_on_stack() 1 #define flat_old_ram_flag(flags) 1 #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) diff --git a/trunk/arch/m32r/include/asm/flat.h b/trunk/arch/m32r/include/asm/flat.h index 5d711c4688fb..d851cf0c4aa5 100644 --- a/trunk/arch/m32r/include/asm/flat.h +++ b/trunk/arch/m32r/include/asm/flat.h @@ -12,6 +12,7 @@ #ifndef __ASM_M32R_FLAT_H #define __ASM_M32R_FLAT_H +#define flat_stack_align(sp) (*sp += (*sp & 3 ? (4 - (*sp & 3)): 0)) #define flat_argvp_envp_on_stack() 0 #define flat_old_ram_flag(flags) (flags) #define flat_set_persistent(relval, p) 0 diff --git a/trunk/arch/m68k/include/asm/flat.h b/trunk/arch/m68k/include/asm/flat.h index a0e290793978..814b5174a8e0 100644 --- a/trunk/arch/m68k/include/asm/flat.h +++ b/trunk/arch/m68k/include/asm/flat.h @@ -5,6 +5,7 @@ #ifndef __M68KNOMMU_FLAT_H__ #define __M68KNOMMU_FLAT_H__ +#define flat_stack_align(sp) /* nothing needed */ #define flat_argvp_envp_on_stack() 1 #define flat_old_ram_flag(flags) (flags) #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 25f3b0a11ca8..09b1287a92ce 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -72,7 +72,6 @@ config MIPS_COBALT select IRQ_CPU select IRQ_GT641XX select PCI_GT64XXX_PCI0 - select PCI select SYS_HAS_CPU_NEVADA select SYS_HAS_EARLY_PRINTK select SYS_SUPPORTS_32BIT_KERNEL @@ -594,7 +593,7 @@ config WR_PPMC board, which is based on GT64120 bridge chip. config CAVIUM_OCTEON_SIMULATOR - bool "Cavium Networks Octeon Simulator" + bool "Support for the Cavium Networks Octeon Simulator" select CEVT_R4K select 64BIT_PHYS_ADDR select DMA_COHERENT @@ -608,7 +607,7 @@ config CAVIUM_OCTEON_SIMULATOR hardware. config CAVIUM_OCTEON_REFERENCE_BOARD - bool "Cavium Networks Octeon reference board" + bool "Support for the Cavium Networks Octeon reference board" select CEVT_R4K select 64BIT_PHYS_ADDR select DMA_COHERENT diff --git a/trunk/arch/mips/include/asm/cpu-info.h b/trunk/arch/mips/include/asm/cpu-info.h index 126044308dec..744cd8fb107f 100644 --- a/trunk/arch/mips/include/asm/cpu-info.h +++ b/trunk/arch/mips/include/asm/cpu-info.h @@ -39,8 +39,8 @@ struct cache_desc { #define MIPS_CACHE_PINDEX 0x00000020 /* Physically indexed cache */ struct cpuinfo_mips { - unsigned int udelay_val; - unsigned int asid_cache; + unsigned long udelay_val; + unsigned long asid_cache; /* * Capability and feature descriptor structure for MIPS CPU diff --git a/trunk/arch/mips/include/asm/delay.h b/trunk/arch/mips/include/asm/delay.h index a07e51b2be13..b0bccd2c4ed5 100644 --- a/trunk/arch/mips/include/asm/delay.h +++ b/trunk/arch/mips/include/asm/delay.h @@ -11,12 +11,94 @@ #ifndef _ASM_DELAY_H #define _ASM_DELAY_H -extern void __delay(unsigned int loops); -extern void __ndelay(unsigned int ns); -extern void __udelay(unsigned int us); +#include +#include -#define ndelay(ns) __udelay(ns) -#define udelay(us) __udelay(us) +#include +#include + +static inline void __delay(unsigned long loops) +{ + if (sizeof(long) == 4) + __asm__ __volatile__ ( + " .set noreorder \n" + " .align 3 \n" + "1: bnez %0, 1b \n" + " subu %0, 1 \n" + " .set reorder \n" + : "=r" (loops) + : "0" (loops)); + else if (sizeof(long) == 8 && !DADDI_WAR) + __asm__ __volatile__ ( + " .set noreorder \n" + " .align 3 \n" + "1: bnez %0, 1b \n" + " dsubu %0, 1 \n" + " .set reorder \n" + : "=r" (loops) + : "0" (loops)); + else if (sizeof(long) == 8 && DADDI_WAR) + __asm__ __volatile__ ( + " .set noreorder \n" + " .align 3 \n" + "1: bnez %0, 1b \n" + " dsubu %0, %2 \n" + " .set reorder \n" + : "=r" (loops) + : "0" (loops), "r" (1)); +} + + +/* + * Division by multiplication: you don't have to worry about + * loss of precision. + * + * Use only for very small delays ( < 1 msec). Should probably use a + * lookup table, really, as the multiplications take much too long with + * short delays. This is a "reasonable" implementation, though (and the + * first constant multiplications gets optimized away if the delay is + * a constant) + */ + +static inline void __udelay(unsigned long usecs, unsigned long lpj) +{ + unsigned long hi, lo; + + /* + * The rates of 128 is rounded wrongly by the catchall case + * for 64-bit. Excessive precission? Probably ... + */ +#if defined(CONFIG_64BIT) && (HZ == 128) + usecs *= 0x0008637bd05af6c7UL; /* 2**64 / (1000000 / HZ) */ +#elif defined(CONFIG_64BIT) + usecs *= (0x8000000000000000UL / (500000 / HZ)); +#else /* 32-bit junk follows here */ + usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + + 0x80000000ULL) >> 32); +#endif + + if (sizeof(long) == 4) + __asm__("multu\t%2, %3" + : "=h" (usecs), "=l" (lo) + : "r" (usecs), "r" (lpj) + : GCC_REG_ACCUM); + else if (sizeof(long) == 8 && !R4000_WAR) + __asm__("dmultu\t%2, %3" + : "=h" (usecs), "=l" (lo) + : "r" (usecs), "r" (lpj) + : GCC_REG_ACCUM); + else if (sizeof(long) == 8 && R4000_WAR) + __asm__("dmultu\t%3, %4\n\tmfhi\t%0" + : "=r" (usecs), "=h" (hi), "=l" (lo) + : "r" (usecs), "r" (lpj) + : GCC_REG_ACCUM); + + __delay(usecs); +} + +#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val + +#define udelay(usecs) __udelay((usecs), __udelay_val) /* make sure "usecs *= ..." in udelay do not overflow. */ #if HZ >= 1000 diff --git a/trunk/arch/mips/include/asm/ioctl.h b/trunk/arch/mips/include/asm/ioctl.h index 916163401b2c..85067e248a83 100644 --- a/trunk/arch/mips/include/asm/ioctl.h +++ b/trunk/arch/mips/include/asm/ioctl.h @@ -60,16 +60,12 @@ ((nr) << _IOC_NRSHIFT) | \ ((size) << _IOC_SIZESHIFT)) -#ifdef __KERNEL__ /* provoke compile error for invalid uses of size argument */ extern unsigned int __invalid_size_argument_for_IOC; #define _IOC_TYPECHECK(t) \ ((sizeof(t) == sizeof(t[1]) && \ sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ sizeof(t) : __invalid_size_argument_for_IOC) -#else -#define _IOC_TYPECHECK(t) (sizeof(t)) -#endif /* used to create numbers */ #define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0) diff --git a/trunk/arch/mips/kernel/proc.c b/trunk/arch/mips/kernel/proc.c index e0a4ac18fa07..26760cad8b69 100644 --- a/trunk/arch/mips/kernel/proc.c +++ b/trunk/arch/mips/kernel/proc.c @@ -42,7 +42,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, fmt, __cpu_name[n], (version >> 4) & 0x0f, version & 0x0f, (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); - seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", + seq_printf(m, "BogoMIPS\t\t: %lu.%02lu\n", cpu_data[n].udelay_val / (500000/HZ), (cpu_data[n].udelay_val / (5000/HZ)) % 100); seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); diff --git a/trunk/arch/mips/lib/Makefile b/trunk/arch/mips/lib/Makefile index 2adead5a8a37..c13c7ad2cdae 100644 --- a/trunk/arch/mips/lib/Makefile +++ b/trunk/arch/mips/lib/Makefile @@ -2,8 +2,8 @@ # Makefile for MIPS-specific library files.. # -lib-y += csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \ - strlen_user.o strncpy_user.o strnlen_user.o uncached.o +lib-y += csum_partial.o memcpy.o memcpy-inatomic.o memset.o strlen_user.o \ + strncpy_user.o strnlen_user.o uncached.o obj-y += iomap.o obj-$(CONFIG_PCI) += iomap-pci.o diff --git a/trunk/arch/mips/lib/delay.c b/trunk/arch/mips/lib/delay.c deleted file mode 100644 index f69c6b569eb3..000000000000 --- a/trunk/arch/mips/lib/delay.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1994 by Waldorf Electronics - * Copyright (C) 1995 - 2000, 01, 03 by Ralf Baechle - * Copyright (C) 1999, 2000 Silicon Graphics, Inc. - * Copyright (C) 2007 Maciej W. Rozycki - */ -#include -#include -#include - -#include -#include - -inline void __delay(unsigned int loops) -{ - __asm__ __volatile__ ( - " .set noreorder \n" - " .align 3 \n" - "1: bnez %0, 1b \n" - " subu %0, 1 \n" - " .set reorder \n" - : "=r" (loops) - : "0" (loops)); -} -EXPORT_SYMBOL(__delay); - -/* - * Division by multiplication: you don't have to worry about - * loss of precision. - * - * Use only for very small delays ( < 1 msec). Should probably use a - * lookup table, really, as the multiplications take much too long with - * short delays. This is a "reasonable" implementation, though (and the - * first constant multiplications gets optimized away if the delay is - * a constant) - */ - -void __udelay(unsigned long us) -{ - unsigned int lpj = current_cpu_data.udelay_val; - - __delay((us * 0x000010c7 * HZ * lpj) >> 32); -} -EXPORT_SYMBOL(__udelay); - -void __ndelay(unsigned long ns) -{ - unsigned int lpj = current_cpu_data.udelay_val; - - __delay((us * 0x00000005 * HZ * lpj) >> 32); -} -EXPORT_SYMBOL(__ndelay); diff --git a/trunk/arch/mips/sibyte/cfe/setup.c b/trunk/arch/mips/sibyte/cfe/setup.c index eb5396cf81bb..3de30f79db3f 100644 --- a/trunk/arch/mips/sibyte/cfe/setup.c +++ b/trunk/arch/mips/sibyte/cfe/setup.c @@ -288,7 +288,13 @@ void __init prom_init(void) */ cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE); if (cfe_getenv("LINUX_CMDLINE", arcs_cmdline, CL_SIZE) < 0) { - if (argc >= 0) { + if (argc < 0) { + /* + * It's OK for direct boot to not provide a + * command line + */ + strcpy(arcs_cmdline, "root=/dev/ram0 "); + } else { /* The loader should have set the command line */ /* too early for panic to do any good */ printk("LINUX_CMDLINE not defined in cfe."); diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index cdc9a6ff4be8..a0d1146a0578 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -868,18 +868,6 @@ config TASK_SIZE default "0x80000000" if PPC_PREP || PPC_8xx default "0xc0000000" -config CONSISTENT_SIZE_BOOL - bool "Set custom consistent memory pool size" - depends on ADVANCED_OPTIONS && NOT_COHERENT_CACHE - help - This option allows you to set the size of the - consistent memory pool. This pool of virtual memory - is used to make consistent memory allocations. - -config CONSISTENT_SIZE - hex "Size of consistent memory pool" if CONSISTENT_SIZE_BOOL - default "0x00200000" if NOT_COHERENT_CACHE - config PIN_TLB bool "Pinned Kernel TLBs (860 ONLY)" depends on ADVANCED_OPTIONS && 8xx diff --git a/trunk/arch/powerpc/configs/pmac32_defconfig b/trunk/arch/powerpc/configs/pmac32_defconfig index ea8870a34482..5339bb44cce9 100644 --- a/trunk/arch/powerpc/configs/pmac32_defconfig +++ b/trunk/arch/powerpc/configs/pmac32_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.30-rc7 -# Mon May 25 14:53:25 2009 +# Linux kernel version: 2.6.28-rc3 +# Tue Nov 11 19:36:51 2008 # # CONFIG_PPC64 is not set @@ -14,7 +14,6 @@ CONFIG_6xx=y # CONFIG_40x is not set # CONFIG_44x is not set # CONFIG_E200 is not set -CONFIG_PPC_BOOK3S=y CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y CONFIG_PPC_STD_MMU=y @@ -44,7 +43,7 @@ CONFIG_GENERIC_FIND_NEXT_BIT=y CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_GENERIC_NVRAM=y -CONFIG_SCHED_OMIT_FRAME_POINTER=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -53,14 +52,12 @@ CONFIG_OF=y CONFIG_AUDIT_ARCH=y CONFIG_GENERIC_BUG=y CONFIG_SYS_SUPPORTS_APM_EMULATION=y -CONFIG_DTC=y # CONFIG_DEFAULT_UIMAGE is not set CONFIG_HIBERNATE_32=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y # CONFIG_PPC_DCR_NATIVE is not set # CONFIG_PPC_DCR_MMIO is not set -CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" # @@ -75,24 +72,14 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y -CONFIG_POSIX_MQUEUE_SYSCTL=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set - -# -# RCU Subsystem -# -CONFIG_CLASSIC_RCU=y -# CONFIG_TREE_RCU is not set -# CONFIG_PREEMPT_RCU is not set -# CONFIG_TREE_RCU_TRACE is not set -# CONFIG_PREEMPT_RCU_TRACE is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_GROUP_SCHED is not set # 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 @@ -101,27 +88,23 @@ CONFIG_NAMESPACES=y # CONFIG_IPC_NS is not set # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set -# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_RD_GZIP=y -CONFIG_RD_BZIP2=y -CONFIG_RD_LZMA=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y -CONFIG_ANON_INODES=y # CONFIG_EMBEDDED is not set CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_KALLSYMS_EXTRA_PASS is not set -# CONFIG_STRIP_ASM_SYMS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y +# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y +CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y @@ -131,12 +114,10 @@ CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y CONFIG_PCI_QUIRKS=y CONFIG_SLUB_DEBUG=y -# CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_PROFILING=y -CONFIG_TRACEPOINTS=y # CONFIG_MARKERS is not set CONFIG_OPROFILE=y CONFIG_HAVE_OPROFILE=y @@ -146,10 +127,10 @@ CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y -# CONFIG_SLOW_WORK is not set # 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 @@ -157,8 +138,11 @@ CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_KMOD=y CONFIG_BLOCK=y CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y CONFIG_BLK_DEV_BSG=y # CONFIG_BLK_DEV_INTEGRITY is not set @@ -174,11 +158,14 @@ 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_CLASSIC32=y # CONFIG_PPC_CHRP is not set # CONFIG_MPC5121_ADS is not set # CONFIG_MPC5121_GENERIC is not set @@ -191,9 +178,7 @@ CONFIG_PPC_PMAC=y # CONFIG_PPC_83xx is not set # CONFIG_PPC_86xx is not set # CONFIG_EMBEDDED6xx is not set -# CONFIG_AMIGAONE is not set CONFIG_PPC_NATIVE=y -CONFIG_PPC_OF_BOOT_TRAMPOLINE=y # CONFIG_IPIC is not set CONFIG_MPIC=y # CONFIG_MPIC_WEIRD is not set @@ -227,12 +212,11 @@ CONFIG_CPU_FREQ_PMAC=y CONFIG_PPC601_SYNC_FIX=y # CONFIG_TAU is not set # CONFIG_FSL_ULI1575 is not set -# CONFIG_SIMPLE_GPIO is not set # # Kernel options # -CONFIG_HIGHMEM=y +# CONFIG_HIGHMEM is not set CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y @@ -255,7 +239,6 @@ CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_HAS_WALK_MEMORY=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y # CONFIG_KEXEC is not set -# CONFIG_CRASH_DUMP is not set CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_ARCH_POPULATES_NODE_MAP=y CONFIG_SELECT_MEMORY_MODEL=y @@ -267,17 +250,12 @@ CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 # CONFIG_MIGRATION is not set +# 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_HAVE_MLOCK=y -CONFIG_HAVE_MLOCKED_PAGE_BIT=y -CONFIG_PPC_4K_PAGES=y -# CONFIG_PPC_16K_PAGES is not set -# CONFIG_PPC_64K_PAGES is not set -# CONFIG_PPC_256K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=11 CONFIG_PROC_DEVICETREE=y # CONFIG_CMDLINE_BOOL is not set @@ -310,8 +288,6 @@ CONFIG_ARCH_SUPPORTS_MSI=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_LEGACY is not set # CONFIG_PCI_DEBUG is not set -# CONFIG_PCI_STUB is not set -# CONFIG_PCI_IOV is not set CONFIG_PCCARD=m # CONFIG_PCMCIA_DEBUG is not set CONFIG_PCMCIA=m @@ -421,8 +397,6 @@ CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set # CONFIG_NETFILTER_XT_TARGET_DSCP is not set -CONFIG_NETFILTER_XT_TARGET_HL=m -# CONFIG_NETFILTER_XT_TARGET_LED is not set CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m @@ -431,7 +405,6 @@ CONFIG_NETFILTER_XT_TARGET_RATEEST=m CONFIG_NETFILTER_XT_TARGET_TRACE=m CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m -# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set CONFIG_NETFILTER_XT_MATCH_COMMENT=m # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m @@ -442,7 +415,6 @@ CONFIG_NETFILTER_XT_MATCH_DSCP=m CONFIG_NETFILTER_XT_MATCH_ESP=m # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set CONFIG_NETFILTER_XT_MATCH_HELPER=m -CONFIG_NETFILTER_XT_MATCH_HL=m CONFIG_NETFILTER_XT_MATCH_IPRANGE=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m @@ -506,15 +478,17 @@ CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # +CONFIG_IP_DCCP_CCID2=m # CONFIG_IP_DCCP_CCID2_DEBUG is not set -CONFIG_IP_DCCP_CCID3=y +CONFIG_IP_DCCP_CCID3=m # CONFIG_IP_DCCP_CCID3_DEBUG is not set CONFIG_IP_DCCP_CCID3_RTO=100 -CONFIG_IP_DCCP_TFRC_LIB=y +CONFIG_IP_DCCP_TFRC_LIB=m # # DCCP Kernel Hacking @@ -534,16 +508,13 @@ CONFIG_IP_DCCP_TFRC_LIB=y # CONFIG_LAPB is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set -# CONFIG_PHONET is not set # CONFIG_NET_SCHED is not set CONFIG_NET_CLS_ROUTE=y -# CONFIG_DCB is not set # # Network testing # # CONFIG_NET_PKTGEN is not set -# CONFIG_NET_DROP_MONITOR is not set # CONFIG_HAMRADIO is not set # CONFIG_CAN is not set CONFIG_IRDA=m @@ -606,6 +577,8 @@ CONFIG_BT_HIDP=m # # Bluetooth device drivers # +CONFIG_BT_HCIUSB=m +# CONFIG_BT_HCIUSB_SCO is not set # CONFIG_BT_HCIBTUSB is not set # CONFIG_BT_HCIUART is not set CONFIG_BT_HCIBCM203X=m @@ -617,27 +590,31 @@ CONFIG_BT_HCIBFUSB=m # CONFIG_BT_HCIBTUART is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_AF_RXRPC is not set +# CONFIG_PHONET is not set CONFIG_WIRELESS=y CONFIG_CFG80211=m -# CONFIG_CFG80211_REG_DEBUG is not set +CONFIG_NL80211=y CONFIG_WIRELESS_OLD_REGULATORY=y CONFIG_WIRELESS_EXT=y CONFIG_WIRELESS_EXT_SYSFS=y -# CONFIG_LIB80211 is not set CONFIG_MAC80211=m # # Rate control algorithm selection # -CONFIG_MAC80211_RC_MINSTREL=y -# CONFIG_MAC80211_RC_DEFAULT_PID is not set -CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y -CONFIG_MAC80211_RC_DEFAULT="minstrel" +CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT="pid" # CONFIG_MAC80211_MESH is not set CONFIG_MAC80211_LEDS=y -# CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -# CONFIG_WIMAX is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -685,27 +662,17 @@ CONFIG_BLK_DEV_RAM_SIZE=4096 # 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_ISL29003 is not set -# CONFIG_C2PORT is not set - -# -# EEPROM support -# -# CONFIG_EEPROM_AT24 is not set -# CONFIG_EEPROM_LEGACY is not set -# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y CONFIG_IDE=y # # Please see Documentation/ide/ide.txt for help/info on IDE drives # -CONFIG_IDE_XFER_MODE=y CONFIG_IDE_TIMINGS=y CONFIG_IDE_ATAPI=y # CONFIG_BLK_DEV_IDE_SATA is not set @@ -717,6 +684,7 @@ CONFIG_BLK_DEV_IDECS=m CONFIG_BLK_DEV_IDECD=y CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y # CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDESCSI=y # CONFIG_IDE_TASK_IOCTL is not set CONFIG_IDE_PROC_FS=y @@ -746,7 +714,6 @@ CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_IT8172 is not set # CONFIG_BLK_DEV_IT8213 is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set @@ -761,6 +728,7 @@ CONFIG_BLK_DEV_SL82C105=y # CONFIG_BLK_DEV_TC86C001 is not set CONFIG_BLK_DEV_IDE_PMAC=y CONFIG_BLK_DEV_IDE_PMAC_ATA100FIRST=y +CONFIG_BLK_DEV_IDEDMA_PMAC=y CONFIG_BLK_DEV_IDEDMA=y # @@ -804,7 +772,6 @@ CONFIG_SCSI_FC_ATTRS=y # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set -# CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_ACARD is not set @@ -824,12 +791,8 @@ CONFIG_SCSI_AIC7XXX_OLD=m # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_LIBFC is not set -# CONFIG_LIBFCOE is not set -# CONFIG_FCOE is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set @@ -859,7 +822,6 @@ CONFIG_SCSI_MAC53C94=y # CONFIG_SCSI_SRP is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set # CONFIG_SCSI_DH is not set -# CONFIG_SCSI_OSD_INITIATOR is not set # CONFIG_ATA is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=m @@ -919,7 +881,6 @@ CONFIG_THERM_ADT746X=m # CONFIG_ANSLCD is not set CONFIG_PMAC_RACKMETER=m CONFIG_NETDEVICES=y -CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_DUMMY=m # CONFIG_BONDING is not set # CONFIG_MACVLAN is not set @@ -937,8 +898,6 @@ CONFIG_BMAC=y CONFIG_SUNGEM=y # CONFIG_CASSINI is not set # CONFIG_NET_VENDOR_3COM is not set -# CONFIG_ETHOC is not set -# CONFIG_DNET is not set # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set # CONFIG_IBM_NEW_EMAC_ZMII is not set @@ -954,6 +913,7 @@ CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set # CONFIG_B44 is not set # CONFIG_FORCEDETH is not set +# CONFIG_EEPRO100 is not set # CONFIG_E100 is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set @@ -963,7 +923,6 @@ CONFIG_PCNET32=y # CONFIG_R6040 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set -# CONFIG_SMSC9420 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set @@ -976,7 +935,6 @@ CONFIG_NETDEV_1000=y # CONFIG_E1000E is not set # CONFIG_IP1000 is not set # CONFIG_IGB is not set -# CONFIG_IGBVF is not set # CONFIG_NS83820 is not set # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set @@ -987,20 +945,18 @@ CONFIG_NETDEV_1000=y # CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 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_ATL1C is not set # CONFIG_JME is not set CONFIG_NETDEV_10000=y # CONFIG_CHELSIO_T1 is not set -CONFIG_CHELSIO_T3_DEPENDS=y # 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_VXGE is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NIU is not set @@ -1010,7 +966,6 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_BNX2X is not set # CONFIG_QLGE is not set # CONFIG_SFC is not set -# CONFIG_BE2NET is not set # CONFIG_TR is not set # @@ -1019,11 +974,20 @@ CONFIG_CHELSIO_T3_DEPENDS=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_PCMCIA_RAYCS is not set +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set # CONFIG_LIBERTAS is not set # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_AIRO is not set +CONFIG_HERMES=m +CONFIG_APPLE_AIRPORT=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_NORTEL_HERMES is not set +CONFIG_PCI_HERMES=m +CONFIG_PCMCIA_HERMES=m +# CONFIG_PCMCIA_SPECTRUM is not set # CONFIG_ATMEL is not set -# CONFIG_AT76C50X_USB is not set # CONFIG_AIRO_CS is not set # CONFIG_PCMCIA_WL3501 is not set CONFIG_PRISM54=m @@ -1033,17 +997,15 @@ CONFIG_PRISM54=m # CONFIG_RTL8187 is not set # CONFIG_ADM8211 is not set # CONFIG_MAC80211_HWSIM is not set -# CONFIG_MWL8K is not set CONFIG_P54_COMMON=m # CONFIG_P54_USB is not set # CONFIG_P54_PCI is not set -CONFIG_P54_LEDS=y # CONFIG_ATH5K is not set # CONFIG_ATH9K is not set -# CONFIG_AR9170_USB is not set -# CONFIG_IPW2100 is not set -# CONFIG_IPW2200 is not set -# CONFIG_IWLWIFI is not set +# CONFIG_IWLCORE is not set +# CONFIG_IWLWIFI_LEDS is not set +# CONFIG_IWLAGN is not set +# CONFIG_IWL3945 is not set # CONFIG_HOSTAP is not set CONFIG_B43=m CONFIG_B43_PCI_AUTOSELECT=y @@ -1063,19 +1025,6 @@ CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y # CONFIG_B43LEGACY_PIO_MODE is not set # CONFIG_ZD1211RW is not set # CONFIG_RT2X00 is not set -CONFIG_HERMES=m -CONFIG_HERMES_CACHE_FW_ON_INIT=y -CONFIG_APPLE_AIRPORT=m -# CONFIG_PLX_HERMES is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_NORTEL_HERMES is not set -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -# CONFIG_PCMCIA_SPECTRUM is not set - -# -# Enable WiMAX (Networking options) to see the WiMAX drivers -# # # USB Network Adapters @@ -1087,7 +1036,6 @@ CONFIG_PCMCIA_HERMES=m CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m CONFIG_USB_NET_CDCETHER=m -# CONFIG_USB_NET_CDC_EEM is not set # CONFIG_USB_NET_DM9601 is not set # CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set @@ -1151,7 +1099,7 @@ CONFIG_INPUT_KEYBOARD=y CONFIG_INPUT_MOUSE=y # CONFIG_MOUSE_PS2 is not set # CONFIG_MOUSE_SERIAL is not set -CONFIG_MOUSE_APPLETOUCH=y +# CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_BCM5974 is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_INPUT_JOYSTICK is not set @@ -1202,13 +1150,10 @@ CONFIG_SERIAL_PMACZILOG_TTYS=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_OF_PLATFORM is not set CONFIG_UNIX98_PTYS=y -# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 -# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=m -# CONFIG_HW_RANDOM_TIMERIOMEM is not set CONFIG_NVRAM=y CONFIG_GEN_RTC=y # CONFIG_GEN_RTC_X is not set @@ -1287,9 +1232,12 @@ CONFIG_I2C_POWERMAC=y # Miscellaneous I2C Chip support # # CONFIG_DS1682 is not set +# CONFIG_EEPROM_AT24 is not set +# CONFIG_EEPROM_LEGACY 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 is not set @@ -1311,11 +1259,11 @@ CONFIG_BATTERY_PMU=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=m CONFIG_SSB_SPROM=y CONFIG_SSB_PCIHOST_POSSIBLE=y @@ -1333,13 +1281,18 @@ CONFIG_SSB_DRIVER_PCICORE=y # CONFIG_MFD_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set -# CONFIG_TWL4030_CORE 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_MFD_PCF50633 is not set + +# +# Voltage and Current regulators +# # CONFIG_REGULATOR is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set +# CONFIG_REGULATOR_BQ24022 is not set # # Multimedia devices @@ -1437,7 +1390,6 @@ CONFIG_FB_ATY_BACKLIGHT=y # CONFIG_FB_KYRO is not set CONFIG_FB_3DFX=y # CONFIG_FB_3DFX_ACCEL is not set -CONFIG_FB_3DFX_I2C=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set @@ -1447,14 +1399,12 @@ CONFIG_FB_3DFX_I2C=y # 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_FB_BROADSHEET 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_GENERIC=y +# CONFIG_BACKLIGHT_CORGI is not set # # Display device support @@ -1494,13 +1444,11 @@ CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y -# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set -CONFIG_SND_VMASTER=y CONFIG_SND_DRIVERS=y CONFIG_SND_DUMMY=m # CONFIG_SND_VIRMIDI is not set @@ -1538,8 +1486,6 @@ CONFIG_SND_PCI=y # CONFIG_SND_INDIGO is not set # CONFIG_SND_INDIGOIO is not set # CONFIG_SND_INDIGODJ is not set -# CONFIG_SND_INDIGOIOX is not set -# CONFIG_SND_INDIGODJX is not set # CONFIG_SND_EMU10K1 is not set # CONFIG_SND_EMU10K1X is not set # CONFIG_SND_ENS1370 is not set @@ -1605,31 +1551,28 @@ CONFIG_USB_HID=y # # Special HID drivers # +CONFIG_HID_COMPAT=y CONFIG_HID_A4TECH=y CONFIG_HID_APPLE=y CONFIG_HID_BELKIN=y +CONFIG_HID_BRIGHT=y CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y CONFIG_HID_CYPRESS=y -# CONFIG_DRAGONRISE_FF is not set +CONFIG_HID_DELL=y CONFIG_HID_EZKEY=y -CONFIG_HID_KYE=y CONFIG_HID_GYRATION=y -CONFIG_HID_KENSINGTON=y CONFIG_HID_LOGITECH=y # CONFIG_LOGITECH_FF is not set # CONFIG_LOGIRUMBLEPAD2_FF is not set CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y -CONFIG_HID_NTRIG=y CONFIG_HID_PANTHERLORD=y # CONFIG_PANTHERLORD_FF is not set CONFIG_HID_PETALYNX=y CONFIG_HID_SAMSUNG=y CONFIG_HID_SONY=y CONFIG_HID_SUNPLUS=y -# CONFIG_GREENASIA_FF is not set -CONFIG_HID_TOPSEED=y # CONFIG_THRUSTMASTER_FF is not set # CONFIG_ZEROPLUS_FF is not set CONFIG_USB_SUPPORT=y @@ -1660,7 +1603,6 @@ CONFIG_USB_EHCI_HCD=m CONFIG_USB_EHCI_ROOT_HUB_TT=y # CONFIG_USB_EHCI_TT_NEWSCHED is not set # CONFIG_USB_EHCI_HCD_PPC_OF is not set -# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=y @@ -1683,23 +1625,24 @@ CONFIG_USB_PRINTER=m # CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' # # -# also be needed; see USB_STORAGE Help for more info +# may also be needed; see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # 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=m +CONFIG_USB_STORAGE_ONETOUCH=y # CONFIG_USB_STORAGE_KARMA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set @@ -1722,7 +1665,7 @@ CONFIG_USB_EZUSB=y # CONFIG_USB_SERIAL_CH341 is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP210X is not set +# CONFIG_USB_SERIAL_CP2101 is not set # CONFIG_USB_SERIAL_CYPRESS_M8 is not set # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set @@ -1758,19 +1701,15 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_SERIAL_NAVMAN is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_OTI6858 is not set -# CONFIG_USB_SERIAL_QUALCOMM is not set # CONFIG_USB_SERIAL_SPCP8X5 is not set # CONFIG_USB_SERIAL_HP4X is not set # CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_SIEMENS_MPI is not set # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set -# CONFIG_USB_SERIAL_SYMBOL is not set # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set -# CONFIG_USB_SERIAL_OPTICON is not set # CONFIG_USB_SERIAL_DEBUG is not set # @@ -1787,6 +1726,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGET is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set CONFIG_USB_APPLEDISPLAY=m @@ -1798,11 +1738,6 @@ CONFIG_USB_APPLEDISPLAY=m # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set - -# -# OTG and related infrastructure -# -# CONFIG_NOP_USB_XCEIV is not set # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set @@ -1813,9 +1748,7 @@ CONFIG_LEDS_CLASS=y # LED drivers # # CONFIG_LEDS_PCA9532 is not set -# CONFIG_LEDS_LP5521 is not set # CONFIG_LEDS_PCA955X is not set -# CONFIG_LEDS_BD2802 is not set # # LED Triggers @@ -1826,16 +1759,11 @@ CONFIG_LEDS_TRIGGER_IDE_DISK=y # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=y - -# -# iptables trigger is under Netfilter config (LED target) -# # 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_AUXDISPLAY is not set # CONFIG_UIO is not set # CONFIG_STAGING is not set @@ -1846,7 +1774,6 @@ CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y -# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y # CONFIG_EXT3_FS_SECURITY is not set @@ -1856,9 +1783,7 @@ CONFIG_EXT4_FS_XATTR=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set CONFIG_JBD2=y -# CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set @@ -1867,7 +1792,6 @@ CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set -# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y @@ -1876,11 +1800,6 @@ CONFIG_INOTIFY_USER=y CONFIG_AUTOFS4_FS=m CONFIG_FUSE_FS=m -# -# Caches -# -# CONFIG_FSCACHE is not set - # # CD-ROM/DVD Filesystems # @@ -1912,7 +1831,10 @@ CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set # CONFIG_HUGETLB_PAGE is not set # CONFIG_CONFIGFS_FS is not set -CONFIG_MISC_FILESYSTEMS=y + +# +# Miscellaneous filesystems +# # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set CONFIG_HFS_FS=m @@ -1921,7 +1843,6 @@ CONFIG_HFSPLUS_FS=m # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_CRAMFS is not set -# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1930,7 +1851,6 @@ CONFIG_HFSPLUS_FS=m # CONFIG_ROMFS_FS is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set -# CONFIG_NILFS2_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y CONFIG_NFS_V3=y @@ -1948,6 +1868,7 @@ CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m @@ -2019,13 +1940,11 @@ CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_KOI8_U is not set CONFIG_NLS_UTF8=m # CONFIG_DLM is not set -CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y -CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y @@ -2035,18 +1954,15 @@ CONFIG_CRC32=y CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y -CONFIG_DECOMPRESS_GZIP=y -CONFIG_DECOMPRESS_BZIP2=y -CONFIG_DECOMPRESS_LZMA=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m +CONFIG_PLIST=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT=y CONFIG_HAS_DMA=y CONFIG_HAVE_LMB=y -CONFIG_NLATTR=y # # Kernel hacking @@ -2057,16 +1973,13 @@ CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=1024 CONFIG_MAGIC_SYSRQ=y # CONFIG_UNUSED_SYMBOLS is not set -CONFIG_DEBUG_FS=y +# 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_DETECT_HUNG_TASK=y -# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set -CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 CONFIG_SCHED_DEBUG=y CONFIG_SCHEDSTATS=y # CONFIG_TIMER_STATS is not set @@ -2081,7 +1994,6 @@ CONFIG_SCHEDSTATS=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set -# CONFIG_DEBUG_HIGHMEM is not set CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_VM is not set @@ -2089,7 +2001,6 @@ CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_LIST is not set # CONFIG_DEBUG_SG is not set -# CONFIG_DEBUG_NOTIFIERS 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 @@ -2098,14 +2009,7 @@ CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_FAULT_INJECTION is not set CONFIG_LATENCYTOP=y CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y -CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y -CONFIG_HAVE_DYNAMIC_FTRACE=y -CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_RING_BUFFER=y -CONFIG_TRACING=y -CONFIG_TRACING_SUPPORT=y # # Tracers @@ -2113,19 +2017,12 @@ CONFIG_TRACING_SUPPORT=y # CONFIG_FUNCTION_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set -# CONFIG_EVENT_TRACER is not set # CONFIG_BOOT_TRACER is not set -# CONFIG_TRACE_BRANCH_PROFILING is not set # CONFIG_STACK_TRACER is not set -# CONFIG_KMEMTRACE is not set -# CONFIG_WORKQUEUE_TRACER is not set -# CONFIG_BLK_DEV_IO_TRACE is not set -# CONFIG_FTRACE_STARTUP_TEST is not set -# CONFIG_DYNAMIC_DEBUG 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_PRINT_STACK_DEPTH=64 # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_CODE_PATCHING_SELFTEST is not set @@ -2136,7 +2033,6 @@ CONFIG_XMON_DEFAULT=y CONFIG_XMON_DISASSEMBLY=y CONFIG_DEBUGGER=y CONFIG_IRQSTACKS=y -# CONFIG_VIRQ_DEBUG is not set # CONFIG_BDI_SWITCH is not set CONFIG_BOOTX_TEXT=y # CONFIG_PPC_EARLY_DEBUG is not set @@ -2155,20 +2051,13 @@ CONFIG_CRYPTO=y # # CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y -CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y -CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y -CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y -CONFIG_CRYPTO_HASH2=y -CONFIG_CRYPTO_RNG2=y -CONFIG_CRYPTO_PCOMP=y +CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_MANAGER=y -CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_NULL=m -CONFIG_CRYPTO_WORKQUEUE=y # CONFIG_CRYPTO_CRYPTD is not set CONFIG_CRYPTO_AUTHENC=y # CONFIG_CRYPTO_TEST is not set @@ -2238,7 +2127,6 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m # Compression # CONFIG_CRYPTO_DEFLATE=m -# CONFIG_CRYPTO_ZLIB is not set # CONFIG_CRYPTO_LZO is not set # diff --git a/trunk/arch/powerpc/include/asm/dma-mapping.h b/trunk/arch/powerpc/include/asm/dma-mapping.h index cb448d68452c..c69f2b5f0cc4 100644 --- a/trunk/arch/powerpc/include/asm/dma-mapping.h +++ b/trunk/arch/powerpc/include/asm/dma-mapping.h @@ -26,9 +26,7 @@ * allocate the space "normally" and use the cache management functions * to ensure it is consistent. */ -struct device; -extern void *__dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *handle, gfp_t gfp); +extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp); extern void __dma_free_coherent(size_t size, void *vaddr); extern void __dma_sync(void *vaddr, size_t size, int direction); extern void __dma_sync_page(struct page *page, unsigned long offset, @@ -39,7 +37,7 @@ extern void __dma_sync_page(struct page *page, unsigned long offset, * Cache coherent cores. */ -#define __dma_alloc_coherent(dev, gfp, size, handle) NULL +#define __dma_alloc_coherent(gfp, size, handle) NULL #define __dma_free_coherent(size, addr) ((void)0) #define __dma_sync(addr, size, rw) ((void)0) #define __dma_sync_page(pg, off, sz, rw) ((void)0) diff --git a/trunk/arch/powerpc/include/asm/fixmap.h b/trunk/arch/powerpc/include/asm/fixmap.h index f1f4e23a84e9..d60fd18f428c 100644 --- a/trunk/arch/powerpc/include/asm/fixmap.h +++ b/trunk/arch/powerpc/include/asm/fixmap.h @@ -14,6 +14,8 @@ #ifndef _ASM_FIXMAP_H #define _ASM_FIXMAP_H +extern unsigned long FIXADDR_TOP; + #ifndef __ASSEMBLY__ #include #include @@ -22,8 +24,6 @@ #include #endif -#define FIXADDR_TOP ((unsigned long)(-PAGE_SIZE)) - /* * Here we define all the compile-time 'special' virtual * addresses. The point is to have a constant address at diff --git a/trunk/arch/powerpc/include/asm/mpc52xx_psc.h b/trunk/arch/powerpc/include/asm/mpc52xx_psc.h index fb8412057450..a218da6bec7c 100644 --- a/trunk/arch/powerpc/include/asm/mpc52xx_psc.h +++ b/trunk/arch/powerpc/include/asm/mpc52xx_psc.h @@ -28,10 +28,6 @@ #define MPC52xx_PSC_MAXNUM 6 /* Programmable Serial Controller (PSC) status register bits */ -#define MPC52xx_PSC_SR_UNEX_RX 0x0001 -#define MPC52xx_PSC_SR_DATA_VAL 0x0002 -#define MPC52xx_PSC_SR_DATA_OVR 0x0004 -#define MPC52xx_PSC_SR_CMDSEND 0x0008 #define MPC52xx_PSC_SR_CDE 0x0080 #define MPC52xx_PSC_SR_RXRDY 0x0100 #define MPC52xx_PSC_SR_RXFULL 0x0200 @@ -65,12 +61,6 @@ #define MPC52xx_PSC_RXTX_FIFO_EMPTY 0x0001 /* PSC interrupt status/mask bits */ -#define MPC52xx_PSC_IMR_UNEX_RX_SLOT 0x0001 -#define MPC52xx_PSC_IMR_DATA_VALID 0x0002 -#define MPC52xx_PSC_IMR_DATA_OVR 0x0004 -#define MPC52xx_PSC_IMR_CMD_SEND 0x0008 -#define MPC52xx_PSC_IMR_ERROR 0x0040 -#define MPC52xx_PSC_IMR_DEOF 0x0080 #define MPC52xx_PSC_IMR_TXRDY 0x0100 #define MPC52xx_PSC_IMR_RXRDY 0x0200 #define MPC52xx_PSC_IMR_DB 0x0400 @@ -127,7 +117,6 @@ #define MPC52xx_PSC_SICR_SIM_FIR (0x6 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_24 (0x7 << 24) #define MPC52xx_PSC_SICR_SIM_CODEC_32 (0xf << 24) -#define MPC52xx_PSC_SICR_AWR (1 << 30) #define MPC52xx_PSC_SICR_GENCLK (1 << 23) #define MPC52xx_PSC_SICR_I2S (1 << 22) #define MPC52xx_PSC_SICR_CLKPOL (1 << 21) diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h index c9ff9d75990e..ba45c997830f 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc32.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc32.h @@ -10,7 +10,7 @@ extern unsigned long va_to_phys(unsigned long address); extern pte_t *va_to_pte(unsigned long address); -extern unsigned long ioremap_bot; +extern unsigned long ioremap_bot, ioremap_base; #ifdef CONFIG_44x extern int icache_44x_need_flush; @@ -55,31 +55,9 @@ extern int icache_44x_need_flush; #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -/* - * This is the bottom of the PKMAP area with HIGHMEM or an arbitrary - * value (for now) on others, from where we can start layout kernel - * virtual space that goes below PKMAP and FIXMAP - */ -#ifdef CONFIG_HIGHMEM -#define KVIRT_TOP PKMAP_BASE -#else -#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */ -#endif - -/* - * ioremap_bot starts at that address. Early ioremaps move down from there, - * until mem_init() at which point this becomes the top of the vmalloc - * and ioremap space - */ -#ifdef CONFIG_NOT_COHERENT_CACHE -#define IOREMAP_TOP ((KVIRT_TOP - CONFIG_CONSISTENT_SIZE) & PAGE_MASK) -#else -#define IOREMAP_TOP KVIRT_TOP -#endif - /* * Just any arbitrary offset to the start of the vmalloc VM area: the - * current 16MB value just means that there will be a 64MB "hole" after the + * current 64MB value just means that there will be a 64MB "hole" after the * physical memory until the kernel virtual memory starts. That means that * any out-of-bounds memory accesses will hopefully be caught. * The vmalloc() routines leaves a hole of 4kB between each vmalloced diff --git a/trunk/arch/powerpc/kernel/dma.c b/trunk/arch/powerpc/kernel/dma.c index 6b02793dc75b..53c7788cba78 100644 --- a/trunk/arch/powerpc/kernel/dma.c +++ b/trunk/arch/powerpc/kernel/dma.c @@ -32,7 +32,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, { void *ret; #ifdef CONFIG_NOT_COHERENT_CACHE - ret = __dma_alloc_coherent(dev, size, dma_handle, flag); + ret = __dma_alloc_coherent(size, dma_handle, flag); if (ret == NULL) return NULL; *dma_handle += get_dma_direct_offset(dev); diff --git a/trunk/arch/powerpc/lib/Makefile b/trunk/arch/powerpc/lib/Makefile index 29b742b90f1f..8db35278a4b4 100644 --- a/trunk/arch/powerpc/lib/Makefile +++ b/trunk/arch/powerpc/lib/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ memcpy_64.o usercopy_64.o mem_64.o string.o obj-$(CONFIG_XMON) += sstep.o obj-$(CONFIG_KPROBES) += sstep.o +obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o ifeq ($(CONFIG_PPC64),y) obj-$(CONFIG_SMP) += locks.o diff --git a/trunk/arch/powerpc/lib/dma-noncoherent.c b/trunk/arch/powerpc/lib/dma-noncoherent.c new file mode 100644 index 000000000000..005a28d380af --- /dev/null +++ b/trunk/arch/powerpc/lib/dma-noncoherent.c @@ -0,0 +1,237 @@ +/* + * PowerPC version derived from arch/arm/mm/consistent.c + * Copyright (C) 2001 Dan Malek (dmalek@jlc.net) + * + * Copyright (C) 2000 Russell King + * + * Consistent memory allocators. Used for DMA devices that want to + * share uncached memory with the processor core. The function return + * is the virtual address and 'dma_handle' is the physical address. + * Mostly stolen from the ARM port, with some changes for PowerPC. + * -- Dan + * + * Reorganized to get rid of the arch-specific consistent_* functions + * and provide non-coherent implementations for the DMA API. -Matt + * + * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent() + * implementation. This is pulled straight from ARM and barely + * modified. -Matt + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include + +/* + * Allocate DMA-coherent memory space and return both the kernel remapped + * virtual and bus address for that space. + */ +void * +__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp) +{ + struct page *page; + unsigned long order; + int i; + unsigned int nr_pages = PAGE_ALIGN(size)>>PAGE_SHIFT; + unsigned int array_size = nr_pages * sizeof(struct page *); + struct page **pages; + struct page *end; + u64 mask = 0x00ffffff, limit; /* ISA default */ + struct vm_struct *area; + + BUG_ON(!mem_init_done); + size = PAGE_ALIGN(size); + limit = (mask + 1) & ~mask; + if (limit && size >= limit) { + printk(KERN_WARNING "coherent allocation too big (requested " + "%#x mask %#Lx)\n", size, mask); + return NULL; + } + + order = get_order(size); + + if (mask != 0xffffffff) + gfp |= GFP_DMA; + + page = alloc_pages(gfp, order); + if (!page) + goto no_page; + + end = page + (1 << order); + + /* + * Invalidate any data that might be lurking in the + * kernel direct-mapped region for device DMA. + */ + { + unsigned long kaddr = (unsigned long)page_address(page); + memset(page_address(page), 0, size); + flush_dcache_range(kaddr, kaddr + size); + } + + split_page(page, order); + + /* + * Set the "dma handle" + */ + *handle = page_to_phys(page); + + area = get_vm_area_caller(size, VM_IOREMAP, + __builtin_return_address(1)); + if (!area) + goto out_free_pages; + + if (array_size > PAGE_SIZE) { + pages = vmalloc(array_size); + area->flags |= VM_VPAGES; + } else { + pages = kmalloc(array_size, GFP_KERNEL); + } + if (!pages) + goto out_free_area; + + area->pages = pages; + area->nr_pages = nr_pages; + + for (i = 0; i < nr_pages; i++) + pages[i] = page + i; + + if (map_vm_area(area, pgprot_noncached(PAGE_KERNEL), &pages)) + goto out_unmap; + + /* + * Free the otherwise unused pages. + */ + page += nr_pages; + while (page < end) { + __free_page(page); + page++; + } + + return area->addr; +out_unmap: + vunmap(area->addr); + if (array_size > PAGE_SIZE) + vfree(pages); + else + kfree(pages); + goto out_free_pages; +out_free_area: + free_vm_area(area); +out_free_pages: + if (page) + __free_pages(page, order); +no_page: + return NULL; +} +EXPORT_SYMBOL(__dma_alloc_coherent); + +/* + * free a page as defined by the above mapping. + */ +void __dma_free_coherent(size_t size, void *vaddr) +{ + vfree(vaddr); + +} +EXPORT_SYMBOL(__dma_free_coherent); + +/* + * make an area consistent. + */ +void __dma_sync(void *vaddr, size_t size, int direction) +{ + unsigned long start = (unsigned long)vaddr; + unsigned long end = start + size; + + switch (direction) { + case DMA_NONE: + BUG(); + case DMA_FROM_DEVICE: + /* + * invalidate only when cache-line aligned otherwise there is + * the potential for discarding uncommitted data from the cache + */ + if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1))) + flush_dcache_range(start, end); + else + invalidate_dcache_range(start, end); + break; + case DMA_TO_DEVICE: /* writeback only */ + clean_dcache_range(start, end); + break; + case DMA_BIDIRECTIONAL: /* writeback and invalidate */ + flush_dcache_range(start, end); + break; + } +} +EXPORT_SYMBOL(__dma_sync); + +#ifdef CONFIG_HIGHMEM +/* + * __dma_sync_page() implementation for systems using highmem. + * In this case, each page of a buffer must be kmapped/kunmapped + * in order to have a virtual address for __dma_sync(). This must + * not sleep so kmap_atomic()/kunmap_atomic() are used. + * + * Note: yes, it is possible and correct to have a buffer extend + * beyond the first page. + */ +static inline void __dma_sync_page_highmem(struct page *page, + unsigned long offset, size_t size, int direction) +{ + size_t seg_size = min((size_t)(PAGE_SIZE - offset), size); + size_t cur_size = seg_size; + unsigned long flags, start, seg_offset = offset; + int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE; + int seg_nr = 0; + + local_irq_save(flags); + + do { + start = (unsigned long)kmap_atomic(page + seg_nr, + KM_PPC_SYNC_PAGE) + seg_offset; + + /* Sync this buffer segment */ + __dma_sync((void *)start, seg_size, direction); + kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE); + seg_nr++; + + /* Calculate next buffer segment size */ + seg_size = min((size_t)PAGE_SIZE, size - cur_size); + + /* Add the segment size to our running total */ + cur_size += seg_size; + seg_offset = 0; + } while (seg_nr < nr_segs); + + local_irq_restore(flags); +} +#endif /* CONFIG_HIGHMEM */ + +/* + * __dma_sync_page makes memory consistent. identical to __dma_sync, but + * takes a struct page instead of a virtual address + */ +void __dma_sync_page(struct page *page, unsigned long offset, + size_t size, int direction) +{ +#ifdef CONFIG_HIGHMEM + __dma_sync_page_highmem(page, offset, size, direction); +#else + unsigned long start = (unsigned long)page_address(page) + offset; + __dma_sync((void *)start, size, direction); +#endif +} +EXPORT_SYMBOL(__dma_sync_page); diff --git a/trunk/arch/powerpc/mm/Makefile b/trunk/arch/powerpc/mm/Makefile index b746f4ca4209..17290bcedc5e 100644 --- a/trunk/arch/powerpc/mm/Makefile +++ b/trunk/arch/powerpc/mm/Makefile @@ -26,4 +26,3 @@ obj-$(CONFIG_NEED_MULTIPLE_NODES) += numa.o obj-$(CONFIG_PPC_MM_SLICES) += slice.o obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o obj-$(CONFIG_PPC_SUBPAGE_PROT) += subpage-prot.o -obj-$(CONFIG_NOT_COHERENT_CACHE) += dma-noncoherent.o diff --git a/trunk/arch/powerpc/mm/dma-noncoherent.c b/trunk/arch/powerpc/mm/dma-noncoherent.c deleted file mode 100644 index 36692f5c9a76..000000000000 --- a/trunk/arch/powerpc/mm/dma-noncoherent.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * PowerPC version derived from arch/arm/mm/consistent.c - * Copyright (C) 2001 Dan Malek (dmalek@jlc.net) - * - * Copyright (C) 2000 Russell King - * - * Consistent memory allocators. Used for DMA devices that want to - * share uncached memory with the processor core. The function return - * is the virtual address and 'dma_handle' is the physical address. - * Mostly stolen from the ARM port, with some changes for PowerPC. - * -- Dan - * - * Reorganized to get rid of the arch-specific consistent_* functions - * and provide non-coherent implementations for the DMA API. -Matt - * - * Added in_interrupt() safe dma_alloc_coherent()/dma_free_coherent() - * implementation. This is pulled straight from ARM and barely - * modified. -Matt - * - * 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 -#include -#include -#include -#include -#include -#include - -#include - -#include "mmu_decl.h" - -/* - * This address range defaults to a value that is safe for all - * platforms which currently set CONFIG_NOT_COHERENT_CACHE. It - * can be further configured for specific applications under - * the "Advanced Setup" menu. -Matt - */ -#define CONSISTENT_BASE (IOREMAP_TOP) -#define CONSISTENT_END (CONSISTENT_BASE + CONFIG_CONSISTENT_SIZE) -#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) - -/* - * This is the page table (2MB) covering uncached, DMA consistent allocations - */ -static DEFINE_SPINLOCK(consistent_lock); - -/* - * VM region handling support. - * - * This should become something generic, handling VM region allocations for - * vmalloc and similar (ioremap, module space, etc). - * - * I envisage vmalloc()'s supporting vm_struct becoming: - * - * struct vm_struct { - * struct vm_region region; - * unsigned long flags; - * struct page **pages; - * unsigned int nr_pages; - * unsigned long phys_addr; - * }; - * - * get_vm_area() would then call vm_region_alloc with an appropriate - * struct vm_region head (eg): - * - * struct vm_region vmalloc_head = { - * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), - * .vm_start = VMALLOC_START, - * .vm_end = VMALLOC_END, - * }; - * - * However, vmalloc_head.vm_start is variable (typically, it is dependent on - * the amount of RAM found at boot time.) I would imagine that get_vm_area() - * would have to initialise this each time prior to calling vm_region_alloc(). - */ -struct ppc_vm_region { - struct list_head vm_list; - unsigned long vm_start; - unsigned long vm_end; -}; - -static struct ppc_vm_region consistent_head = { - .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), - .vm_start = CONSISTENT_BASE, - .vm_end = CONSISTENT_END, -}; - -static struct ppc_vm_region * -ppc_vm_region_alloc(struct ppc_vm_region *head, size_t size, gfp_t gfp) -{ - unsigned long addr = head->vm_start, end = head->vm_end - size; - unsigned long flags; - struct ppc_vm_region *c, *new; - - new = kmalloc(sizeof(struct ppc_vm_region), gfp); - if (!new) - goto out; - - spin_lock_irqsave(&consistent_lock, flags); - - list_for_each_entry(c, &head->vm_list, vm_list) { - if ((addr + size) < addr) - goto nospc; - if ((addr + size) <= c->vm_start) - goto found; - addr = c->vm_end; - if (addr > end) - goto nospc; - } - - found: - /* - * Insert this entry _before_ the one we found. - */ - list_add_tail(&new->vm_list, &c->vm_list); - new->vm_start = addr; - new->vm_end = addr + size; - - spin_unlock_irqrestore(&consistent_lock, flags); - return new; - - nospc: - spin_unlock_irqrestore(&consistent_lock, flags); - kfree(new); - out: - return NULL; -} - -static struct ppc_vm_region *ppc_vm_region_find(struct ppc_vm_region *head, unsigned long addr) -{ - struct ppc_vm_region *c; - - list_for_each_entry(c, &head->vm_list, vm_list) { - if (c->vm_start == addr) - goto out; - } - c = NULL; - out: - return c; -} - -/* - * Allocate DMA-coherent memory space and return both the kernel remapped - * virtual and bus address for that space. - */ -void * -__dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) -{ - struct page *page; - struct ppc_vm_region *c; - unsigned long order; - u64 mask = ISA_DMA_THRESHOLD, limit; - - if (dev) { - mask = dev->coherent_dma_mask; - - /* - * Sanity check the DMA mask - it must be non-zero, and - * must be able to be satisfied by a DMA allocation. - */ - if (mask == 0) { - dev_warn(dev, "coherent DMA mask is unset\n"); - goto no_page; - } - - if ((~mask) & ISA_DMA_THRESHOLD) { - dev_warn(dev, "coherent DMA mask %#llx is smaller " - "than system GFP_DMA mask %#llx\n", - mask, (unsigned long long)ISA_DMA_THRESHOLD); - goto no_page; - } - } - - - size = PAGE_ALIGN(size); - limit = (mask + 1) & ~mask; - if ((limit && size >= limit) || - size >= (CONSISTENT_END - CONSISTENT_BASE)) { - printk(KERN_WARNING "coherent allocation too big (requested %#x mask %#Lx)\n", - size, mask); - return NULL; - } - - order = get_order(size); - - /* Might be useful if we ever have a real legacy DMA zone... */ - if (mask != 0xffffffff) - gfp |= GFP_DMA; - - page = alloc_pages(gfp, order); - if (!page) - goto no_page; - - /* - * Invalidate any data that might be lurking in the - * kernel direct-mapped region for device DMA. - */ - { - unsigned long kaddr = (unsigned long)page_address(page); - memset(page_address(page), 0, size); - flush_dcache_range(kaddr, kaddr + size); - } - - /* - * Allocate a virtual address in the consistent mapping region. - */ - c = ppc_vm_region_alloc(&consistent_head, size, - gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); - if (c) { - unsigned long vaddr = c->vm_start; - struct page *end = page + (1 << order); - - split_page(page, order); - - /* - * Set the "dma handle" - */ - *handle = page_to_phys(page); - - do { - SetPageReserved(page); - map_page(vaddr, page_to_phys(page), - pgprot_noncached(PAGE_KERNEL)); - page++; - vaddr += PAGE_SIZE; - } while (size -= PAGE_SIZE); - - /* - * Free the otherwise unused pages. - */ - while (page < end) { - __free_page(page); - page++; - } - - return (void *)c->vm_start; - } - - if (page) - __free_pages(page, order); - no_page: - return NULL; -} -EXPORT_SYMBOL(__dma_alloc_coherent); - -/* - * free a page as defined by the above mapping. - */ -void __dma_free_coherent(size_t size, void *vaddr) -{ - struct ppc_vm_region *c; - unsigned long flags, addr; - - size = PAGE_ALIGN(size); - - spin_lock_irqsave(&consistent_lock, flags); - - c = ppc_vm_region_find(&consistent_head, (unsigned long)vaddr); - if (!c) - goto no_area; - - if ((c->vm_end - c->vm_start) != size) { - printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", - __func__, c->vm_end - c->vm_start, size); - dump_stack(); - size = c->vm_end - c->vm_start; - } - - addr = c->vm_start; - do { - pte_t *ptep; - unsigned long pfn; - - ptep = pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(addr), - addr), - addr), - addr); - if (!pte_none(*ptep) && pte_present(*ptep)) { - pfn = pte_pfn(*ptep); - pte_clear(&init_mm, addr, ptep); - if (pfn_valid(pfn)) { - struct page *page = pfn_to_page(pfn); - - ClearPageReserved(page); - __free_page(page); - } - } - addr += PAGE_SIZE; - } while (size -= PAGE_SIZE); - - flush_tlb_kernel_range(c->vm_start, c->vm_end); - - list_del(&c->vm_list); - - spin_unlock_irqrestore(&consistent_lock, flags); - - kfree(c); - return; - - no_area: - spin_unlock_irqrestore(&consistent_lock, flags); - printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", - __func__, vaddr); - dump_stack(); -} -EXPORT_SYMBOL(__dma_free_coherent); - -/* - * make an area consistent. - */ -void __dma_sync(void *vaddr, size_t size, int direction) -{ - unsigned long start = (unsigned long)vaddr; - unsigned long end = start + size; - - switch (direction) { - case DMA_NONE: - BUG(); - case DMA_FROM_DEVICE: - /* - * invalidate only when cache-line aligned otherwise there is - * the potential for discarding uncommitted data from the cache - */ - if ((start & (L1_CACHE_BYTES - 1)) || (size & (L1_CACHE_BYTES - 1))) - flush_dcache_range(start, end); - else - invalidate_dcache_range(start, end); - break; - case DMA_TO_DEVICE: /* writeback only */ - clean_dcache_range(start, end); - break; - case DMA_BIDIRECTIONAL: /* writeback and invalidate */ - flush_dcache_range(start, end); - break; - } -} -EXPORT_SYMBOL(__dma_sync); - -#ifdef CONFIG_HIGHMEM -/* - * __dma_sync_page() implementation for systems using highmem. - * In this case, each page of a buffer must be kmapped/kunmapped - * in order to have a virtual address for __dma_sync(). This must - * not sleep so kmap_atomic()/kunmap_atomic() are used. - * - * Note: yes, it is possible and correct to have a buffer extend - * beyond the first page. - */ -static inline void __dma_sync_page_highmem(struct page *page, - unsigned long offset, size_t size, int direction) -{ - size_t seg_size = min((size_t)(PAGE_SIZE - offset), size); - size_t cur_size = seg_size; - unsigned long flags, start, seg_offset = offset; - int nr_segs = 1 + ((size - seg_size) + PAGE_SIZE - 1)/PAGE_SIZE; - int seg_nr = 0; - - local_irq_save(flags); - - do { - start = (unsigned long)kmap_atomic(page + seg_nr, - KM_PPC_SYNC_PAGE) + seg_offset; - - /* Sync this buffer segment */ - __dma_sync((void *)start, seg_size, direction); - kunmap_atomic((void *)start, KM_PPC_SYNC_PAGE); - seg_nr++; - - /* Calculate next buffer segment size */ - seg_size = min((size_t)PAGE_SIZE, size - cur_size); - - /* Add the segment size to our running total */ - cur_size += seg_size; - seg_offset = 0; - } while (seg_nr < nr_segs); - - local_irq_restore(flags); -} -#endif /* CONFIG_HIGHMEM */ - -/* - * __dma_sync_page makes memory consistent. identical to __dma_sync, but - * takes a struct page instead of a virtual address - */ -void __dma_sync_page(struct page *page, unsigned long offset, - size_t size, int direction) -{ -#ifdef CONFIG_HIGHMEM - __dma_sync_page_highmem(page, offset, size, direction); -#else - unsigned long start = (unsigned long)page_address(page) + offset; - __dma_sync((void *)start, size, direction); -#endif -} -EXPORT_SYMBOL(__dma_sync_page); diff --git a/trunk/arch/powerpc/mm/init_32.c b/trunk/arch/powerpc/mm/init_32.c index 3de6a0d93824..666a5e8a5be1 100644 --- a/trunk/arch/powerpc/mm/init_32.c +++ b/trunk/arch/powerpc/mm/init_32.c @@ -168,8 +168,12 @@ void __init MMU_init(void) ppc_md.progress("MMU:mapin", 0x301); mapin_ram(); - /* Initialize early top-down ioremap allocator */ - ioremap_bot = IOREMAP_TOP; +#ifdef CONFIG_HIGHMEM + ioremap_base = PKMAP_BASE; +#else + ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */ +#endif /* CONFIG_HIGHMEM */ + ioremap_bot = ioremap_base; /* Map in I/O resources */ if (ppc_md.progress) diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 579382c163a9..d0602a76bf7f 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -380,23 +380,6 @@ void __init mem_init(void) bsssize >> 10, initsize >> 10); -#ifdef CONFIG_PPC32 - pr_info("Kernel virtual memory layout:\n"); - pr_info(" * 0x%08lx..0x%08lx : fixmap\n", FIXADDR_START, FIXADDR_TOP); -#ifdef CONFIG_HIGHMEM - pr_info(" * 0x%08lx..0x%08lx : highmem PTEs\n", - PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP)); -#endif /* CONFIG_HIGHMEM */ -#ifdef CONFIG_NOT_COHERENT_CACHE - pr_info(" * 0x%08lx..0x%08lx : consistent mem\n", - IOREMAP_TOP, IOREMAP_TOP + CONFIG_CONSISTENT_SIZE); -#endif /* CONFIG_NOT_COHERENT_CACHE */ - pr_info(" * 0x%08lx..0x%08lx : early ioremap\n", - ioremap_bot, IOREMAP_TOP); - pr_info(" * 0x%08lx..0x%08lx : vmalloc & ioremap\n", - VMALLOC_START, VMALLOC_END); -#endif /* CONFIG_PPC32 */ - mem_init_done = 1; } diff --git a/trunk/arch/powerpc/mm/pgtable_32.c b/trunk/arch/powerpc/mm/pgtable_32.c index 5422169626ba..430d0908fa50 100644 --- a/trunk/arch/powerpc/mm/pgtable_32.c +++ b/trunk/arch/powerpc/mm/pgtable_32.c @@ -399,6 +399,8 @@ void kernel_map_pages(struct page *page, int numpages, int enable) #endif /* CONFIG_DEBUG_PAGEALLOC */ static int fixmaps; +unsigned long FIXADDR_TOP = (-PAGE_SIZE); +EXPORT_SYMBOL(FIXADDR_TOP); void __set_fixmap (enum fixed_addresses idx, phys_addr_t phys, pgprot_t flags) { diff --git a/trunk/arch/sh/include/asm/flat.h b/trunk/arch/sh/include/asm/flat.h index 5d84df5e27f6..d3b2b4f109e3 100644 --- a/trunk/arch/sh/include/asm/flat.h +++ b/trunk/arch/sh/include/asm/flat.h @@ -12,6 +12,7 @@ #ifndef __ASM_SH_FLAT_H #define __ASM_SH_FLAT_H +#define flat_stack_align(sp) /* nothing needed */ #define flat_argvp_envp_on_stack() 0 #define flat_old_ram_flag(flags) (flags) #define flat_reloc_valid(reloc, size) ((reloc) <= (size)) diff --git a/trunk/arch/sparc/include/asm/elf_64.h b/trunk/arch/sparc/include/asm/elf_64.h index d42e393078c4..425c2f9be6d5 100644 --- a/trunk/arch/sparc/include/asm/elf_64.h +++ b/trunk/arch/sparc/include/asm/elf_64.h @@ -208,9 +208,8 @@ do { unsigned long new_flags = current_thread_info()->flags; \ else \ clear_thread_flag(TIF_ABI_PENDING); \ /* flush_thread will update pgd cache */ \ - if (personality(current->personality) != PER_LINUX32) \ - set_personality(PER_LINUX | \ - (current->personality & (~PER_MASK))); \ + if (current->personality != PER_LINUX32) \ + set_personality(PER_LINUX); \ } while (0) #endif /* !(__ASM_SPARC64_ELF_H) */ diff --git a/trunk/arch/sparc/lib/csum_copy_from_user.S b/trunk/arch/sparc/lib/csum_copy_from_user.S index e0304e6a2242..a22eddbe5dba 100644 --- a/trunk/arch/sparc/lib/csum_copy_from_user.S +++ b/trunk/arch/sparc/lib/csum_copy_from_user.S @@ -5,7 +5,7 @@ #define EX_LD(x) \ 98: x; \ - .section .fixup, "ax"; \ + .section .fixup; \ .align 4; \ 99: retl; \ mov -1, %o0; \ diff --git a/trunk/arch/sparc/lib/csum_copy_to_user.S b/trunk/arch/sparc/lib/csum_copy_to_user.S index afd01acc587c..d5b12f441f02 100644 --- a/trunk/arch/sparc/lib/csum_copy_to_user.S +++ b/trunk/arch/sparc/lib/csum_copy_to_user.S @@ -5,7 +5,7 @@ #define EX_ST(x) \ 98: x; \ - .section .fixup,"ax"; \ + .section .fixup; \ .align 4; \ 99: retl; \ mov -1, %o0; \ diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c index 752e8c6b2c7e..208ecf6643df 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c @@ -550,7 +550,7 @@ static int __init acpi_cpufreq_early_init(void) return -ENOMEM; } for_each_possible_cpu(i) { - if (!zalloc_cpumask_var_node( + if (!alloc_cpumask_var_node( &per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map, GFP_KERNEL, cpu_to_node(i))) { @@ -693,8 +693,8 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && policy->cpuinfo.transition_latency > 20 * 1000) { policy->cpuinfo.transition_latency = 20 * 1000; - printk_once(KERN_INFO - "P-state transition latency capped at 20 uS\n"); + printk_once(KERN_INFO "Capping off P-state tranision" + " latency at 20 uS\n"); } /* table init */ diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c index d47c775eb0ab..a8363e5be4ef 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k7.c @@ -322,7 +322,7 @@ static int powernow_acpi_init(void) goto err0; } - if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map, + if (!alloc_cpumask_var(&acpi_processor_perf->shared_cpu_map, GFP_KERNEL)) { retval = -ENOMEM; goto err05; diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index cf52215d9eb1..f6b32d112357 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/powernow-k8.c @@ -835,7 +835,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { struct cpufreq_frequency_table *powernow_table; int ret_val = -ENODEV; - acpi_integer control, status; + acpi_integer space_id; if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { dprintk("register performance failed: bad ACPI data\n"); @@ -848,13 +848,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) goto err_out; } - control = data->acpi_data.control_register.space_id; - status = data->acpi_data.status_register.space_id; - - if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) || - (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) { + space_id = data->acpi_data.control_register.space_id; + if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || + (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { dprintk("Invalid control/status registers (%x - %x)\n", - control, status); + data->acpi_data.control_register.space_id, + space_id); goto err_out; } @@ -887,7 +886,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* notify BIOS that we exist */ acpi_processor_notify_smm(THIS_MODULE); - if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { + if (!alloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) { printk(KERN_ERR PFX "unable to alloc powernow_k8_data cpumask\n"); ret_val = -ENOMEM; diff --git a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c index 55c831ed71ce..c9f1fdc02830 100644 --- a/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ b/trunk/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -471,7 +471,7 @@ static int centrino_target (struct cpufreq_policy *policy, if (unlikely(!alloc_cpumask_var(&saved_mask, GFP_KERNEL))) return -ENOMEM; - if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))) { + if (unlikely(!alloc_cpumask_var(&covered_cpus, GFP_KERNEL))) { free_cpumask_var(saved_mask); return -ENOMEM; } diff --git a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c index 09dd1d414fc3..6fb0b359d2a5 100644 --- a/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c +++ b/trunk/arch/x86/kernel/cpu/mcheck/mce_64.c @@ -1163,7 +1163,7 @@ static __init int mce_init_device(void) if (!mce_available(&boot_cpu_data)) return -EIO; - zalloc_cpumask_var(&mce_device_initialized, GFP_KERNEL); + alloc_cpumask_var(&mce_device_initialized, GFP_KERNEL); err = mce_init_banks(); if (err) diff --git a/trunk/arch/x86/kernel/tlb_uv.c b/trunk/arch/x86/kernel/tlb_uv.c index 8c7b03b0cfcb..ed0c33761e6d 100644 --- a/trunk/arch/x86/kernel/tlb_uv.c +++ b/trunk/arch/x86/kernel/tlb_uv.c @@ -832,7 +832,7 @@ static int __init uv_bau_init(void) return 0; for_each_possible_cpu(cur_cpu) - zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), + alloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu), GFP_KERNEL, cpu_to_node(cur_cpu)); uv_bau_retry_limit = 1; diff --git a/trunk/arch/x86/lguest/Makefile b/trunk/arch/x86/lguest/Makefile index 94e0e54056a9..27f0c9ed7f60 100644 --- a/trunk/arch/x86/lguest/Makefile +++ b/trunk/arch/x86/lguest/Makefile @@ -1,2 +1 @@ obj-y := i386_head.o boot.o -CFLAGS_boot.o := $(call cc-option, -fno-stack-protector) diff --git a/trunk/arch/x86/lguest/boot.c b/trunk/arch/x86/lguest/boot.c index 33a93b417396..ca7ec44bafc3 100644 --- a/trunk/arch/x86/lguest/boot.c +++ b/trunk/arch/x86/lguest/boot.c @@ -67,7 +67,6 @@ #include #include #include -#include #include /* for struct machine_ops */ /*G:010 Welcome to the Guest! @@ -1089,21 +1088,13 @@ __init void lguest_init(void) * lguest_init() where the rest of the fairly chaotic boot setup * occurs. */ - /* The stack protector is a weird thing where gcc places a canary - * value on the stack and then checks it on return. This file is - * compiled with -fno-stack-protector it, so we got this far without - * problems. The value of the canary is kept at offset 20 from the - * %gs register, so we need to set that up before calling C functions - * in other files. */ - setup_stack_canary_segment(0); - /* We could just call load_stack_canary_segment(), but we might as - * call switch_to_new_gdt() which loads the whole table and sets up - * the per-cpu segment descriptor register %fs as well. */ - switch_to_new_gdt(0); - /* As described in head_32.S, we map the first 128M of memory. */ max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; + /* Load the %fs segment register (the per-cpu segment register) with + * the normal data segment to get through booting. */ + asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); + /* The Host<->Guest Switcher lives at the top of our address space, and * the Host told us how big it is when we made LGUEST_INIT hypercall: * it put the answer in lguest_data.reserve_mem */ diff --git a/trunk/arch/x86/mm/hugetlbpage.c b/trunk/arch/x86/mm/hugetlbpage.c index f46c340727b8..8f307d914c2e 100644 --- a/trunk/arch/x86/mm/hugetlbpage.c +++ b/trunk/arch/x86/mm/hugetlbpage.c @@ -26,16 +26,12 @@ static unsigned long page_table_shareable(struct vm_area_struct *svma, unsigned long sbase = saddr & PUD_MASK; unsigned long s_end = sbase + PUD_SIZE; - /* Allow segments to share if only one is marked locked */ - unsigned long vm_flags = vma->vm_flags & ~VM_LOCKED; - unsigned long svm_flags = svma->vm_flags & ~VM_LOCKED; - /* * match the virtual addresses, permission and the alignment of the * page table page. */ if (pmd_index(addr) != pmd_index(saddr) || - vm_flags != svm_flags || + vma->vm_flags != svma->vm_flags || sbase < svma->vm_start || svma->vm_end < s_end) return 0; diff --git a/trunk/arch/x86/pci/mmconfig-shared.c b/trunk/arch/x86/pci/mmconfig-shared.c index 8766b0e216c5..5fa10bb9604f 100644 --- a/trunk/arch/x86/pci/mmconfig-shared.c +++ b/trunk/arch/x86/pci/mmconfig-shared.c @@ -375,7 +375,7 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res, if (!fixmem32) return AE_OK; if ((mcfg_res->start >= fixmem32->address) && - (mcfg_res->end < (fixmem32->address + + (mcfg_res->end <= (fixmem32->address + fixmem32->address_length))) { mcfg_res->flags = 1; return AE_CTRL_TERMINATE; @@ -392,7 +392,7 @@ static acpi_status __init check_mcfg_resource(struct acpi_resource *res, return AE_OK; if ((mcfg_res->start >= address.minimum) && - (mcfg_res->end < (address.minimum + address.address_length))) { + (mcfg_res->end <= (address.minimum + address.address_length))) { mcfg_res->flags = 1; return AE_CTRL_TERMINATE; } @@ -418,7 +418,7 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used) struct resource mcfg_res; mcfg_res.start = start; - mcfg_res.end = end - 1; + mcfg_res.end = end; mcfg_res.flags = 0; acpi_get_devices("PNP0C01", find_mboard_resource, &mcfg_res, NULL); diff --git a/trunk/block/bsg.c b/trunk/block/bsg.c index dd81be455e00..206060e795da 100644 --- a/trunk/block/bsg.c +++ b/trunk/block/bsg.c @@ -315,7 +315,6 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, blk_put_request(rq); if (next_rq) { blk_rq_unmap_user(next_rq->bio); - next_rq->bio = NULL; blk_put_request(next_rq); } return ERR_PTR(ret); @@ -449,7 +448,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, hdr->dout_resid = rq->data_len; hdr->din_resid = rq->next_rq->data_len; blk_rq_unmap_user(bidi_bio); - rq->next_rq->bio = NULL; blk_put_request(rq->next_rq); } else if (rq_data_dir(rq) == READ) hdr->din_resid = rq->data_len; @@ -468,7 +466,6 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr, blk_rq_unmap_user(bio); if (rq->cmd != rq->__cmd) kfree(rq->cmd); - rq->bio = NULL; blk_put_request(rq); return ret; diff --git a/trunk/crypto/ahash.c b/trunk/crypto/ahash.c index f3476374f764..b2d1ee32cfe8 100644 --- a/trunk/crypto/ahash.c +++ b/trunk/crypto/ahash.c @@ -82,11 +82,10 @@ int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err) if (err) return err; - if (nbytes) { - walk->offset = 0; - walk->pg++; + walk->offset = 0; + + if (nbytes) return hash_walk_next(walk); - } if (!walk->total) return 0; diff --git a/trunk/drivers/acpi/pci_bind.c b/trunk/drivers/acpi/pci_bind.c index bc46de3d967f..95650f83ce2e 100644 --- a/trunk/drivers/acpi/pci_bind.c +++ b/trunk/drivers/acpi/pci_bind.c @@ -116,6 +116,9 @@ int acpi_pci_bind(struct acpi_device *device) struct acpi_pci_data *pdata; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_handle handle; + struct pci_dev *dev; + struct pci_bus *bus; + if (!device || !device->parent) return -EINVAL; @@ -173,9 +176,20 @@ int acpi_pci_bind(struct acpi_device *device) * Locate matching device in PCI namespace. If it doesn't exist * this typically means that the device isn't currently inserted * (e.g. docking station, port replicator, etc.). + * We cannot simply search the global pci device list, since + * PCI devices are added to the global pci list when the root + * bridge start ops are run, which may not have happened yet. */ - data->dev = pci_get_slot(pdata->bus, - PCI_DEVFN(data->id.device, data->id.function)); + bus = pci_find_bus(data->id.segment, data->id.bus); + if (bus) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->devfn == PCI_DEVFN(data->id.device, + data->id.function)) { + data->dev = dev; + break; + } + } + } if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %04x:%02x:%02x.%d not present in PCI namespace\n", @@ -245,10 +259,9 @@ int acpi_pci_bind(struct acpi_device *device) end: kfree(buffer.pointer); - if (result) { - pci_dev_put(data->dev); + if (result) kfree(data); - } + return result; } @@ -290,7 +303,6 @@ static int acpi_pci_unbind(struct acpi_device *device) if (data->dev->subordinate) { acpi_pci_irq_del_prt(data->id.segment, data->bus->number); } - pci_dev_put(data->dev); kfree(data); end: diff --git a/trunk/drivers/acpi/processor_core.c b/trunk/drivers/acpi/processor_core.c index 23f0fb84f1c1..45ad3288c5ff 100644 --- a/trunk/drivers/acpi/processor_core.c +++ b/trunk/drivers/acpi/processor_core.c @@ -844,7 +844,7 @@ static int acpi_processor_add(struct acpi_device *device) if (!pr) return -ENOMEM; - if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { + if (!alloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) { kfree(pr); return -ENOMEM; } diff --git a/trunk/drivers/acpi/processor_idle.c b/trunk/drivers/acpi/processor_idle.c index 10a2d913635a..72069ba5f1ed 100644 --- a/trunk/drivers/acpi/processor_idle.c +++ b/trunk/drivers/acpi/processor_idle.c @@ -148,9 +148,6 @@ static void acpi_timer_check_state(int state, struct acpi_processor *pr, if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT)) return; - if (boot_cpu_has(X86_FEATURE_AMDC1E)) - type = ACPI_STATE_C1; - /* * Check, if one of the previous states already marked the lapic * unstable @@ -614,7 +611,6 @@ static int acpi_processor_power_verify(struct acpi_processor *pr) switch (cx->type) { case ACPI_STATE_C1: cx->valid = 1; - acpi_timer_check_state(i, pr, cx); break; case ACPI_STATE_C2: @@ -834,12 +830,11 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, /* Do not access any ACPI IO ports in suspend path */ if (acpi_idle_suspend) { + acpi_safe_halt(); local_irq_enable(); - cpu_relax(); return 0; } - acpi_state_timer_broadcast(pr, cx, 1); kt1 = ktime_get_real(); acpi_idle_do_entry(cx); kt2 = ktime_get_real(); @@ -847,7 +842,6 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, local_irq_enable(); cx->usage++; - acpi_state_timer_broadcast(pr, cx, 0); return idle_time; } diff --git a/trunk/drivers/acpi/processor_perflib.c b/trunk/drivers/acpi/processor_perflib.c index 60e543d3234e..cafb41000f6b 100644 --- a/trunk/drivers/acpi/processor_perflib.c +++ b/trunk/drivers/acpi/processor_perflib.c @@ -309,15 +309,9 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) (u32) px->bus_master_latency, (u32) px->control, (u32) px->status)); - /* - * Check that ACPI's u64 MHz will be valid as u32 KHz in cpufreq - */ - if (!px->core_frequency || - ((u32)(px->core_frequency * 1000) != - (px->core_frequency * 1000))) { - printk(KERN_ERR FW_BUG PREFIX - "Invalid BIOS _PSS frequency: 0x%llx MHz\n", - px->core_frequency); + if (!px->core_frequency) { + printk(KERN_ERR PREFIX + "Invalid _PSS data: freq is zero\n"); result = -EFAULT; kfree(pr->performance->states); goto end; diff --git a/trunk/drivers/acpi/processor_throttling.c b/trunk/drivers/acpi/processor_throttling.c index 227543789ba9..7f16f5f8e7d3 100644 --- a/trunk/drivers/acpi/processor_throttling.c +++ b/trunk/drivers/acpi/processor_throttling.c @@ -840,7 +840,7 @@ static int acpi_processor_get_throttling_ptc(struct acpi_processor *pr) state = acpi_get_throttling_state(pr, value); if (state == -1) { ACPI_WARNING((AE_INFO, - "Invalid throttling state, reset")); + "Invalid throttling state, reset\n")); state = 0; ret = acpi_processor_set_throttling(pr, state); if (ret) diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 1bdfb37377e3..810cca90ca7f 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -570,22 +570,6 @@ static struct dmi_system_id video_dmi_table[] __initdata = { DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5710Z"), }, }, - { - .callback = video_set_bqc_offset, - .ident = "eMachines E510", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "EMACHINES"), - DMI_MATCH(DMI_PRODUCT_NAME, "eMachines E510"), - }, - }, - { - .callback = video_set_bqc_offset, - .ident = "Acer Aspire 5315", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5315"), - }, - }, {} }; @@ -2350,7 +2334,7 @@ static int __init acpi_video_init(void) return acpi_video_register(); } -void acpi_video_exit(void) +void __exit acpi_video_exit(void) { acpi_bus_unregister_driver(&acpi_video_bus); diff --git a/trunk/drivers/ata/ahci.c b/trunk/drivers/ata/ahci.c index 6b91c26a4635..08186ecbaf8d 100644 --- a/trunk/drivers/ata/ahci.c +++ b/trunk/drivers/ata/ahci.c @@ -220,7 +220,6 @@ enum { AHCI_HFLAG_NO_HOTPLUG = (1 << 7), /* ignore PxSERR.DIAG.N */ AHCI_HFLAG_SECT255 = (1 << 8), /* max 255 sectors */ AHCI_HFLAG_YES_NCQ = (1 << 9), /* force NCQ cap on */ - AHCI_HFLAG_NO_SUSPEND = (1 << 10), /* don't suspend */ /* ap->flags bits */ @@ -2317,17 +2316,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg) static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg) { struct ata_host *host = dev_get_drvdata(&pdev->dev); - struct ahci_host_priv *hpriv = host->private_data; void __iomem *mmio = host->iomap[AHCI_PCI_BAR]; u32 ctl; - if (mesg.event & PM_EVENT_SUSPEND && - hpriv->flags & AHCI_HFLAG_NO_SUSPEND) { - dev_printk(KERN_ERR, &pdev->dev, - "BIOS update required for suspend/resume\n"); - return -EIO; - } - if (mesg.event & PM_EVENT_SLEEP) { /* AHCI spec rev1.1 section 8.3.3: * Software must disable interrupts prior to requesting a @@ -2619,63 +2610,6 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev) return false; } -static bool ahci_broken_suspend(struct pci_dev *pdev) -{ - static const struct dmi_system_id sysids[] = { - /* - * On HP dv[4-6] and HDX18 with earlier BIOSen, link - * to the harddisk doesn't become online after - * resuming from STR. Warn and fail suspend. - */ - { - .ident = "dv4", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, - "HP Pavilion dv4 Notebook PC"), - }, - .driver_data = "F.30", /* cutoff BIOS version */ - }, - { - .ident = "dv5", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, - "HP Pavilion dv5 Notebook PC"), - }, - .driver_data = "F.16", /* cutoff BIOS version */ - }, - { - .ident = "dv6", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, - "HP Pavilion dv6 Notebook PC"), - }, - .driver_data = "F.21", /* cutoff BIOS version */ - }, - { - .ident = "HDX18", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, - "HP HDX18 Notebook PC"), - }, - .driver_data = "F.23", /* cutoff BIOS version */ - }, - { } /* terminate list */ - }; - const struct dmi_system_id *dmi = dmi_first_match(sysids); - const char *ver; - - if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2)) - return false; - - ver = dmi_get_system_info(DMI_BIOS_VERSION); - - return !ver || strcmp(ver, dmi->driver_data) < 0; -} - static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int printed_version; @@ -2781,12 +2715,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) "quirky BIOS, skipping spindown on poweroff\n"); } - if (ahci_broken_suspend(pdev)) { - hpriv->flags |= AHCI_HFLAG_NO_SUSPEND; - dev_printk(KERN_WARNING, &pdev->dev, - "BIOS update required for suspend/resume\n"); - } - /* CAP.NP sometimes indicate the index of the last enabled * port, at other times, that of the last possible port, so * determining the maximum port number requires looking at diff --git a/trunk/drivers/ata/ata_piix.c b/trunk/drivers/ata/ata_piix.c index 1aeb7082b0c4..d51a17c0f59b 100644 --- a/trunk/drivers/ata/ata_piix.c +++ b/trunk/drivers/ata/ata_piix.c @@ -1455,15 +1455,6 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) /* PCI slot number of the controller */ .driver_data = (void *)0x1FUL, }, - { - .ident = "HP Compaq nc6000", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), - DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nc6000"), - }, - /* PCI slot number of the controller */ - .driver_data = (void *)0x1FUL, - }, { } /* terminate list */ }; diff --git a/trunk/drivers/ata/pata_ali.c b/trunk/drivers/ata/pata_ali.c index fc9c5d6d7d80..751b7ea4816c 100644 --- a/trunk/drivers/ata/pata_ali.c +++ b/trunk/drivers/ata/pata_ali.c @@ -497,16 +497,14 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; /* Revision 0x20 added DMA */ static const struct ata_port_info info_20 = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .port_ops = &ali_20_port_ops }; /* Revision 0x20 with support logic added UDMA */ static const struct ata_port_info info_20_udma = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA2, @@ -514,8 +512,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; /* Revision 0xC2 adds UDMA66 */ static const struct ata_port_info info_c2 = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA4, @@ -523,8 +520,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; /* Revision 0xC3 is UDMA66 for now */ static const struct ata_port_info info_c3 = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA4, @@ -532,8 +528,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; /* Revision 0xC4 is UDMA100 */ static const struct ata_port_info info_c4 = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48 | - ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA5, @@ -541,7 +536,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id) }; /* Revision 0xC5 is UDMA133 with LBA48 DMA */ static const struct ata_port_info info_c5 = { - .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_IGN_SIMPLEX, + .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = ATA_PIO4, .mwdma_mask = ATA_MWDMA2, .udma_mask = ATA_UDMA6, diff --git a/trunk/drivers/ata/pata_efar.c b/trunk/drivers/ata/pata_efar.c index 2a6412f5d117..2085e0a3a05a 100644 --- a/trunk/drivers/ata/pata_efar.c +++ b/trunk/drivers/ata/pata_efar.c @@ -22,7 +22,7 @@ #include #define DRV_NAME "pata_efar" -#define DRV_VERSION "0.4.5" +#define DRV_VERSION "0.4.4" /** * efar_pre_reset - Enable bits @@ -98,17 +98,18 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) { 2, 1 }, { 2, 3 }, }; - if (pio > 1) - control |= 1; /* TIME */ + if (pio > 2) + control |= 1; /* TIME1 enable */ if (ata_pio_need_iordy(adev)) /* PIO 3/4 require IORDY */ - control |= 2; /* IE */ - /* Intel specifies that the prefetch/posting is for disk only */ + control |= 2; /* IE enable */ + /* Intel specifies that the PPE functionality is for disk only */ if (adev->class == ATA_DEV_ATA) - control |= 4; /* PPE */ + control |= 4; /* PPE enable */ pci_read_config_word(dev, idetm_port, &idetm_data); - /* Set PPE, IE, and TIME as appropriate */ + /* Enable PPE, IE and TIME as appropriate */ + if (adev->devno == 0) { idetm_data &= 0xCCF0; idetm_data |= control; @@ -128,7 +129,7 @@ static void efar_set_piomode (struct ata_port *ap, struct ata_device *adev) pci_write_config_byte(dev, 0x44, slave_data); } - idetm_data |= 0x4000; /* Ensure SITRE is set */ + idetm_data |= 0x4000; /* Ensure SITRE is enabled */ pci_write_config_word(dev, idetm_port, idetm_data); } diff --git a/trunk/drivers/ata/pata_legacy.c b/trunk/drivers/ata/pata_legacy.c index 6932e56d179c..f72c6c5b820f 100644 --- a/trunk/drivers/ata/pata_legacy.c +++ b/trunk/drivers/ata/pata_legacy.c @@ -48,7 +48,6 @@ * */ -#include #include #include #include @@ -1029,7 +1028,6 @@ static __init int legacy_init_one(struct legacy_probe *probe) &legacy_sht); if (ret) goto fail; - async_synchronize_full(); ld->platform_dev = pdev; /* Nothing found means we drop the port as its probably not there */ diff --git a/trunk/drivers/ata/pata_netcell.c b/trunk/drivers/ata/pata_netcell.c index f0d52f72f5bb..bdb236957cb9 100644 --- a/trunk/drivers/ata/pata_netcell.c +++ b/trunk/drivers/ata/pata_netcell.c @@ -20,24 +20,13 @@ /* No PIO or DMA methods needed for this device */ -static unsigned int netcell_read_id(struct ata_device *adev, - struct ata_taskfile *tf, u16 *id) -{ - unsigned int err_mask = ata_do_dev_read_id(adev, tf, id); - /* Firmware forgets to mark words 85-87 valid */ - if (err_mask == 0) - id[ATA_ID_CSF_DEFAULT] |= 0x4000; - return err_mask; -} - static struct scsi_host_template netcell_sht = { ATA_BMDMA_SHT(DRV_NAME), }; static struct ata_port_operations netcell_ops = { .inherits = &ata_bmdma_port_ops, - .cable_detect = ata_cable_80wire, - .read_id = netcell_read_id, + .cable_detect = ata_cable_80wire, }; diff --git a/trunk/drivers/base/bus.c b/trunk/drivers/base/bus.c index c6599618523e..dc030f1f00f1 100644 --- a/trunk/drivers/base/bus.c +++ b/trunk/drivers/base/bus.c @@ -700,10 +700,8 @@ int bus_add_driver(struct device_driver *drv) } kobject_uevent(&priv->kobj, KOBJ_ADD); - return 0; + return error; out_unregister: - kfree(drv->p); - drv->p = NULL; kobject_put(&priv->kobj); out_put_bus: bus_put(bus); diff --git a/trunk/drivers/base/core.c b/trunk/drivers/base/core.c index 1977d4beb89e..4aa527b8a913 100644 --- a/trunk/drivers/base/core.c +++ b/trunk/drivers/base/core.c @@ -879,7 +879,7 @@ int device_add(struct device *dev) } if (!dev_name(dev)) - goto name_error; + goto done; pr_debug("device: '%s': %s\n", dev_name(dev), __func__); @@ -978,9 +978,6 @@ int device_add(struct device *dev) cleanup_device_parent(dev); if (parent) put_device(parent); -name_error: - kfree(dev->p); - dev->p = NULL; goto done; } diff --git a/trunk/drivers/base/driver.c b/trunk/drivers/base/driver.c index 8ae0f63602e0..c51f11bb29ae 100644 --- a/trunk/drivers/base/driver.c +++ b/trunk/drivers/base/driver.c @@ -257,10 +257,6 @@ EXPORT_SYMBOL_GPL(driver_register); */ void driver_unregister(struct device_driver *drv) { - if (!drv || !drv->p) { - WARN(1, "Unexpected driver unregister!\n"); - return; - } driver_remove_groups(drv, drv->groups); bus_remove_driver(drv); } diff --git a/trunk/drivers/char/mem.c b/trunk/drivers/char/mem.c index 65e12bca657c..8f05c38c2f06 100644 --- a/trunk/drivers/char/mem.c +++ b/trunk/drivers/char/mem.c @@ -694,9 +694,6 @@ static ssize_t read_zero(struct file * file, char __user * buf, written += chunk - unwritten; if (unwritten) break; - /* Consider changing this to just 'signal_pending()' with lots of testing */ - if (fatal_signal_pending(current)) - return written ? written : -EINTR; buf += chunk; count -= chunk; cond_resched(); diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 13f8871e5b21..a420e8d437dd 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -2711,7 +2711,7 @@ static int __init mxser_module_init(void) continue; brd = &mxser_boards[m]; - retval = mxser_get_ISA_conf(ioaddr[b], brd); + retval = mxser_get_ISA_conf(!ioaddr[b], brd); if (retval <= 0) { brd->info = NULL; continue; diff --git a/trunk/drivers/cpufreq/cpufreq.c b/trunk/drivers/cpufreq/cpufreq.c index 6e2ec0b18948..47d2ad0ae079 100644 --- a/trunk/drivers/cpufreq/cpufreq.c +++ b/trunk/drivers/cpufreq/cpufreq.c @@ -808,7 +808,7 @@ static int cpufreq_add_dev(struct sys_device *sys_dev) ret = -ENOMEM; goto nomem_out; } - if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) { + if (!alloc_cpumask_var(&policy->related_cpus, GFP_KERNEL)) { free_cpumask_var(policy->cpus); kfree(policy); ret = -ENOMEM; diff --git a/trunk/drivers/dma/fsldma.c b/trunk/drivers/dma/fsldma.c index f18d1bde0439..da8a8ed9e411 100644 --- a/trunk/drivers/dma/fsldma.c +++ b/trunk/drivers/dma/fsldma.c @@ -179,14 +179,9 @@ static void dma_halt(struct fsl_dma_chan *fsl_chan) static void set_ld_eol(struct fsl_dma_chan *fsl_chan, struct fsl_desc_sw *desc) { - u64 snoop_bits; - - snoop_bits = ((fsl_chan->feature & FSL_DMA_IP_MASK) == FSL_DMA_IP_83XX) - ? FSL_DMA_SNEN : 0; - desc->hw.next_ln_addr = CPU_TO_DMA(fsl_chan, - DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL - | snoop_bits, 64); + DMA_TO_CPU(fsl_chan, desc->hw.next_ln_addr, 64) | FSL_DMA_EOL, + 64); } static void append_ld_queue(struct fsl_dma_chan *fsl_chan, @@ -318,8 +313,8 @@ static void fsl_chan_toggle_ext_start(struct fsl_dma_chan *fsl_chan, int enable) static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx) { + struct fsl_desc_sw *desc = tx_to_fsl_desc(tx); struct fsl_dma_chan *fsl_chan = to_fsl_chan(tx->chan); - struct fsl_desc_sw *desc; unsigned long flags; dma_cookie_t cookie; @@ -327,17 +322,14 @@ static dma_cookie_t fsl_dma_tx_submit(struct dma_async_tx_descriptor *tx) spin_lock_irqsave(&fsl_chan->desc_lock, flags); cookie = fsl_chan->common.cookie; - list_for_each_entry(desc, &tx->tx_list, node) { - cookie++; - if (cookie < 0) - cookie = 1; + cookie++; + if (cookie < 0) + cookie = 1; + desc->async_tx.cookie = cookie; + fsl_chan->common.cookie = desc->async_tx.cookie; - desc->async_tx.cookie = cookie; - } - - fsl_chan->common.cookie = cookie; - append_ld_queue(fsl_chan, tx_to_fsl_desc(tx)); - list_splice_init(&tx->tx_list, fsl_chan->ld_queue.prev); + append_ld_queue(fsl_chan, desc); + list_splice_init(&desc->async_tx.tx_list, fsl_chan->ld_queue.prev); spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); @@ -462,8 +454,8 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy( { struct fsl_dma_chan *fsl_chan; struct fsl_desc_sw *first = NULL, *prev = NULL, *new; - struct list_head *list; size_t copy; + LIST_HEAD(link_chain); if (!chan) return NULL; @@ -480,7 +472,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy( if (!new) { dev_err(fsl_chan->dev, "No free memory for link descriptor\n"); - goto fail; + return NULL; } #ifdef FSL_DMA_LD_DEBUG dev_dbg(fsl_chan->dev, "new link desc alloc %p\n", new); @@ -515,19 +507,7 @@ static struct dma_async_tx_descriptor *fsl_dma_prep_memcpy( /* Set End-of-link to the last link descriptor of new list*/ set_ld_eol(fsl_chan, new); - return &first->async_tx; - -fail: - if (!first) - return NULL; - - list = &first->async_tx.tx_list; - list_for_each_entry_safe_reverse(new, prev, list, node) { - list_del(&new->node); - dma_pool_free(fsl_chan->desc_pool, new, new->async_tx.phys); - } - - return NULL; + return first ? &first->async_tx : NULL; } /** @@ -618,16 +598,15 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan) dma_addr_t next_dest_addr; unsigned long flags; - spin_lock_irqsave(&fsl_chan->desc_lock, flags); - if (!dma_is_idle(fsl_chan)) - goto out_unlock; + return; dma_halt(fsl_chan); /* If there are some link descriptors * not transfered in queue. We need to start it. */ + spin_lock_irqsave(&fsl_chan->desc_lock, flags); /* Find the first un-transfer desciptor */ for (ld_node = fsl_chan->ld_queue.next; @@ -638,20 +617,19 @@ static void fsl_chan_xfer_ld_queue(struct fsl_dma_chan *fsl_chan) fsl_chan->common.cookie) == DMA_SUCCESS); ld_node = ld_node->next); + spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); + if (ld_node != &fsl_chan->ld_queue) { /* Get the ld start address from ld_queue */ next_dest_addr = to_fsl_desc(ld_node)->async_tx.phys; - dev_dbg(fsl_chan->dev, "xfer LDs staring from 0x%llx\n", - (unsigned long long)next_dest_addr); + dev_dbg(fsl_chan->dev, "xfer LDs staring from %p\n", + (void *)next_dest_addr); set_cdar(fsl_chan, next_dest_addr); dma_start(fsl_chan); } else { set_cdar(fsl_chan, 0); set_ndar(fsl_chan, 0); } - -out_unlock: - spin_unlock_irqrestore(&fsl_chan->desc_lock, flags); } /** @@ -756,9 +734,8 @@ static irqreturn_t fsl_dma_chan_do_interrupt(int irq, void *data) */ if (stat & FSL_DMA_SR_EOSI) { dev_dbg(fsl_chan->dev, "event: End-of-segments INT\n"); - dev_dbg(fsl_chan->dev, "event: clndar 0x%llx, nlndar 0x%llx\n", - (unsigned long long)get_cdar(fsl_chan), - (unsigned long long)get_ndar(fsl_chan)); + dev_dbg(fsl_chan->dev, "event: clndar %p, nlndar %p\n", + (void *)get_cdar(fsl_chan), (void *)get_ndar(fsl_chan)); stat &= ~FSL_DMA_SR_EOSI; update_cookie = 1; } @@ -853,7 +830,7 @@ static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev, new_fsl_chan->reg.end - new_fsl_chan->reg.start + 1); new_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7; - if (new_fsl_chan->id >= FSL_DMA_MAX_CHANS_PER_DEVICE) { + if (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) { dev_err(fdev->dev, "There is no %d channel!\n", new_fsl_chan->id); err = -EINVAL; @@ -948,8 +925,8 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, } dev_info(&dev->dev, "Probe the Freescale DMA driver for %s " - "controller at 0x%llx...\n", - match->compatible, (unsigned long long)fdev->reg.start); + "controller at %p...\n", + match->compatible, (void *)fdev->reg.start); fdev->reg_base = ioremap(fdev->reg.start, fdev->reg.end - fdev->reg.start + 1); diff --git a/trunk/drivers/dma/ioat_dma.c b/trunk/drivers/dma/ioat_dma.c index a600fc0f7962..1955ee8d6d20 100644 --- a/trunk/drivers/dma/ioat_dma.c +++ b/trunk/drivers/dma/ioat_dma.c @@ -173,7 +173,7 @@ static int ioat_dma_enumerate_channels(struct ioatdma_device *device) xfercap = (xfercap_scale == 0 ? -1 : (1UL << xfercap_scale)); #ifdef CONFIG_I7300_IDLE_IOAT_CHANNEL - if (i7300_idle_platform_probe(NULL, NULL, 1) == 0) { + if (i7300_idle_platform_probe(NULL, NULL) == 0) { device->common.chancnt--; } #endif diff --git a/trunk/drivers/edac/Kconfig b/trunk/drivers/edac/Kconfig index 956982f8739b..e5f5c5a8ba6c 100644 --- a/trunk/drivers/edac/Kconfig +++ b/trunk/drivers/edac/Kconfig @@ -192,20 +192,16 @@ config EDAC_PPC4XX config EDAC_AMD8131 tristate "AMD8131 HyperTransport PCI-X Tunnel" - depends on EDAC_MM_EDAC && PCI && PPC_MAPLE + depends on EDAC_MM_EDAC && PCI help Support for error detection and correction on the AMD8131 HyperTransport PCI-X Tunnel chip. - Note, add more Kconfig dependency if it's adopted - on some machine other than Maple. config EDAC_AMD8111 tristate "AMD8111 HyperTransport I/O Hub" - depends on EDAC_MM_EDAC && PCI && PPC_MAPLE + depends on EDAC_MM_EDAC && PCI help Support for error detection and correction on the AMD8111 HyperTransport I/O Hub chip. - Note, add more Kconfig dependency if it's adopted - on some machine other than Maple. endif # EDAC diff --git a/trunk/drivers/edac/Makefile b/trunk/drivers/edac/Makefile index 59076819135d..a5fdcf02f591 100644 --- a/trunk/drivers/edac/Makefile +++ b/trunk/drivers/edac/Makefile @@ -35,5 +35,3 @@ obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac.o obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o obj-$(CONFIG_EDAC_CELL) += cell_edac.o obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o -obj-$(CONFIG_EDAC_AMD8111) += amd8111_edac.o -obj-$(CONFIG_EDAC_AMD8131) += amd8131_edac.o diff --git a/trunk/drivers/edac/amd8111_edac.c b/trunk/drivers/edac/amd8111_edac.c index 2cb58ef743e0..614692181120 100644 --- a/trunk/drivers/edac/amd8111_edac.c +++ b/trunk/drivers/edac/amd8111_edac.c @@ -389,7 +389,7 @@ static int amd8111_dev_probe(struct pci_dev *dev, dev_info->edac_dev->dev = &dev_info->dev->dev; dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR; dev_info->edac_dev->ctl_name = dev_info->ctl_name; - dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev); + dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id; if (edac_op_state == EDAC_OPSTATE_POLL) dev_info->edac_dev->edac_check = dev_info->check; @@ -473,7 +473,7 @@ static int amd8111_pci_probe(struct pci_dev *dev, pci_info->edac_dev->dev = &pci_info->dev->dev; pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR; pci_info->edac_dev->ctl_name = pci_info->ctl_name; - pci_info->edac_dev->dev_name = dev_name(&pci_info->dev->dev); + pci_info->edac_dev->dev_name = pci_info->dev->dev.bus_id; if (edac_op_state == EDAC_OPSTATE_POLL) pci_info->edac_dev->edac_check = pci_info->check; diff --git a/trunk/drivers/edac/amd8131_edac.c b/trunk/drivers/edac/amd8131_edac.c index b432d60c622a..c083b31cac5a 100644 --- a/trunk/drivers/edac/amd8131_edac.c +++ b/trunk/drivers/edac/amd8131_edac.c @@ -287,7 +287,7 @@ static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id) dev_info->edac_dev->dev = &dev_info->dev->dev; dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR; dev_info->edac_dev->ctl_name = dev_info->ctl_name; - dev_info->edac_dev->dev_name = dev_name(&dev_info->dev->dev); + dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id; if (edac_op_state == EDAC_OPSTATE_POLL) dev_info->edac_dev->edac_check = amd8131_chipset.check; diff --git a/trunk/drivers/gpu/drm/Kconfig b/trunk/drivers/gpu/drm/Kconfig index f5d46e7199d4..4cd35d8fd799 100644 --- a/trunk/drivers/gpu/drm/Kconfig +++ b/trunk/drivers/gpu/drm/Kconfig @@ -67,18 +67,12 @@ config DRM_I830 will load the correct one. config DRM_I915 - tristate "i915 driver" select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB select FRAMEBUFFER_CONSOLE if !EMBEDDED - # i915 depends on ACPI_VIDEO when ACPI is enabled - # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI - select BACKLIGHT_CLASS_DEVICE if ACPI - select INPUT if ACPI - select ACPI_VIDEO if ACPI + tristate "i915 driver" help Choose this option if you have a system that has Intel 830M, 845G, 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the @@ -90,6 +84,12 @@ config DRM_I915 config DRM_I915_KMS bool "Enable modesetting on intel by default" depends on DRM_I915 + # i915 KMS depends on ACPI_VIDEO when ACPI is enabled + # but for select to work, need to select ACPI_VIDEO's dependencies, ick + select VIDEO_OUTPUT_CONTROL if ACPI + select BACKLIGHT_CLASS_DEVICE if ACPI + select INPUT if ACPI + select ACPI_VIDEO if ACPI help Choose this option if you want kernel modesetting enabled by default, and you have a new enough userspace to support this. Running old diff --git a/trunk/drivers/gpu/drm/drm_crtc.c b/trunk/drivers/gpu/drm/drm_crtc.c index 8fab7890a363..94a768871734 100644 --- a/trunk/drivers/gpu/drm/drm_crtc.c +++ b/trunk/drivers/gpu/drm/drm_crtc.c @@ -2294,12 +2294,7 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev, } } - /* Do DPMS ourselves */ - if (property == connector->dev->mode_config.dpms_property) { - if (connector->funcs->dpms) - (*connector->funcs->dpms)(connector, (int) out_resp->value); - ret = 0; - } else if (connector->funcs->set_property) + if (connector->funcs->set_property) ret = connector->funcs->set_property(connector, property, out_resp->value); /* store the property value if succesful */ diff --git a/trunk/drivers/gpu/drm/drm_crtc_helper.c b/trunk/drivers/gpu/drm/drm_crtc_helper.c index a6f73f1e99d9..45890447feec 100644 --- a/trunk/drivers/gpu/drm/drm_crtc_helper.c +++ b/trunk/drivers/gpu/drm/drm_crtc_helper.c @@ -198,29 +198,6 @@ static void drm_helper_add_std_modes(struct drm_device *dev, } } -/** - * drm_helper_encoder_in_use - check if a given encoder is in use - * @encoder: encoder to check - * - * LOCKING: - * Caller must hold mode config lock. - * - * Walk @encoders's DRM device's mode_config and see if it's in use. - * - * RETURNS: - * True if @encoder is part of the mode_config, false otherwise. - */ -bool drm_helper_encoder_in_use(struct drm_encoder *encoder) -{ - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - return true; - return false; -} -EXPORT_SYMBOL(drm_helper_encoder_in_use); - /** * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config * @crtc: CRTC to check @@ -239,7 +216,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; /* FIXME: Locking around list access? */ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) - if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder)) + if (encoder->crtc == crtc) return true; return false; } @@ -263,7 +240,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { encoder_funcs = encoder->helper_private; - if (!drm_helper_encoder_in_use(encoder)) + if (!encoder->crtc) (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF); } @@ -958,88 +935,6 @@ bool drm_helper_initial_config(struct drm_device *dev) } EXPORT_SYMBOL(drm_helper_initial_config); -static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder) -{ - int dpms = DRM_MODE_DPMS_OFF; - struct drm_connector *connector; - struct drm_device *dev = encoder->dev; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder == encoder) - if (connector->dpms < dpms) - dpms = connector->dpms; - return dpms; -} - -static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc) -{ - int dpms = DRM_MODE_DPMS_OFF; - struct drm_connector *connector; - struct drm_device *dev = crtc->dev; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - if (connector->encoder && connector->encoder->crtc == crtc) - if (connector->dpms < dpms) - dpms = connector->dpms; - return dpms; -} - -/** - * drm_helper_connector_dpms - * @connector affected connector - * @mode DPMS mode - * - * Calls the low-level connector DPMS function, then - * calls appropriate encoder and crtc DPMS functions as well - */ -void drm_helper_connector_dpms(struct drm_connector *connector, int mode) -{ - struct drm_encoder *encoder = connector->encoder; - struct drm_crtc *crtc = encoder ? encoder->crtc : NULL; - int old_dpms; - - if (mode == connector->dpms) - return; - - old_dpms = connector->dpms; - connector->dpms = mode; - - /* from off to on, do crtc then encoder */ - if (mode < old_dpms) { - if (crtc) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (crtc_funcs->dpms) - (*crtc_funcs->dpms) (crtc, - drm_helper_choose_crtc_dpms(crtc)); - } - if (encoder) { - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - if (encoder_funcs->dpms) - (*encoder_funcs->dpms) (encoder, - drm_helper_choose_encoder_dpms(encoder)); - } - } - - /* from on to off, do encoder then crtc */ - if (mode > old_dpms) { - if (encoder) { - struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private; - if (encoder_funcs->dpms) - (*encoder_funcs->dpms) (encoder, - drm_helper_choose_encoder_dpms(encoder)); - } - if (crtc) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - if (crtc_funcs->dpms) - (*crtc_funcs->dpms) (crtc, - drm_helper_choose_crtc_dpms(crtc)); - } - } - - return; -} -EXPORT_SYMBOL(drm_helper_connector_dpms); - /** * drm_hotplug_stage_two * @dev DRM device diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 6f6b26479d82..ca9c61656714 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -289,11 +289,6 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, struct drm_display_mode *mode; struct detailed_pixel_timing *pt = &timing->data.pixel_data; - /* ignore tiny modes */ - if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 || - ((pt->vactive_hi << 8) | pt->hactive_lo) < 64) - return NULL; - if (pt->stereo) { printk(KERN_WARNING "stereo mode not supported\n"); return NULL; diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index fc8e5acd9d9a..93e677a481f5 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -196,7 +196,6 @@ int drm_irq_install(struct drm_device *dev) { int ret = 0; unsigned long sh_flags = 0; - char *irqname; if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) return -EINVAL; @@ -228,13 +227,8 @@ int drm_irq_install(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) sh_flags = IRQF_SHARED; - if (dev->devname) - irqname = dev->devname; - else - irqname = dev->driver->name; - ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler, - sh_flags, irqname, dev); + sh_flags, dev->devname, dev); if (ret < 0) { mutex_lock(&dev->struct_mutex); diff --git a/trunk/drivers/gpu/drm/drm_sysfs.c b/trunk/drivers/gpu/drm/drm_sysfs.c index 9987ab880835..8f9372921f82 100644 --- a/trunk/drivers/gpu/drm/drm_sysfs.c +++ b/trunk/drivers/gpu/drm/drm_sysfs.c @@ -147,7 +147,7 @@ static ssize_t status_show(struct device *device, enum drm_connector_status status; status = connector->funcs->detect(connector); - return snprintf(buf, PAGE_SIZE, "%s\n", + return snprintf(buf, PAGE_SIZE, "%s", drm_get_connector_status_name(status)); } @@ -166,7 +166,7 @@ static ssize_t dpms_show(struct device *device, if (ret) return 0; - return snprintf(buf, PAGE_SIZE, "%s\n", + return snprintf(buf, PAGE_SIZE, "%s", drm_get_dpms_name((int)dpms_status)); } @@ -176,7 +176,7 @@ static ssize_t enabled_show(struct device *device, { struct drm_connector *connector = to_drm_connector(device); - return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" : + return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" : "disabled"); } @@ -317,7 +317,6 @@ static struct device_attribute connector_attrs_opt1[] = { static struct bin_attribute edid_attr = { .attr.name = "edid", - .attr.mode = 0444, .size = 128, .read = edid_show, }; diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 0ccb63ee50ee..53d544552625 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -987,6 +987,12 @@ static int i915_load_modeset_init(struct drm_device *dev) int fb_bar = IS_I9XX(dev) ? 2 : 0; int ret = 0; + dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL); + if (!dev->devname) { + ret = -ENOMEM; + goto out; + } + dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) & 0xff000000; @@ -1000,7 +1006,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ret = i915_probe_agp(dev, &agp_size, &prealloc_size); if (ret) - goto out; + goto kfree_devname; /* Basic memrange allocator for stolen space (aka vram) */ drm_mm_init(&dev_priv->vram, 0, prealloc_size); @@ -1018,7 +1024,7 @@ static int i915_load_modeset_init(struct drm_device *dev) ret = i915_gem_init_ringbuffer(dev); if (ret) - goto out; + goto kfree_devname; /* Allow hardware batchbuffers unless told otherwise. */ @@ -1050,6 +1056,8 @@ static int i915_load_modeset_init(struct drm_device *dev) destroy_ringbuffer: i915_gem_cleanup_ringbuffer(dev); +kfree_devname: + kfree(dev->devname); out: return ret; } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 39f5c658ef5e..717b6a854bcd 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -1145,13 +1145,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) mutex_unlock(&dev->struct_mutex); return VM_FAULT_SIGBUS; } - - ret = i915_gem_object_set_to_gtt_domain(obj, write); - if (ret) { - mutex_unlock(&dev->struct_mutex); - return VM_FAULT_SIGBUS; - } - list_add_tail(&obj_priv->list, &dev_priv->mm.inactive_list); } @@ -2135,10 +2128,8 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) return; } - pitch_val = obj_priv->stride / 128; - pitch_val = ffs(pitch_val) - 1; - WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); - + pitch_val = (obj_priv->stride / 128) - 1; + WARN_ON(pitch_val & ~0x0000000f); val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; @@ -2260,6 +2251,9 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, bool write) goto try_again; } + BUG_ON(old_obj_priv->active || + (reg->obj->write_domain & I915_GEM_GPU_DOMAINS)); + /* * Zap this virtual mapping so we can set up a fence again * for this object next time we need it. @@ -2427,16 +2421,6 @@ i915_gem_clflush_object(struct drm_gem_object *obj) if (obj_priv->pages == NULL) return; - /* XXX: The 865 in particular appears to be weird in how it handles - * cache flushing. We haven't figured it out, but the - * clflush+agp_chipset_flush doesn't appear to successfully get the - * data visible to the PGU, while wbinvd + agp_chipset_flush does. - */ - if (IS_I865G(obj->dev)) { - wbinvd(); - return; - } - drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); } diff --git a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c index 540dd336e6ec..52a059354e83 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -213,8 +213,7 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) if (tiling_mode == I915_TILING_NONE) return true; - if (!IS_I9XX(dev) || - (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + if (tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) tile_width = 128; else tile_width = 512; @@ -226,18 +225,11 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) if (stride / 128 > I965_FENCE_MAX_PITCH_VAL) return false; } else if (IS_I9XX(dev)) { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - - /* XXX: For Y tiling, FENCE_MAX_PITCH_VAL is actually 6 (8KB) - * instead of 4 (2KB) on 945s. - */ - if (pitch_val > I915_FENCE_MAX_PITCH_VAL || + if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL || size > (I830_FENCE_MAX_SIZE_VAL << 20)) return false; } else { - uint32_t pitch_val = ffs(stride / tile_width) - 1; - - if (pitch_val > I830_FENCE_MAX_PITCH_VAL || + if (stride / 128 > I830_FENCE_MAX_PITCH_VAL || size > (I830_FENCE_MAX_SIZE_VAL << 19)) return false; } diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index 375569d01d01..9668cc0d7f4e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -190,8 +190,7 @@ #define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8) #define I830_FENCE_PITCH_SHIFT 4 #define I830_FENCE_REG_VALID (1<<0) -#define I915_FENCE_MAX_PITCH_VAL 0x10 -#define I830_FENCE_MAX_PITCH_VAL 6 +#define I830_FENCE_MAX_PITCH_VAL 0x10 #define I830_FENCE_MAX_SIZE_VAL (1<<8) #define I915_FENCE_START_MASK 0x0ff00000 diff --git a/trunk/drivers/gpu/drm/i915/intel_crt.c b/trunk/drivers/gpu/drm/i915/intel_crt.c index 79acc4f4c1f8..640f5158effc 100644 --- a/trunk/drivers/gpu/drm/i915/intel_crt.c +++ b/trunk/drivers/gpu/drm/i915/intel_crt.c @@ -381,6 +381,11 @@ static int intel_crt_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { + struct drm_device *dev = connector->dev; + + if (property == dev->mode_config.dpms_property && connector->encoder) + intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf)); + return 0; } @@ -397,7 +402,6 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { }; static const struct drm_connector_funcs intel_crt_connector_funcs = { - .dpms = drm_helper_connector_dpms, .detect = intel_crt_detect, .fill_modes = drm_helper_probe_single_connector_modes, .destroy = intel_crt_destroy, diff --git a/trunk/drivers/gpu/drm/i915/intel_dvo.c b/trunk/drivers/gpu/drm/i915/intel_dvo.c index 1ee3007d6ec0..8b8d6e65cd3f 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_dvo.c @@ -316,7 +316,6 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = { }; static const struct drm_connector_funcs intel_dvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, .save = intel_dvo_save, .restore = intel_dvo_restore, .detect = intel_dvo_detect, diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 7d6bdd705326..d0983bb93a18 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -219,7 +219,6 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = { }; static const struct drm_connector_funcs intel_hdmi_connector_funcs = { - .dpms = drm_helper_connector_dpms, .save = intel_hdmi_save, .restore = intel_hdmi_restore, .detect = intel_hdmi_detect, diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 53cccfa58b95..53731f0ffcb5 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -343,6 +343,11 @@ static int intel_lvds_set_property(struct drm_connector *connector, struct drm_property *property, uint64_t value) { + struct drm_device *dev = connector->dev; + + if (property == dev->mode_config.dpms_property && connector->encoder) + intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf)); + return 0; } @@ -361,7 +366,6 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs }; static const struct drm_connector_funcs intel_lvds_connector_funcs = { - .dpms = drm_helper_connector_dpms, .save = intel_lvds_save, .restore = intel_lvds_restore, .detect = intel_lvds_detect, @@ -387,7 +391,7 @@ static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id) } /* These systems claim to have LVDS, but really don't */ -static const struct dmi_system_id intel_no_lvds[] = { +static const struct dmi_system_id __initdata intel_no_lvds[] = { { .callback = intel_no_lvds_dmi_callback, .ident = "Apple Mac Mini (Core series)", diff --git a/trunk/drivers/gpu/drm/i915/intel_sdvo.c b/trunk/drivers/gpu/drm/i915/intel_sdvo.c index 3093b4d4a4dd..f3ef6bfd8ffc 100644 --- a/trunk/drivers/gpu/drm/i915/intel_sdvo.c +++ b/trunk/drivers/gpu/drm/i915/intel_sdvo.c @@ -1616,7 +1616,6 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { }; static const struct drm_connector_funcs intel_sdvo_connector_funcs = { - .dpms = drm_helper_connector_dpms, .save = intel_sdvo_save, .restore = intel_sdvo_restore, .detect = intel_sdvo_detect, diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 98ac0546b7bd..d2c32983242d 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1626,7 +1626,6 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = { }; static const struct drm_connector_funcs intel_tv_connector_funcs = { - .dpms = drm_helper_connector_dpms, .save = intel_tv_save, .restore = intel_tv_restore, .detect = intel_tv_detect, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_cp.c b/trunk/drivers/gpu/drm/radeon/radeon_cp.c index aff90bb96488..77a7a4d84650 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_cp.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_cp.c @@ -2185,9 +2185,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv) /* check if the ring is padded out to 16-dword alignment */ - tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1); + tail_aligned = dev_priv->ring.tail & 0xf; if (tail_aligned) { - int num_p2 = RADEON_RING_ALIGN - tail_aligned; + int num_p2 = 16 - tail_aligned; ring = dev_priv->ring.start; /* pad with some CP_PACKET2 */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.h b/trunk/drivers/gpu/drm/radeon/radeon_drv.h index 0c6bfc1de153..8071d965f142 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.h @@ -1964,14 +1964,11 @@ do { \ #define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring; -#define RADEON_RING_ALIGN 16 - #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \ } \ - _align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1)); \ - _align_nr += n; \ + _align_nr = (n + 0xf) & ~0xf; \ if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \ COMMIT_RING(); \ radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \ diff --git a/trunk/drivers/hwmon/lm78.c b/trunk/drivers/hwmon/lm78.c index a1787fdf5b9f..b5e3b2851698 100644 --- a/trunk/drivers/hwmon/lm78.c +++ b/trunk/drivers/hwmon/lm78.c @@ -182,7 +182,7 @@ static struct platform_driver lm78_isa_driver = { .name = "lm78", }, .probe = lm78_isa_probe, - .remove = __devexit_p(lm78_isa_remove), + .remove = lm78_isa_remove, }; diff --git a/trunk/drivers/ide/ide-pci-generic.c b/trunk/drivers/ide/ide-pci-generic.c index 39d4e01f5c9c..61111fd27130 100644 --- a/trunk/drivers/ide/ide-pci-generic.c +++ b/trunk/drivers/ide/ide-pci-generic.c @@ -33,16 +33,6 @@ static int ide_generic_all; /* Set to claim all devices */ module_param_named(all_generic_ide, ide_generic_all, bool, 0444); MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); -static void netcell_quirkproc(ide_drive_t *drive) -{ - /* mark words 85-87 as valid */ - drive->id[ATA_ID_CSF_DEFAULT] |= 0x4000; -} - -static const struct ide_port_ops netcell_port_ops = { - .quirkproc = netcell_quirkproc, -}; - #define DECLARE_GENERIC_PCI_DEV(extra_flags) \ { \ .name = DRV_NAME, \ @@ -84,7 +74,6 @@ static const struct ide_port_info generic_chipsets[] __devinitdata = { { /* 6: Revolution */ .name = DRV_NAME, - .port_ops = &netcell_port_ops, .host_flags = IDE_HFLAG_CLEAR_SIMPLEX | IDE_HFLAG_TRUST_BIOS_FOR_DMA | IDE_HFLAG_OFF_BOARD, diff --git a/trunk/drivers/ide/pdc202xx_old.c b/trunk/drivers/ide/pdc202xx_old.c index b3bc96f930a6..248a54bd2386 100644 --- a/trunk/drivers/ide/pdc202xx_old.c +++ b/trunk/drivers/ide/pdc202xx_old.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1998-2002 Andre Hedrick - * Copyright (C) 2006-2007, 2009 MontaVista Software, Inc. + * Copyright (C) 2006-2007 MontaVista Software, Inc. * Copyright (C) 2007 Bartlomiej Zolnierkiewicz * * Portions Copyright (C) 1999 Promise Technology, Inc. @@ -227,19 +227,28 @@ static int pdc202xx_dma_test_irq(ide_drive_t *drive) return (dma_stat & 4) == 4; /* return 1 if INTR asserted */ } -static void pdc202xx_reset(ide_drive_t *drive) +static void pdc202xx_reset_host (ide_hwif_t *hwif) { - ide_hwif_t *hwif = drive->hwif; unsigned long high_16 = hwif->extra_base - 16; u8 udma_speed_flag = inb(high_16 | 0x001f); - printk(KERN_WARNING "PDC202xx: software reset...\n"); - outb(udma_speed_flag | 0x10, high_16 | 0x001f); mdelay(100); outb(udma_speed_flag & ~0x10, high_16 | 0x001f); mdelay(2000); /* 2 seconds ?! */ + printk(KERN_WARNING "PDC202XX: %s channel reset.\n", + hwif->channel ? "Secondary" : "Primary"); +} + +static void pdc202xx_reset (ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + ide_hwif_t *mate = hwif->mate; + + pdc202xx_reset_host(hwif); + pdc202xx_reset_host(mate); + ide_set_max_pio(drive); } @@ -319,8 +328,9 @@ static const struct ide_dma_ops pdc20246_dma_ops = { .dma_start = ide_dma_start, .dma_end = ide_dma_end, .dma_test_irq = pdc202xx_dma_test_irq, - .dma_lost_irq = ide_dma_lost_irq, + .dma_lost_irq = pdc202xx_dma_lost_irq, .dma_timer_expiry = ide_dma_sff_timer_expiry, + .dma_clear = pdc202xx_reset, .dma_sff_read_status = ide_dma_sff_read_status, }; diff --git a/trunk/drivers/idle/i7300_idle.c b/trunk/drivers/idle/i7300_idle.c index 949c97ff57e3..bf740394d704 100644 --- a/trunk/drivers/idle/i7300_idle.c +++ b/trunk/drivers/idle/i7300_idle.c @@ -41,10 +41,6 @@ static int debug; module_param_named(debug, debug, uint, 0644); MODULE_PARM_DESC(debug, "Enable debug printks in this driver"); -static int forceload; -module_param_named(forceload, forceload, uint, 0644); -MODULE_PARM_DESC(debug, "Enable driver testing on unvalidated i5000"); - #define dprintk(fmt, arg...) \ do { if (debug) printk(KERN_INFO I7300_PRINT fmt, ##arg); } while (0) @@ -556,7 +552,7 @@ static int __init i7300_idle_init(void) cpus_clear(idle_cpumask); total_us = 0; - if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev, forceload)) + if (i7300_idle_platform_probe(&fbd_dev, &ioat_dev)) return -ENODEV; if (i7300_idle_thrt_save()) diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 5d445f48789b..e54e002665b0 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -42,7 +42,6 @@ static unsigned int input_abs_bypass_init_data[] __initdata = { ABS_MT_POSITION_Y, ABS_MT_TOOL_TYPE, ABS_MT_BLOB_ID, - ABS_MT_TRACKING_ID, 0 }; static unsigned long input_abs_bypass[BITS_TO_LONGS(ABS_CNT)]; diff --git a/trunk/drivers/input/serio/libps2.c b/trunk/drivers/input/serio/libps2.c index be5bbbb8ae4e..67248c31e19a 100644 --- a/trunk/drivers/input/serio/libps2.c +++ b/trunk/drivers/input/serio/libps2.c @@ -210,7 +210,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command) timeout = wait_event_timeout(ps2dev->wait, !(ps2dev->flags & PS2_FLAG_CMD1), timeout); - if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) { + if (ps2dev->cmdcnt && timeout > 0) { timeout = ps2_adjust_timeout(ps2dev, command, timeout); wait_event_timeout(ps2dev->wait, diff --git a/trunk/drivers/input/touchscreen/ucb1400_ts.c b/trunk/drivers/input/touchscreen/ucb1400_ts.c index 6954f5500108..f100c7f4c1db 100644 --- a/trunk/drivers/input/touchscreen/ucb1400_ts.c +++ b/trunk/drivers/input/touchscreen/ucb1400_ts.c @@ -419,7 +419,7 @@ static int ucb1400_ts_remove(struct platform_device *dev) #ifdef CONFIG_PM static int ucb1400_ts_resume(struct platform_device *dev) { - struct ucb1400_ts *ucb = dev->dev.platform_data; + struct ucb1400_ts *ucb = platform_get_drvdata(dev); if (ucb->ts_task) { /* diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index bb37fb1b2d82..3c3626d2a1f9 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -362,7 +362,7 @@ static void raid5_unplug_device(struct request_queue *q); static struct stripe_head * get_active_stripe(raid5_conf_t *conf, sector_t sector, - int previous, int noblock, int noquiesce) + int previous, int noblock) { struct stripe_head *sh; @@ -372,7 +372,7 @@ get_active_stripe(raid5_conf_t *conf, sector_t sector, do { wait_event_lock_irq(conf->wait_for_stripe, - conf->quiesce == 0 || noquiesce, + conf->quiesce == 0, conf->device_lock, /* nothing */); sh = __find_stripe(conf, sector, conf->generation - previous); if (!sh) { @@ -2671,7 +2671,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh, sector_t bn = compute_blocknr(sh, i, 1); sector_t s = raid5_compute_sector(conf, bn, 0, &dd_idx, NULL); - sh2 = get_active_stripe(conf, s, 0, 1, 1); + sh2 = get_active_stripe(conf, s, 0, 1); if (sh2 == NULL) /* so far only the early blocks of this stripe * have been requested. When later blocks @@ -2944,7 +2944,7 @@ static bool handle_stripe5(struct stripe_head *sh) /* Finish reconstruct operations initiated by the expansion process */ if (sh->reconstruct_state == reconstruct_state_result) { struct stripe_head *sh2 - = get_active_stripe(conf, sh->sector, 1, 1, 1); + = get_active_stripe(conf, sh->sector, 1, 1); if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { /* sh cannot be written until sh2 has been read. * so arrange for sh to be delayed a little @@ -3189,7 +3189,7 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page) if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) { struct stripe_head *sh2 - = get_active_stripe(conf, sh->sector, 1, 1, 1); + = get_active_stripe(conf, sh->sector, 1, 1); if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) { /* sh cannot be written until sh2 has been read. * so arrange for sh to be delayed a little @@ -3288,7 +3288,7 @@ static void unplug_slaves(mddev_t *mddev) int i; rcu_read_lock(); - for (i = 0; i < conf->raid_disks; i++) { + for (i=0; iraid_disks; i++) { mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); if (rdev && !test_bit(Faulty, &rdev->flags) && atomic_read(&rdev->nr_pending)) { struct request_queue *r_queue = bdev_get_queue(rdev->bdev); @@ -3675,7 +3675,7 @@ static int make_request(struct request_queue *q, struct bio * bi) (unsigned long long)logical_sector); sh = get_active_stripe(conf, new_sector, previous, - (bi->bi_rw&RWA_MASK), 0); + (bi->bi_rw&RWA_MASK)); if (sh) { if (unlikely(previous)) { /* expansion might have moved on while waiting for a @@ -3811,13 +3811,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped safepos = conf->reshape_safe; sector_div(safepos, data_disks); if (mddev->delta_disks < 0) { - writepos -= min_t(sector_t, reshape_sectors, writepos); + writepos -= min(reshape_sectors, writepos); readpos += reshape_sectors; safepos += reshape_sectors; } else { writepos += reshape_sectors; - readpos -= min_t(sector_t, reshape_sectors, readpos); - safepos -= min_t(sector_t, reshape_sectors, safepos); + readpos -= min(reshape_sectors, readpos); + safepos -= min(reshape_sectors, safepos); } /* 'writepos' is the most advanced device address we might write. @@ -3873,7 +3873,7 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) { int j; int skipped = 0; - sh = get_active_stripe(conf, stripe_addr+i, 0, 0, 1); + sh = get_active_stripe(conf, stripe_addr+i, 0, 0); set_bit(STRIPE_EXPANDING, &sh->state); atomic_inc(&conf->reshape_stripes); /* If any of this stripe is beyond the end of the old @@ -3916,13 +3916,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped raid5_compute_sector(conf, stripe_addr*(new_data_disks), 1, &dd_idx, NULL); last_sector = - raid5_compute_sector(conf, ((stripe_addr+reshape_sectors) + raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512) *(new_data_disks) - 1), 1, &dd_idx, NULL); if (last_sector >= mddev->dev_sectors) last_sector = mddev->dev_sectors - 1; while (first_sector <= last_sector) { - sh = get_active_stripe(conf, first_sector, 1, 0, 1); + sh = get_active_stripe(conf, first_sector, 1, 0); set_bit(STRIPE_EXPAND_SOURCE, &sh->state); set_bit(STRIPE_HANDLE, &sh->state); release_stripe(sh); @@ -4022,9 +4022,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski bitmap_cond_end_sync(mddev->bitmap, sector_nr); - sh = get_active_stripe(conf, sector_nr, 0, 1, 0); + sh = get_active_stripe(conf, sector_nr, 0, 1); if (sh == NULL) { - sh = get_active_stripe(conf, sector_nr, 0, 0, 0); + sh = get_active_stripe(conf, sector_nr, 0, 0); /* make sure we don't swamp the stripe cache if someone else * is trying to get access */ @@ -4034,7 +4034,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski * We don't need to check the 'failed' flag as when that gets set, * recovery aborts. */ - for (i = 0; i < conf->raid_disks; i++) + for (i=0; iraid_disks; i++) if (conf->disks[i].rdev == NULL) still_degraded = 1; @@ -4086,7 +4086,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) /* already done this stripe */ continue; - sh = get_active_stripe(conf, sector, 0, 1, 0); + sh = get_active_stripe(conf, sector, 0, 1); if (!sh) { /* failed to get a stripe - must wait */ diff --git a/trunk/drivers/media/video/ivtv/ivtv-queue.c b/trunk/drivers/media/video/ivtv/ivtv-queue.c index 7fde36e6d227..ff7b7deded4f 100644 --- a/trunk/drivers/media/video/ivtv/ivtv-queue.c +++ b/trunk/drivers/media/video/ivtv/ivtv-queue.c @@ -230,8 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s) return -ENOMEM; } if (ivtv_might_use_dma(s)) { - s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, - sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE); + s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma); ivtv_stream_sync_for_cpu(s); } diff --git a/trunk/drivers/mmc/host/mvsdio.c b/trunk/drivers/mmc/host/mvsdio.c index b56d72ff06e9..c643d0fe118f 100644 --- a/trunk/drivers/mmc/host/mvsdio.c +++ b/trunk/drivers/mmc/host/mvsdio.c @@ -64,31 +64,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) unsigned int tmout; int tmout_index; - /* - * Hardware weirdness. The FIFO_EMPTY bit of the HW_STATE - * register is sometimes not set before a while when some - * "unusual" data block sizes are used (such as with the SWITCH - * command), even despite the fact that the XFER_DONE interrupt - * was raised. And if another data transfer starts before - * this bit comes to good sense (which eventually happens by - * itself) then the new transfer simply fails with a timeout. - */ - if (!(mvsd_read(MVSD_HW_STATE) & (1 << 13))) { - unsigned long t = jiffies + HZ; - unsigned int hw_state, count = 0; - do { - if (time_after(jiffies, t)) { - dev_warn(host->dev, "FIFO_EMPTY bit missing\n"); - break; - } - hw_state = mvsd_read(MVSD_HW_STATE); - count++; - } while (!(hw_state & (1 << 13))); - dev_dbg(host->dev, "*** wait for FIFO_EMPTY bit " - "(hw=0x%04x, count=%d, jiffies=%ld)\n", - hw_state, count, jiffies - (t - HZ)); - } - /* If timeout=0 then maximum timeout index is used. */ tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk); tmout += data->timeout_clks; @@ -645,18 +620,9 @@ static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (ios->bus_width == MMC_BUS_WIDTH_4) ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS; - /* - * The HI_SPEED_EN bit is causing trouble with many (but not all) - * high speed SD, SDHC and SDIO cards. Not enabling that bit - * makes all cards work. So let's just ignore that bit for now - * and revisit this issue if problems for not enabling this bit - * are ever reported. - */ -#if 0 if (ios->timing == MMC_TIMING_MMC_HS || ios->timing == MMC_TIMING_SD_HS) ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN; -#endif host->ctrl = ctrl_reg; mvsd_write(MVSD_HOST_CTRL, ctrl_reg); @@ -916,4 +882,3 @@ module_param(nodma, int, 0); MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre"); MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mvsdio"); diff --git a/trunk/drivers/mmc/host/mxcmmc.c b/trunk/drivers/mmc/host/mxcmmc.c index f4cbe473670e..b4a615c55f28 100644 --- a/trunk/drivers/mmc/host/mxcmmc.c +++ b/trunk/drivers/mmc/host/mxcmmc.c @@ -140,8 +140,6 @@ struct mxcmci_host { struct work_struct datawork; }; -static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); - static inline int mxcmci_use_dma(struct mxcmci_host *host) { return host->do_dma; @@ -162,7 +160,7 @@ static void mxcmci_softreset(struct mxcmci_host *host) writew(0xff, host->base + MMC_REG_RES_TO); } -static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) +static void mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) { unsigned int nob = data->blocks; unsigned int blksz = data->blksz; @@ -170,7 +168,6 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) #ifdef HAS_DMA struct scatterlist *sg; int i; - int ret; #endif if (data->flags & MMC_DATA_STREAM) nob = 0xffff; @@ -186,7 +183,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) for_each_sg(data->sg, sg, data->sg_len, i) { if (sg->offset & 3 || sg->length & 3) { host->do_dma = 0; - return 0; + return; } } @@ -195,30 +192,23 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); - ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, - datasize, - host->res->start + MMC_REG_BUFFER_ACCESS, - DMA_MODE_READ); + imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, + host->res->start + MMC_REG_BUFFER_ACCESS, + DMA_MODE_READ); } else { host->dma_dir = DMA_TO_DEVICE; host->dma_nents = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir); - ret = imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, - datasize, - host->res->start + MMC_REG_BUFFER_ACCESS, - DMA_MODE_WRITE); + imx_dma_setup_sg(host->dma, data->sg, host->dma_nents, datasize, + host->res->start + MMC_REG_BUFFER_ACCESS, + DMA_MODE_WRITE); } - if (ret) { - dev_err(mmc_dev(host->mmc), "failed to setup DMA : %d\n", ret); - return ret; - } wmb(); imx_dma_enable(host->dma); #endif /* HAS_DMA */ - return 0; } static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, @@ -355,11 +345,8 @@ static int mxcmci_poll_status(struct mxcmci_host *host, u32 mask) stat = readl(host->base + MMC_REG_STATUS); if (stat & STATUS_ERR_MASK) return stat; - if (time_after(jiffies, timeout)) { - mxcmci_softreset(host); - mxcmci_set_clk_rate(host, host->clock); + if (time_after(jiffies, timeout)) return STATUS_TIME_OUT_READ; - } if (stat & mask) return 0; cpu_relax(); @@ -544,7 +531,6 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) { struct mxcmci_host *host = mmc_priv(mmc); unsigned int cmdat = host->cmdat; - int error; WARN_ON(host->req != NULL); @@ -554,12 +540,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) host->do_dma = 1; #endif if (req->data) { - error = mxcmci_setup_data(host, req->data); - if (error) { - req->cmd->error = error; - goto out; - } - + mxcmci_setup_data(host, req->data); cmdat |= CMD_DAT_CONT_DATA_ENABLE; @@ -567,9 +548,7 @@ static void mxcmci_request(struct mmc_host *mmc, struct mmc_request *req) cmdat |= CMD_DAT_CONT_WRITE; } - error = mxcmci_start_cmd(host, req->cmd, cmdat); -out: - if (error) + if (mxcmci_start_cmd(host, req->cmd, cmdat)) mxcmci_finish_request(host, req); } @@ -745,9 +724,7 @@ static int mxcmci_probe(struct platform_device *pdev) goto out_clk_put; } - mmc->f_min = clk_get_rate(host->clk) >> 16; - if (mmc->f_min < 400000) - mmc->f_min = 400000; + mmc->f_min = clk_get_rate(host->clk) >> 7; mmc->f_max = clk_get_rate(host->clk) >> 1; /* recommended in data sheet */ diff --git a/trunk/drivers/mmc/host/omap.c b/trunk/drivers/mmc/host/omap.c index dceb5ee3bda0..bfa25c01c872 100644 --- a/trunk/drivers/mmc/host/omap.c +++ b/trunk/drivers/mmc/host/omap.c @@ -822,7 +822,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id) del_timer(&host->cmd_abort_timer); host->abort = 1; OMAP_MMC_WRITE(host, IE, 0); - disable_irq_nosync(host->irq); + disable_irq(host->irq); schedule_work(&host->cmd_abort_work); return IRQ_HANDLED; } diff --git a/trunk/drivers/mmc/host/omap_hsmmc.c b/trunk/drivers/mmc/host/omap_hsmmc.c index c40cb96255a2..e62a22a7f00c 100644 --- a/trunk/drivers/mmc/host/omap_hsmmc.c +++ b/trunk/drivers/mmc/host/omap_hsmmc.c @@ -680,7 +680,7 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data) host->dma_ch = -1; /* * DMA Callback: run in interrupt context. - * mutex_unlock will throw a kernel warning if used. + * mutex_unlock will through a kernel warning if used. */ up(&host->sem); } diff --git a/trunk/drivers/mmc/host/sdhci-of.c b/trunk/drivers/mmc/host/sdhci-of.c index 128c614d11aa..3ff4ac3abe8b 100644 --- a/trunk/drivers/mmc/host/sdhci-of.c +++ b/trunk/drivers/mmc/host/sdhci-of.c @@ -55,13 +55,7 @@ static u32 esdhc_readl(struct sdhci_host *host, int reg) static u16 esdhc_readw(struct sdhci_host *host, int reg) { - u16 ret; - - if (unlikely(reg == SDHCI_HOST_VERSION)) - ret = in_be16(host->ioaddr + reg); - else - ret = in_be16(host->ioaddr + (reg ^ 0x2)); - return ret; + return in_be16(host->ioaddr + (reg ^ 0x2)); } static u8 esdhc_readb(struct sdhci_host *host, int reg) @@ -283,7 +277,6 @@ static int __devexit sdhci_of_remove(struct of_device *ofdev) static const struct of_device_id sdhci_of_match[] = { { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, }, { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, }, - { .compatible = "fsl,esdhc", .data = &sdhci_esdhc, }, { .compatible = "generic-sdhci", }, {}, }; diff --git a/trunk/drivers/mtd/nand/davinci_nand.c b/trunk/drivers/mtd/nand/davinci_nand.c index 02700f769b8a..0119220de7d0 100644 --- a/trunk/drivers/mtd/nand/davinci_nand.c +++ b/trunk/drivers/mtd/nand/davinci_nand.c @@ -407,17 +407,16 @@ static int __init nand_davinci_probe(struct platform_device *pdev) } info->chip.ecc.mode = ecc_mode; - info->clk = clk_get(&pdev->dev, "aemif"); + info->clk = clk_get(&pdev->dev, "AEMIFCLK"); if (IS_ERR(info->clk)) { ret = PTR_ERR(info->clk); - dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); + dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret); goto err_clk; } ret = clk_enable(info->clk); if (ret < 0) { - dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", - ret); + dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret); goto err_clk_enable; } diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index 40c26080ecda..f3548d048014 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -831,7 +831,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, break; case NAND_CMD_READID: - host->col_addr = 0; send_read_id(host); break; @@ -868,7 +867,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) mtd->priv = this; mtd->owner = THIS_MODULE; mtd->dev.parent = &pdev->dev; - mtd->name = "mxc_nand"; /* 50 us command delay time */ this->chip_delay = 5; @@ -884,10 +882,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->verify_buf = mxc_nand_verify_buf; host->clk = clk_get(&pdev->dev, "nfc"); - if (IS_ERR(host->clk)) { - err = PTR_ERR(host->clk); + if (IS_ERR(host->clk)) goto eclk; - } clk_enable(host->clk); host->clk_act = 1; @@ -900,7 +896,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->regs = ioremap(res->start, res->end - res->start + 1); if (!host->regs) { - err = -ENOMEM; + err = -EIO; goto eres; } @@ -1015,35 +1011,30 @@ static int __devexit mxcnd_remove(struct platform_device *pdev) #ifdef CONFIG_PM static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state) { - struct mtd_info *mtd = platform_get_drvdata(pdev); - struct nand_chip *nand_chip = mtd->priv; - struct mxc_nand_host *host = nand_chip->priv; + struct mtd_info *info = platform_get_drvdata(pdev); int ret = 0; DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND suspend\n"); - if (mtd) { - ret = mtd->suspend(mtd); - /* Disable the NFC clock */ - clk_disable(host->clk); - } + if (info) + ret = info->suspend(info); + + /* Disable the NFC clock */ + clk_disable(nfc_clk); /* FIXME */ return ret; } static int mxcnd_resume(struct platform_device *pdev) { - struct mtd_info *mtd = platform_get_drvdata(pdev); - struct nand_chip *nand_chip = mtd->priv; - struct mxc_nand_host *host = nand_chip->priv; + struct mtd_info *info = platform_get_drvdata(pdev); int ret = 0; DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND : NAND resume\n"); + /* Enable the NFC clock */ + clk_enable(nfc_clk); /* FIXME */ - if (mtd) { - /* Enable the NFC clock */ - clk_enable(host->clk); - mtd->resume(mtd); - } + if (info) + info->resume(info); return ret; } @@ -1064,7 +1055,13 @@ static struct platform_driver mxcnd_driver = { static int __init mxc_nd_init(void) { - return platform_driver_probe(&mxcnd_driver, mxcnd_probe); + /* Register the device driver structure. */ + pr_info("MXC MTD nand Driver\n"); + if (platform_driver_probe(&mxcnd_driver, mxcnd_probe) != 0) { + printk(KERN_ERR "Driver register failed for mxcnd_driver\n"); + return -ENODEV; + } + return 0; } static void __exit mxc_nd_cleanup(void) diff --git a/trunk/drivers/net/3c509.c b/trunk/drivers/net/3c509.c index 682aad897081..fbb371921991 100644 --- a/trunk/drivers/net/3c509.c +++ b/trunk/drivers/net/3c509.c @@ -480,13 +480,9 @@ static int pnp_registered; #ifdef CONFIG_EISA static struct eisa_device_id el3_eisa_ids[] = { - { "TCM5090" }, - { "TCM5091" }, { "TCM5092" }, { "TCM5093" }, - { "TCM5094" }, { "TCM5095" }, - { "TCM5098" }, { "" } }; MODULE_DEVICE_TABLE(eisa, el3_eisa_ids); diff --git a/trunk/drivers/net/atl1e/atl1e_main.c b/trunk/drivers/net/atl1e/atl1e_main.c index 1342418fb209..fb57b750866b 100644 --- a/trunk/drivers/net/atl1e/atl1e_main.c +++ b/trunk/drivers/net/atl1e/atl1e_main.c @@ -37,7 +37,6 @@ char atl1e_driver_version[] = DRV_VERSION; */ static struct pci_device_id atl1e_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)}, - {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)}, /* required last entry */ { 0 } }; diff --git a/trunk/drivers/net/atlx/atl1.c b/trunk/drivers/net/atlx/atl1.c index 4e817126e280..0ab22540bf59 100644 --- a/trunk/drivers/net/atlx/atl1.c +++ b/trunk/drivers/net/atlx/atl1.c @@ -82,12 +82,6 @@ #include "atl1.h" -#define ATLX_DRIVER_VERSION "2.1.3" -MODULE_AUTHOR("Xiong Huang , \ - Chris Snook , Jay Cliburn "); -MODULE_LICENSE("GPL"); -MODULE_VERSION(ATLX_DRIVER_VERSION); - /* Temporary hack for merging atl1 and atl2 */ #include "atlx.c" diff --git a/trunk/drivers/net/atlx/atlx.h b/trunk/drivers/net/atlx/atlx.h index 14054b75aa62..297a03da6b7f 100644 --- a/trunk/drivers/net/atlx/atlx.h +++ b/trunk/drivers/net/atlx/atlx.h @@ -29,6 +29,12 @@ #include #include +#define ATLX_DRIVER_VERSION "2.1.3" +MODULE_AUTHOR("Xiong Huang , \ + Chris Snook , Jay Cliburn "); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ATLX_DRIVER_VERSION); + #define ATLX_ERR_PHY 2 #define ATLX_ERR_PHY_SPEED 7 #define ATLX_ERR_PHY_RES 8 diff --git a/trunk/drivers/net/bfin_mac.c b/trunk/drivers/net/bfin_mac.c index b4da18213324..9f971ed6b58d 100644 --- a/trunk/drivers/net/bfin_mac.c +++ b/trunk/drivers/net/bfin_mac.c @@ -979,7 +979,22 @@ static int bfin_mac_open(struct net_device *dev) return 0; } +static const struct net_device_ops bfin_mac_netdev_ops = { + .ndo_open = bfin_mac_open, + .ndo_stop = bfin_mac_close, + .ndo_start_xmit = bfin_mac_hard_start_xmit, + .ndo_set_mac_address = bfin_mac_set_mac_address, + .ndo_tx_timeout = bfin_mac_timeout, + .ndo_set_multicast_list = bfin_mac_set_multicast_list, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = bfin_mac_poll, +#endif +}; + /* + * * this makes the board clean up everything that it can * and not talk to the outside world. Caused by * an 'ifconfig ethX down' @@ -1004,20 +1019,6 @@ static int bfin_mac_close(struct net_device *dev) return 0; } -static const struct net_device_ops bfin_mac_netdev_ops = { - .ndo_open = bfin_mac_open, - .ndo_stop = bfin_mac_close, - .ndo_start_xmit = bfin_mac_hard_start_xmit, - .ndo_set_mac_address = bfin_mac_set_mac_address, - .ndo_tx_timeout = bfin_mac_timeout, - .ndo_set_multicast_list = bfin_mac_set_multicast_list, - .ndo_validate_addr = eth_validate_addr, - .ndo_change_mtu = eth_change_mtu, -#ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = bfin_mac_poll, -#endif -}; - static int __devinit bfin_mac_probe(struct platform_device *pdev) { struct net_device *ndev; diff --git a/trunk/drivers/net/cxgb3/adapter.h b/trunk/drivers/net/cxgb3/adapter.h index c888e97c9671..714df2b675e6 100644 --- a/trunk/drivers/net/cxgb3/adapter.h +++ b/trunk/drivers/net/cxgb3/adapter.h @@ -85,8 +85,8 @@ struct fl_pg_chunk { struct page *page; void *va; unsigned int offset; - unsigned long *p_cnt; - dma_addr_t mapping; + u64 *p_cnt; + DECLARE_PCI_UNMAP_ADDR(mapping); }; struct rx_desc; diff --git a/trunk/drivers/net/cxgb3/cxgb3_main.c b/trunk/drivers/net/cxgb3/cxgb3_main.c index 17858b9a5830..7ea48414c6cb 100644 --- a/trunk/drivers/net/cxgb3/cxgb3_main.c +++ b/trunk/drivers/net/cxgb3/cxgb3_main.c @@ -2496,16 +2496,14 @@ static void check_link_status(struct adapter *adapter) for_each_port(adapter, i) { struct net_device *dev = adapter->port[i]; struct port_info *p = netdev_priv(dev); - int link_fault; spin_lock_irq(&adapter->work_lock); - link_fault = p->link_fault; - spin_unlock_irq(&adapter->work_lock); - - if (link_fault) { + if (p->link_fault) { t3_link_fault(adapter, i); + spin_unlock_irq(&adapter->work_lock); continue; } + spin_unlock_irq(&adapter->work_lock); if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) { t3_xgm_intr_disable(adapter, i); diff --git a/trunk/drivers/net/cxgb3/sge.c b/trunk/drivers/net/cxgb3/sge.c index b3ee2bc1a005..26d3587f3399 100644 --- a/trunk/drivers/net/cxgb3/sge.c +++ b/trunk/drivers/net/cxgb3/sge.c @@ -355,7 +355,7 @@ static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q, (*d->pg_chunk.p_cnt)--; if (!*d->pg_chunk.p_cnt) pci_unmap_page(pdev, - d->pg_chunk.mapping, + pci_unmap_addr(&d->pg_chunk, mapping), q->alloc_size, PCI_DMA_FROMDEVICE); put_page(d->pg_chunk.page); @@ -454,7 +454,7 @@ static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q, q->pg_chunk.offset = 0; mapping = pci_map_page(adapter->pdev, q->pg_chunk.page, 0, q->alloc_size, PCI_DMA_FROMDEVICE); - q->pg_chunk.mapping = mapping; + pci_unmap_addr_set(&q->pg_chunk, mapping, mapping); } sd->pg_chunk = q->pg_chunk; @@ -511,7 +511,8 @@ static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp) nomem: q->alloc_failed++; break; } - mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset; + mapping = pci_unmap_addr(&sd->pg_chunk, mapping) + + sd->pg_chunk.offset; pci_unmap_addr_set(sd, dma_addr, mapping); add_one_rx_chunk(mapping, d, q->gen); @@ -880,7 +881,7 @@ static struct sk_buff *get_packet_pg(struct adapter *adap, struct sge_fl *fl, (*sd->pg_chunk.p_cnt)--; if (!*sd->pg_chunk.p_cnt) pci_unmap_page(adap->pdev, - sd->pg_chunk.mapping, + pci_unmap_addr(&sd->pg_chunk, mapping), fl->alloc_size, PCI_DMA_FROMDEVICE); if (!skb) { @@ -2095,7 +2096,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs, (*sd->pg_chunk.p_cnt)--; if (!*sd->pg_chunk.p_cnt) pci_unmap_page(adap->pdev, - sd->pg_chunk.mapping, + pci_unmap_addr(&sd->pg_chunk, mapping), fl->alloc_size, PCI_DMA_FROMDEVICE); diff --git a/trunk/drivers/net/cxgb3/t3_hw.c b/trunk/drivers/net/cxgb3/t3_hw.c index 4950d5d789ae..4f68aeb2679a 100644 --- a/trunk/drivers/net/cxgb3/t3_hw.c +++ b/trunk/drivers/net/cxgb3/t3_hw.c @@ -1274,11 +1274,6 @@ void t3_link_fault(struct adapter *adapter, int port_id) A_XGM_INT_STATUS + mac->offset); link_fault &= F_LINKFAULTCHANGE; - link_ok = lc->link_ok; - speed = lc->speed; - duplex = lc->duplex; - fc = lc->fc; - phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); if (link_fault) { diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index fffb006b7d95..b1419e21b46b 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -4027,9 +4027,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, PCI_DMA_FROMDEVICE); length = le16_to_cpu(rx_desc->length); - /* !EOP means multiple descriptors were used to store a single - * packet, also make sure the frame isn't just CRC only */ - if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) { + + if (unlikely(!(status & E1000_RXD_STAT_EOP))) { /* All receives must fit into a single buffer */ E1000_DBG("%s: Receive packet consumed multiple" " buffers\n", netdev->name); diff --git a/trunk/drivers/net/forcedeth.c b/trunk/drivers/net/forcedeth.c index 9f6a68fb7b45..f9a846b1b92f 100644 --- a/trunk/drivers/net/forcedeth.c +++ b/trunk/drivers/net/forcedeth.c @@ -897,12 +897,6 @@ enum { }; static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED; -/* - * Power down phy when interface is down (persists through reboot; - * older Linux and other OSes may not power it up again) - */ -static int phy_power_down = 0; - static inline struct fe_priv *get_nvpriv(struct net_device *dev) { return netdev_priv(dev); @@ -1491,10 +1485,7 @@ static int phy_init(struct net_device *dev) /* restart auto negotiation, power down phy */ mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); - mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE); - if (phy_power_down) { - mii_control |= BMCR_PDOWN; - } + mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN); if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) { return PHY_ERROR; } @@ -5522,7 +5513,7 @@ static int nv_close(struct net_device *dev) nv_drain_rxtx(dev); - if (np->wolenabled || !phy_power_down) { + if (np->wolenabled) { writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags); nv_start_rx(dev); } else { @@ -6376,8 +6367,6 @@ module_param(dma_64bit, int, 0); MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0."); module_param(phy_cross, int, 0); MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0."); -module_param(phy_power_down, int, 0); -MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0)."); MODULE_AUTHOR("Manfred Spraul "); MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver"); diff --git a/trunk/drivers/net/gianfar.h b/trunk/drivers/net/gianfar.h index cf352961ae9b..0642d52aef5c 100644 --- a/trunk/drivers/net/gianfar.h +++ b/trunk/drivers/net/gianfar.h @@ -259,7 +259,7 @@ extern const char gfar_driver_version[]; (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \ IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \ | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \ - | IEVENT_MAG | IEVENT_BABR) + | IEVENT_MAG) #define IMASK_INIT_CLEAR 0x00000000 #define IMASK_BABR 0x80000000 diff --git a/trunk/drivers/net/mac8390.c b/trunk/drivers/net/mac8390.c index 22e74a0e0361..f26667d5eaae 100644 --- a/trunk/drivers/net/mac8390.c +++ b/trunk/drivers/net/mac8390.c @@ -489,7 +489,7 @@ static const struct net_device_ops mac8390_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, .ndo_change_mtu = eth_change_mtu, #ifdef CONFIG_NET_POLL_CONTROLLER - .ndo_poll_controller = __ei_poll, + .ndo_poll_controller = ei_poll, #endif }; diff --git a/trunk/drivers/net/mlx4/en_tx.c b/trunk/drivers/net/mlx4/en_tx.c index e5c98a98ad37..ac6fc499b280 100644 --- a/trunk/drivers/net/mlx4/en_tx.c +++ b/trunk/drivers/net/mlx4/en_tx.c @@ -426,7 +426,7 @@ void mlx4_en_poll_tx_cq(unsigned long data) INC_PERF_COUNTER(priv->pstats.tx_poll); - if (!spin_trylock_irq(&ring->comp_lock)) { + if (!spin_trylock(&ring->comp_lock)) { mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT); return; } @@ -439,7 +439,7 @@ void mlx4_en_poll_tx_cq(unsigned long data) if (inflight && priv->port_up) mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT); - spin_unlock_irq(&ring->comp_lock); + spin_unlock(&ring->comp_lock); } static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv, @@ -482,9 +482,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind) /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */ if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0) - if (spin_trylock_irq(&ring->comp_lock)) { + if (spin_trylock(&ring->comp_lock)) { mlx4_en_process_tx_cq(priv->dev, cq); - spin_unlock_irq(&ring->comp_lock); + spin_unlock(&ring->comp_lock); } } diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 3b19e0ce290f..8247a945a1d9 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -66,6 +66,7 @@ static const int multicast_filter_limit = 32; #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ #define EarlyTxThld 0x3F /* 0x3F means NO early transmit */ +#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */ #define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */ #define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */ @@ -2356,10 +2357,10 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr) return cmd; } -static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz) +static void rtl_set_rx_max_size(void __iomem *ioaddr) { /* Low hurts. Let's disable the filtering. */ - RTL_W16(RxMaxSize, rx_buf_sz); + RTL_W16(RxMaxSize, 16383); } static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version) @@ -2406,7 +2407,7 @@ static void rtl_hw_start_8169(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr); if ((tp->mac_version == RTL_GIGA_MAC_VER_01) || (tp->mac_version == RTL_GIGA_MAC_VER_02) || @@ -2667,7 +2668,7 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr); tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1; @@ -2845,7 +2846,7 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(EarlyTxThres, EarlyTxThld); - rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz); + rtl_set_rx_max_size(ioaddr); tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW; diff --git a/trunk/drivers/net/wireless/Kconfig b/trunk/drivers/net/wireless/Kconfig index 3d94e7dfea69..8a0823588c51 100644 --- a/trunk/drivers/net/wireless/Kconfig +++ b/trunk/drivers/net/wireless/Kconfig @@ -430,7 +430,6 @@ config RTL8187 ASUS P5B Deluxe Toshiba Satellite Pro series of laptops Asus Wireless Link - Linksys WUSB54GC-EU Thanks to Realtek for their support! diff --git a/trunk/drivers/net/wireless/at76c50x-usb.c b/trunk/drivers/net/wireless/at76c50x-usb.c index 8d93ca4651b9..744f4f4dd3d1 100644 --- a/trunk/drivers/net/wireless/at76c50x-usb.c +++ b/trunk/drivers/net/wireless/at76c50x-usb.c @@ -1873,18 +1873,18 @@ static void at76_dwork_hw_scan(struct work_struct *work) if (ret != CMD_STATUS_COMPLETE) { queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, SCAN_POLL_INTERVAL); - mutex_unlock(&priv->mtx); - return; + goto exit; } + ieee80211_scan_completed(priv->hw, false); + if (is_valid_ether_addr(priv->bssid)) at76_join(priv); - mutex_unlock(&priv->mtx); - - ieee80211_scan_completed(priv->hw, false); - ieee80211_wake_queues(priv->hw); + +exit: + mutex_unlock(&priv->mtx); } static int at76_hw_scan(struct ieee80211_hw *hw, diff --git a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c index d51ba0a88c23..bac6cfba6abd 100644 --- a/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c +++ b/trunk/drivers/net/wireless/rtl818x/rtl8187_dev.c @@ -71,8 +71,6 @@ static struct usb_device_id rtl8187_table[] __devinitdata = { {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187}, /* AirLive */ {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187}, - /* Linksys */ - {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B}, {} }; diff --git a/trunk/drivers/parport/parport_gsc.c b/trunk/drivers/parport/parport_gsc.c index ea31a452b153..e6a7e847ee80 100644 --- a/trunk/drivers/parport/parport_gsc.c +++ b/trunk/drivers/parport/parport_gsc.c @@ -352,8 +352,8 @@ static int __devinit parport_init_chip(struct parisc_device *dev) unsigned long port; if (!dev->irq) { - printk(KERN_WARNING "IRQ not found for parallel device at 0x%llx\n", - (unsigned long long)dev->hpa.start); + printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n", + dev->hpa.start); return -ENODEV; } diff --git a/trunk/drivers/parport/share.c b/trunk/drivers/parport/share.c index dffa5d4fb298..0ebca450ed29 100644 --- a/trunk/drivers/parport/share.c +++ b/trunk/drivers/parport/share.c @@ -614,10 +614,7 @@ parport_register_device(struct parport *port, const char *name, * pardevice fields. -arca */ port->ops->init_state(tmp, tmp->state); - if (!test_and_set_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags)) { - port->proc_device = tmp; - parport_device_proc_register(tmp); - } + parport_device_proc_register(tmp); return tmp; out_free_all: @@ -649,13 +646,9 @@ void parport_unregister_device(struct pardevice *dev) } #endif - port = dev->port->physport; + parport_device_proc_unregister(dev); - if (port->proc_device == dev) { - port->proc_device = NULL; - clear_bit(PARPORT_DEVPROC_REGISTERED, &port->devflags); - parport_device_proc_unregister(dev); - } + port = dev->port->physport; if (port->cad == dev) { printk(KERN_DEBUG "%s: %s forgot to release port\n", diff --git a/trunk/drivers/pci/hotplug/acpiphp.h b/trunk/drivers/pci/hotplug/acpiphp.h index e68d5f20ffb3..4fc168b70095 100644 --- a/trunk/drivers/pci/hotplug/acpiphp.h +++ b/trunk/drivers/pci/hotplug/acpiphp.h @@ -129,6 +129,7 @@ struct acpiphp_func { struct acpiphp_bridge *bridge; /* Ejectable PCI-to-PCI bridge */ struct list_head sibling; + struct pci_dev *pci_dev; struct notifier_block nb; acpi_handle handle; diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 3a6064bce561..a33794d9e0dc 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -32,6 +32,9 @@ /* * Lifetime rules for pci_dev: + * - The one in acpiphp_func has its refcount elevated by pci_get_slot() + * when the driver is loaded or when an insertion event occurs. It loses + * a refcount when its ejected or the driver unloads. * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() * when the bridge is scanned and it loses a refcount when the bridge * is removed. @@ -127,7 +130,6 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) unsigned long long adr, sun; int device, function, retval; struct pci_bus *pbus = bridge->pci_bus; - struct pci_dev *pdev; if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle)) return AE_OK; @@ -211,10 +213,10 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) newfunc->slot = slot; list_add_tail(&newfunc->sibling, &slot->funcs); - pdev = pci_get_slot(pbus, PCI_DEVFN(device, function)); - if (pdev) { + /* associate corresponding pci_dev */ + newfunc->pci_dev = pci_get_slot(pbus, PCI_DEVFN(device, function)); + if (newfunc->pci_dev) { slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); - pci_dev_put(pdev); } if (is_dock_device(handle)) { @@ -615,6 +617,7 @@ static void cleanup_bridge(struct acpiphp_bridge *bridge) if (ACPI_FAILURE(status)) err("failed to remove notify handler\n"); } + pci_dev_put(func->pci_dev); list_del(list); kfree(func); } @@ -1098,24 +1101,22 @@ static int __ref enable_device(struct acpiphp_slot *slot) pci_enable_bridges(bus); pci_bus_add_devices(bus); + /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - dev = pci_get_slot(bus, PCI_DEVFN(slot->device, - func->function)); - if (!dev) + func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, + func->function)); + if (!func->pci_dev) continue; - if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && - dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { - pci_dev_put(dev); + if (func->pci_dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && + func->pci_dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) continue; - } status = find_p2p_bridge(func->handle, (u32)1, bus, NULL); if (ACPI_FAILURE(status)) warn("find_p2p_bridge failed (error code = 0x%x)\n", status); - pci_dev_put(dev); } slot->flags |= SLOT_ENABLED; @@ -1141,14 +1142,17 @@ static void disable_bridges(struct pci_bus *bus) */ static int disable_device(struct acpiphp_slot *slot) { + int retval = 0; struct acpiphp_func *func; - struct pci_dev *pdev; + struct list_head *l; /* is this slot already disabled? */ if (!(slot->flags & SLOT_ENABLED)) goto err_exit; - list_for_each_entry(func, &slot->funcs, sibling) { + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); + if (func->bridge) { /* cleanup p2p bridges under this P2P bridge */ cleanup_p2p_bridge(func->bridge->handle, @@ -1156,28 +1160,35 @@ static int disable_device(struct acpiphp_slot *slot) func->bridge = NULL; } - pdev = pci_get_slot(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, func->function)); - if (pdev) { - pci_stop_bus_device(pdev); - if (pdev->subordinate) { - disable_bridges(pdev->subordinate); - pci_disable_device(pdev); + if (func->pci_dev) { + pci_stop_bus_device(func->pci_dev); + if (func->pci_dev->subordinate) { + disable_bridges(func->pci_dev->subordinate); + pci_disable_device(func->pci_dev); } - pci_remove_bus_device(pdev); - pci_dev_put(pdev); } } - list_for_each_entry(func, &slot->funcs, sibling) { + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); + acpiphp_unconfigure_ioapics(func->handle); acpiphp_bus_trim(func->handle); + /* try to remove anyway. + * acpiphp_bus_add might have been failed */ + + if (!func->pci_dev) + continue; + + pci_remove_bus_device(func->pci_dev); + pci_dev_put(func->pci_dev); + func->pci_dev = NULL; } slot->flags &= (~SLOT_ENABLED); -err_exit: - return 0; + err_exit: + return retval; } diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index f1ae2475ffff..e3c3e081b834 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -745,8 +745,6 @@ int pci_setup_device(struct pci_dev *dev) /* Early fixups, before probing the BARs */ pci_fixup_device(pci_fixup_early, dev); - /* device class may be changed after fixup */ - class = dev->class >> 8; switch (dev->hdr_type) { /* header type */ case PCI_HEADER_TYPE_NORMAL: /* standard header */ diff --git a/trunk/drivers/serial/8250.c b/trunk/drivers/serial/8250.c index a0127e93ade0..b4b39811b445 100644 --- a/trunk/drivers/serial/8250.c +++ b/trunk/drivers/serial/8250.c @@ -137,7 +137,6 @@ struct uart_8250_port { unsigned char mcr; unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ - unsigned char cur_iotype; /* Running I/O type */ /* * Some bits in registers are cleared on a read, so they must @@ -472,7 +471,6 @@ static void io_serial_out(struct uart_port *p, int offset, int value) static void set_io_from_upio(struct uart_port *p) { - struct uart_8250_port *up = (struct uart_8250_port *)p; switch (p->iotype) { case UPIO_HUB6: p->serial_in = hub6_serial_in; @@ -511,8 +509,6 @@ static void set_io_from_upio(struct uart_port *p) p->serial_out = io_serial_out; break; } - /* Remember loaded iotype */ - up->cur_iotype = p->iotype; } static void @@ -1941,9 +1937,6 @@ static int serial8250_startup(struct uart_port *port) up->capabilities = uart_config[up->port.type].flags; up->mcr = 0; - if (up->port.iotype != up->cur_iotype) - set_io_from_upio(port); - if (up->port.type == PORT_16C950) { /* Wake up and initialize UART */ up->acr = 0; @@ -2570,9 +2563,6 @@ static void serial8250_config_port(struct uart_port *port, int flags) if (ret < 0) probeflags &= ~PROBE_RSA; - if (up->port.iotype != up->cur_iotype) - set_io_from_upio(port); - if (flags & UART_CONFIG_TYPE) autoconfig(up, probeflags); if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ) @@ -2681,11 +2671,6 @@ serial8250_register_ports(struct uart_driver *drv, struct device *dev) { int i; - for (i = 0; i < nr_uarts; i++) { - struct uart_8250_port *up = &serial8250_ports[i]; - up->cur_iotype = 0xFF; - } - serial8250_isa_init_ports(); for (i = 0; i < nr_uarts; i++) { diff --git a/trunk/drivers/serial/8250_gsc.c b/trunk/drivers/serial/8250_gsc.c index 33149d982e82..418b4fe9a0a1 100644 --- a/trunk/drivers/serial/8250_gsc.c +++ b/trunk/drivers/serial/8250_gsc.c @@ -39,9 +39,9 @@ static int __init serial_init_chip(struct parisc_device *dev) */ if (parisc_parent(dev)->id.hw_type != HPHW_IOA) printk(KERN_INFO - "Serial: device 0x%llx not configured.\n" + "Serial: device 0x%lx not configured.\n" "Enable support for Wax, Lasi, Asp or Dino.\n", - (unsigned long long)dev->hpa.start); + dev->hpa.start); return -ENODEV; } diff --git a/trunk/drivers/serial/imx.c b/trunk/drivers/serial/imx.c index 5f0be40dfdab..9f460b175c50 100644 --- a/trunk/drivers/serial/imx.c +++ b/trunk/drivers/serial/imx.c @@ -1031,8 +1031,6 @@ imx_console_setup(struct console *co, char *options) if (co->index == -1 || co->index >= ARRAY_SIZE(imx_ports)) co->index = 0; sport = imx_ports[co->index]; - if(sport == NULL) - return -ENODEV; if (options) uart_parse_options(options, &baud, &parity, &bits, &flow); diff --git a/trunk/drivers/serial/mpc52xx_uart.c b/trunk/drivers/serial/mpc52xx_uart.c index b3feb6198d57..7f72f8ceaa6f 100644 --- a/trunk/drivers/serial/mpc52xx_uart.c +++ b/trunk/drivers/serial/mpc52xx_uart.c @@ -988,7 +988,7 @@ mpc52xx_console_setup(struct console *co, char *options) pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n", co, co->index, options); - if ((co->index < 0) || (co->index >= MPC52xx_PSC_MAXNUM)) { + if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) { pr_debug("PSC%x out of range\n", co->index); return -EINVAL; } diff --git a/trunk/drivers/ssb/embedded.c b/trunk/drivers/ssb/embedded.c index a0e0d246b592..7dc3a6b41397 100644 --- a/trunk/drivers/ssb/embedded.c +++ b/trunk/drivers/ssb/embedded.c @@ -29,7 +29,6 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) } return -ENODEV; } -EXPORT_SYMBOL(ssb_watchdog_timer_set); u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) { diff --git a/trunk/drivers/usb/Makefile b/trunk/drivers/usb/Makefile index 0a3dc5ece634..0716cdb44cd8 100644 --- a/trunk/drivers/usb/Makefile +++ b/trunk/drivers/usb/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_USB_MON) += mon/ obj-$(CONFIG_PCI) += host/ obj-$(CONFIG_USB_EHCI_HCD) += host/ obj-$(CONFIG_USB_ISP116X_HCD) += host/ +obj-$(CONFIG_USB_ISP1760_HCD) += host/ obj-$(CONFIG_USB_OHCI_HCD) += host/ obj-$(CONFIG_USB_UHCI_HCD) += host/ obj-$(CONFIG_USB_FHCI_HCD) += host/ diff --git a/trunk/drivers/usb/class/cdc-acm.c b/trunk/drivers/usb/class/cdc-acm.c index 7a1164dd1d37..0a69c0977e3f 100644 --- a/trunk/drivers/usb/class/cdc-acm.c +++ b/trunk/drivers/usb/class/cdc-acm.c @@ -1375,9 +1375,6 @@ static struct usb_device_id acm_ids[] = { { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ }, - { USB_DEVICE(0x0572, 0x1328), /* Shiro / Aztech USB MODEM UM-3100 */ - .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ - }, { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ }, { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ diff --git a/trunk/drivers/usb/gadget/atmel_usba_udc.c b/trunk/drivers/usb/gadget/atmel_usba_udc.c index 05c913cc3658..563d57275448 100644 --- a/trunk/drivers/usb/gadget/atmel_usba_udc.c +++ b/trunk/drivers/usb/gadget/atmel_usba_udc.c @@ -794,8 +794,7 @@ usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) if (ep->desc) { list_add_tail(&req->queue, &ep->queue); - if ((!ep_is_control(ep) && ep->is_in) || - (ep_is_control(ep) + if (ep->is_in || (ep_is_control(ep) && (ep->state == DATA_STAGE_IN || ep->state == STATUS_STAGE_IN))) usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); @@ -1941,7 +1940,7 @@ static int __init usba_udc_probe(struct platform_device *pdev) usba_writel(udc, CTRL, USBA_DISABLE_MASK); clk_disable(pclk); - usba_ep = kzalloc(sizeof(struct usba_ep) * pdata->num_ep, + usba_ep = kmalloc(sizeof(struct usba_ep) * pdata->num_ep, GFP_KERNEL); if (!usba_ep) goto err_alloc_ep; diff --git a/trunk/drivers/usb/host/isp1760-hcd.c b/trunk/drivers/usb/host/isp1760-hcd.c index 15438469f21a..cd07ea3f0c63 100644 --- a/trunk/drivers/usb/host/isp1760-hcd.c +++ b/trunk/drivers/usb/host/isp1760-hcd.c @@ -1658,7 +1658,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, u32 reg_base, or_reg, skip_reg; unsigned long flags; struct ptd ptd; - packet_enqueue *pe; switch (usb_pipetype(urb->pipe)) { case PIPE_ISOCHRONOUS: @@ -1670,7 +1669,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, reg_base = INT_REGS_OFFSET; or_reg = HC_INT_IRQ_MASK_OR_REG; skip_reg = HC_INT_PTD_SKIPMAP_REG; - pe = enqueue_an_INT_packet; break; default: @@ -1678,7 +1676,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, reg_base = ATL_REGS_OFFSET; or_reg = HC_ATL_IRQ_MASK_OR_REG; skip_reg = HC_ATL_PTD_SKIPMAP_REG; - pe = enqueue_an_ATL_packet; break; } @@ -1690,7 +1687,6 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, u32 skip_map; u32 or_map; struct isp1760_qtd *qtd; - struct isp1760_qh *qh = ints->qh; skip_map = isp1760_readl(hcd->regs + skip_reg); skip_map |= 1 << i; @@ -1703,7 +1699,8 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, priv_write_copy(priv, (u32 *)&ptd, hcd->regs + reg_base + i * sizeof(ptd), sizeof(ptd)); qtd = ints->qtd; - qtd = clean_up_qtdlist(qtd); + + clean_up_qtdlist(qtd); free_mem(priv, ints->payload); @@ -1714,24 +1711,7 @@ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, ints->payload = 0; isp1760_urb_done(priv, urb, status); - if (qtd) - pe(hcd, qh, qtd); break; - - } else if (ints->qtd) { - struct isp1760_qtd *qtd, *prev_qtd = ints->qtd; - - for (qtd = ints->qtd->hw_next; qtd; qtd = qtd->hw_next) { - if (qtd->urb == urb) { - prev_qtd->hw_next = clean_up_qtdlist(qtd); - isp1760_urb_done(priv, urb, status); - break; - } - prev_qtd = qtd; - } - /* we found the urb before the end of the list */ - if (qtd) - break; } ints++; } diff --git a/trunk/drivers/usb/serial/usb-serial.c b/trunk/drivers/usb/serial/usb-serial.c index f331e2bde88a..0a566eea49c0 100644 --- a/trunk/drivers/usb/serial/usb-serial.c +++ b/trunk/drivers/usb/serial/usb-serial.c @@ -974,7 +974,6 @@ int usb_serial_probe(struct usb_interface *interface, if (retval > 0) { /* quietly accept this device, but don't bind to a serial port as it's about to disappear */ - serial->num_ports = 0; goto exit; } } diff --git a/trunk/drivers/video/atmel_lcdfb.c b/trunk/drivers/video/atmel_lcdfb.c index 2fb63f6ea2f1..9a577a800db5 100644 --- a/trunk/drivers/video/atmel_lcdfb.c +++ b/trunk/drivers/video/atmel_lcdfb.c @@ -29,8 +29,14 @@ /* configurable parameters */ #define ATMEL_LCDC_CVAL_DEFAULT 0xc8 -#define ATMEL_LCDC_DMA_BURST_LEN 8 /* words */ -#define ATMEL_LCDC_FIFO_SIZE 512 /* words */ +#define ATMEL_LCDC_DMA_BURST_LEN 8 + +#if defined(CONFIG_ARCH_AT91SAM9263) || defined(CONFIG_ARCH_AT91CAP9) || \ + defined(CONFIG_ARCH_AT91SAM9RL) +#define ATMEL_LCDC_FIFO_SIZE 2048 +#else +#define ATMEL_LCDC_FIFO_SIZE 512 +#endif #if defined(CONFIG_ARCH_AT91) #define ATMEL_LCDFB_FBINFO_DEFAULT (FBINFO_DEFAULT \ diff --git a/trunk/drivers/video/s3c-fb.c b/trunk/drivers/video/s3c-fb.c index d3a568e6b169..5e9c6302433b 100644 --- a/trunk/drivers/video/s3c-fb.c +++ b/trunk/drivers/video/s3c-fb.c @@ -947,8 +947,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) int win; for (win = 0; win <= S3C_FB_MAX_WIN; win++) - if (sfb->windows[win]) - s3c_fb_release_win(sfb, sfb->windows[win]); + s3c_fb_release_win(sfb, sfb->windows[win]); iounmap(sfb->regs); @@ -986,20 +985,11 @@ static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state) static int s3c_fb_resume(struct platform_device *pdev) { struct s3c_fb *sfb = platform_get_drvdata(pdev); - struct s3c_fb_platdata *pd = sfb->pdata; struct s3c_fb_win *win; int win_no; clk_enable(sfb->bus_clk); - /* setup registers */ - writel(pd->vidcon1, sfb->regs + VIDCON1); - - /* zero all windows before we do anything */ - for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) - s3c_fb_clear_win(sfb, win_no); - - /* restore framebuffers */ for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) { win = sfb->windows[win_no]; if (!win) diff --git a/trunk/firmware/cis/.gitignore b/trunk/firmware/cis/.gitignore deleted file mode 100644 index 1de39847f261..000000000000 --- a/trunk/firmware/cis/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.cis diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index 2341375386f8..eeb246845909 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -297,14 +297,20 @@ static int validate_request(struct autofs_wait_queue **wait, */ if (notify == NFY_MOUNT) { /* - * If the dentry was successfully mounted while we slept - * on the wait queue mutex we can return success. If it - * isn't mounted (doesn't have submounts for the case of - * a multi-mount with no mount at it's base) we can - * continue on and create a new request. - */ - if (have_submounts(dentry)) - return 0; + * If the dentry isn't hashed just go ahead and try the + * mount again with a new wait (not much else we can do). + */ + if (!d_unhashed(dentry)) { + /* + * But if the dentry is hashed, that means that we + * got here through the revalidate path. Thus, we + * need to check if the dentry has been mounted + * while we waited on the wq_mutex. If it has, + * simply return success. + */ + if (d_mountpoint(dentry)) + return 0; + } } return 1; diff --git a/trunk/fs/binfmt_flat.c b/trunk/fs/binfmt_flat.c index 697f6b5f1313..5cebf0b37798 100644 --- a/trunk/fs/binfmt_flat.c +++ b/trunk/fs/binfmt_flat.c @@ -41,7 +41,6 @@ #include #include #include -#include /****************************************************************************/ @@ -55,18 +54,6 @@ #define DBG_FLT(a...) #endif -/* - * User data (stack, data section and bss) needs to be aligned - * for the same reasons as SLAB memory is, and to the same amount. - * Avoid duplicating architecture specific code by using the same - * macro as with SLAB allocation: - */ -#ifdef ARCH_SLAB_MINALIGN -#define FLAT_DATA_ALIGN (ARCH_SLAB_MINALIGN) -#else -#define FLAT_DATA_ALIGN (sizeof(void *)) -#endif - #define RELOC_FAILED 0xff00ff01 /* Relocation incorrect somewhere */ #define UNLOADED_LIB 0x7ff000ff /* Placeholder for unused library */ @@ -127,18 +114,20 @@ static unsigned long create_flat_tables( int envc = bprm->envc; char uninitialized_var(dummy); - sp = (unsigned long *)p; - sp -= (envc + argc + 2) + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - sp = (unsigned long *) ((unsigned long)sp & -FLAT_DATA_ALIGN); - argv = sp + 1 + (flat_argvp_envp_on_stack() ? 2 : 0); - envp = argv + (argc + 1); + sp = (unsigned long *) ((-(unsigned long)sizeof(char *))&(unsigned long) p); + sp -= envc+1; + envp = sp; + sp -= argc+1; + argv = sp; + + flat_stack_align(sp); if (flat_argvp_envp_on_stack()) { - put_user((unsigned long) envp, sp + 2); - put_user((unsigned long) argv, sp + 1); + --sp; put_user((unsigned long) envp, sp); + --sp; put_user((unsigned long) argv, sp); } - put_user(argc, sp); + put_user(argc,--sp); current->mm->arg_start = (unsigned long) p; while (argc-->0) { put_user((unsigned long) p, argv++); @@ -569,9 +558,7 @@ static int load_flat_file(struct linux_binprm * bprm, ret = realdatastart; goto err; } - datapos = ALIGN(realdatastart + - MAX_SHARED_LIBS * sizeof(unsigned long), - FLAT_DATA_ALIGN); + datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); DBG_FLT("BINFMT_FLAT: Allocated data+bss+stack (%d bytes): %x\n", (int)(data_len + bss_len + stack_len), (int)datapos); @@ -617,12 +604,9 @@ static int load_flat_file(struct linux_binprm * bprm, } realdatastart = textpos + ntohl(hdr->data_start); - datapos = ALIGN(realdatastart + - MAX_SHARED_LIBS * sizeof(unsigned long), - FLAT_DATA_ALIGN); - - reloc = (unsigned long *) - (datapos + (ntohl(hdr->reloc_start) - text_len)); + datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); + reloc = (unsigned long *) (textpos + ntohl(hdr->reloc_start) + + MAX_SHARED_LIBS * sizeof(unsigned long)); memp = textpos; memp_size = len; #ifdef CONFIG_BINFMT_ZFLAT @@ -870,7 +854,7 @@ static int load_flat_binary(struct linux_binprm * bprm, struct pt_regs * regs) stack_len = TOP_OF_ARGS - bprm->p; /* the strings */ stack_len += (bprm->argc + 1) * sizeof(char *); /* the argv array */ stack_len += (bprm->envc + 1) * sizeof(char *); /* the envp array */ - stack_len += FLAT_DATA_ALIGN - 1; /* reserve for upcoming alignment */ + res = load_flat_file(bprm, &libinfo, 0, &stack_len); if (res > (unsigned long)-4096) diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 35af93355063..3e2c7c738f23 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -2622,18 +2622,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, search_start); if (block_group && block_group_bits(block_group, data)) { down_read(&space_info->groups_sem); - if (list_empty(&block_group->list) || - block_group->ro) { - /* - * someone is removing this block group, - * we can't jump into the have_block_group - * target because our list pointers are not - * valid - */ - btrfs_put_block_group(block_group); - up_read(&space_info->groups_sem); - } else - goto have_block_group; + goto have_block_group; } else if (block_group) { btrfs_put_block_group(block_group); } @@ -2667,13 +2656,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, * people trying to start a new cluster */ spin_lock(&last_ptr->refill_lock); - if (last_ptr->block_group && - (last_ptr->block_group->ro || - !block_group_bits(last_ptr->block_group, data))) { - offset = 0; - goto refill_cluster; - } - offset = btrfs_alloc_from_cluster(block_group, last_ptr, num_bytes, search_start); if (offset) { @@ -2699,17 +2681,10 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, last_ptr_loop = 1; search_start = block_group->key.objectid; - /* - * we know this block group is properly - * in the list because - * btrfs_remove_block_group, drops the - * cluster before it removes the block - * group from the list - */ goto have_block_group; } spin_unlock(&last_ptr->lock); -refill_cluster: + /* * this cluster didn't work out, free it and * start over @@ -5993,7 +5968,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, { struct btrfs_path *path; struct btrfs_block_group_cache *block_group; - struct btrfs_free_cluster *cluster; struct btrfs_key key; int ret; @@ -6005,21 +5979,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, memcpy(&key, &block_group->key, sizeof(key)); - /* make sure this block group isn't part of an allocation cluster */ - cluster = &root->fs_info->data_alloc_cluster; - spin_lock(&cluster->refill_lock); - btrfs_return_cluster_to_free_space(block_group, cluster); - spin_unlock(&cluster->refill_lock); - - /* - * make sure this block group isn't part of a metadata - * allocation cluster - */ - cluster = &root->fs_info->meta_alloc_cluster; - spin_lock(&cluster->refill_lock); - btrfs_return_cluster_to_free_space(block_group, cluster); - spin_unlock(&cluster->refill_lock); - path = btrfs_alloc_path(); BUG_ON(!path); @@ -6029,11 +5988,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, spin_unlock(&root->fs_info->block_group_cache_lock); btrfs_remove_free_space_cache(block_group); down_write(&block_group->space_info->groups_sem); - /* - * we must use list_del_init so people can check to see if they - * are still on the list after taking the semaphore - */ - list_del_init(&block_group->list); + list_del(&block_group->list); up_write(&block_group->space_info->groups_sem); spin_lock(&block_group->space_info->lock); diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index a6d35b0054ca..5f01dad4b696 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1440,7 +1440,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) device->io_align = root->sectorsize; device->sector_size = root->sectorsize; device->total_bytes = i_size_read(bdev->bd_inode); - device->disk_total_bytes = device->total_bytes; device->dev_root = root->fs_info->dev_root; device->bdev = bdev; device->in_fs_metadata = 1; diff --git a/trunk/fs/buffer.c b/trunk/fs/buffer.c index 49106127a4aa..aed297739eb0 100644 --- a/trunk/fs/buffer.c +++ b/trunk/fs/buffer.c @@ -2736,8 +2736,6 @@ int nobh_truncate_page(struct address_space *mapping, pos += blocksize; } - map_bh.b_size = blocksize; - map_bh.b_state = 0; err = get_block(inode, iblock, &map_bh, 0); if (err) goto unlock; diff --git a/trunk/fs/cachefiles/internal.h b/trunk/fs/cachefiles/internal.h index f7c255f9c624..19218e1463d6 100644 --- a/trunk/fs/cachefiles/internal.h +++ b/trunk/fs/cachefiles/internal.h @@ -122,13 +122,13 @@ static inline void cachefiles_state_changed(struct cachefiles_cache *cache) } /* - * bind.c + * cf-bind.c */ extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args); extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache); /* - * daemon.c + * cf-daemon.c */ extern const struct file_operations cachefiles_daemon_fops; @@ -136,17 +136,17 @@ extern int cachefiles_has_space(struct cachefiles_cache *cache, unsigned fnr, unsigned bnr); /* - * interface.c + * cf-interface.c */ extern const struct fscache_cache_ops cachefiles_cache_ops; /* - * key.c + * cf-key.c */ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type); /* - * namei.c + * cf-namei.c */ extern int cachefiles_delete_object(struct cachefiles_cache *cache, struct cachefiles_object *object); @@ -165,7 +165,7 @@ extern int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir, char *filename); /* - * proc.c + * cf-proc.c */ #ifdef CONFIG_CACHEFILES_HISTOGRAM extern atomic_t cachefiles_lookup_histogram[HZ]; @@ -190,7 +190,7 @@ void cachefiles_hist(atomic_t histogram[], unsigned long start_jif) #endif /* - * rdwr.c + * cf-rdwr.c */ extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *, struct page *, gfp_t); @@ -205,7 +205,7 @@ extern int cachefiles_write_page(struct fscache_storage *, struct page *); extern void cachefiles_uncache_page(struct fscache_object *, struct page *); /* - * security.c + * cf-security.c */ extern int cachefiles_get_security_ID(struct cachefiles_cache *cache); extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache, @@ -225,7 +225,7 @@ static inline void cachefiles_end_secure(struct cachefiles_cache *cache, } /* - * xattr.c + * cf-xattr.c */ extern int cachefiles_check_object_type(struct cachefiles_object *object); extern int cachefiles_set_object_xattr(struct cachefiles_object *object, diff --git a/trunk/fs/fscache/internal.h b/trunk/fs/fscache/internal.h index 1c341304621f..e0cbd16f6dc9 100644 --- a/trunk/fs/fscache/internal.h +++ b/trunk/fs/fscache/internal.h @@ -28,7 +28,7 @@ #define FSCACHE_MAX_THREADS 32 /* - * cache.c + * fsc-cache.c */ extern struct list_head fscache_cache_list; extern struct rw_semaphore fscache_addremove_sem; @@ -37,7 +37,7 @@ extern struct fscache_cache *fscache_select_cache_for_object( struct fscache_cookie *); /* - * cookie.c + * fsc-cookie.c */ extern struct kmem_cache *fscache_cookie_jar; @@ -45,13 +45,13 @@ extern void fscache_cookie_init_once(void *); extern void __fscache_cookie_put(struct fscache_cookie *); /* - * fsdef.c + * fsc-fsdef.c */ extern struct fscache_cookie fscache_fsdef_index; extern struct fscache_cookie_def fscache_fsdef_netfs_def; /* - * histogram.c + * fsc-histogram.c */ #ifdef CONFIG_FSCACHE_HISTOGRAM extern atomic_t fscache_obj_instantiate_histogram[HZ]; @@ -75,7 +75,7 @@ extern const struct file_operations fscache_histogram_fops; #endif /* - * main.c + * fsc-main.c */ extern unsigned fscache_defer_lookup; extern unsigned fscache_defer_create; @@ -86,14 +86,14 @@ extern int fscache_wait_bit(void *); extern int fscache_wait_bit_interruptible(void *); /* - * object.c + * fsc-object.c */ extern void fscache_withdrawing_object(struct fscache_cache *, struct fscache_object *); extern void fscache_enqueue_object(struct fscache_object *); /* - * operation.c + * fsc-operation.c */ extern int fscache_submit_exclusive_op(struct fscache_object *, struct fscache_operation *); @@ -104,7 +104,7 @@ extern void fscache_start_operations(struct fscache_object *); extern void fscache_operation_gc(struct work_struct *); /* - * proc.c + * fsc-proc.c */ #ifdef CONFIG_PROC_FS extern int __init fscache_proc_init(void); @@ -115,7 +115,7 @@ extern void fscache_proc_cleanup(void); #endif /* - * stats.c + * fsc-stats.c */ #ifdef CONFIG_FSCACHE_STATS extern atomic_t fscache_n_ops_processed[FSCACHE_MAX_THREADS]; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index bca0c618fdb3..0571983755dc 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -219,7 +219,6 @@ static struct inode *alloc_inode(struct super_block *sb) void destroy_inode(struct inode *inode) { BUG_ON(inode_has_buffers(inode)); - ima_inode_free(inode); security_inode_free(inode); if (inode->i_sb->s_op->destroy_inode) inode->i_sb->s_op->destroy_inode(inode); @@ -1054,22 +1053,13 @@ int insert_inode_locked(struct inode *inode) struct super_block *sb = inode->i_sb; ino_t ino = inode->i_ino; struct hlist_head *head = inode_hashtable + hash(sb, ino); + struct inode *old; inode->i_state |= I_LOCK|I_NEW; while (1) { - struct hlist_node *node; - struct inode *old = NULL; spin_lock(&inode_lock); - hlist_for_each_entry(old, node, head, i_hash) { - if (old->i_ino != ino) - continue; - if (old->i_sb != sb) - continue; - if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) - continue; - break; - } - if (likely(!node)) { + old = find_inode_fast(sb, head, ino); + if (likely(!old)) { hlist_add_head(&inode->i_hash, head); spin_unlock(&inode_lock); return 0; @@ -1091,24 +1081,14 @@ int insert_inode_locked4(struct inode *inode, unsigned long hashval, { struct super_block *sb = inode->i_sb; struct hlist_head *head = inode_hashtable + hash(sb, hashval); + struct inode *old; inode->i_state |= I_LOCK|I_NEW; while (1) { - struct hlist_node *node; - struct inode *old = NULL; - spin_lock(&inode_lock); - hlist_for_each_entry(old, node, head, i_hash) { - if (old->i_sb != sb) - continue; - if (!test(old, data)) - continue; - if (old->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) - continue; - break; - } - if (likely(!node)) { + old = find_inode(sb, head, test, data); + if (likely(!old)) { hlist_add_head(&inode->i_hash, head); spin_unlock(&inode_lock); return 0; diff --git a/trunk/fs/jbd/commit.c b/trunk/fs/jbd/commit.c index 618e21c0b7a3..06560c520f49 100644 --- a/trunk/fs/jbd/commit.c +++ b/trunk/fs/jbd/commit.c @@ -241,7 +241,7 @@ static int journal_submit_data_buffers(journal_t *journal, spin_lock(&journal->j_list_lock); } /* Someone already cleaned up the buffer? */ - if (!buffer_jbd(bh) || bh2jh(bh) != jh + if (!buffer_jbd(bh) || jh->b_transaction != commit_transaction || jh->b_jlist != BJ_SyncData) { jbd_unlock_bh_state(bh); @@ -478,9 +478,7 @@ void journal_commit_transaction(journal_t *journal) spin_lock(&journal->j_list_lock); continue; } - if (buffer_jbd(bh) && bh2jh(bh) == jh && - jh->b_transaction == commit_transaction && - jh->b_jlist == BJ_Locked) { + if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) { __journal_unfile_buffer(jh); jbd_unlock_bh_state(bh); journal_remove_journal_head(bh); diff --git a/trunk/fs/jffs2/erase.c b/trunk/fs/jffs2/erase.c index a0244740b75a..c32b4a1ad6cf 100644 --- a/trunk/fs/jffs2/erase.c +++ b/trunk/fs/jffs2/erase.c @@ -480,6 +480,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb return; filebad: + mutex_lock(&c->erase_free_sem); + spin_lock(&c->erase_completion_lock); + /* Stick it on a list (any list) so erase_failed can take it + right off again. Silly, but shouldn't happen often. */ + list_move(&jeb->list, &c->erasing_list); + spin_unlock(&c->erase_completion_lock); + mutex_unlock(&c->erase_free_sem); jffs2_erase_failed(c, jeb, bad_offset); return; diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index b660435978d2..6c68ffd6b4bb 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -1015,7 +1015,6 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, host_err = vfs_writev(file, (struct iovec __user *)vec, vlen, &offset); set_fs(oldfs); if (host_err >= 0) { - *cnt = host_err; nfsdstats.io_write += host_err; fsnotify_modify(file->f_path.dentry); } @@ -1061,9 +1060,10 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, } dprintk("nfsd: write complete host_err=%d\n", host_err); - if (host_err >= 0) + if (host_err >= 0) { err = 0; - else + *cnt = host_err; + } else err = nfserrno(host_err); out: return err; diff --git a/trunk/fs/nilfs2/cpfile.c b/trunk/fs/nilfs2/cpfile.c index 300f1cdfa862..e90b60dfced9 100644 --- a/trunk/fs/nilfs2/cpfile.c +++ b/trunk/fs/nilfs2/cpfile.c @@ -311,7 +311,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); if (ret < 0) { if (ret != -ENOENT) - goto out_header; + goto out_sem; /* skip hole */ ret = 0; continue; @@ -344,7 +344,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, continue; printk(KERN_ERR "%s: cannot delete block\n", __func__); - goto out_header; + goto out_sem; } } @@ -361,8 +361,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, nilfs_mdt_mark_dirty(cpfile); kunmap_atomic(kaddr, KM_USER0); } - - out_header: brelse(header_bh); out_sem: diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 3326bbf9ab95..fb45615943c2 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -1956,7 +1956,7 @@ static struct dentry *proc_pident_instantiate(struct inode *dir, const struct pid_entry *p = ptr; struct inode *inode; struct proc_inode *ei; - struct dentry *error = ERR_PTR(-ENOENT); + struct dentry *error = ERR_PTR(-EINVAL); inode = proc_pid_make_inode(dir->i_sb, task); if (!inode) diff --git a/trunk/fs/sysfs/file.c b/trunk/fs/sysfs/file.c index 561a9c050cef..b1606e07b7a3 100644 --- a/trunk/fs/sysfs/file.c +++ b/trunk/fs/sysfs/file.c @@ -723,7 +723,7 @@ int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), mutex_unlock(&sysfs_workq_mutex); if (sysfs_workqueue == NULL) { - sysfs_workqueue = create_singlethread_workqueue("sysfsd"); + sysfs_workqueue = create_workqueue("sysfsd"); if (sysfs_workqueue == NULL) { module_put(owner); return -ENOMEM; diff --git a/trunk/fs/xfs/linux-2.6/kmem.h b/trunk/fs/xfs/linux-2.6/kmem.h index 179cbd630f69..af6843c7ee4b 100644 --- a/trunk/fs/xfs/linux-2.6/kmem.h +++ b/trunk/fs/xfs/linux-2.6/kmem.h @@ -103,7 +103,7 @@ extern void *kmem_zone_zalloc(kmem_zone_t *, unsigned int __nocast); static inline int kmem_shake_allow(gfp_t gfp_mask) { - return ((gfp_mask & __GFP_WAIT) && (gfp_mask & __GFP_FS)); + return (gfp_mask & __GFP_WAIT) != 0; } #endif /* __XFS_SUPPORT_KMEM_H__ */ diff --git a/trunk/fs/xfs/xfs_dfrag.c b/trunk/fs/xfs/xfs_dfrag.c index 7465f9ee125f..e6d839bddbf0 100644 --- a/trunk/fs/xfs/xfs_dfrag.c +++ b/trunk/fs/xfs/xfs_dfrag.c @@ -347,14 +347,12 @@ xfs_swap_extents( error = xfs_trans_commit(tp, XFS_TRANS_SWAPEXT); -out: - kmem_free(tempifp); - return error; - out_unlock: xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); xfs_iunlock(tip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); - goto out; +out: + kmem_free(tempifp); + return error; out_trans_cancel: xfs_trans_cancel(tp, 0); diff --git a/trunk/fs/xfs/xfs_fsops.c b/trunk/fs/xfs/xfs_fsops.c index cbd451bb4848..8379e3bca26c 100644 --- a/trunk/fs/xfs/xfs_fsops.c +++ b/trunk/fs/xfs/xfs_fsops.c @@ -160,7 +160,7 @@ xfs_growfs_data_private( nagcount = new + (nb_mod != 0); if (nb_mod && nb_mod < XFS_MIN_AG_BLOCKS) { nagcount--; - nb = (xfs_rfsblock_t)nagcount * mp->m_sb.sb_agblocks; + nb = nagcount * mp->m_sb.sb_agblocks; if (nb < mp->m_sb.sb_dblocks) return XFS_ERROR(EINVAL); } diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index 7300fb866767..3c1924c010e8 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -471,9 +471,6 @@ struct drm_connector { u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY]; uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY]; - /* requested DPMS state */ - int dpms; - void *helper_private; uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER]; diff --git a/trunk/include/drm/drm_crtc_helper.h b/trunk/include/drm/drm_crtc_helper.h index 6769ff6c1bc0..ec073d8288d9 100644 --- a/trunk/include/drm/drm_crtc_helper.h +++ b/trunk/include/drm/drm_crtc_helper.h @@ -99,8 +99,6 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_framebuffer *old_fb); extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc); -extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode); - extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb, struct drm_mode_fb_cmd *mode_cmd); diff --git a/trunk/include/linux/amba/serial.h b/trunk/include/linux/amba/serial.h index 64a982ea5d5f..48ee32a18ac5 100644 --- a/trunk/include/linux/amba/serial.h +++ b/trunk/include/linux/amba/serial.h @@ -159,7 +159,6 @@ #define UART01x_FR_MODEM_ANY (UART01x_FR_DCD|UART01x_FR_DSR|UART01x_FR_CTS) #ifndef __ASSEMBLY__ -struct amba_device; /* in uncompress this is included but amba/bus.h is not */ struct amba_pl010_data { void (*set_mctrl)(struct amba_device *dev, void __iomem *base, unsigned int mctrl); }; diff --git a/trunk/include/linux/auto_fs.h b/trunk/include/linux/auto_fs.h index 7b09c8348fd3..63265852b7d1 100644 --- a/trunk/include/linux/auto_fs.h +++ b/trunk/include/linux/auto_fs.h @@ -14,12 +14,13 @@ #ifndef _LINUX_AUTO_FS_H #define _LINUX_AUTO_FS_H -#include #ifdef __KERNEL__ #include #include +#include #include #else +#include #include #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/cpumask.h b/trunk/include/linux/cpumask.h index c5ac87ca7bc6..9f315382610b 100644 --- a/trunk/include/linux/cpumask.h +++ b/trunk/include/linux/cpumask.h @@ -1022,8 +1022,6 @@ typedef struct cpumask *cpumask_var_t; bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node); bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); -bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node); -bool zalloc_cpumask_var(cpumask_var_t *mask, gfp_t flags); void alloc_bootmem_cpumask_var(cpumask_var_t *mask); void free_cpumask_var(cpumask_var_t mask); void free_bootmem_cpumask_var(cpumask_var_t mask); @@ -1042,19 +1040,6 @@ static inline bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, return true; } -static inline bool zalloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) -{ - cpumask_clear(*mask); - return true; -} - -static inline bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, - int node) -{ - cpumask_clear(*mask); - return true; -} - static inline void alloc_bootmem_cpumask_var(cpumask_var_t *mask) { } diff --git a/trunk/include/linux/cred.h b/trunk/include/linux/cred.h index 4fa999696310..3282ee4318e7 100644 --- a/trunk/include/linux/cred.h +++ b/trunk/include/linux/cred.h @@ -13,7 +13,6 @@ #define _LINUX_CRED_H #include -#include #include #include diff --git a/trunk/include/linux/i7300_idle.h b/trunk/include/linux/i7300_idle.h index 1587b7dec505..05a80c44513c 100644 --- a/trunk/include/linux/i7300_idle.h +++ b/trunk/include/linux/i7300_idle.h @@ -16,33 +16,35 @@ struct fbd_ioat { unsigned int vendor; unsigned int ioat_dev; - unsigned int enabled; }; /* * The i5000 chip-set has the same hooks as the i7300 - * but it is not enabled by default and must be manually - * manually enabled with "forceload=1" because it is - * only lightly validated. + * but support is disabled by default because this driver + * has not been validated on that platform. */ +#define SUPPORT_I5000 0 static const struct fbd_ioat fbd_ioat_list[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB, 1}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT, 0}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB}, +#if SUPPORT_I5000 + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT}, +#endif {0, 0} }; /* table of devices that work with this driver */ static const struct pci_device_id pci_tbl[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_FBD_CNB) }, +#if SUPPORT_I5000 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, +#endif { } /* Terminating entry */ }; /* Check for known platforms with I/O-AT */ static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev, - struct pci_dev **ioat_dev, - int enable_all) + struct pci_dev **ioat_dev) { int i; struct pci_dev *memdev, *dmadev; @@ -67,8 +69,6 @@ static inline int i7300_idle_platform_probe(struct pci_dev **fbd_dev, for (i = 0; fbd_ioat_list[i].vendor != 0; i++) { if (dmadev->vendor == fbd_ioat_list[i].vendor && dmadev->device == fbd_ioat_list[i].ioat_dev) { - if (!(fbd_ioat_list[i].enabled || enable_all)) - continue; if (fbd_dev) *fbd_dev = memdev; if (ioat_dev) diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 6fed4f6a9c9e..0e6ff5de3588 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -656,7 +656,6 @@ struct input_absinfo { #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ #define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */ #define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ -#define ABS_MT_TRACKING_ID 0x39 /* Unique ID of initiated contact */ #define ABS_MAX 0x3f #define ABS_CNT (ABS_MAX+1) diff --git a/trunk/include/linux/net_dropmon.h b/trunk/include/linux/net_dropmon.h index 0e2e100c44a2..0217fb81a630 100644 --- a/trunk/include/linux/net_dropmon.h +++ b/trunk/include/linux/net_dropmon.h @@ -1,7 +1,6 @@ #ifndef __NET_DROPMON_H #define __NET_DROPMON_H -#include #include struct net_dm_drop_point { diff --git a/trunk/include/linux/netfilter/nf_conntrack_tcp.h b/trunk/include/linux/netfilter/nf_conntrack_tcp.h index b2f384d42611..3066789b972a 100644 --- a/trunk/include/linux/netfilter/nf_conntrack_tcp.h +++ b/trunk/include/linux/netfilter/nf_conntrack_tcp.h @@ -35,9 +35,6 @@ enum tcp_conntrack { /* Has unacknowledged data */ #define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED 0x10 -/* The field td_maxack has been set */ -#define IP_CT_TCP_FLAG_MAXACK_SET 0x20 - struct nf_ct_tcp_flags { __u8 flags; __u8 mask; @@ -49,7 +46,6 @@ struct ip_ct_tcp_state { u_int32_t td_end; /* max of seq + len */ u_int32_t td_maxend; /* max of ack + max(win, 1) */ u_int32_t td_maxwin; /* max(win) */ - u_int32_t td_maxack; /* max of ack */ u_int8_t td_scale; /* window scale factor */ u_int8_t flags; /* per direction options */ }; diff --git a/trunk/include/linux/parport.h b/trunk/include/linux/parport.h index 38a423ed3c01..e1f83c5065c5 100644 --- a/trunk/include/linux/parport.h +++ b/trunk/include/linux/parport.h @@ -324,10 +324,6 @@ struct parport { int spintime; atomic_t ref_count; - unsigned long devflags; -#define PARPORT_DEVPROC_REGISTERED 0 - struct pardevice *proc_device; /* Currently register proc device */ - struct list_head full_list; struct parport *slaves[3]; }; diff --git a/trunk/include/linux/swap.h b/trunk/include/linux/swap.h index d476aad3ff57..62d81435347a 100644 --- a/trunk/include/linux/swap.h +++ b/trunk/include/linux/swap.h @@ -437,11 +437,6 @@ static inline int mem_cgroup_cache_charge_swapin(struct page *page, return 0; } -static inline void -mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent) -{ -} - #endif /* CONFIG_SWAP */ #endif /* __KERNEL__*/ #endif /* _LINUX_SWAP_H */ diff --git a/trunk/include/linux/tracehook.h b/trunk/include/linux/tracehook.h index eb96603d92db..c7aa154f4bfc 100644 --- a/trunk/include/linux/tracehook.h +++ b/trunk/include/linux/tracehook.h @@ -259,12 +259,14 @@ static inline void tracehook_finish_clone(struct task_struct *child, /** * tracehook_report_clone - in parent, new child is about to start running + * @trace: return value from tracehook_prepare_clone() * @regs: parent's user register state * @clone_flags: flags from parent's system call * @pid: new child's PID in the parent's namespace * @child: new child task * - * Called after a child is set up, but before it has been started running. + * Called after a child is set up, but before it has been started + * running. @trace is the value returned by tracehook_prepare_clone(). * This is not a good place to block, because the child has not started * yet. Suspend the child here if desired, and then block in * tracehook_report_clone_complete(). This must prevent the child from @@ -274,14 +276,13 @@ static inline void tracehook_finish_clone(struct task_struct *child, * * Called with no locks held, but the child cannot run until this returns. */ -static inline void tracehook_report_clone(struct pt_regs *regs, +static inline void tracehook_report_clone(int trace, struct pt_regs *regs, unsigned long clone_flags, pid_t pid, struct task_struct *child) { - if (unlikely(task_ptrace(child))) { + if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) { /* - * It doesn't matter who attached/attaching to this - * task, the pending SIGSTOP is right in any case. + * The child starts up with an immediate SIGSTOP. */ sigaddset(&child->pending.signal, SIGSTOP); set_tsk_thread_flag(child, TIF_SIGPENDING); diff --git a/trunk/include/sound/soc-dai.h b/trunk/include/sound/soc-dai.h index 352d7eee9b6d..13676472ddfc 100644 --- a/trunk/include/sound/soc-dai.h +++ b/trunk/include/sound/soc-dai.h @@ -44,6 +44,24 @@ struct snd_pcm_substream; #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. * @@ -78,10 +96,6 @@ struct snd_pcm_substream; #define SND_SOC_CLOCK_IN 0 #define SND_SOC_CLOCK_OUT 1 -#define SND_SOC_STD_AC97_FMTS (SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S32_LE |\ - SNDRV_PCM_FMTBIT_S32_BE) - struct snd_soc_dai_ops; struct snd_soc_dai; struct snd_ac97_bus_ops; @@ -194,7 +208,6 @@ struct snd_soc_dai { /* DAI capabilities */ struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; - unsigned int symmetric_rates:1; /* DAI runtime info */ struct snd_pcm_runtime *runtime; @@ -206,8 +219,11 @@ struct snd_soc_dai { /* DAI private data */ void *private_data; - /* parent platform */ - struct snd_soc_platform *platform; + /* parent codec/platform */ + union { + struct snd_soc_codec *codec; + struct snd_soc_platform *platform; + }; struct list_head list; }; diff --git a/trunk/include/sound/soc-dapm.h b/trunk/include/sound/soc-dapm.h index ec8a45f9a069..a7def6a9a030 100644 --- a/trunk/include/sound/soc-dapm.h +++ b/trunk/include/sound/soc-dapm.h @@ -140,30 +140,16 @@ #define SND_SOC_DAPM_DAC(wname, stname, wreg, wshift, winvert) \ { .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ .shift = wshift, .invert = winvert} -#define SND_SOC_DAPM_DAC_E(wname, stname, wreg, wshift, winvert, \ - wevent, wflags) \ -{ .id = snd_soc_dapm_dac, .name = wname, .sname = stname, .reg = wreg, \ - .shift = wshift, .invert = winvert, \ - .event = wevent, .event_flags = wflags} #define SND_SOC_DAPM_ADC(wname, stname, wreg, wshift, winvert) \ { .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ .shift = wshift, .invert = winvert} -#define SND_SOC_DAPM_ADC_E(wname, stname, wreg, wshift, winvert, \ - wevent, wflags) \ -{ .id = snd_soc_dapm_adc, .name = wname, .sname = stname, .reg = wreg, \ - .shift = wshift, .invert = winvert, \ - .event = wevent, .event_flags = wflags} -/* generic widgets */ +/* generic register modifier widget */ #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ { .id = wid, .name = wname, .kcontrols = NULL, .num_kcontrols = 0, \ .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \ .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} -#define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \ -{ .id = snd_soc_dapm_supply, .name = wname, .reg = wreg, \ - .shift = wshift, .invert = winvert, .event = wevent, \ - .event_flags = wflags} /* dapm kcontrol types */ #define SOC_DAPM_SINGLE(xname, reg, shift, max, invert) \ @@ -279,6 +265,8 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, /* dapm events */ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, char *stream, int event); +int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, + enum snd_soc_bias_level level); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); @@ -310,7 +298,6 @@ enum snd_soc_dapm_type { snd_soc_dapm_vmid, /* codec bias/vmid - to minimise pops */ snd_soc_dapm_pre, /* machine specific pre widget - exec first */ snd_soc_dapm_post, /* machine specific post widget - exec last */ - snd_soc_dapm_supply, /* power/clock supply */ }; /* @@ -370,8 +357,6 @@ struct snd_soc_dapm_widget { unsigned char suspend:1; /* was active before suspend */ unsigned char pmdown:1; /* waiting for timeout */ - int (*power_check)(struct snd_soc_dapm_widget *w); - /* external events */ unsigned short event_flags; /* flags to specify event types */ int (*event)(struct snd_soc_dapm_widget*, struct snd_kcontrol *, int); @@ -383,9 +368,6 @@ struct snd_soc_dapm_widget { /* widget input and outputs */ struct list_head sources; struct list_head sinks; - - /* used during DAPM updates */ - struct list_head power_list; }; #endif diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h index cf6111d72b17..a40bc6f316fc 100644 --- a/trunk/include/sound/soc.h +++ b/trunk/include/sound/soc.h @@ -118,14 +118,6 @@ .info = snd_soc_info_volsw, \ .get = xhandler_get, .put = xhandler_put, \ .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } -#define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\ - xhandler_get, xhandler_put) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ - .info = snd_soc_info_volsw, \ - .get = xhandler_get, .put = xhandler_put, \ - .private_value = (unsigned long)&(struct soc_mixer_control) \ - {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ - .max = xmax, .invert = xinvert} } #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ xhandler_get, xhandler_put, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ @@ -214,6 +206,10 @@ void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, struct snd_soc_jack_gpio *gpios); #endif +/* codec IO */ +#define snd_soc_read(codec, reg) codec->read(codec, reg) +#define snd_soc_write(codec, reg, value) codec->write(codec, reg, value) + /* codec register bit access */ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, unsigned short mask, unsigned short value); @@ -335,7 +331,6 @@ struct snd_soc_codec { struct module *owner; struct mutex mutex; struct device *dev; - struct snd_soc_device *socdev; struct list_head list; @@ -369,8 +364,6 @@ struct snd_soc_codec { enum snd_soc_bias_level bias_level; enum snd_soc_bias_level suspend_bias_level; struct delayed_work delayed_work; - struct list_head up_list; - struct list_head down_list; /* codec DAI's */ struct snd_soc_dai *dai; @@ -424,12 +417,6 @@ struct snd_soc_dai_link { /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_codec *codec); - /* Symmetry requirements */ - unsigned int symmetric_rates:1; - - /* Symmetry data - only valid if symmetry is being enforced */ - unsigned int rate; - /* DAI pcm */ struct snd_pcm *pcm; }; @@ -503,19 +490,6 @@ struct soc_enum { void *dapm; }; -/* codec IO */ -static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return codec->read(codec, reg); -} - -static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val) -{ - return codec->write(codec, reg, val); -} - #include #endif diff --git a/trunk/include/sound/wm9081.h b/trunk/include/sound/wm9081.h deleted file mode 100644 index e173ddbf6bd4..000000000000 --- a/trunk/include/sound/wm9081.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * linux/sound/wm9081.h -- Platform data for WM9081 - * - * Copyright 2009 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. - */ - -#ifndef __LINUX_SND_WM_9081_H -#define __LINUX_SND_WM_9081_H - -struct wm9081_retune_mobile_setting { - const char *name; - unsigned int rate; - u16 config[20]; -}; - -struct wm9081_retune_mobile_config { - struct wm9081_retune_mobile_setting *configs; - int num_configs; -}; - -#endif diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 425971600485..faa46da99ebe 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -969,13 +969,10 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg) SYSCALL_DEFINE1(shmdt, char __user *, shmaddr) { struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; + struct vm_area_struct *vma, *next; unsigned long addr = (unsigned long)shmaddr; - int retval = -EINVAL; -#ifdef CONFIG_MMU loff_t size = 0; - struct vm_area_struct *next; -#endif + int retval = -EINVAL; if (addr & ~PAGE_MASK) return retval; diff --git a/trunk/kernel/async.c b/trunk/kernel/async.c index 27235f5de198..50540301ed0f 100644 --- a/trunk/kernel/async.c +++ b/trunk/kernel/async.c @@ -92,18 +92,23 @@ extern int initcall_debug; static async_cookie_t __lowest_in_progress(struct list_head *running) { struct async_entry *entry; + async_cookie_t ret = next_cookie; /* begin with "infinity" value */ if (!list_empty(running)) { entry = list_first_entry(running, struct async_entry, list); - return entry->cookie; + ret = entry->cookie; } - list_for_each_entry(entry, &async_pending, list) - if (entry->running == running) - return entry->cookie; + if (!list_empty(&async_pending)) { + list_for_each_entry(entry, &async_pending, list) + if (entry->running == running) { + ret = entry->cookie; + break; + } + } - return next_cookie; /* "infinity" value */ + return ret; } static async_cookie_t lowest_in_progress(struct list_head *running) diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 875ffbdd96d0..b9e2edd00726 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -1409,7 +1409,7 @@ long do_fork(unsigned long clone_flags, } audit_finish_fork(p); - tracehook_report_clone(regs, clone_flags, nr, p); + tracehook_report_clone(trace, regs, clone_flags, nr, p); /* * We set PF_STARTING at creation in case tracing wants to diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 42c317874cfa..0692ab5a0d67 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -304,8 +304,6 @@ int ptrace_detach(struct task_struct *child, unsigned int data) if (child->ptrace) { child->exit_code = data; dead = __ptrace_detach(current, child); - if (!child->exit_state) - wake_up_process(child); } write_unlock_irq(&tasklist_lock); diff --git a/trunk/kernel/sched_cpupri.c b/trunk/kernel/sched_cpupri.c index 344712a5e3ed..cdd3c89574cd 100644 --- a/trunk/kernel/sched_cpupri.c +++ b/trunk/kernel/sched_cpupri.c @@ -165,7 +165,7 @@ int __init_refok cpupri_init(struct cpupri *cp, bool bootmem) vec->count = 0; if (bootmem) alloc_bootmem_cpumask_var(&vec->mask); - else if (!zalloc_cpumask_var(&vec->mask, GFP_KERNEL)) + else if (!alloc_cpumask_var(&vec->mask, GFP_KERNEL)) goto cleanup; } diff --git a/trunk/kernel/sched_rt.c b/trunk/kernel/sched_rt.c index 9bf0d2a73045..f2c66f8f9712 100644 --- a/trunk/kernel/sched_rt.c +++ b/trunk/kernel/sched_rt.c @@ -1591,7 +1591,7 @@ static inline void init_sched_rt_class(void) unsigned int i; for_each_possible_cpu(i) - zalloc_cpumask_var_node(&per_cpu(local_cpu_mask, i), + alloc_cpumask_var_node(&per_cpu(local_cpu_mask, i), GFP_KERNEL, cpu_to_node(i)); } #endif /* CONFIG_SMP */ diff --git a/trunk/kernel/smp.c b/trunk/kernel/smp.c index ad63d8501207..858baac568ee 100644 --- a/trunk/kernel/smp.c +++ b/trunk/kernel/smp.c @@ -52,7 +52,7 @@ hotplug_cfd(struct notifier_block *nfb, unsigned long action, void *hcpu) switch (action) { case CPU_UP_PREPARE: case CPU_UP_PREPARE_FROZEN: - if (!zalloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL, + if (!alloc_cpumask_var_node(&cfd->cpumask, GFP_KERNEL, cpu_to_node(cpu))) return NOTIFY_BAD; break; diff --git a/trunk/lib/cpumask.c b/trunk/lib/cpumask.c index eb23aaa0c7b8..1f71b97de0f9 100644 --- a/trunk/lib/cpumask.c +++ b/trunk/lib/cpumask.c @@ -119,12 +119,6 @@ bool alloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) } EXPORT_SYMBOL(alloc_cpumask_var_node); -bool zalloc_cpumask_var_node(cpumask_var_t *mask, gfp_t flags, int node) -{ - return alloc_cpumask_var_node(mask, flags | __GFP_ZERO, node); -} -EXPORT_SYMBOL(zalloc_cpumask_var_node); - /** * alloc_cpumask_var - allocate a struct cpumask * @mask: pointer to cpumask_var_t where the cpumask is returned @@ -141,12 +135,6 @@ bool alloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) } EXPORT_SYMBOL(alloc_cpumask_var); -bool zalloc_cpumask_var(cpumask_var_t *mask, gfp_t flags) -{ - return alloc_cpumask_var(mask, flags | __GFP_ZERO); -} -EXPORT_SYMBOL(zalloc_cpumask_var); - /** * alloc_bootmem_cpumask_var - allocate a struct cpumask from the bootmem arena. * @mask: pointer to cpumask_var_t where the cpumask is returned diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 1b60f30cebfa..379ff0bcbf6e 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -121,6 +121,7 @@ void __remove_from_page_cache(struct page *page) mapping->nrpages--; __dec_zone_page_state(page, NR_FILE_PAGES); BUG_ON(page_mapped(page)); + mem_cgroup_uncharge_cache_page(page); /* * Some filesystems seem to re-dirty the page even after @@ -144,7 +145,6 @@ void remove_from_page_cache(struct page *page) spin_lock_irq(&mapping->tree_lock); __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); - mem_cgroup_uncharge_cache_page(page); } static int sync_page(void *word) @@ -476,13 +476,13 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, if (likely(!error)) { mapping->nrpages++; __inc_zone_page_state(page, NR_FILE_PAGES); - spin_unlock_irq(&mapping->tree_lock); } else { page->mapping = NULL; - spin_unlock_irq(&mapping->tree_lock); mem_cgroup_uncharge_cache_page(page); page_cache_release(page); } + + spin_unlock_irq(&mapping->tree_lock); radix_tree_preload_end(); } else mem_cgroup_uncharge_cache_page(page); diff --git a/trunk/mm/hugetlb.c b/trunk/mm/hugetlb.c index e83ad2c9228c..28c655ba9353 100644 --- a/trunk/mm/hugetlb.c +++ b/trunk/mm/hugetlb.c @@ -316,7 +316,7 @@ static void resv_map_release(struct kref *ref) static struct resv_map *vma_resv_map(struct vm_area_struct *vma) { VM_BUG_ON(!is_vm_hugetlb_page(vma)); - if (!(vma->vm_flags & VM_MAYSHARE)) + if (!(vma->vm_flags & VM_SHARED)) return (struct resv_map *)(get_vma_private_data(vma) & ~HPAGE_RESV_MASK); return NULL; @@ -325,7 +325,7 @@ static struct resv_map *vma_resv_map(struct vm_area_struct *vma) static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map) { VM_BUG_ON(!is_vm_hugetlb_page(vma)); - VM_BUG_ON(vma->vm_flags & VM_MAYSHARE); + VM_BUG_ON(vma->vm_flags & VM_SHARED); set_vma_private_data(vma, (get_vma_private_data(vma) & HPAGE_RESV_MASK) | (unsigned long)map); @@ -334,7 +334,7 @@ static void set_vma_resv_map(struct vm_area_struct *vma, struct resv_map *map) static void set_vma_resv_flags(struct vm_area_struct *vma, unsigned long flags) { VM_BUG_ON(!is_vm_hugetlb_page(vma)); - VM_BUG_ON(vma->vm_flags & VM_MAYSHARE); + VM_BUG_ON(vma->vm_flags & VM_SHARED); set_vma_private_data(vma, get_vma_private_data(vma) | flags); } @@ -353,7 +353,7 @@ static void decrement_hugepage_resv_vma(struct hstate *h, if (vma->vm_flags & VM_NORESERVE) return; - if (vma->vm_flags & VM_MAYSHARE) { + if (vma->vm_flags & VM_SHARED) { /* Shared mappings always use reserves */ h->resv_huge_pages--; } else if (is_vma_resv_set(vma, HPAGE_RESV_OWNER)) { @@ -369,14 +369,14 @@ static void decrement_hugepage_resv_vma(struct hstate *h, void reset_vma_resv_huge_pages(struct vm_area_struct *vma) { VM_BUG_ON(!is_vm_hugetlb_page(vma)); - if (!(vma->vm_flags & VM_MAYSHARE)) + if (!(vma->vm_flags & VM_SHARED)) vma->vm_private_data = (void *)0; } /* Returns true if the VMA has associated reserve pages */ static int vma_has_reserves(struct vm_area_struct *vma) { - if (vma->vm_flags & VM_MAYSHARE) + if (vma->vm_flags & VM_SHARED) return 1; if (is_vma_resv_set(vma, HPAGE_RESV_OWNER)) return 1; @@ -924,7 +924,7 @@ static long vma_needs_reservation(struct hstate *h, struct address_space *mapping = vma->vm_file->f_mapping; struct inode *inode = mapping->host; - if (vma->vm_flags & VM_MAYSHARE) { + if (vma->vm_flags & VM_SHARED) { pgoff_t idx = vma_hugecache_offset(h, vma, addr); return region_chg(&inode->i_mapping->private_list, idx, idx + 1); @@ -949,7 +949,7 @@ static void vma_commit_reservation(struct hstate *h, struct address_space *mapping = vma->vm_file->f_mapping; struct inode *inode = mapping->host; - if (vma->vm_flags & VM_MAYSHARE) { + if (vma->vm_flags & VM_SHARED) { pgoff_t idx = vma_hugecache_offset(h, vma, addr); region_add(&inode->i_mapping->private_list, idx, idx + 1); @@ -1893,7 +1893,7 @@ static int hugetlb_cow(struct mm_struct *mm, struct vm_area_struct *vma, * at the time of fork() could consume its reserves on COW instead * of the full address range. */ - if (!(vma->vm_flags & VM_MAYSHARE) && + if (!(vma->vm_flags & VM_SHARED) && is_vma_resv_set(vma, HPAGE_RESV_OWNER) && old_page != pagecache_page) outside_reserve = 1; @@ -2000,7 +2000,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma, clear_huge_page(page, address, huge_page_size(h)); __SetPageUptodate(page); - if (vma->vm_flags & VM_MAYSHARE) { + if (vma->vm_flags & VM_SHARED) { int err; struct inode *inode = mapping->host; @@ -2104,7 +2104,7 @@ int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, goto out_mutex; } - if (!(vma->vm_flags & VM_MAYSHARE)) + if (!(vma->vm_flags & VM_SHARED)) pagecache_page = hugetlbfs_pagecache_page(h, vma, address); } @@ -2289,7 +2289,7 @@ int hugetlb_reserve_pages(struct inode *inode, * to reserve the full area even if read-only as mprotect() may be * called to make the mapping read-write. Assume !vma is a shm mapping */ - if (!vma || vma->vm_flags & VM_MAYSHARE) + if (!vma || vma->vm_flags & VM_SHARED) chg = region_chg(&inode->i_mapping->private_list, from, to); else { struct resv_map *resv_map = resv_map_alloc(); @@ -2330,7 +2330,7 @@ int hugetlb_reserve_pages(struct inode *inode, * consumed reservations are stored in the map. Hence, nothing * else has to be done for private mappings here */ - if (!vma || vma->vm_flags & VM_MAYSHARE) + if (!vma || vma->vm_flags & VM_SHARED) region_add(&inode->i_mapping->private_list, from, to); return 0; } diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 78eb8552818b..01c2d8f14685 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -314,6 +314,14 @@ static struct mem_cgroup *try_get_mem_cgroup_from_mm(struct mm_struct *mm) return mem; } +static bool mem_cgroup_is_obsolete(struct mem_cgroup *mem) +{ + if (!mem) + return true; + return css_is_removed(&mem->css); +} + + /* * Call callback function against all cgroup under hierarchy tree. */ @@ -924,7 +932,7 @@ static int __mem_cgroup_try_charge(struct mm_struct *mm, if (unlikely(!mem)) return 0; - VM_BUG_ON(css_is_removed(&mem->css)); + VM_BUG_ON(!mem || mem_cgroup_is_obsolete(mem)); while (1) { int ret; @@ -1480,9 +1488,8 @@ void mem_cgroup_uncharge_cache_page(struct page *page) __mem_cgroup_uncharge_common(page, MEM_CGROUP_CHARGE_TYPE_CACHE); } -#ifdef CONFIG_SWAP /* - * called after __delete_from_swap_cache() and drop "page" account. + * called from __delete_from_swap_cache() and drop "page" account. * memcg information is recorded to swap_cgroup of "ent" */ void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent) @@ -1499,7 +1506,6 @@ void mem_cgroup_uncharge_swapcache(struct page *page, swp_entry_t ent) if (memcg) css_put(&memcg->css); } -#endif #ifdef CONFIG_CGROUP_MEM_RES_CTLR_SWAP /* diff --git a/trunk/mm/oom_kill.c b/trunk/mm/oom_kill.c index a7b2460e922b..92bcf1db16b2 100644 --- a/trunk/mm/oom_kill.c +++ b/trunk/mm/oom_kill.c @@ -284,28 +284,22 @@ static void dump_tasks(const struct mem_cgroup *mem) printk(KERN_INFO "[ pid ] uid tgid total_vm rss cpu oom_adj " "name\n"); do_each_thread(g, p) { - struct mm_struct *mm; - + /* + * total_vm and rss sizes do not exist for tasks with a + * detached mm so there's no need to report them. + */ + if (!p->mm) + continue; if (mem && !task_in_mem_cgroup(p, mem)) continue; if (!thread_group_leader(p)) continue; task_lock(p); - mm = p->mm; - if (!mm) { - /* - * total_vm and rss sizes do not exist for tasks with no - * mm so there's no need to report them; they can't be - * oom killed anyway. - */ - task_unlock(p); - continue; - } printk(KERN_INFO "[%5d] %5d %5d %8lu %8lu %3d %3d %s\n", - p->pid, __task_cred(p)->uid, p->tgid, mm->total_vm, - get_mm_rss(mm), (int)task_cpu(p), p->oomkilladj, - p->comm); + p->pid, __task_cred(p)->uid, p->tgid, + p->mm->total_vm, get_mm_rss(p->mm), (int)task_cpu(p), + p->oomkilladj, p->comm); task_unlock(p); } while_each_thread(g, p); } diff --git a/trunk/mm/swap_state.c b/trunk/mm/swap_state.c index 1416e7e9e02d..3ecea98ecb45 100644 --- a/trunk/mm/swap_state.c +++ b/trunk/mm/swap_state.c @@ -109,6 +109,8 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask) */ void __delete_from_swap_cache(struct page *page) { + swp_entry_t ent = {.val = page_private(page)}; + VM_BUG_ON(!PageLocked(page)); VM_BUG_ON(!PageSwapCache(page)); VM_BUG_ON(PageWriteback(page)); @@ -119,6 +121,7 @@ void __delete_from_swap_cache(struct page *page) total_swapcache_pages--; __dec_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(del_total); + mem_cgroup_uncharge_swapcache(page, ent); } /** @@ -188,7 +191,6 @@ void delete_from_swap_cache(struct page *page) __delete_from_swap_cache(page); spin_unlock_irq(&swapper_space.tree_lock); - mem_cgroup_uncharge_swapcache(page, entry); swap_free(entry); page_cache_release(page); } diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index 12e1579f9165..55206fab7b99 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -359,7 +359,6 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) BUG_ON(page_has_private(page)); __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); - mem_cgroup_uncharge_cache_page(page); page_cache_release(page); /* pagecache ref */ return 1; failed: diff --git a/trunk/mm/vmscan.c b/trunk/mm/vmscan.c index d254306562cd..5fa3eda1f03f 100644 --- a/trunk/mm/vmscan.c +++ b/trunk/mm/vmscan.c @@ -470,12 +470,10 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) swp_entry_t swap = { .val = page_private(page) }; __delete_from_swap_cache(page); spin_unlock_irq(&mapping->tree_lock); - mem_cgroup_uncharge_swapcache(page, swap); swap_free(swap); } else { __remove_from_page_cache(page); spin_unlock_irq(&mapping->tree_lock); - mem_cgroup_uncharge_cache_page(page); } return 1; diff --git a/trunk/net/bluetooth/hci_sysfs.c b/trunk/net/bluetooth/hci_sysfs.c index 95f7a7a544b4..4cc3624bd22d 100644 --- a/trunk/net/bluetooth/hci_sysfs.c +++ b/trunk/net/bluetooth/hci_sysfs.c @@ -90,6 +90,9 @@ static void add_conn(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, work_add); struct hci_dev *hdev = conn->hdev; + /* ensure previous del is complete */ + flush_work(&conn->work_del); + dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle); if (device_add(&conn->dev) < 0) { @@ -115,6 +118,9 @@ static void del_conn(struct work_struct *work) struct hci_conn *conn = container_of(work, struct hci_conn, work_del); struct hci_dev *hdev = conn->hdev; + /* ensure previous add is complete */ + flush_work(&conn->work_add); + if (!device_is_registered(&conn->dev)) return; diff --git a/trunk/net/netfilter/nf_conntrack_proto_dccp.c b/trunk/net/netfilter/nf_conntrack_proto_dccp.c index aee0d6bea309..8e757dd53396 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_dccp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_dccp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static DEFINE_RWLOCK(dccp_lock); @@ -554,9 +553,6 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, ct->proto.dccp.state = new_state; write_unlock_bh(&dccp_lock); - if (new_state != old_state) - nf_conntrack_event_cache(IPCT_PROTOINFO, ct); - dn = dccp_pernet(net); nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]); diff --git a/trunk/net/netfilter/nf_conntrack_proto_tcp.c b/trunk/net/netfilter/nf_conntrack_proto_tcp.c index 97a6e93d742e..b5ccf2b4b2e7 100644 --- a/trunk/net/netfilter/nf_conntrack_proto_tcp.c +++ b/trunk/net/netfilter/nf_conntrack_proto_tcp.c @@ -634,14 +634,6 @@ static bool tcp_in_window(const struct nf_conn *ct, sender->td_end = end; sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED; } - if (tcph->ack) { - if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) { - sender->td_maxack = ack; - sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET; - } else if (after(ack, sender->td_maxack)) - sender->td_maxack = ack; - } - /* * Update receiver data. */ @@ -926,16 +918,6 @@ static int tcp_packet(struct nf_conn *ct, "nf_ct_tcp: invalid state "); return -NF_ACCEPT; case TCP_CONNTRACK_CLOSE: - if (index == TCP_RST_SET - && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET) - && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) { - /* Invalid RST */ - write_unlock_bh(&tcp_lock); - if (LOG_INVALID(net, IPPROTO_TCP)) - nf_log_packet(pf, 0, skb, NULL, NULL, NULL, - "nf_ct_tcp: invalid RST "); - return -NF_ACCEPT; - } if (index == TCP_RST_SET && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status) && ct->proto.tcp.last_index == TCP_SYN_SET) diff --git a/trunk/net/netfilter/nfnetlink_log.c b/trunk/net/netfilter/nfnetlink_log.c index 66a6dd5c519a..fd326ac27ec8 100644 --- a/trunk/net/netfilter/nfnetlink_log.c +++ b/trunk/net/netfilter/nfnetlink_log.c @@ -581,12 +581,6 @@ nfulnl_log_packet(u_int8_t pf, + nla_total_size(sizeof(struct nfulnl_msg_packet_hw)) + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp)); - if (in && skb_mac_header_was_set(skb)) { - size += nla_total_size(skb->dev->hard_header_len) - + nla_total_size(sizeof(u_int16_t)) /* hwtype */ - + nla_total_size(sizeof(u_int16_t)); /* hwlen */ - } - spin_lock_bh(&inst->lock); if (inst->flags & NFULNL_CFG_F_SEQ) diff --git a/trunk/net/netfilter/xt_hashlimit.c b/trunk/net/netfilter/xt_hashlimit.c index 219dcdbe388c..a5b5369c30f9 100644 --- a/trunk/net/netfilter/xt_hashlimit.c +++ b/trunk/net/netfilter/xt_hashlimit.c @@ -926,7 +926,7 @@ static int dl_seq_show(struct seq_file *s, void *v) if (!hlist_empty(&htable->hash[*bucket])) { hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node) if (dl_seq_real_show(ent, htable->family, s)) - return -1; + return 1; } return 0; } diff --git a/trunk/net/sched/cls_api.c b/trunk/net/sched/cls_api.c index 09cdcdfe7e91..0759f32e9dca 100644 --- a/trunk/net/sched/cls_api.c +++ b/trunk/net/sched/cls_api.c @@ -135,7 +135,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) unsigned long cl; unsigned long fh; int err; - int tp_created = 0; if (net != &init_net) return -EINVAL; @@ -267,7 +266,10 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) goto errout; } - tp_created = 1; + spin_lock_bh(root_lock); + tp->next = *back; + *back = tp; + spin_unlock_bh(root_lock); } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) goto errout; @@ -294,11 +296,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) switch (n->nlmsg_type) { case RTM_NEWTFILTER: err = -EEXIST; - if (n->nlmsg_flags & NLM_F_EXCL) { - if (tp_created) - tcf_destroy(tp); + if (n->nlmsg_flags & NLM_F_EXCL) goto errout; - } break; case RTM_DELTFILTER: err = tp->ops->delete(tp, fh); @@ -315,18 +314,8 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) } err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); - if (err == 0) { - if (tp_created) { - spin_lock_bh(root_lock); - tp->next = *back; - *back = tp; - spin_unlock_bh(root_lock); - } + if (err == 0) tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); - } else { - if (tp_created) - tcf_destroy(tp); - } errout: if (cl) diff --git a/trunk/net/sched/cls_cgroup.c b/trunk/net/sched/cls_cgroup.c index e5becb92b3e7..91a3db4a76f8 100644 --- a/trunk/net/sched/cls_cgroup.c +++ b/trunk/net/sched/cls_cgroup.c @@ -104,7 +104,8 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_result *res) { struct cls_cgroup_head *head = tp->root; - u32 classid; + struct cgroup_cls_state *cs; + int ret = 0; /* * Due to the nature of the classifier it is required to ignore all @@ -120,18 +121,17 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp, return -1; rcu_read_lock(); - classid = task_cls_state(current)->classid; - rcu_read_unlock(); - - if (!classid) - return -1; + cs = task_cls_state(current); + if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) { + res->classid = cs->classid; + res->class = 0; + ret = tcf_exts_exec(skb, &head->exts, res); + } else + ret = -1; - if (!tcf_em_tree_match(skb, &head->ematches, NULL)) - return -1; + rcu_read_unlock(); - res->classid = classid; - res->class = 0; - return tcf_exts_exec(skb, &head->exts, res); + return ret; } static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) @@ -167,9 +167,6 @@ static int cls_cgroup_change(struct tcf_proto *tp, unsigned long base, struct tcf_exts e; int err; - if (!tca[TCA_OPTIONS]) - return -EINVAL; - if (head == NULL) { if (!handle) return -EINVAL; diff --git a/trunk/net/sunrpc/svcsock.c b/trunk/net/sunrpc/svcsock.c index 9d504234af4a..af3198814c15 100644 --- a/trunk/net/sunrpc/svcsock.c +++ b/trunk/net/sunrpc/svcsock.c @@ -345,7 +345,6 @@ static void svc_sock_setbufsize(struct socket *sock, unsigned int snd, lock_sock(sock->sk); sock->sk->sk_sndbuf = snd * 2; sock->sk->sk_rcvbuf = rcv * 2; - sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK|SOCK_RCVBUF_LOCK; release_sock(sock->sk); #endif } @@ -797,23 +796,6 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp) test_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags), test_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags)); - if (test_and_clear_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags)) - /* sndbuf needs to have room for one request - * per thread, otherwise we can stall even when the - * network isn't a bottleneck. - * - * We count all threads rather than threads in a - * particular pool, which provides an upper bound - * on the number of threads which will access the socket. - * - * rcvbuf just needs to be able to hold a few requests. - * Normally they will be removed from the queue - * as soon a a complete request arrives. - */ - svc_sock_setbufsize(svsk->sk_sock, - (serv->sv_nrthreads+3) * serv->sv_max_mesg, - 3 * serv->sv_max_mesg); - clear_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); /* Receive data. If we haven't got the record length yet, get @@ -1061,15 +1043,6 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv) tcp_sk(sk)->nonagle |= TCP_NAGLE_OFF; - /* initialise setting must have enough space to - * receive and respond to one request. - * svc_tcp_recvfrom will re-adjust if necessary - */ - svc_sock_setbufsize(svsk->sk_sock, - 3 * svsk->sk_xprt.xpt_server->sv_max_mesg, - 3 * svsk->sk_xprt.xpt_server->sv_max_mesg); - - set_bit(XPT_CHNGBUF, &svsk->sk_xprt.xpt_flags); set_bit(XPT_DATA, &svsk->sk_xprt.xpt_flags); if (sk->sk_state != TCP_ESTABLISHED) set_bit(XPT_CLOSE, &svsk->sk_xprt.xpt_flags); @@ -1139,8 +1112,14 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv, /* Initialize the socket */ if (sock->type == SOCK_DGRAM) svc_udp_init(svsk, serv); - else + else { + /* initialise setting must have enough space to + * receive and respond to one request. + */ + svc_sock_setbufsize(svsk->sk_sock, 4 * serv->sv_max_mesg, + 4 * serv->sv_max_mesg); svc_tcp_init(svsk, serv); + } dprintk("svc: svc_setup_socket created %p (inet %p)\n", svsk, svsk->sk_sk); diff --git a/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c index f11be72a1a80..8b510c5e8777 100644 --- a/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/trunk/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -128,8 +128,7 @@ static int fast_reg_xdr(struct svcxprt_rdma *xprt, page_bytes -= sge_bytes; frmr->page_list->page_list[page_no] = - ib_dma_map_single(xprt->sc_cm_id->device, - page_address(page), + ib_dma_map_page(xprt->sc_cm_id->device, page, 0, PAGE_SIZE, DMA_TO_DEVICE); if (ib_dma_mapping_error(xprt->sc_cm_id->device, frmr->page_list->page_list[page_no])) @@ -533,17 +532,18 @@ static int send_reply(struct svcxprt_rdma *rdma, clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags); /* Prepare the SGE for the RPCRDMA Header */ - ctxt->sge[0].lkey = rdma->sc_dma_lkey; - ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp); ctxt->sge[0].addr = - ib_dma_map_single(rdma->sc_cm_id->device, page_address(page), - ctxt->sge[0].length, DMA_TO_DEVICE); + ib_dma_map_page(rdma->sc_cm_id->device, + page, 0, PAGE_SIZE, DMA_TO_DEVICE); if (ib_dma_mapping_error(rdma->sc_cm_id->device, ctxt->sge[0].addr)) goto err; atomic_inc(&rdma->sc_dma_used); ctxt->direction = DMA_TO_DEVICE; + ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp); + ctxt->sge[0].lkey = rdma->sc_dma_lkey; + /* Determine how many of our SGE are to be transmitted */ for (sge_no = 1; byte_count && sge_no < vec->count; sge_no++) { sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count); diff --git a/trunk/net/sunrpc/xprtrdma/svc_rdma_transport.c b/trunk/net/sunrpc/xprtrdma/svc_rdma_transport.c index 5151f9f6c573..4b0c2fa15e0b 100644 --- a/trunk/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/trunk/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -500,8 +500,8 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt) BUG_ON(sge_no >= xprt->sc_max_sge); page = svc_rdma_get_page(); ctxt->pages[sge_no] = page; - pa = ib_dma_map_single(xprt->sc_cm_id->device, - page_address(page), PAGE_SIZE, + pa = ib_dma_map_page(xprt->sc_cm_id->device, + page, 0, PAGE_SIZE, DMA_FROM_DEVICE); if (ib_dma_mapping_error(xprt->sc_cm_id->device, pa)) goto err_put_ctxt; @@ -1315,8 +1315,8 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp, length = svc_rdma_xdr_encode_error(xprt, rmsgp, err, va); /* Prepare SGE for local address */ - sge.addr = ib_dma_map_single(xprt->sc_cm_id->device, - page_address(p), PAGE_SIZE, DMA_FROM_DEVICE); + sge.addr = ib_dma_map_page(xprt->sc_cm_id->device, + p, 0, PAGE_SIZE, DMA_FROM_DEVICE); if (ib_dma_mapping_error(xprt->sc_cm_id->device, sge.addr)) { put_page(p); return; @@ -1343,7 +1343,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp, if (ret) { dprintk("svcrdma: Error %d posting send for protocol error\n", ret); - ib_dma_unmap_single(xprt->sc_cm_id->device, + ib_dma_unmap_page(xprt->sc_cm_id->device, sge.addr, PAGE_SIZE, DMA_FROM_DEVICE); svc_rdma_put_context(ctxt, 1); diff --git a/trunk/security/tomoyo/tomoyo.c b/trunk/security/tomoyo/tomoyo.c index e42be5c4f055..5b481912752a 100644 --- a/trunk/security/tomoyo/tomoyo.c +++ b/trunk/security/tomoyo/tomoyo.c @@ -27,12 +27,6 @@ static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) { - int rc; - - rc = cap_bprm_set_creds(bprm); - if (rc) - return rc; - /* * Do only if this function is called for the first time of an execve * operation. diff --git a/trunk/sound/aoa/fabrics/layout.c b/trunk/sound/aoa/fabrics/layout.c index 586965f9605f..fbf5c933baa4 100644 --- a/trunk/sound/aoa/fabrics/layout.c +++ b/trunk/sound/aoa/fabrics/layout.c @@ -1037,7 +1037,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) } ldev->selfptr_headphone.ptr = ldev; ldev->selfptr_lineout.ptr = ldev; - dev_set_drvdata(&sdev->ofdev.dev, ldev); + sdev->ofdev.dev.driver_data = ldev; list_add(&ldev->list, &layouts_list); layouts_list_items++; @@ -1081,7 +1081,7 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) static int aoa_fabric_layout_remove(struct soundbus_dev *sdev) { - struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev); + struct layout_dev *ldev = sdev->ofdev.dev.driver_data; int i; for (i=0; iofdev.dev); + struct layout_dev *ldev = sdev->ofdev.dev.driver_data; if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_off(&ldev->gpio); @@ -1124,7 +1124,7 @@ static int aoa_fabric_layout_suspend(struct soundbus_dev *sdev, pm_message_t sta static int aoa_fabric_layout_resume(struct soundbus_dev *sdev) { - struct layout_dev *ldev = dev_get_drvdata(&sdev->ofdev.dev); + struct layout_dev *ldev = sdev->ofdev.dev.driver_data; if (ldev->gpio.methods && ldev->gpio.methods->all_amps_off) ldev->gpio.methods->all_amps_restore(&ldev->gpio); diff --git a/trunk/sound/aoa/soundbus/i2sbus/core.c b/trunk/sound/aoa/soundbus/i2sbus/core.c index 4e3b819d4993..418c84c99d69 100644 --- a/trunk/sound/aoa/soundbus/i2sbus/core.c +++ b/trunk/sound/aoa/soundbus/i2sbus/core.c @@ -358,14 +358,14 @@ static int i2sbus_probe(struct macio_dev* dev, const struct of_device_id *match) return -ENODEV; } - dev_set_drvdata(&dev->ofdev.dev, control); + dev->ofdev.dev.driver_data = control; return 0; } static int i2sbus_remove(struct macio_dev* dev) { - struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); + struct i2sbus_control *control = dev->ofdev.dev.driver_data; struct i2sbus_dev *i2sdev, *tmp; list_for_each_entry_safe(i2sdev, tmp, &control->list, item) @@ -377,7 +377,7 @@ static int i2sbus_remove(struct macio_dev* dev) #ifdef CONFIG_PM static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) { - struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); + struct i2sbus_control *control = dev->ofdev.dev.driver_data; struct codec_info_item *cii; struct i2sbus_dev* i2sdev; int err, ret = 0; @@ -407,7 +407,7 @@ static int i2sbus_suspend(struct macio_dev* dev, pm_message_t state) static int i2sbus_resume(struct macio_dev* dev) { - struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); + struct i2sbus_control *control = dev->ofdev.dev.driver_data; struct codec_info_item *cii; struct i2sbus_dev* i2sdev; int err, ret = 0; diff --git a/trunk/sound/core/pcm_lib.c b/trunk/sound/core/pcm_lib.c index d659995ac3ac..a2a792c18c40 100644 --- a/trunk/sound/core/pcm_lib.c +++ b/trunk/sound/core/pcm_lib.c @@ -249,11 +249,6 @@ static int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *substream) new_hw_ptr = hw_base + pos; } } - - /* Do jiffies check only in xrun_debug mode */ - if (!xrun_debug(substream)) - goto no_jiffies_check; - /* Skip the jiffies check for hardwares with BATCH flag. * Such hardware usually just increases the position at each IRQ, * thus it can't give any strange position. @@ -341,9 +336,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream) hw_base = 0; new_hw_ptr = hw_base + pos; } - /* Do jiffies check only in xrun_debug mode */ - if (xrun_debug(substream) && - ((delta * HZ) / runtime->rate) > jdelta + HZ/100) { + if (((delta * HZ) / runtime->rate) > jdelta + HZ/100) { hw_ptr_error(substream, "hw_ptr skipping! " "(pos=%ld, delta=%ld, period=%ld, jdelta=%lu/%lu)\n", @@ -1485,6 +1478,7 @@ static int snd_pcm_lib_ioctl_reset(struct snd_pcm_substream *substream, runtime->status->hw_ptr %= runtime->buffer_size; else runtime->status->hw_ptr = 0; + runtime->hw_ptr_jiffies = jiffies; snd_pcm_stream_unlock_irqrestore(substream, flags); return 0; } diff --git a/trunk/sound/core/pcm_native.c b/trunk/sound/core/pcm_native.c index b5da656d1ece..fc6f98e257df 100644 --- a/trunk/sound/core/pcm_native.c +++ b/trunk/sound/core/pcm_native.c @@ -848,7 +848,6 @@ static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state) { struct snd_pcm_runtime *runtime = substream->runtime; snd_pcm_trigger_tstamp(substream); - runtime->hw_ptr_jiffies = jiffies; runtime->status->state = state; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && runtime->silence_size > 0) @@ -962,11 +961,6 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) { if (substream->runtime->trigger_master != substream) return 0; - /* The jiffies check in snd_pcm_update_hw_ptr*() is done by - * a delta betwen the current jiffies, this gives a large enough - * delta, effectively to skip the check once. - */ - substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; return substream->ops->trigger(substream, push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH : SNDRV_PCM_TRIGGER_PAUSE_RELEASE); diff --git a/trunk/sound/pci/au88x0/au88x0_core.c b/trunk/sound/pci/au88x0/au88x0_core.c index 3906f5afe27a..f84bb19c7fdd 100644 --- a/trunk/sound/pci/au88x0/au88x0_core.c +++ b/trunk/sound/pci/au88x0/au88x0_core.c @@ -1255,8 +1255,8 @@ static int inline vortex_adbdma_getlinearpos(vortex_t * vortex, int adbdma) int temp; temp = hwread(vortex->mmio, VORTEX_ADBDMA_STAT + (adbdma << 2)); - temp = (dma->period_virt * dma->period_bytes) + (temp & POS_MASK); - return (temp); + temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1)); + return temp; } static void vortex_adbdma_startfifo(vortex_t * vortex, int adbdma) @@ -1504,8 +1504,7 @@ static int inline vortex_wtdma_getlinearpos(vortex_t * vortex, int wtdma) int temp; temp = hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)); - //temp = (temp & POS_MASK) + (((temp>>WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK)*(dma->cfg0&POS_MASK)); - temp = (temp & POS_MASK) + ((dma->period_virt) * (dma->period_bytes)); + temp = (dma->period_virt * dma->period_bytes) + (temp & (dma->period_bytes - 1)); return temp; } diff --git a/trunk/sound/pci/hda/patch_conexant.c b/trunk/sound/pci/hda/patch_conexant.c index 4fcbe21829ab..56ce19e68cb5 100644 --- a/trunk/sound/pci/hda/patch_conexant.c +++ b/trunk/sound/pci/hda/patch_conexant.c @@ -1848,7 +1848,6 @@ static const char *cxt5051_models[CXT5051_MODELS] = { static struct snd_pci_quirk cxt5051_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), - SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5051_LAPTOP), SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), diff --git a/trunk/sound/soc/Kconfig b/trunk/sound/soc/Kconfig index d3e786a9a0a7..3d2bb6fc6dcc 100644 --- a/trunk/sound/soc/Kconfig +++ b/trunk/sound/soc/Kconfig @@ -32,9 +32,7 @@ source "sound/soc/fsl/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/pxa/Kconfig" source "sound/soc/s3c24xx/Kconfig" -source "sound/soc/s6000/Kconfig" source "sound/soc/sh/Kconfig" -source "sound/soc/txx9/Kconfig" # Supported codecs source "sound/soc/codecs/Kconfig" diff --git a/trunk/sound/soc/Makefile b/trunk/sound/soc/Makefile index 6f1e28de23cf..0237879fd412 100644 --- a/trunk/sound/soc/Makefile +++ b/trunk/sound/soc/Makefile @@ -10,6 +10,4 @@ obj-$(CONFIG_SND_SOC) += fsl/ obj-$(CONFIG_SND_SOC) += omap/ obj-$(CONFIG_SND_SOC) += pxa/ obj-$(CONFIG_SND_SOC) += s3c24xx/ -obj-$(CONFIG_SND_SOC) += s6000/ obj-$(CONFIG_SND_SOC) += sh/ -obj-$(CONFIG_SND_SOC) += txx9/ diff --git a/trunk/sound/soc/atmel/Kconfig b/trunk/sound/soc/atmel/Kconfig index e720d5e6f04c..a608d7009dbd 100644 --- a/trunk/sound/soc/atmel/Kconfig +++ b/trunk/sound/soc/atmel/Kconfig @@ -41,11 +41,3 @@ config SND_AT32_SOC_PLAYPAQ_SLAVE 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. - -config SND_AT91_SOC_AFEB9260 - tristate "SoC Audio support for AFEB9260 board" - depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC - select SND_ATMEL_SOC_SSC - select SND_SOC_TLV320AIC23 - help - Say Y here to support sound on AFEB9260 board. diff --git a/trunk/sound/soc/atmel/Makefile b/trunk/sound/soc/atmel/Makefile index e7ea56bd5f82..f54a7cc68e66 100644 --- a/trunk/sound/soc/atmel/Makefile +++ b/trunk/sound/soc/atmel/Makefile @@ -13,4 +13,3 @@ 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 -obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o diff --git a/trunk/sound/soc/atmel/playpaq_wm8510.c b/trunk/sound/soc/atmel/playpaq_wm8510.c index 9eb610c2ba91..70657534e6b1 100644 --- a/trunk/sound/soc/atmel/playpaq_wm8510.c +++ b/trunk/sound/soc/atmel/playpaq_wm8510.c @@ -117,7 +117,7 @@ static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( * Find actual rate, compare to requested rate */ actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1)); - pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n", + pr_debug("playpaq_wm8510: Request rate = %d, actual rate = %d\n", rate, actual_rate); diff --git a/trunk/sound/soc/atmel/snd-soc-afeb9260.c b/trunk/sound/soc/atmel/snd-soc-afeb9260.c deleted file mode 100644 index 23349de27313..000000000000 --- a/trunk/sound/soc/atmel/snd-soc-afeb9260.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * afeb9260.c -- SoC audio for AFEB9260 - * - * Copyright (C) 2009 Sergey Lapin - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "../codecs/tlv320aic23.h" -#include "atmel-pcm.h" -#include "atmel_ssc_dai.h" - -#define CODEC_CLOCK 12000000 - -static int afeb9260_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 err; - - /* Set codec DAI configuration */ - err = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S| - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBM_CFM); - if (err < 0) { - printk(KERN_ERR "can't set codec DAI configuration\n"); - return err; - } - - /* Set cpu DAI configuration */ - err = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_IF | - SND_SOC_DAIFMT_CBM_CFM); - if (err < 0) { - printk(KERN_ERR "can't set cpu DAI configuration\n"); - return err; - } - - /* Set the codec system clock for DAC and ADC */ - err = - snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); - - if (err < 0) { - printk(KERN_ERR "can't set codec system clock\n"); - return err; - } - - return err; -} - -static struct snd_soc_ops afeb9260_ops = { - .hw_params = afeb9260_hw_params, -}; - -static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - {"LLINEIN", NULL, "Line In"}, - {"RLINEIN", NULL, "Line In"}, - - {"MICIN", NULL, "Mic Jack"}, -}; - -static int afeb9260_tlv320aic23_init(struct snd_soc_codec *codec) -{ - - /* Add afeb9260 specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, - ARRAY_SIZE(tlv320aic23_dapm_widgets)); - - /* Set up afeb9260 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - - snd_soc_dapm_sync(codec); - - return 0; -} - -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link afeb9260_dai = { - .name = "TLV320AIC23", - .stream_name = "AIC23", - .cpu_dai = &atmel_ssc_dai[0], - .codec_dai = &tlv320aic23_dai, - .init = afeb9260_tlv320aic23_init, - .ops = &afeb9260_ops, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_machine_afeb9260 = { - .name = "AFEB9260", - .platform = &atmel_soc_platform, - .dai_link = &afeb9260_dai, - .num_links = 1, -}; - -/* Audio subsystem */ -static struct snd_soc_device afeb9260_snd_devdata = { - .card = &snd_soc_machine_afeb9260, - .codec_dev = &soc_codec_dev_tlv320aic23, -}; - -static struct platform_device *afeb9260_snd_device; - -static int __init afeb9260_soc_init(void) -{ - int err; - struct device *dev; - struct atmel_ssc_info *ssc_p = afeb9260_dai.cpu_dai->private_data; - struct ssc_device *ssc = NULL; - - if (!(machine_is_afeb9260())) - return -ENODEV; - - ssc = ssc_request(0); - if (IS_ERR(ssc)) { - printk(KERN_ERR "ASoC: Failed to request SSC 0\n"); - err = PTR_ERR(ssc); - ssc = NULL; - goto err_ssc; - } - ssc_p->ssc = ssc; - - afeb9260_snd_device = platform_device_alloc("soc-audio", -1); - if (!afeb9260_snd_device) { - printk(KERN_ERR "ASoC: Platform device allocation failed\n"); - return -ENOMEM; - } - - platform_set_drvdata(afeb9260_snd_device, &afeb9260_snd_devdata); - afeb9260_snd_devdata.dev = &afeb9260_snd_device->dev; - err = platform_device_add(afeb9260_snd_device); - if (err) - goto err1; - - dev = &afeb9260_snd_device->dev; - - return 0; -err1: - platform_device_del(afeb9260_snd_device); - platform_device_put(afeb9260_snd_device); -err_ssc: - return err; - -} - -static void __exit afeb9260_soc_exit(void) -{ - platform_device_unregister(afeb9260_snd_device); -} - -module_init(afeb9260_soc_init); -module_exit(afeb9260_soc_exit); - -MODULE_AUTHOR("Sergey Lapin "); -MODULE_DESCRIPTION("ALSA SoC for AFEB9260"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/sound/soc/blackfin/bf5xx-ac97.c b/trunk/sound/soc/blackfin/bf5xx-ac97.c index b1ed423fabd5..8a935f2d1767 100644 --- a/trunk/sound/soc/blackfin/bf5xx-ac97.c +++ b/trunk/sound/soc/blackfin/bf5xx-ac97.c @@ -31,15 +31,6 @@ #include "bf5xx-sport.h" #include "bf5xx-ac97.h" -/* Anomaly notes: - * 05000250 - AD1980 is running in TDM mode and RFS/TFS are generated by SPORT - * contrtoller. But, RFSDIV and TFSDIV are always set to 16*16-1, - * while the max AC97 data size is 13*16. The DIV is always larger - * than data size. AD73311 and ad2602 are not running in TDM mode. - * AD1836 and AD73322 depend on external RFS/TFS only. So, this - * anomaly does not affect blackfin sound drivers. -*/ - static int *cmd_count; static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; diff --git a/trunk/sound/soc/blackfin/bf5xx-sport.c b/trunk/sound/soc/blackfin/bf5xx-sport.c index 469ce7fab20c..b7953c8cf838 100644 --- a/trunk/sound/soc/blackfin/bf5xx-sport.c +++ b/trunk/sound/soc/blackfin/bf5xx-sport.c @@ -190,7 +190,7 @@ static inline int sport_hook_rx_dummy(struct sport_device *sport) desc = get_dma_next_desc_ptr(sport->dma_rx_chan); /* Copy the descriptor which will be damaged to backup */ temp_desc = *desc; - desc->x_count = sport->dummy_count / 2; + desc->x_count = 0xa; desc->y_count = 0; desc->next_desc_addr = sport->dummy_rx_desc; local_irq_restore(flags); @@ -309,7 +309,7 @@ static inline int sport_hook_tx_dummy(struct sport_device *sport) desc = get_dma_next_desc_ptr(sport->dma_tx_chan); /* Store the descriptor which will be damaged */ temp_desc = *desc; - desc->x_count = sport->dummy_count / 2; + desc->x_count = 0xa; desc->y_count = 0; desc->next_desc_addr = sport->dummy_tx_desc; local_irq_restore(flags); diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index bbc97fd76648..b6c7f7a01cb0 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -18,9 +18,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4535 if I2C select SND_SOC_CS4270 if I2C select SND_SOC_PCM3008 - select SND_SOC_SPDIF select SND_SOC_SSM2602 if I2C - select SND_SOC_STAC9766 if SND_SOC_AC97_BUS select SND_SOC_TLV320AIC23 if I2C select SND_SOC_TLV320AIC26 if SPI_MASTER select SND_SOC_TLV320AIC3X if I2C @@ -37,12 +35,8 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C - select SND_SOC_WM8940 if I2C - select SND_SOC_WM8960 if I2C select SND_SOC_WM8971 if I2C - select SND_SOC_WM8988 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8990 if I2C - select SND_SOC_WM9081 if I2C select SND_SOC_WM9705 if SND_SOC_AC97_BUS select SND_SOC_WM9712 if SND_SOC_AC97_BUS select SND_SOC_WM9713 if SND_SOC_AC97_BUS @@ -92,15 +86,9 @@ config SND_SOC_L3 config SND_SOC_PCM3008 tristate -config SND_SOC_SPDIF - tristate - config SND_SOC_SSM2602 tristate -config SND_SOC_STAC9766 - tristate - config SND_SOC_TLV320AIC23 tristate @@ -150,24 +138,12 @@ config SND_SOC_WM8900 config SND_SOC_WM8903 tristate -config SND_SOC_WM8940 - tristate - -config SND_SOC_WM8960 - tristate - config SND_SOC_WM8971 tristate -config SND_SOC_WM8988 - tristate - config SND_SOC_WM8990 tristate -config SND_SOC_WM9081 - tristate - config SND_SOC_WM9705 tristate diff --git a/trunk/sound/soc/codecs/Makefile b/trunk/sound/soc/codecs/Makefile index 8b7530546f4d..f2653803ede8 100644 --- a/trunk/sound/soc/codecs/Makefile +++ b/trunk/sound/soc/codecs/Makefile @@ -6,9 +6,7 @@ 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-spdif-objs := spdif_transciever.o snd-soc-ssm2602-objs := ssm2602.o -snd-soc-stac9766-objs := stac9766.o snd-soc-tlv320aic23-objs := tlv320aic23.o snd-soc-tlv320aic26-objs := tlv320aic26.o snd-soc-tlv320aic3x-objs := tlv320aic3x.o @@ -25,12 +23,8 @@ snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o -snd-soc-wm8940-objs := wm8940.o -snd-soc-wm8960-objs := wm8960.o snd-soc-wm8971-objs := wm8971.o -snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o -snd-soc-wm9081-objs := wm9081.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o snd-soc-wm9713-objs := wm9713.o @@ -43,9 +37,7 @@ 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_SPDIF) += snd-soc-spdif.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o -obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.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 @@ -63,11 +55,7 @@ obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8971) += snd-soc-wm8971.o -obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o -obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o -obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o -obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o diff --git a/trunk/sound/soc/codecs/ac97.c b/trunk/sound/soc/codecs/ac97.c index 932299bb5d1e..b0d4af145b87 100644 --- a/trunk/sound/soc/codecs/ac97.c +++ b/trunk/sound/soc/codecs/ac97.c @@ -53,13 +53,13 @@ struct snd_soc_dai ac97_dai = { .channels_min = 1, .channels_max = 2, .rates = STD_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .capture = { .stream_name = "AC97 Capture", .channels_min = 1, .channels_max = 2, .rates = STD_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &ac97_dai_ops, }; EXPORT_SYMBOL_GPL(ac97_dai); diff --git a/trunk/sound/soc/codecs/ad1980.c b/trunk/sound/soc/codecs/ad1980.c index d7440a982d22..ddb3b08ac23c 100644 --- a/trunk/sound/soc/codecs/ad1980.c +++ b/trunk/sound/soc/codecs/ad1980.c @@ -137,13 +137,13 @@ struct snd_soc_dai ad1980_dai = { .channels_min = 2, .channels_max = 6, .rates = SNDRV_PCM_RATE_48000, - .formats = SND_SOC_STD_AC97_FMTS, }, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { .stream_name = "Capture", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000, - .formats = SND_SOC_STD_AC97_FMTS, }, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, }; EXPORT_SYMBOL_GPL(ad1980_dai); diff --git a/trunk/sound/soc/codecs/cs4270.c b/trunk/sound/soc/codecs/cs4270.c index a32b8226c8a4..7fa09a387622 100644 --- a/trunk/sound/soc/codecs/cs4270.c +++ b/trunk/sound/soc/codecs/cs4270.c @@ -18,7 +18,7 @@ * - The machine driver's 'startup' function must call * cs4270_set_dai_sysclk() with the value of MCLK. * - Only I2S and left-justified modes are supported - * - Power management is supported + * - Power management is not supported */ #include @@ -27,7 +27,6 @@ #include #include #include -#include #include "cs4270.h" @@ -57,7 +56,6 @@ #define CS4270_FIRSTREG 0x01 #define CS4270_LASTREG 0x08 #define CS4270_NUMREGS (CS4270_LASTREG - CS4270_FIRSTREG + 1) -#define CS4270_I2C_INCR 0x80 /* Bit masks for the CS4270 registers */ #define CS4270_CHIPID_ID 0xF0 @@ -66,8 +64,6 @@ #define CS4270_PWRCTL_PDN_ADC 0x20 #define CS4270_PWRCTL_PDN_DAC 0x02 #define CS4270_PWRCTL_PDN 0x01 -#define CS4270_PWRCTL_PDN_ALL \ - (CS4270_PWRCTL_PDN_ADC | CS4270_PWRCTL_PDN_DAC | CS4270_PWRCTL_PDN) #define CS4270_MODE_SPEED_MASK 0x30 #define CS4270_MODE_1X 0x00 #define CS4270_MODE_2X 0x10 @@ -113,7 +109,6 @@ struct cs4270_private { unsigned int mclk; /* Input frequency of the MCLK pin */ unsigned int mode; /* The mode (I2S or left-justified) */ unsigned int slave_mode; - unsigned int manual_mute; }; /** @@ -300,7 +295,7 @@ static int cs4270_fill_cache(struct snd_soc_codec *codec) s32 length; length = i2c_smbus_read_i2c_block_data(i2c_client, - CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache); + CS4270_FIRSTREG | 0x80, CS4270_NUMREGS, cache); if (length != CS4270_NUMREGS) { dev_err(codec->dev, "i2c read failure, addr=0x%x\n", @@ -458,7 +453,7 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, } /** - * cs4270_dai_mute - enable/disable the CS4270 external mute + * cs4270_mute - enable/disable the CS4270 external mute * @dai: the SOC DAI * @mute: 0 = disable mute, 1 = enable mute * @@ -467,52 +462,21 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream, * board does not have the MUTEA or MUTEB pins connected to such circuitry, * then this function will do nothing. */ -static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) +static int cs4270_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - struct cs4270_private *cs4270 = codec->private_data; int reg6; reg6 = snd_soc_read(codec, CS4270_MUTE); if (mute) reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; - else { + else reg6 &= ~(CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B); - reg6 |= cs4270->manual_mute; - } return snd_soc_write(codec, CS4270_MUTE, reg6); } -/** - * cs4270_soc_put_mute - put callback for the 'Master Playback switch' - * alsa control. - * @kcontrol: mixer control - * @ucontrol: control element information - * - * This function basically passes the arguments on to the generic - * snd_soc_put_volsw() function and saves the mute information in - * our private data structure. This is because we want to prevent - * cs4270_dai_mute() neglecting the user's decision to manually - * mute the codec's output. - * - * Returns 0 for success. - */ -static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct cs4270_private *cs4270 = codec->private_data; - int left = !ucontrol->value.integer.value[0]; - int right = !ucontrol->value.integer.value[1]; - - cs4270->manual_mute = (left ? CS4270_MUTE_DAC_A : 0) | - (right ? CS4270_MUTE_DAC_B : 0); - - return snd_soc_put_volsw(kcontrol, ucontrol); -} - /* A list of non-DAPM controls that the CS4270 supports */ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_DOUBLE_R("Master Playback Volume", @@ -522,9 +486,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = { SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), - SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), - SOC_DOUBLE_EXT("Master Playback Switch", CS4270_MUTE, 0, 1, 1, 1, - snd_soc_get_volsw, cs4270_soc_put_mute), + SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 0) }; /* @@ -544,7 +506,7 @@ static struct snd_soc_dai_ops cs4270_dai_ops = { .hw_params = cs4270_hw_params, .set_sysclk = cs4270_set_dai_sysclk, .set_fmt = cs4270_set_dai_fmt, - .digital_mute = cs4270_dai_mute, + .digital_mute = cs4270_mute, }; struct snd_soc_dai cs4270_dai = { @@ -791,57 +753,6 @@ static struct i2c_device_id cs4270_id[] = { }; MODULE_DEVICE_TABLE(i2c, cs4270_id); -#ifdef CONFIG_PM - -/* This suspend/resume implementation can handle both - a simple standby - * where the codec remains powered, and a full suspend, where the voltage - * domain the codec is connected to is teared down and/or any other hardware - * reset condition is asserted. - * - * The codec's own power saving features are enabled in the suspend callback, - * and all registers are written back to the hardware when resuming. - */ - -static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg) -{ - struct cs4270_private *cs4270 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = &cs4270->codec; - int reg = snd_soc_read(codec, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; - - return snd_soc_write(codec, CS4270_PWRCTL, reg); -} - -static int cs4270_i2c_resume(struct i2c_client *client) -{ - struct cs4270_private *cs4270 = i2c_get_clientdata(client); - struct snd_soc_codec *codec = &cs4270->codec; - int reg; - - /* In case the device was put to hard reset during sleep, we need to - * wait 500ns here before any I2C communication. */ - ndelay(500); - - /* first restore the entire register cache ... */ - for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { - u8 val = snd_soc_read(codec, reg); - - if (i2c_smbus_write_byte_data(client, reg, val)) { - dev_err(codec->dev, "i2c write failed\n"); - return -EIO; - } - } - - /* ... then disable the power-down bits */ - reg = snd_soc_read(codec, CS4270_PWRCTL); - reg &= ~CS4270_PWRCTL_PDN_ALL; - - return snd_soc_write(codec, CS4270_PWRCTL, reg); -} -#else -#define cs4270_i2c_suspend NULL -#define cs4270_i2c_resume NULL -#endif /* CONFIG_PM */ - /* * cs4270_i2c_driver - I2C device identification * @@ -856,8 +767,6 @@ static struct i2c_driver cs4270_i2c_driver = { .id_table = cs4270_id, .probe = cs4270_i2c_probe, .remove = cs4270_i2c_remove, - .suspend = cs4270_i2c_suspend, - .resume = cs4270_i2c_resume, }; /* diff --git a/trunk/sound/soc/codecs/spdif_transciever.c b/trunk/sound/soc/codecs/spdif_transciever.c deleted file mode 100644 index 218b33adad90..000000000000 --- a/trunk/sound/soc/codecs/spdif_transciever.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ALSA SoC SPDIF DIT driver - * - * This driver is used by controllers which can operate in DIT (SPDI/F) where - * no codec is needed. This file provides stub codec that can be used - * in these configurations. TI DaVinci Audio controller uses this driver. - * - * Author: Steve Chen, - * Copyright: (C) 2009 MontaVista Software, Inc., - * Copyright: (C) 2009 Texas Instruments, India - * - * 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 -#include -#include -#include - -#include "spdif_transciever.h" - -#define STUB_RATES SNDRV_PCM_RATE_8000_96000 -#define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE - -struct snd_soc_dai dit_stub_dai = { - .name = "DIT", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 384, - .rates = STUB_RATES, - .formats = STUB_FORMATS, - }, -}; - -static int spdif_dit_probe(struct platform_device *pdev) -{ - dit_stub_dai.dev = &pdev->dev; - return snd_soc_register_dai(&dit_stub_dai); -} - -static int spdif_dit_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&dit_stub_dai); - return 0; -} - -static struct platform_driver spdif_dit_driver = { - .probe = spdif_dit_probe, - .remove = spdif_dit_remove, - .driver = { - .name = "spdif-dit", - .owner = THIS_MODULE, - }, -}; - -static int __init dit_modinit(void) -{ - return platform_driver_register(&spdif_dit_driver); -} - -static void __exit dit_exit(void) -{ - platform_driver_unregister(&spdif_dit_driver); -} - -module_init(dit_modinit); -module_exit(dit_exit); - diff --git a/trunk/sound/soc/codecs/spdif_transciever.h b/trunk/sound/soc/codecs/spdif_transciever.h deleted file mode 100644 index 296f2eb6c4ef..000000000000 --- a/trunk/sound/soc/codecs/spdif_transciever.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * ALSA SoC DIT/DIR driver header - * - * Author: Steve Chen, - * Copyright: (C) 2008 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 CODEC_STUBS_H -#define CODEC_STUBS_H - -extern struct snd_soc_dai dit_stub_dai; - -#endif /* CODEC_STUBS_H */ diff --git a/trunk/sound/soc/codecs/ssm2602.c b/trunk/sound/soc/codecs/ssm2602.c index 1fc4c8e0899c..87f606c76822 100644 --- a/trunk/sound/soc/codecs/ssm2602.c +++ b/trunk/sound/soc/codecs/ssm2602.c @@ -336,17 +336,15 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, master_runtime->sample_bits, master_runtime->rate); - if (master_runtime->rate != 0) - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - master_runtime->rate, - master_runtime->rate); - - if (master_runtime->sample_bits != 0) - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - master_runtime->sample_bits, - master_runtime->sample_bits); + 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); ssm2602->slave_substream = substream; } else @@ -374,11 +372,6 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, struct snd_soc_device *socdev = rtd->socdev; struct snd_soc_codec *codec = socdev->card->codec; struct ssm2602_priv *ssm2602 = codec->private_data; - - if (ssm2602->master_substream == substream) - ssm2602->master_substream = ssm2602->slave_substream; - - ssm2602->slave_substream = NULL; /* deactivate */ if (!codec->active) ssm2602_write(codec, SSM2602_ACTIVE, 0); @@ -504,9 +497,11 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, return 0; } -#define SSM2602_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_32000 |\ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\ - SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) +#define SSM2602_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 SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) diff --git a/trunk/sound/soc/codecs/stac9766.c b/trunk/sound/soc/codecs/stac9766.c deleted file mode 100644 index 8ad4b7b3e3ba..000000000000 --- a/trunk/sound/soc/codecs/stac9766.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * stac9766.c -- ALSA SoC STAC9766 codec support - * - * Copyright 2009 Jon Smirl, Digispeaker - * Author: Jon Smirl - * - * 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. - * - * Features:- - * - * o Support for AC97 Codec, S/PDIF - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "stac9766.h" - -#define STAC9766_VERSION "0.10" - -/* - * STAC9766 register cache - */ -static const u16 stac9766_reg[] = { - 0x6A90, 0x8000, 0x8000, 0x8000, /* 6 */ - 0x0000, 0x0000, 0x8008, 0x8008, /* e */ - 0x8808, 0x8808, 0x8808, 0x8808, /* 16 */ - 0x8808, 0x0000, 0x8000, 0x0000, /* 1e */ - 0x0000, 0x0000, 0x0000, 0x000f, /* 26 */ - 0x0a05, 0x0400, 0xbb80, 0x0000, /* 2e */ - 0x0000, 0xbb80, 0x0000, 0x0000, /* 36 */ - 0x0000, 0x2000, 0x0000, 0x0100, /* 3e */ - 0x0000, 0x0000, 0x0080, 0x0000, /* 46 */ - 0x0000, 0x0000, 0x0003, 0xffff, /* 4e */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 56 */ - 0x4000, 0x0000, 0x0000, 0x0000, /* 5e */ - 0x1201, 0xFFFF, 0xFFFF, 0x0000, /* 66 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */ - 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 7e */ -}; - -static const char *stac9766_record_mux[] = {"Mic", "CD", "Video", "AUX", - "Line", "Stereo Mix", "Mono Mix", "Phone"}; -static const char *stac9766_mono_mux[] = {"Mix", "Mic"}; -static const char *stac9766_mic_mux[] = {"Mic1", "Mic2"}; -static const char *stac9766_SPDIF_mux[] = {"PCM", "ADC Record"}; -static const char *stac9766_popbypass_mux[] = {"Normal", "Bypass Mixer"}; -static const char *stac9766_record_all_mux[] = {"All analog", - "Analog plus DAC"}; -static const char *stac9766_boost1[] = {"0dB", "10dB"}; -static const char *stac9766_boost2[] = {"0dB", "20dB"}; -static const char *stac9766_stereo_mic[] = {"Off", "On"}; - -static const struct soc_enum stac9766_record_enum = - SOC_ENUM_DOUBLE(AC97_REC_SEL, 8, 0, 8, stac9766_record_mux); -static const struct soc_enum stac9766_mono_enum = - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 9, 2, stac9766_mono_mux); -static const struct soc_enum stac9766_mic_enum = - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 8, 2, stac9766_mic_mux); -static const struct soc_enum stac9766_SPDIF_enum = - SOC_ENUM_SINGLE(AC97_STAC_DA_CONTROL, 1, 2, stac9766_SPDIF_mux); -static const struct soc_enum stac9766_popbypass_enum = - SOC_ENUM_SINGLE(AC97_GENERAL_PURPOSE, 15, 2, stac9766_popbypass_mux); -static const struct soc_enum stac9766_record_all_enum = - SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 12, 2, - stac9766_record_all_mux); -static const struct soc_enum stac9766_boost1_enum = - SOC_ENUM_SINGLE(AC97_MIC, 6, 2, stac9766_boost1); /* 0/10dB */ -static const struct soc_enum stac9766_boost2_enum = - SOC_ENUM_SINGLE(AC97_STAC_ANALOG_SPECIAL, 2, 2, stac9766_boost2); /* 0/20dB */ -static const struct soc_enum stac9766_stereo_mic_enum = - SOC_ENUM_SINGLE(AC97_STAC_STEREO_MIC, 2, 1, stac9766_stereo_mic); - -static const DECLARE_TLV_DB_LINEAR(master_tlv, -4600, 0); -static const DECLARE_TLV_DB_LINEAR(record_tlv, 0, 2250); -static const DECLARE_TLV_DB_LINEAR(beep_tlv, -4500, 0); -static const DECLARE_TLV_DB_LINEAR(mix_tlv, -3450, 1200); - -static const struct snd_kcontrol_new stac9766_snd_ac97_controls[] = { - SOC_DOUBLE_TLV("Speaker Volume", AC97_MASTER, 8, 0, 31, 1, master_tlv), - SOC_SINGLE("Speaker Switch", AC97_MASTER, 15, 1, 1), - SOC_DOUBLE_TLV("Headphone Volume", AC97_HEADPHONE, 8, 0, 31, 1, - master_tlv), - SOC_SINGLE("Headphone Switch", AC97_HEADPHONE, 15, 1, 1), - SOC_SINGLE_TLV("Mono Out Volume", AC97_MASTER_MONO, 0, 31, 1, - master_tlv), - SOC_SINGLE("Mono Out Switch", AC97_MASTER_MONO, 15, 1, 1), - - SOC_DOUBLE_TLV("Record Volume", AC97_REC_GAIN, 8, 0, 15, 0, record_tlv), - SOC_SINGLE("Record Switch", AC97_REC_GAIN, 15, 1, 1), - - - SOC_SINGLE_TLV("Beep Volume", AC97_PC_BEEP, 1, 15, 1, beep_tlv), - SOC_SINGLE("Beep Switch", AC97_PC_BEEP, 15, 1, 1), - SOC_SINGLE("Beep Frequency", AC97_PC_BEEP, 5, 127, 1), - SOC_SINGLE_TLV("Phone Volume", AC97_PHONE, 0, 31, 1, mix_tlv), - SOC_SINGLE("Phone Switch", AC97_PHONE, 15, 1, 1), - - SOC_ENUM("Mic Boost1", stac9766_boost1_enum), - SOC_ENUM("Mic Boost2", stac9766_boost2_enum), - SOC_SINGLE_TLV("Mic Volume", AC97_MIC, 0, 31, 1, mix_tlv), - SOC_SINGLE("Mic Switch", AC97_MIC, 15, 1, 1), - SOC_ENUM("Stereo Mic", stac9766_stereo_mic_enum), - - SOC_DOUBLE_TLV("Line Volume", AC97_LINE, 8, 0, 31, 1, mix_tlv), - SOC_SINGLE("Line Switch", AC97_LINE, 15, 1, 1), - SOC_DOUBLE_TLV("CD Volume", AC97_CD, 8, 0, 31, 1, mix_tlv), - SOC_SINGLE("CD Switch", AC97_CD, 15, 1, 1), - SOC_DOUBLE_TLV("AUX Volume", AC97_AUX, 8, 0, 31, 1, mix_tlv), - SOC_SINGLE("AUX Switch", AC97_AUX, 15, 1, 1), - SOC_DOUBLE_TLV("Video Volume", AC97_VIDEO, 8, 0, 31, 1, mix_tlv), - SOC_SINGLE("Video Switch", AC97_VIDEO, 15, 1, 1), - - SOC_DOUBLE_TLV("DAC Volume", AC97_PCM, 8, 0, 31, 1, mix_tlv), - SOC_SINGLE("DAC Switch", AC97_PCM, 15, 1, 1), - SOC_SINGLE("Loopback Test Switch", AC97_GENERAL_PURPOSE, 7, 1, 0), - SOC_SINGLE("3D Volume", AC97_3D_CONTROL, 3, 2, 1), - SOC_SINGLE("3D Switch", AC97_GENERAL_PURPOSE, 13, 1, 0), - - SOC_ENUM("SPDIF Mux", stac9766_SPDIF_enum), - SOC_ENUM("Mic1/2 Mux", stac9766_mic_enum), - SOC_ENUM("Record All Mux", stac9766_record_all_enum), - SOC_ENUM("Record Mux", stac9766_record_enum), - SOC_ENUM("Mono Mux", stac9766_mono_enum), - SOC_ENUM("Pop Bypass Mux", stac9766_popbypass_enum), -}; - -static int stac9766_ac97_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int val) -{ - u16 *cache = codec->reg_cache; - - if (reg > AC97_STAC_PAGE0) { - stac9766_ac97_write(codec, AC97_INT_PAGING, 0); - soc_ac97_ops.write(codec->ac97, reg, val); - stac9766_ac97_write(codec, AC97_INT_PAGING, 1); - return 0; - } - if (reg / 2 > ARRAY_SIZE(stac9766_reg)) - return -EIO; - - soc_ac97_ops.write(codec->ac97, reg, val); - cache[reg / 2] = val; - return 0; -} - -static unsigned int stac9766_ac97_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 val = 0, *cache = codec->reg_cache; - - if (reg > AC97_STAC_PAGE0) { - stac9766_ac97_write(codec, AC97_INT_PAGING, 0); - val = soc_ac97_ops.read(codec->ac97, reg - AC97_STAC_PAGE0); - stac9766_ac97_write(codec, AC97_INT_PAGING, 1); - return val; - } - if (reg / 2 > ARRAY_SIZE(stac9766_reg)) - return -EIO; - - if (reg == AC97_RESET || reg == AC97_GPIO_STATUS || - reg == AC97_INT_PAGING || reg == AC97_VENDOR_ID1 || - reg == AC97_VENDOR_ID2) { - - val = soc_ac97_ops.read(codec->ac97, reg); - return val; - } - return cache[reg / 2]; -} - -static int ac97_analog_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; - unsigned short reg, vra; - - vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); - - vra |= 0x1; /* enable variable rate audio */ - - stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - reg = AC97_PCM_FRONT_DAC_RATE; - else - reg = AC97_PCM_LR_ADC_RATE; - - return stac9766_ac97_write(codec, reg, runtime->rate); -} - -static int ac97_digital_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; - unsigned short reg, vra; - - stac9766_ac97_write(codec, AC97_SPDIF, 0x2002); - - vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); - vra |= 0x5; /* Enable VRA and SPDIF out */ - - stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); - - reg = AC97_PCM_FRONT_DAC_RATE; - - return stac9766_ac97_write(codec, reg, runtime->rate); -} - -static int ac97_digital_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned short vra; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - vra = stac9766_ac97_read(codec, AC97_EXTENDED_STATUS); - vra &= !0x04; - stac9766_ac97_write(codec, AC97_EXTENDED_STATUS, vra); - break; - } - return 0; -} - -static int stac9766_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - switch (level) { - case SND_SOC_BIAS_ON: /* full On */ - case SND_SOC_BIAS_PREPARE: /* partial On */ - case SND_SOC_BIAS_STANDBY: /* Off, with power */ - stac9766_ac97_write(codec, AC97_POWERDOWN, 0x0000); - break; - case SND_SOC_BIAS_OFF: /* Off, without power */ - /* disable everything including AC link */ - stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff); - break; - } - codec->bias_level = level; - return 0; -} - -static int stac9766_reset(struct snd_soc_codec *codec, int try_warm) -{ - if (try_warm && soc_ac97_ops.warm_reset) { - soc_ac97_ops.warm_reset(codec->ac97); - if (stac9766_ac97_read(codec, 0) == stac9766_reg[0]) - return 1; - } - - soc_ac97_ops.reset(codec->ac97); - if (soc_ac97_ops.warm_reset) - soc_ac97_ops.warm_reset(codec->ac97); - if (stac9766_ac97_read(codec, 0) != stac9766_reg[0]) - return -EIO; - return 0; -} - -static int stac9766_codec_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - stac9766_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int stac9766_codec_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - u16 id, reset; - - reset = 0; - /* give the codec an AC97 warm reset to start the link */ -reset: - if (reset > 5) { - printk(KERN_ERR "stac9766 failed to resume"); - return -EIO; - } - codec->ac97->bus->ops->warm_reset(codec->ac97); - id = soc_ac97_ops.read(codec->ac97, AC97_VENDOR_ID2); - if (id != 0x4c13) { - stac9766_reset(codec, 0); - reset++; - goto reset; - } - stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) - stac9766_set_bias_level(codec, SND_SOC_BIAS_ON); - - return 0; -} - -static struct snd_soc_dai_ops stac9766_dai_ops_analog = { - .prepare = ac97_analog_prepare, -}; - -static struct snd_soc_dai_ops stac9766_dai_ops_digital = { - .prepare = ac97_digital_prepare, - .trigger = ac97_digital_trigger, -}; - -struct snd_soc_dai stac9766_dai[] = { -{ - .name = "stac9766 analog", - .id = 0, - .ac97_control = 1, - - /* stream cababilities */ - .playback = { - .stream_name = "stac9766 analog", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SND_SOC_STD_AC97_FMTS, - }, - .capture = { - .stream_name = "stac9766 analog", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SND_SOC_STD_AC97_FMTS, - }, - /* alsa ops */ - .ops = &stac9766_dai_ops_analog, -}, -{ - .name = "stac9766 IEC958", - .id = 1, - .ac97_control = 1, - - /* stream cababilities */ - .playback = { - .stream_name = "stac9766 IEC958", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE, - }, - /* alsa ops */ - .ops = &stac9766_dai_ops_digital, -} -}; -EXPORT_SYMBOL_GPL(stac9766_dai); - -static int stac9766_codec_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); - - socdev->card->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); - if (socdev->card->codec == NULL) - return -ENOMEM; - codec = socdev->card->codec; - mutex_init(&codec->mutex); - - codec->reg_cache = kmemdup(stac9766_reg, sizeof(stac9766_reg), - GFP_KERNEL); - if (codec->reg_cache == NULL) { - ret = -ENOMEM; - goto cache_err; - } - codec->reg_cache_size = sizeof(stac9766_reg); - codec->reg_cache_step = 2; - - codec->name = "STAC9766"; - codec->owner = THIS_MODULE; - codec->dai = stac9766_dai; - codec->num_dai = ARRAY_SIZE(stac9766_dai); - codec->write = stac9766_ac97_write; - codec->read = stac9766_ac97_read; - codec->set_bias_level = stac9766_set_bias_level; - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); - if (ret < 0) - goto codec_err; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) - goto pcm_err; - - /* do a cold reset for the controller and then try - * a warm reset followed by an optional cold reset for codec */ - stac9766_reset(codec, 0); - ret = stac9766_reset(codec, 1); - if (ret < 0) { - printk(KERN_ERR "Failed to reset STAC9766: AC97 link error\n"); - goto reset_err; - } - - stac9766_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - snd_soc_add_controls(codec, stac9766_snd_ac97_controls, - ARRAY_SIZE(stac9766_snd_ac97_controls)); - - ret = snd_soc_init_card(socdev); - if (ret < 0) - goto reset_err; - return 0; - -reset_err: - snd_soc_free_pcms(socdev); -pcm_err: - snd_soc_free_ac97_codec(codec); -codec_err: - kfree(codec->private_data); -cache_err: - kfree(socdev->card->codec); - socdev->card->codec = NULL; - return ret; -} - -static int stac9766_codec_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - if (codec == NULL) - return 0; - - snd_soc_free_pcms(socdev); - snd_soc_free_ac97_codec(codec); - kfree(codec->reg_cache); - kfree(codec); - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_stac9766 = { - .probe = stac9766_codec_probe, - .remove = stac9766_codec_remove, - .suspend = stac9766_codec_suspend, - .resume = stac9766_codec_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_stac9766); - -MODULE_DESCRIPTION("ASoC stac9766 driver"); -MODULE_AUTHOR("Jon Smirl "); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/stac9766.h b/trunk/sound/soc/codecs/stac9766.h deleted file mode 100644 index 65642eb8393e..000000000000 --- a/trunk/sound/soc/codecs/stac9766.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * stac9766.h -- STAC9766 Soc Audio driver - */ - -#ifndef _STAC9766_H -#define _STAC9766_H - -#define AC97_STAC_PAGE0 0x1000 -#define AC97_STAC_DA_CONTROL (AC97_STAC_PAGE0 | 0x6A) -#define AC97_STAC_ANALOG_SPECIAL (AC97_STAC_PAGE0 | 0x6E) -#define AC97_STAC_STEREO_MIC 0x78 - -/* STAC9766 DAI ID's */ -#define STAC9766_DAI_AC97_ANALOG 0 -#define STAC9766_DAI_AC97_DIGITAL 1 - -extern struct snd_soc_dai stac9766_dai[]; -extern struct snd_soc_codec_device soc_codec_dev_stac9766; - - -#endif diff --git a/trunk/sound/soc/codecs/tlv320aic23.c b/trunk/sound/soc/codecs/tlv320aic23.c index 0b8dcb5cd729..c3f4afb5d017 100644 --- a/trunk/sound/soc/codecs/tlv320aic23.c +++ b/trunk/sound/soc/codecs/tlv320aic23.c @@ -86,7 +86,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg, */ if ((reg < 0 || reg > 9) && (reg != 15)) { - printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg); + printk(KERN_WARNING "%s Invalid register R%d\n", __func__, reg); return -1; } @@ -98,7 +98,7 @@ static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg, if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; - printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__, + printk(KERN_ERR "%s cannot write %03x to register R%d\n", __func__, value, reg); return -EIO; @@ -273,14 +273,14 @@ static const unsigned short sr_valid_mask[] = { * Every divisor is a factor of 11*12 */ #define SR_MULT (11*12) -#define A(x) (SR_MULT/x) +#define A(x) (x) ? (SR_MULT/x) : 0 static const unsigned char sr_adc_mult_table[] = { - A(2), A(2), A(12), A(12), 0, 0, A(3), A(1), - A(2), A(2), A(11), A(11), 0, 0, 0, A(1) + 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), 0, 0, A(3), A(1), - A(2), A(11), A(2), A(11), 0, 0, 0, A(1) + 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, @@ -523,8 +523,6 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_I2S: iface_reg |= TLV320AIC23_FOR_I2S; break; - case SND_SOC_DAIFMT_DSP_A: - iface_reg |= TLV320AIC23_LRP_ON; case SND_SOC_DAIFMT_DSP_B: iface_reg |= TLV320AIC23_FOR_DSP; break; diff --git a/trunk/sound/soc/codecs/twl4030.c b/trunk/sound/soc/codecs/twl4030.c index 4dbb853eef5a..df7c8c281d2f 100644 --- a/trunk/sound/soc/codecs/twl4030.c +++ b/trunk/sound/soc/codecs/twl4030.c @@ -115,7 +115,6 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = { 0x00, /* REG_VIBRA_PWM_SET (0x47) */ 0x00, /* REG_ANAMIC_GAIN (0x48) */ 0x00, /* REG_MISC_SET_2 (0x49) */ - 0x00, /* REG_SW_SHADOW (0x4A) - Shadow, non HW register */ }; /* codec private data */ @@ -126,17 +125,6 @@ struct twl4030_priv { struct snd_pcm_substream *master_substream; struct snd_pcm_substream *slave_substream; - - unsigned int configured; - unsigned int rate; - unsigned int sample_bits; - unsigned int channels; - - unsigned int sysclk; - - /* Headset output state handling */ - unsigned int hsl_enabled; - unsigned int hsr_enabled; }; /* @@ -173,11 +161,7 @@ static int twl4030_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { twl4030_write_reg_cache(codec, reg, value); - if (likely(reg < TWL4030_REG_SW_SHADOW)) - return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, - reg); - else - return 0; + return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); } static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) @@ -204,7 +188,6 @@ static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) static void twl4030_init_chip(struct snd_soc_codec *codec) { - u8 *cache = codec->reg_cache; int i; /* clear CODECPDZ prior to setting register defaults */ @@ -212,7 +195,7 @@ static void twl4030_init_chip(struct snd_soc_codec *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, cache[i]); + twl4030_write(codec, i, twl4030_reg[i]); } @@ -249,7 +232,7 @@ static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) TWL4030_REG_PRECKL_CTL); reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_PRECKR_CTL); twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, - reg_val & (~TWL4030_PRECKR_GAIN), + reg_val & (~TWL4030_PRECKL_GAIN), TWL4030_REG_PRECKR_CTL); /* Disable PLL */ @@ -333,60 +316,104 @@ static void twl4030_power_down(struct snd_soc_codec *codec) } /* Earpiece */ -static const struct snd_kcontrol_new twl4030_dapm_earpiece_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_EAR_CTL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_EAR_CTL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_EAR_CTL, 2, 1, 0), - SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_EAR_CTL, 3, 1, 0), -}; +static const char *twl4030_earpiece_texts[] = + {"Off", "DACL1", "DACL2", "DACR1"}; + +static const unsigned int twl4030_earpiece_values[] = + {0x0, 0x1, 0x2, 0x4}; + +static const struct soc_enum twl4030_earpiece_enum = + SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7, + ARRAY_SIZE(twl4030_earpiece_texts), + twl4030_earpiece_texts, + twl4030_earpiece_values); + +static const struct snd_kcontrol_new twl4030_dapm_earpiece_control = +SOC_DAPM_VALUE_ENUM("Route", twl4030_earpiece_enum); /* PreDrive Left */ -static const struct snd_kcontrol_new twl4030_dapm_predrivel_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDL_CTL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PREDL_CTL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDL_CTL, 2, 1, 0), - SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDL_CTL, 3, 1, 0), -}; +static const char *twl4030_predrivel_texts[] = + {"Off", "DACL1", "DACL2", "DACR2"}; + +static const unsigned int twl4030_predrivel_values[] = + {0x0, 0x1, 0x2, 0x4}; + +static const struct soc_enum twl4030_predrivel_enum = + SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7, + ARRAY_SIZE(twl4030_predrivel_texts), + twl4030_predrivel_texts, + twl4030_predrivel_values); + +static const struct snd_kcontrol_new twl4030_dapm_predrivel_control = +SOC_DAPM_VALUE_ENUM("Route", twl4030_predrivel_enum); /* PreDrive Right */ -static const struct snd_kcontrol_new twl4030_dapm_predriver_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_PREDR_CTL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PREDR_CTL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PREDR_CTL, 2, 1, 0), - SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PREDR_CTL, 3, 1, 0), -}; +static const char *twl4030_predriver_texts[] = + {"Off", "DACR1", "DACR2", "DACL2"}; + +static const unsigned int twl4030_predriver_values[] = + {0x0, 0x1, 0x2, 0x4}; + +static const struct soc_enum twl4030_predriver_enum = + SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7, + ARRAY_SIZE(twl4030_predriver_texts), + twl4030_predriver_texts, + twl4030_predriver_values); + +static const struct snd_kcontrol_new twl4030_dapm_predriver_control = +SOC_DAPM_VALUE_ENUM("Route", twl4030_predriver_enum); /* Headset Left */ -static const struct snd_kcontrol_new twl4030_dapm_hsol_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_HS_SEL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_HS_SEL, 2, 1, 0), -}; +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 struct snd_kcontrol_new twl4030_dapm_hsor_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_HS_SEL, 3, 1, 0), - SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_HS_SEL, 4, 1, 0), - SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_HS_SEL, 5, 1, 0), -}; +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 struct snd_kcontrol_new twl4030_dapm_carkitl_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKL_CTL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioL1", TWL4030_REG_PRECKL_CTL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioL2", TWL4030_REG_PRECKL_CTL, 2, 1, 0), -}; +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 struct snd_kcontrol_new twl4030_dapm_carkitr_controls[] = { - SOC_DAPM_SINGLE("Voice", TWL4030_REG_PRECKR_CTL, 0, 1, 0), - SOC_DAPM_SINGLE("AudioR1", TWL4030_REG_PRECKR_CTL, 1, 1, 0), - SOC_DAPM_SINGLE("AudioR2", TWL4030_REG_PRECKR_CTL, 2, 1, 0), -}; +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", "AudioL1", "AudioL2", "AudioR2"}; + {"Voice", "DACL1", "DACL2", "DACR2"}; static const struct soc_enum twl4030_handsfreel_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0, @@ -396,13 +423,9 @@ static const struct soc_enum twl4030_handsfreel_enum = static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control = SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum); -/* Handsfree Left virtual mute */ -static const struct snd_kcontrol_new twl4030_dapm_handsfreelmute_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 0, 1, 0); - /* Handsfree Right */ static const char *twl4030_handsfreer_texts[] = - {"Voice", "AudioR1", "AudioR2", "AudioL2"}; + {"Voice", "DACR1", "DACR2", "DACL2"}; static const struct soc_enum twl4030_handsfreer_enum = SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0, @@ -412,48 +435,37 @@ static const struct soc_enum twl4030_handsfreer_enum = static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control = SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum); -/* Handsfree Right virtual mute */ -static const struct snd_kcontrol_new twl4030_dapm_handsfreermute_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_SW_SHADOW, 1, 1, 0); +/* Left analog microphone selection */ +static const char *twl4030_analoglmic_texts[] = + {"Off", "Main mic", "Headset mic", "AUXL", "Carkit mic"}; -/* Vibra */ -/* Vibra audio path selection */ -static const char *twl4030_vibra_texts[] = - {"AudioL1", "AudioR1", "AudioL2", "AudioR2"}; +static const unsigned int twl4030_analoglmic_values[] = + {0x0, 0x1, 0x2, 0x4, 0x8}; -static const struct soc_enum twl4030_vibra_enum = - SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 2, - ARRAY_SIZE(twl4030_vibra_texts), - twl4030_vibra_texts); +static const struct soc_enum twl4030_analoglmic_enum = + SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf, + ARRAY_SIZE(twl4030_analoglmic_texts), + twl4030_analoglmic_texts, + twl4030_analoglmic_values); -static const struct snd_kcontrol_new twl4030_dapm_vibra_control = -SOC_DAPM_ENUM("Route", twl4030_vibra_enum); +static const struct snd_kcontrol_new twl4030_dapm_analoglmic_control = +SOC_DAPM_VALUE_ENUM("Route", twl4030_analoglmic_enum); -/* Vibra path selection: local vibrator (PWM) or audio driven */ -static const char *twl4030_vibrapath_texts[] = - {"Local vibrator", "Audio"}; +/* Right analog microphone selection */ +static const char *twl4030_analogrmic_texts[] = + {"Off", "Sub mic", "AUXR"}; -static const struct soc_enum twl4030_vibrapath_enum = - SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 4, - ARRAY_SIZE(twl4030_vibrapath_texts), - twl4030_vibrapath_texts); +static const unsigned int twl4030_analogrmic_values[] = + {0x0, 0x1, 0x4}; -static const struct snd_kcontrol_new twl4030_dapm_vibrapath_control = -SOC_DAPM_ENUM("Route", twl4030_vibrapath_enum); +static const struct soc_enum twl4030_analogrmic_enum = + SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5, + ARRAY_SIZE(twl4030_analogrmic_texts), + twl4030_analogrmic_texts, + twl4030_analogrmic_values); -/* Left analog microphone selection */ -static const struct snd_kcontrol_new twl4030_dapm_analoglmic_controls[] = { - SOC_DAPM_SINGLE("Main mic", TWL4030_REG_ANAMICL, 0, 1, 0), - SOC_DAPM_SINGLE("Headset mic", TWL4030_REG_ANAMICL, 1, 1, 0), - SOC_DAPM_SINGLE("AUXL", TWL4030_REG_ANAMICL, 2, 1, 0), - SOC_DAPM_SINGLE("Carkit mic", TWL4030_REG_ANAMICL, 3, 1, 0), -}; - -/* Right analog microphone selection */ -static const struct snd_kcontrol_new twl4030_dapm_analogrmic_controls[] = { - SOC_DAPM_SINGLE("Sub mic", TWL4030_REG_ANAMICR, 0, 1, 0), - SOC_DAPM_SINGLE("AUXR", TWL4030_REG_ANAMICR, 2, 1, 0), -}; +static const struct snd_kcontrol_new twl4030_dapm_analogrmic_control = +SOC_DAPM_VALUE_ENUM("Route", twl4030_analogrmic_enum); /* TX1 L/R Analog/Digital microphone selection */ static const char *twl4030_micpathtx1_texts[] = @@ -495,10 +507,6 @@ static const struct snd_kcontrol_new twl4030_dapm_abypassr2_control = static const struct snd_kcontrol_new twl4030_dapm_abypassl2_control = SOC_DAPM_SINGLE("Switch", TWL4030_REG_ARXL2_APGA_CTL, 2, 1, 0); -/* Analog bypass for Voice */ -static const struct snd_kcontrol_new twl4030_dapm_abypassv_control = - SOC_DAPM_SINGLE("Switch", TWL4030_REG_VDL_APGA_CTL, 2, 1, 0); - /* Digital bypass gain, 0 mutes the bypass */ static const unsigned int twl4030_dapm_dbypass_tlv[] = { TLV_DB_RANGE_HEAD(2), @@ -518,18 +526,6 @@ static const struct snd_kcontrol_new twl4030_dapm_dbypassr_control = TWL4030_REG_ATX2ARXPGA, 0, 7, 0, twl4030_dapm_dbypass_tlv); -/* - * Voice Sidetone GAIN volume control: - * from -51 to -10 dB in 1 dB steps (mute instead of -51 dB) - */ -static DECLARE_TLV_DB_SCALE(twl4030_dapm_dbypassv_tlv, -5100, 100, 1); - -/* Digital bypass voice: sidetone (VUL -> VDL)*/ -static const struct snd_kcontrol_new twl4030_dapm_dbypassv_control = - SOC_DAPM_SINGLE_TLV("Volume", - TWL4030_REG_VSTPGA, 0, 0x29, 0, - twl4030_dapm_dbypassv_tlv); - static int micpath_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -560,143 +556,63 @@ static int micpath_event(struct snd_soc_dapm_widget *w, return 0; } -static void handsfree_ramp(struct snd_soc_codec *codec, int reg, int ramp) +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(codec, reg); + hs_ctl = twl4030_read_reg_cache(w->codec, e->reg); - if (ramp) { - /* HF ramp-up */ - hs_ctl |= TWL4030_HF_CTL_REF_EN; - twl4030_write(codec, reg, hs_ctl); - udelay(10); + if (hs_ctl & TWL4030_HF_CTL_REF_EN) { hs_ctl |= TWL4030_HF_CTL_RAMP_EN; - twl4030_write(codec, reg, hs_ctl); - udelay(40); + 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(codec, reg, hs_ctl); + twl4030_write(w->codec, e->reg, hs_ctl); } else { - /* HF ramp-down */ - hs_ctl &= ~TWL4030_HF_CTL_LOOP_EN; - hs_ctl &= ~TWL4030_HF_CTL_HB_EN; - twl4030_write(codec, reg, hs_ctl); - hs_ctl &= ~TWL4030_HF_CTL_RAMP_EN; - twl4030_write(codec, reg, hs_ctl); - udelay(40); - hs_ctl &= ~TWL4030_HF_CTL_REF_EN; - twl4030_write(codec, reg, hs_ctl); + 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); } -} -static int handsfreelpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 1); - break; - case SND_SOC_DAPM_POST_PMD: - handsfree_ramp(w->codec, TWL4030_REG_HFL_CTL, 0); - break; - } return 0; } -static int handsfreerpga_event(struct snd_soc_dapm_widget *w, +static int headsetl_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 1); - break; - case SND_SOC_DAPM_POST_PMD: - handsfree_ramp(w->codec, TWL4030_REG_HFR_CTL, 0); - break; - } - return 0; -} - -static void headset_ramp(struct snd_soc_codec *codec, int ramp) { unsigned char hs_gain, hs_pop; - struct twl4030_priv *twl4030 = codec->private_data; - /* Base values for ramp delay calculation: 2^19 - 2^26 */ - unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, - 8388608, 16777216, 33554432, 67108864}; - hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); - hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + /* Save the current volume */ + hs_gain = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_GAIN_SET); + hs_pop = twl4030_read_reg_cache(w->codec, TWL4030_REG_HS_POPN_SET); - if (ramp) { - /* Headset ramp-up according to the TRM */ + switch (event) { + case SND_SOC_DAPM_POST_PMU: + /* Do the anti-pop/bias ramp enable according to the TRM */ hs_pop |= TWL4030_VMID_EN; - twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); - twl4030_write(codec, TWL4030_REG_HS_GAIN_SET, hs_gain); + twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); + /* Is this needed? Can we just use whatever gain here? */ + twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, + (hs_gain & (~0x0f)) | 0x0a); hs_pop |= TWL4030_RAMP_EN; - twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); - } else { - /* Headset ramp-down _not_ according to - * the TRM, but in a way that it is working */ + twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); + + /* Restore the original volume */ + twl4030_write(w->codec, TWL4030_REG_HS_GAIN_SET, hs_gain); + break; + case SND_SOC_DAPM_POST_PMD: + /* Do the anti-pop/bias ramp disable according to the TRM */ hs_pop &= ~TWL4030_RAMP_EN; - twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); - /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Bypass the reg_cache to mute the headset */ twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), TWL4030_REG_HS_GAIN_SET); - hs_pop &= ~TWL4030_VMID_EN; - twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); - } -} - -static int headsetlpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct twl4030_priv *twl4030 = w->codec->private_data; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* Do the ramp-up only once */ - if (!twl4030->hsr_enabled) - headset_ramp(w->codec, 1); - - twl4030->hsl_enabled = 1; - break; - case SND_SOC_DAPM_POST_PMD: - /* Do the ramp-down only if both headsetL/R is disabled */ - if (!twl4030->hsr_enabled) - headset_ramp(w->codec, 0); - - twl4030->hsl_enabled = 0; - break; - } - return 0; -} - -static int headsetrpga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct twl4030_priv *twl4030 = w->codec->private_data; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - /* Do the ramp-up only once */ - if (!twl4030->hsl_enabled) - headset_ramp(w->codec, 1); - - twl4030->hsr_enabled = 1; - break; - case SND_SOC_DAPM_POST_PMD: - /* Do the ramp-down only if both headsetL/R is disabled */ - if (!twl4030->hsl_enabled) - headset_ramp(w->codec, 0); - - twl4030->hsr_enabled = 0; + twl4030_write(w->codec, TWL4030_REG_HS_POPN_SET, hs_pop); break; } return 0; @@ -708,7 +624,7 @@ static int bypass_event(struct snd_soc_dapm_widget *w, struct soc_mixer_control *m = (struct soc_mixer_control *)w->kcontrols->private_value; struct twl4030_priv *twl4030 = w->codec->private_data; - unsigned char reg, misc; + unsigned char reg; reg = twl4030_read_reg_cache(w->codec, m->reg); @@ -720,34 +636,14 @@ static int bypass_event(struct snd_soc_dapm_widget *w, else twl4030->bypass_state &= ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL)); - } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) { - /* Analog voice bypass */ - if (reg & (1 << m->shift)) - twl4030->bypass_state |= (1 << 4); - else - twl4030->bypass_state &= ~(1 << 4); - } else if (m->reg == TWL4030_REG_VSTPGA) { - /* Voice digital bypass */ - if (reg) - twl4030->bypass_state |= (1 << 5); - else - twl4030->bypass_state &= ~(1 << 5); } else { /* Digital bypass */ if (reg & (0x7 << m->shift)) - twl4030->bypass_state |= (1 << (m->shift ? 7 : 6)); + twl4030->bypass_state |= (1 << (m->shift ? 5 : 4)); else - twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6)); + twl4030->bypass_state &= ~(1 << (m->shift ? 5 : 4)); } - /* Enable master analog loopback mode if any analog switch is enabled*/ - misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1); - if (twl4030->bypass_state & 0x1F) - misc |= TWL4030_FMLOOP_EN; - else - misc &= ~TWL4030_FMLOOP_EN; - twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc); - if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) { if (twl4030->bypass_state) twl4030_codec_mute(w->codec, 0); @@ -914,48 +810,6 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, return err; } -/* Codec operation modes */ -static const char *twl4030_op_modes_texts[] = { - "Option 2 (voice/audio)", "Option 1 (audio)" -}; - -static const struct soc_enum twl4030_op_modes_enum = - SOC_ENUM_SINGLE(TWL4030_REG_CODEC_MODE, 0, - ARRAY_SIZE(twl4030_op_modes_texts), - twl4030_op_modes_texts); - -int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct twl4030_priv *twl4030 = codec->private_data; - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; - unsigned short val; - unsigned short mask, bitmask; - - if (twl4030->configured) { - printk(KERN_ERR "twl4030 operation mode cannot be " - "changed on-the-fly\n"); - return -EBUSY; - } - - for (bitmask = 1; bitmask < e->max; bitmask <<= 1) - ; - if (ucontrol->value.enumerated.item[0] > e->max - 1) - return -EINVAL; - - val = ucontrol->value.enumerated.item[0] << e->shift_l; - mask = (bitmask - 1) << e->shift_l; - if (e->shift_l != e->shift_r) { - if (ucontrol->value.enumerated.item[1] > e->max - 1) - return -EINVAL; - val |= ucontrol->value.enumerated.item[1] << e->shift_r; - mask |= (bitmask - 1) << e->shift_r; - } - - return snd_soc_update_bits(codec, e->reg, mask, val); -} - /* * FGAIN volume control: * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB) @@ -969,12 +823,6 @@ static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1); */ static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0); -/* - * Voice Downlink GAIN volume control: - * from -37 to 12 dB in 1 dB steps (mute instead of -37 dB) - */ -static DECLARE_TLV_DB_SCALE(digital_voice_downlink_tlv, -3700, 100, 1); - /* * Analog playback gain * -24 dB to 12 dB in 2 dB steps @@ -1016,32 +864,7 @@ static const struct soc_enum twl4030_rampdelay_enum = ARRAY_SIZE(twl4030_rampdelay_texts), twl4030_rampdelay_texts); -/* Vibra H-bridge direction mode */ -static const char *twl4030_vibradirmode_texts[] = { - "Vibra H-bridge direction", "Audio data MSB", -}; - -static const struct soc_enum twl4030_vibradirmode_enum = - SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 5, - ARRAY_SIZE(twl4030_vibradirmode_texts), - twl4030_vibradirmode_texts); - -/* Vibra H-bridge direction */ -static const char *twl4030_vibradir_texts[] = { - "Positive polarity", "Negative polarity", -}; - -static const struct soc_enum twl4030_vibradir_enum = - SOC_ENUM_SINGLE(TWL4030_REG_VIBRA_CTL, 1, - ARRAY_SIZE(twl4030_vibradir_texts), - twl4030_vibradir_texts); - static const struct snd_kcontrol_new twl4030_snd_controls[] = { - /* Codec operation mode control */ - SOC_ENUM_EXT("Codec Operation Mode", twl4030_op_modes_enum, - snd_soc_get_enum_double, - snd_soc_put_twl4030_opmode_enum_double), - /* Common playback gain controls */ SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume", TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA, @@ -1070,16 +893,6 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL, 1, 1, 0), - /* Common voice downlink gain controls */ - SOC_SINGLE_TLV("DAC Voice Digital Downlink Volume", - TWL4030_REG_VRXPGA, 0, 0x31, 0, digital_voice_downlink_tlv), - - SOC_SINGLE_TLV("DAC Voice Analog Downlink Volume", - TWL4030_REG_VDL_APGA_CTL, 3, 0x12, 1, analog_tlv), - - SOC_SINGLE("DAC Voice Analog Downlink Switch", - TWL4030_REG_VDL_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, @@ -1107,9 +920,6 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { 0, 3, 5, 0, input_gain_tlv), SOC_ENUM("HS ramp delay", twl4030_rampdelay_enum), - - SOC_ENUM("Vibra H-bridge mode", twl4030_vibradirmode_enum), - SOC_ENUM("Vibra H-bridge direction", twl4030_vibradir_enum), }; static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { @@ -1137,20 +947,27 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("CARKITR"), SND_SOC_DAPM_OUTPUT("HFL"), SND_SOC_DAPM_OUTPUT("HFR"), - SND_SOC_DAPM_OUTPUT("VIBRA"), /* DACs */ - SND_SOC_DAPM_DAC("DAC Right1", "Right Front HiFi Playback", + SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC Left1", "Left Front HiFi Playback", + SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC Right2", "Right Rear HiFi Playback", + SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback", SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC Left2", "Left Rear HiFi Playback", - SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC Voice", "Voice Playback", + SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback", SND_SOC_NOPM, 0, 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), + /* Analog bypasses */ SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, &twl4030_dapm_abypassr1_control, bypass_event, @@ -1164,9 +981,6 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, &twl4030_dapm_abypassl2_control, bypass_event, SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_abypassv_control, - bypass_event, SND_SOC_DAPM_POST_REG), /* Digital bypasses */ SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, @@ -1175,88 +989,43 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, &twl4030_dapm_dbypassr_control, bypass_event, SND_SOC_DAPM_POST_REG), - SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_dbypassv_control, bypass_event, - SND_SOC_DAPM_POST_REG), - /* Digital mixers, power control for the physical DACs */ - SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", - TWL4030_REG_AVDAC_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Digital L1 Playback Mixer", - TWL4030_REG_AVDAC_CTL, 1, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Digital R2 Playback Mixer", - TWL4030_REG_AVDAC_CTL, 2, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Digital L2 Playback Mixer", - TWL4030_REG_AVDAC_CTL, 3, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Digital Voice Playback Mixer", - TWL4030_REG_AVDAC_CTL, 4, 0, NULL, 0), - - /* Analog mixers, power control for the physical PGAs */ - SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", - TWL4030_REG_ARXR1_APGA_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", - TWL4030_REG_ARXL1_APGA_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", - TWL4030_REG_ARXR2_APGA_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", - TWL4030_REG_ARXL2_APGA_CTL, 0, 0, NULL, 0), - SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", - TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), - - /* Output MIXER controls */ + SND_SOC_DAPM_MIXER("Analog R1 Playback Mixer", TWL4030_REG_AVDAC_CTL, + 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("Analog L1 Playback Mixer", TWL4030_REG_AVDAC_CTL, + 1, 0, NULL, 0), + SND_SOC_DAPM_MIXER("Analog R2 Playback Mixer", TWL4030_REG_AVDAC_CTL, + 2, 0, NULL, 0), + SND_SOC_DAPM_MIXER("Analog L2 Playback Mixer", TWL4030_REG_AVDAC_CTL, + 3, 0, NULL, 0), + + /* Output MUX controls */ /* Earpiece */ - SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_earpiece_controls[0], - ARRAY_SIZE(twl4030_dapm_earpiece_controls)), + SND_SOC_DAPM_VALUE_MUX("Earpiece Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_earpiece_control), /* PreDrivL/R */ - SND_SOC_DAPM_MIXER("PredriveL Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predrivel_controls[0], - ARRAY_SIZE(twl4030_dapm_predrivel_controls)), - SND_SOC_DAPM_MIXER("PredriveR Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_predriver_controls[0], - ARRAY_SIZE(twl4030_dapm_predriver_controls)), + SND_SOC_DAPM_VALUE_MUX("PredriveL Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predrivel_control), + SND_SOC_DAPM_VALUE_MUX("PredriveR Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_predriver_control), /* HeadsetL/R */ - SND_SOC_DAPM_MIXER("HeadsetL Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsol_controls[0], - ARRAY_SIZE(twl4030_dapm_hsol_controls)), - SND_SOC_DAPM_PGA_E("HeadsetL PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, headsetlpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MIXER("HeadsetR Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_hsor_controls[0], - ARRAY_SIZE(twl4030_dapm_hsor_controls)), - SND_SOC_DAPM_PGA_E("HeadsetR PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, headsetrpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX_E("HeadsetL Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsol_control, headsetl_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0, + &twl4030_dapm_hsor_control), /* CarkitL/R */ - SND_SOC_DAPM_MIXER("CarkitL Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitl_controls[0], - ARRAY_SIZE(twl4030_dapm_carkitl_controls)), - SND_SOC_DAPM_MIXER("CarkitR Mixer", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_carkitr_controls[0], - ARRAY_SIZE(twl4030_dapm_carkitr_controls)), - - /* Output MUX controls */ + 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("HandsfreeL Mux", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_handsfreel_control), - SND_SOC_DAPM_SWITCH("HandsfreeL Switch", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_handsfreelmute_control), - SND_SOC_DAPM_PGA_E("HandsfreeL PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, handsfreelpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_MUX("HandsfreeR Mux", SND_SOC_NOPM, 5, 0, - &twl4030_dapm_handsfreer_control), - SND_SOC_DAPM_SWITCH("HandsfreeR Switch", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_handsfreermute_control), - SND_SOC_DAPM_PGA_E("HandsfreeR PGA", SND_SOC_NOPM, - 0, 0, NULL, 0, handsfreerpga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - /* Vibra */ - SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, - &twl4030_dapm_vibra_control), - SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, - &twl4030_dapm_vibrapath_control), + 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), /* Introducing four virtual ADC, since TWL4030 have four channel for capture */ @@ -1281,15 +1050,11 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD| SND_SOC_DAPM_POST_REG), - /* Analog input mixers for the capture amplifiers */ - SND_SOC_DAPM_MIXER("Analog Left Capture Route", - TWL4030_REG_ANAMICL, 4, 0, - &twl4030_dapm_analoglmic_controls[0], - ARRAY_SIZE(twl4030_dapm_analoglmic_controls)), - SND_SOC_DAPM_MIXER("Analog Right Capture Route", - TWL4030_REG_ANAMICR, 4, 0, - &twl4030_dapm_analogrmic_controls[0], - ARRAY_SIZE(twl4030_dapm_analogrmic_controls)), + /* Analog input muxes with switch for the capture amplifiers */ + SND_SOC_DAPM_VALUE_MUX("Analog Left Capture Route", + TWL4030_REG_ANAMICL, 4, 0, &twl4030_dapm_analoglmic_control), + SND_SOC_DAPM_VALUE_MUX("Analog Right Capture Route", + TWL4030_REG_ANAMICR, 4, 0, &twl4030_dapm_analogrmic_control), SND_SOC_DAPM_PGA("ADC Physical Left", TWL4030_REG_AVADC_CTL, 3, 0, NULL, 0), @@ -1308,86 +1073,62 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = { }; static const struct snd_soc_dapm_route intercon[] = { - {"Digital L1 Playback Mixer", NULL, "DAC Left1"}, - {"Digital R1 Playback Mixer", NULL, "DAC Right1"}, - {"Digital L2 Playback Mixer", NULL, "DAC Left2"}, - {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, - {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, - - {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, - {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, - {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, - {"Analog R2 Playback Mixer", NULL, "Digital R2 Playback Mixer"}, - {"Analog Voice Playback Mixer", NULL, "Digital Voice Playback Mixer"}, + {"Analog L1 Playback Mixer", NULL, "DAC Left1"}, + {"Analog R1 Playback Mixer", NULL, "DAC Right1"}, + {"Analog L2 Playback Mixer", NULL, "DAC Left2"}, + {"Analog R2 Playback Mixer", NULL, "DAC Right2"}, + + {"ARXL1_APGA", NULL, "Analog L1 Playback Mixer"}, + {"ARXR1_APGA", NULL, "Analog R1 Playback Mixer"}, + {"ARXL2_APGA", NULL, "Analog L2 Playback Mixer"}, + {"ARXR2_APGA", NULL, "Analog R2 Playback Mixer"}, /* Internal playback routings */ /* Earpiece */ - {"Earpiece Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"Earpiece Mixer", "AudioL1", "Analog L1 Playback Mixer"}, - {"Earpiece Mixer", "AudioL2", "Analog L2 Playback Mixer"}, - {"Earpiece Mixer", "AudioR1", "Analog R1 Playback Mixer"}, + {"Earpiece Mux", "DACL1", "ARXL1_APGA"}, + {"Earpiece Mux", "DACL2", "ARXL2_APGA"}, + {"Earpiece Mux", "DACR1", "ARXR1_APGA"}, /* PreDrivL */ - {"PredriveL Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"PredriveL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, - {"PredriveL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, - {"PredriveL Mixer", "AudioR2", "Analog R2 Playback Mixer"}, + {"PredriveL Mux", "DACL1", "ARXL1_APGA"}, + {"PredriveL Mux", "DACL2", "ARXL2_APGA"}, + {"PredriveL Mux", "DACR2", "ARXR2_APGA"}, /* PreDrivR */ - {"PredriveR Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"PredriveR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, - {"PredriveR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, - {"PredriveR Mixer", "AudioL2", "Analog L2 Playback Mixer"}, + {"PredriveR Mux", "DACR1", "ARXR1_APGA"}, + {"PredriveR Mux", "DACR2", "ARXR2_APGA"}, + {"PredriveR Mux", "DACL2", "ARXL2_APGA"}, /* HeadsetL */ - {"HeadsetL Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"HeadsetL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, - {"HeadsetL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, - {"HeadsetL PGA", NULL, "HeadsetL Mixer"}, + {"HeadsetL Mux", "DACL1", "ARXL1_APGA"}, + {"HeadsetL Mux", "DACL2", "ARXL2_APGA"}, /* HeadsetR */ - {"HeadsetR Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"HeadsetR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, - {"HeadsetR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, - {"HeadsetR PGA", NULL, "HeadsetR Mixer"}, + {"HeadsetR Mux", "DACR1", "ARXR1_APGA"}, + {"HeadsetR Mux", "DACR2", "ARXR2_APGA"}, /* CarkitL */ - {"CarkitL Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"CarkitL Mixer", "AudioL1", "Analog L1 Playback Mixer"}, - {"CarkitL Mixer", "AudioL2", "Analog L2 Playback Mixer"}, + {"CarkitL Mux", "DACL1", "ARXL1_APGA"}, + {"CarkitL Mux", "DACL2", "ARXL2_APGA"}, /* CarkitR */ - {"CarkitR Mixer", "Voice", "Analog Voice Playback Mixer"}, - {"CarkitR Mixer", "AudioR1", "Analog R1 Playback Mixer"}, - {"CarkitR Mixer", "AudioR2", "Analog R2 Playback Mixer"}, + {"CarkitR Mux", "DACR1", "ARXR1_APGA"}, + {"CarkitR Mux", "DACR2", "ARXR2_APGA"}, /* HandsfreeL */ - {"HandsfreeL Mux", "Voice", "Analog Voice Playback Mixer"}, - {"HandsfreeL Mux", "AudioL1", "Analog L1 Playback Mixer"}, - {"HandsfreeL Mux", "AudioL2", "Analog L2 Playback Mixer"}, - {"HandsfreeL Mux", "AudioR2", "Analog R2 Playback Mixer"}, - {"HandsfreeL Switch", "Switch", "HandsfreeL Mux"}, - {"HandsfreeL PGA", NULL, "HandsfreeL Switch"}, + {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"}, + {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"}, + {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"}, /* HandsfreeR */ - {"HandsfreeR Mux", "Voice", "Analog Voice Playback Mixer"}, - {"HandsfreeR Mux", "AudioR1", "Analog R1 Playback Mixer"}, - {"HandsfreeR Mux", "AudioR2", "Analog R2 Playback Mixer"}, - {"HandsfreeR Mux", "AudioL2", "Analog L2 Playback Mixer"}, - {"HandsfreeR Switch", "Switch", "HandsfreeR Mux"}, - {"HandsfreeR PGA", NULL, "HandsfreeR Switch"}, - /* Vibra */ - {"Vibra Mux", "AudioL1", "DAC Left1"}, - {"Vibra Mux", "AudioR1", "DAC Right1"}, - {"Vibra Mux", "AudioL2", "DAC Left2"}, - {"Vibra Mux", "AudioR2", "DAC Right2"}, + {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"}, + {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"}, + {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"}, /* outputs */ - {"OUTL", NULL, "Analog L2 Playback Mixer"}, - {"OUTR", NULL, "Analog R2 Playback Mixer"}, - {"EARPIECE", NULL, "Earpiece Mixer"}, - {"PREDRIVEL", NULL, "PredriveL Mixer"}, - {"PREDRIVER", NULL, "PredriveR Mixer"}, - {"HSOL", NULL, "HeadsetL PGA"}, - {"HSOR", NULL, "HeadsetR PGA"}, - {"CARKITL", NULL, "CarkitL Mixer"}, - {"CARKITR", NULL, "CarkitR Mixer"}, - {"HFL", NULL, "HandsfreeL PGA"}, - {"HFR", NULL, "HandsfreeR PGA"}, - {"Vibra Route", "Audio", "Vibra Mux"}, - {"VIBRA", NULL, "Vibra Route"}, + {"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"}, /* Capture path */ {"Analog Left Capture Route", "Main mic", "MAINMIC"}, @@ -1427,22 +1168,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"Left1 Analog Loopback", "Switch", "Analog Left Capture Route"}, {"Right2 Analog Loopback", "Switch", "Analog Right Capture Route"}, {"Left2 Analog Loopback", "Switch", "Analog Left Capture Route"}, - {"Voice Analog Loopback", "Switch", "Analog Left Capture Route"}, {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, {"Analog L2 Playback Mixer", NULL, "Left2 Analog Loopback"}, - {"Analog Voice Playback Mixer", NULL, "Voice Analog Loopback"}, /* Digital bypass routes */ {"Right Digital Loopback", "Volume", "TX1 Capture Route"}, {"Left Digital Loopback", "Volume", "TX1 Capture Route"}, - {"Voice Digital Loopback", "Volume", "TX2 Capture Route"}, - {"Digital R2 Playback Mixer", NULL, "Right Digital Loopback"}, - {"Digital L2 Playback Mixer", NULL, "Left Digital Loopback"}, - {"Digital Voice Playback Mixer", NULL, "Voice Digital Loopback"}, + {"Analog R2 Playback Mixer", NULL, "Right Digital Loopback"}, + {"Analog L2 Playback Mixer", NULL, "Left Digital Loopback"}, }; @@ -1489,58 +1226,6 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec, return 0; } -static void twl4030_constraints(struct twl4030_priv *twl4030, - struct snd_pcm_substream *mst_substream) -{ - struct snd_pcm_substream *slv_substream; - - /* Pick the stream, which need to be constrained */ - if (mst_substream == twl4030->master_substream) - slv_substream = twl4030->slave_substream; - else if (mst_substream == twl4030->slave_substream) - slv_substream = twl4030->master_substream; - else /* This should not happen.. */ - return; - - /* Set the constraints according to the already configured stream */ - snd_pcm_hw_constraint_minmax(slv_substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - twl4030->rate, - twl4030->rate); - - snd_pcm_hw_constraint_minmax(slv_substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - twl4030->sample_bits, - twl4030->sample_bits); - - snd_pcm_hw_constraint_minmax(slv_substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, - twl4030->channels, - twl4030->channels); -} - -/* In case of 4 channel mode, the RX1 L/R for playback and the TX2 L/R for - * capture has to be enabled/disabled. */ -static void twl4030_tdm_enable(struct snd_soc_codec *codec, int direction, - int enable) -{ - u8 reg, mask; - - reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); - - if (direction == SNDRV_PCM_STREAM_PLAYBACK) - mask = TWL4030_ARXL1_VRX_EN | TWL4030_ARXR1_EN; - else - mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN; - - if (enable) - reg |= mask; - else - reg &= ~mask; - - twl4030_write(codec, TWL4030_REG_OPTION, reg); -} - static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1549,25 +1234,26 @@ static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = socdev->card->codec; struct twl4030_priv *twl4030 = codec->private_data; + /* If we already have a playback or capture going then constrain + * this substream to match it. + */ if (twl4030->master_substream) { + struct snd_pcm_runtime *master_runtime; + master_runtime = twl4030->master_substream->runtime; + + 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); + twl4030->slave_substream = substream; - /* The DAI has one configuration for playback and capture, so - * if the DAI has been already configured then constrain this - * substream to match it. */ - if (twl4030->configured) - twl4030_constraints(twl4030, twl4030->master_substream); - } else { - if (!(twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) & - TWL4030_OPTION_1)) { - /* In option2 4 channel is not supported, set the - * constraint for the first stream for channels, the - * second stream will 'inherit' this cosntraint */ - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, - 2, 2); - } + } else twl4030->master_substream = substream; - } return 0; } @@ -1584,17 +1270,6 @@ static void twl4030_shutdown(struct snd_pcm_substream *substream, twl4030->master_substream = twl4030->slave_substream; twl4030->slave_substream = NULL; - - /* If all streams are closed, or the remaining stream has not yet - * been configured than set the DAI as not configured. */ - if (!twl4030->master_substream) - twl4030->configured = 0; - else if (!twl4030->master_substream->runtime->channels) - twl4030->configured = 0; - - /* If the closing substream had 4 channel, do the necessary cleanup */ - if (substream->runtime->channels == 4) - twl4030_tdm_enable(codec, substream->stream, 0); } static int twl4030_hw_params(struct snd_pcm_substream *substream, @@ -1607,24 +1282,8 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, struct twl4030_priv *twl4030 = codec->private_data; u8 mode, old_mode, format, old_format; - /* If the substream has 4 channel, do the necessary setup */ - if (params_channels(params) == 4) { - u8 format, mode; - - format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); - mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE); - - /* Safety check: are we in the correct operating mode and - * the interface is in TDM mode? */ - if ((mode & TWL4030_OPTION_1) && - ((format & TWL4030_AIF_FORMAT) == TWL4030_AIF_FORMAT_TDM)) - twl4030_tdm_enable(codec, substream->stream, 1); - else - return -EINVAL; - } - - if (twl4030->configured) - /* Ignoring hw_params for already configured DAI */ + if (substream == twl4030->slave_substream) + /* Ignoring hw_params for slave substream */ return 0; /* bit rate */ @@ -1704,21 +1363,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, /* set CODECPDZ afterwards */ twl4030_codec_enable(codec, 1); } - - /* Store the important parameters for the DAI configuration and set - * the DAI as configured */ - twl4030->configured = 1; - twl4030->rate = params_rate(params); - twl4030->sample_bits = hw_param_interval(params, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; - twl4030->channels = params_channels(params); - - /* If both playback and capture streams are open, and one of them - * is setting the hw parameters right now (since we are here), set - * constraints to the other stream to match the current one. */ - if (twl4030->slave_substream) - twl4030_constraints(twl4030, substream); - return 0; } @@ -1726,21 +1370,17 @@ 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; - struct twl4030_priv *twl4030 = codec->private_data; u8 infreq; switch (freq) { case 19200000: infreq = TWL4030_APLL_INFREQ_19200KHZ; - twl4030->sysclk = 19200; break; case 26000000: infreq = TWL4030_APLL_INFREQ_26000KHZ; - twl4030->sysclk = 26000; break; case 38400000: infreq = TWL4030_APLL_INFREQ_38400KHZ; - twl4030->sysclk = 38400; break; default: printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n", @@ -1784,9 +1424,6 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, case SND_SOC_DAIFMT_I2S: format |= TWL4030_AIF_FORMAT_CODEC; break; - case SND_SOC_DAIFMT_DSP_A: - format |= TWL4030_AIF_FORMAT_TDM; - break; default: return -EINVAL; } @@ -1806,180 +1443,6 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, return 0; } -/* In case of voice mode, the RX1 L(VRX) for downlink and the TX2 L/R - * (VTXL, VTXR) for uplink has to be enabled/disabled. */ -static void twl4030_voice_enable(struct snd_soc_codec *codec, int direction, - int enable) -{ - u8 reg, mask; - - reg = twl4030_read_reg_cache(codec, TWL4030_REG_OPTION); - - if (direction == SNDRV_PCM_STREAM_PLAYBACK) - mask = TWL4030_ARXL1_VRX_EN; - else - mask = TWL4030_ATXL2_VTXL_EN | TWL4030_ATXR2_VTXR_EN; - - if (enable) - reg |= mask; - else - reg &= ~mask; - - twl4030_write(codec, TWL4030_REG_OPTION, reg); -} - -static int twl4030_voice_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->card->codec; - u8 infreq; - u8 mode; - - /* If the system master clock is not 26MHz, the voice PCM interface is - * not avilable. - */ - infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) - & TWL4030_APLL_INFREQ; - - if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { - printk(KERN_ERR "TWL4030 voice startup: " - "MCLK is not 26MHz, call set_sysclk() on init\n"); - return -EINVAL; - } - - /* If the codec mode is not option2, the voice PCM interface is not - * avilable. - */ - mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) - & TWL4030_OPT_MODE; - - if (mode != TWL4030_OPTION_2) { - printk(KERN_ERR "TWL4030 voice startup: " - "the codec mode is not option2\n"); - return -EINVAL; - } - - return 0; -} - -static void twl4030_voice_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->card->codec; - - /* Enable voice digital filters */ - twl4030_voice_enable(codec, substream->stream, 0); -} - -static int twl4030_voice_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->card->codec; - u8 old_mode, mode; - - /* Enable voice digital filters */ - twl4030_voice_enable(codec, substream->stream, 1); - - /* bit rate */ - old_mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE) - & ~(TWL4030_CODECPDZ); - mode = old_mode; - - switch (params_rate(params)) { - case 8000: - mode &= ~(TWL4030_SEL_16K); - break; - case 16000: - mode |= TWL4030_SEL_16K; - break; - default: - printk(KERN_ERR "TWL4030 voice hw params: unknown rate %d\n", - params_rate(params)); - return -EINVAL; - } - - if (mode != old_mode) { - /* change rate and set CODECPDZ */ - twl4030_codec_enable(codec, 0); - twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); - twl4030_codec_enable(codec, 1); - } - - return 0; -} - -static int twl4030_voice_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 26000000: - infreq = TWL4030_APLL_INFREQ_26000KHZ; - break; - default: - printk(KERN_ERR "TWL4030 voice 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_voice_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_VOICE_IF); - format = old_format; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFM: - format &= ~(TWL4030_VIF_SLAVE_EN); - break; - case SND_SOC_DAIFMT_CBS_CFS: - format |= TWL4030_VIF_SLAVE_EN; - break; - default: - return -EINVAL; - } - - /* clock inversion */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_IB_NF: - format &= ~(TWL4030_VIF_FORMAT); - break; - case SND_SOC_DAIFMT_NB_IF: - format |= TWL4030_VIF_FORMAT; - break; - default: - return -EINVAL; - } - - if (format != old_format) { - /* change format and set CODECPDZ */ - twl4030_codec_enable(codec, 0); - twl4030_write(codec, TWL4030_REG_VOICE_IF, format); - twl4030_codec_enable(codec, 1); - } - - return 0; -} - #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) #define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) @@ -1991,47 +1454,21 @@ static struct snd_soc_dai_ops twl4030_dai_ops = { .set_fmt = twl4030_set_dai_fmt, }; -static struct snd_soc_dai_ops twl4030_dai_voice_ops = { - .startup = twl4030_voice_startup, - .shutdown = twl4030_voice_shutdown, - .hw_params = twl4030_voice_hw_params, - .set_sysclk = twl4030_voice_set_dai_sysclk, - .set_fmt = twl4030_voice_set_dai_fmt, -}; - -struct snd_soc_dai twl4030_dai[] = { -{ +struct snd_soc_dai twl4030_dai = { .name = "twl4030", .playback = { - .stream_name = "HiFi Playback", + .stream_name = "Playback", .channels_min = 2, - .channels_max = 4, + .channels_max = 2, .rates = TWL4030_RATES | SNDRV_PCM_RATE_96000, .formats = TWL4030_FORMATS,}, .capture = { .stream_name = "Capture", .channels_min = 2, - .channels_max = 4, + .channels_max = 2, .rates = TWL4030_RATES, .formats = TWL4030_FORMATS,}, .ops = &twl4030_dai_ops, -}, -{ - .name = "twl4030 Voice", - .playback = { - .stream_name = "Voice Playback", - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &twl4030_dai_voice_ops, -}, }; EXPORT_SYMBOL_GPL(twl4030_dai); @@ -2063,8 +1500,6 @@ static int twl4030_resume(struct platform_device *pdev) static int twl4030_init(struct snd_soc_device *socdev) { struct snd_soc_codec *codec = socdev->card->codec; - struct twl4030_setup_data *setup = socdev->codec_data; - struct twl4030_priv *twl4030 = codec->private_data; int ret = 0; printk(KERN_INFO "TWL4030 Audio Codec init \n"); @@ -2074,31 +1509,14 @@ static int twl4030_init(struct snd_soc_device *socdev) 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 = ARRAY_SIZE(twl4030_dai), + 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; - /* Configuration for headset ramp delay from setup data */ - if (setup) { - unsigned char hs_pop; - - if (setup->sysclk) - twl4030->sysclk = setup->sysclk; - else - twl4030->sysclk = 26000; - - hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); - hs_pop &= ~TWL4030_RAMP_DELAY; - hs_pop |= (setup->ramp_delay_value << 2); - twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop); - } else { - twl4030->sysclk = 26000; - } - /* register pcms */ ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); if (ret < 0) { @@ -2186,13 +1604,13 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030); static int __init twl4030_modinit(void) { - return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); + return snd_soc_register_dai(&twl4030_dai); } module_init(twl4030_modinit); static void __exit twl4030_exit(void) { - snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); + snd_soc_unregister_dai(&twl4030_dai); } module_exit(twl4030_exit); diff --git a/trunk/sound/soc/codecs/twl4030.h b/trunk/sound/soc/codecs/twl4030.h index fe5f395d9e4f..cb63765db1df 100644 --- a/trunk/sound/soc/codecs/twl4030.h +++ b/trunk/sound/soc/codecs/twl4030.h @@ -92,9 +92,8 @@ #define TWL4030_REG_VIBRA_PWM_SET 0x47 #define TWL4030_REG_ANAMIC_GAIN 0x48 #define TWL4030_REG_MISC_SET_2 0x49 -#define TWL4030_REG_SW_SHADOW 0x4A -#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) +#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1) /* Bitfield Definitions */ @@ -111,22 +110,9 @@ #define TWL4030_APLL_RATE_44100 0x90 #define TWL4030_APLL_RATE_48000 0xA0 #define TWL4030_APLL_RATE_96000 0xE0 -#define TWL4030_SEL_16K 0x08 +#define TWL4030_SEL_16K 0x04 #define TWL4030_CODECPDZ 0x02 #define TWL4030_OPT_MODE 0x01 -#define TWL4030_OPTION_1 (1 << 0) -#define TWL4030_OPTION_2 (0 << 0) - -/* TWL4030_OPTION (0x02) Fields */ - -#define TWL4030_ATXL1_EN (1 << 0) -#define TWL4030_ATXR1_EN (1 << 1) -#define TWL4030_ATXL2_VTXL_EN (1 << 2) -#define TWL4030_ATXR2_VTXR_EN (1 << 3) -#define TWL4030_ARXL1_VRX_EN (1 << 4) -#define TWL4030_ARXR1_EN (1 << 5) -#define TWL4030_ARXL2_EN (1 << 6) -#define TWL4030_ARXR2_EN (1 << 7) /* TWL4030_REG_MICBIAS_CTL (0x04) Fields */ @@ -185,17 +171,6 @@ #define TWL4030_CLK256FS_EN 0x02 #define TWL4030_AIF_EN 0x01 -/* VOICE_IF (0x0F) Fields */ - -#define TWL4030_VIF_SLAVE_EN 0x80 -#define TWL4030_VIF_DIN_EN 0x40 -#define TWL4030_VIF_DOUT_EN 0x20 -#define TWL4030_VIF_SWAP 0x10 -#define TWL4030_VIF_FORMAT 0x08 -#define TWL4030_VIF_TRI_EN 0x04 -#define TWL4030_VIF_SUB_EN 0x02 -#define TWL4030_VIF_EN 0x01 - /* EAR_CTL (0x21) */ #define TWL4030_EAR_GAIN 0x30 @@ -261,19 +236,7 @@ #define TWL4030_SMOOTH_ANAVOL_EN 0x02 #define TWL4030_DIGMIC_LR_SWAP_EN 0x01 -/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ -#define TWL4030_HFL_EN 0x01 -#define TWL4030_HFR_EN 0x02 - -#define TWL4030_DAI_HIFI 0 -#define TWL4030_DAI_VOICE 1 - -extern struct snd_soc_dai twl4030_dai[2]; +extern struct snd_soc_dai twl4030_dai; extern struct snd_soc_codec_device soc_codec_dev_twl4030; -struct twl4030_setup_data { - unsigned int ramp_delay_value; - unsigned int sysclk; -}; - #endif /* End of __TWL4030_AUDIO_H__ */ diff --git a/trunk/sound/soc/codecs/uda134x.c b/trunk/sound/soc/codecs/uda134x.c index 269b108e1de6..ddefb8f80145 100644 --- a/trunk/sound/soc/codecs/uda134x.c +++ b/trunk/sound/soc/codecs/uda134x.c @@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg, pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); if (reg >= UDA134X_REGS_NUM) { - printk(KERN_ERR "%s unkown register: reg: %u", + printk(KERN_ERR "%s unkown register: reg: %d", __func__, reg); return -EINVAL; } @@ -296,7 +296,7 @@ static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai, struct snd_soc_codec *codec = codec_dai->codec; struct uda134x_priv *uda134x = codec->private_data; - pr_debug("%s clk_id: %d, freq: %u, dir: %d\n", __func__, + 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 diff --git a/trunk/sound/soc/codecs/wm8350.c b/trunk/sound/soc/codecs/wm8350.c index e7348d341b76..0275321ff8ab 100644 --- a/trunk/sound/soc/codecs/wm8350.c +++ b/trunk/sound/soc/codecs/wm8350.c @@ -1108,7 +1108,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai, if (ret < 0) return ret; dev_dbg(wm8350->dev, - "FLL in %u FLL out %u N 0x%x K 0x%x div %d ratio %d", + "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); diff --git a/trunk/sound/soc/codecs/wm8350.h b/trunk/sound/soc/codecs/wm8350.h index d088eb4b88bb..d11bd9288cf9 100644 --- a/trunk/sound/soc/codecs/wm8350.h +++ b/trunk/sound/soc/codecs/wm8350.h @@ -13,7 +13,6 @@ #define _WM8350_H #include -#include extern struct snd_soc_dai wm8350_dai; extern struct snd_soc_codec_device soc_codec_dev_wm8350; diff --git a/trunk/sound/soc/codecs/wm8400.c b/trunk/sound/soc/codecs/wm8400.c index 502eefac1ecd..510efa604008 100644 --- a/trunk/sound/soc/codecs/wm8400.c +++ b/trunk/sound/soc/codecs/wm8400.c @@ -954,7 +954,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors, factors->outdiv *= 2; if (factors->outdiv > 32) { dev_err(wm8400->wm8400->dev, - "Unsupported FLL output frequency %uHz\n", + "Unsupported FLL output frequency %dHz\n", Fout); return -EINVAL; } @@ -1003,7 +1003,7 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors, factors->k = K / 10; dev_dbg(wm8400->wm8400->dev, - "FLL: Fref=%u Fout=%u N=%x K=%x, FRATIO=%x OUTDIV=%x\n", + "FLL: Fref=%d Fout=%d N=%x K=%x, FRATIO=%x OUTDIV=%x\n", Fref, Fout, factors->n, factors->k, factors->fratio, factors->outdiv); @@ -1473,8 +1473,8 @@ static int wm8400_codec_probe(struct platform_device *dev) codec = &priv->codec; codec->private_data = priv; - codec->control_data = dev_get_drvdata(&dev->dev); - priv->wm8400 = dev_get_drvdata(&dev->dev); + codec->control_data = dev->dev.driver_data; + priv->wm8400 = dev->dev.driver_data; ret = regulator_bulk_get(priv->wm8400->dev, ARRAY_SIZE(power), &power[0]); diff --git a/trunk/sound/soc/codecs/wm8510.c b/trunk/sound/soc/codecs/wm8510.c index c8b8dba85890..6a4cea09c45d 100644 --- a/trunk/sound/soc/codecs/wm8510.c +++ b/trunk/sound/soc/codecs/wm8510.c @@ -298,7 +298,7 @@ static void pll_factors(unsigned int target, unsigned int source) if ((Ndiv < 6) || (Ndiv > 12)) printk(KERN_WARNING - "WM8510 N value %u outwith recommended range!d\n", + "WM8510 N value %d outwith recommended range!d\n", Ndiv); pll_div.n = Ndiv; diff --git a/trunk/sound/soc/codecs/wm8580.c b/trunk/sound/soc/codecs/wm8580.c index 86c4b24db817..9f6be3d31ac0 100644 --- a/trunk/sound/soc/codecs/wm8580.c +++ b/trunk/sound/soc/codecs/wm8580.c @@ -415,7 +415,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target, unsigned int K, Ndiv, Nmod; int i; - pr_debug("wm8580: PLL %uHz->%uHz\n", source, target); + pr_debug("wm8580: PLL %dHz->%dHz\n", source, target); /* Scale the output frequency up; the PLL should run in the * region of 90-100MHz. @@ -447,7 +447,7 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target, if ((Ndiv < 5) || (Ndiv > 13)) { printk(KERN_ERR - "WM8580 N=%u outside supported range\n", Ndiv); + "WM8580 N=%d outside supported range\n", Ndiv); return -EINVAL; } diff --git a/trunk/sound/soc/codecs/wm8731.c b/trunk/sound/soc/codecs/wm8731.c index 7a205876ef4f..e043e3f60008 100644 --- a/trunk/sound/soc/codecs/wm8731.c +++ b/trunk/sound/soc/codecs/wm8731.c @@ -666,14 +666,14 @@ static int __devinit wm8731_spi_probe(struct spi_device *spi) codec->hw_write = (hw_write_t)wm8731_spi_write; codec->dev = &spi->dev; - dev_set_drvdata(&spi->dev, wm8731); + spi->dev.driver_data = wm8731; return wm8731_register(wm8731); } static int __devexit wm8731_spi_remove(struct spi_device *spi) { - struct wm8731_priv *wm8731 = dev_get_drvdata(&spi->dev); + struct wm8731_priv *wm8731 = spi->dev.driver_data; wm8731_unregister(wm8731); diff --git a/trunk/sound/soc/codecs/wm8753.c b/trunk/sound/soc/codecs/wm8753.c index d28eeaceb857..a6e8f3f7f052 100644 --- a/trunk/sound/soc/codecs/wm8753.c +++ b/trunk/sound/soc/codecs/wm8753.c @@ -703,7 +703,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, if ((Ndiv < 6) || (Ndiv > 12)) printk(KERN_WARNING - "wm8753: unsupported N = %u\n", Ndiv); + "wm8753: unsupported N = %d\n", Ndiv); pll_div->n = Ndiv; Nmod = target % source; @@ -1822,14 +1822,14 @@ static int __devinit wm8753_spi_probe(struct spi_device *spi) codec->hw_write = (hw_write_t)wm8753_spi_write; codec->dev = &spi->dev; - dev_set_drvdata(&spi->dev, wm8753); + spi->dev.driver_data = wm8753; return wm8753_register(wm8753); } static int __devexit wm8753_spi_remove(struct spi_device *spi) { - struct wm8753_priv *wm8753 = dev_get_drvdata(&spi->dev); + struct wm8753_priv *wm8753 = spi->dev.driver_data; wm8753_unregister(wm8753); return 0; } diff --git a/trunk/sound/soc/codecs/wm8900.c b/trunk/sound/soc/codecs/wm8900.c index 3c78945244b8..46c5ea1ff921 100644 --- a/trunk/sound/soc/codecs/wm8900.c +++ b/trunk/sound/soc/codecs/wm8900.c @@ -778,11 +778,11 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, } if (target > 100000000) - printk(KERN_WARNING "wm8900: FLL rate %u out of range, Fref=%u" - " Fout=%u\n", target, Fref, Fout); + printk(KERN_WARNING "wm8900: FLL rate %d out of range, Fref=%d" + " Fout=%d\n", target, Fref, Fout); if (div > 32) { printk(KERN_ERR "wm8900: Invalid FLL division rate %u, " - "Fref=%u, Fout=%u, target=%u\n", + "Fref=%d, Fout=%d, target=%d\n", div, Fref, Fout, target); return -EINVAL; } diff --git a/trunk/sound/soc/codecs/wm8903.c b/trunk/sound/soc/codecs/wm8903.c index d8a9222fbf74..8cf571f1a803 100644 --- a/trunk/sound/soc/codecs/wm8903.c +++ b/trunk/sound/soc/codecs/wm8903.c @@ -217,6 +217,7 @@ struct wm8903_priv { int sysclk; /* Reference counts */ + int charge_pump_users; int class_w_users; int playback_active; int capture_active; @@ -372,15 +373,6 @@ static void wm8903_reset(struct snd_soc_codec *codec) #define WM8903_OUTPUT_INT 0x2 #define WM8903_OUTPUT_IN 0x1 -static int wm8903_cp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - WARN_ON(event != SND_SOC_DAPM_POST_PMU); - mdelay(4); - - return 0; -} - /* * Event for headphone and line out amplifier power changes. Special * power up/down sequences are required in order to maximise pop/click @@ -390,20 +382,19 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct snd_soc_codec *codec = w->codec; + struct wm8903_priv *wm8903 = codec->private_data; + struct i2c_client *i2c = codec->control_data; u16 val; u16 reg; - u16 dcs_reg; - u16 dcs_bit; int shift; + u16 cp_reg = wm8903_read(codec, WM8903_CHARGE_PUMP_0); switch (w->reg) { case WM8903_POWER_MANAGEMENT_2: reg = WM8903_ANALOGUE_HP_0; - dcs_bit = 0 + w->shift; break; case WM8903_POWER_MANAGEMENT_3: reg = WM8903_ANALOGUE_LINEOUT_0; - dcs_bit = 2 + w->shift; break; default: BUG(); @@ -428,6 +419,18 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, /* Short the output */ val &= ~(WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); + + wm8903->charge_pump_users++; + + dev_dbg(&i2c->dev, "Charge pump use count now %d\n", + wm8903->charge_pump_users); + + if (wm8903->charge_pump_users == 1) { + dev_dbg(&i2c->dev, "Enabling charge pump\n"); + wm8903_write(codec, WM8903_CHARGE_PUMP_0, + cp_reg | WM8903_CP_ENA); + mdelay(4); + } } if (event & SND_SOC_DAPM_POST_PMU) { @@ -443,11 +446,6 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, val |= (WM8903_OUTPUT_OUT << shift); wm8903_write(codec, reg, val); - /* Enable the DC servo */ - dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); - dcs_reg |= dcs_bit; - wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); - /* Remove the short */ val |= (WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); @@ -460,17 +458,25 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, val &= ~(WM8903_OUTPUT_SHORT << shift); wm8903_write(codec, reg, val); - /* Disable the DC servo */ - dcs_reg = wm8903_read(codec, WM8903_DC_SERVO_0); - dcs_reg &= ~dcs_bit; - wm8903_write(codec, WM8903_DC_SERVO_0, dcs_reg); - /* Then disable the intermediate and output stages */ val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | WM8903_OUTPUT_IN) << shift); wm8903_write(codec, reg, val); } + if (event & SND_SOC_DAPM_POST_PMD) { + wm8903->charge_pump_users--; + + dev_dbg(&i2c->dev, "Charge pump use count now %d\n", + wm8903->charge_pump_users); + + if (wm8903->charge_pump_users == 0) { + dev_dbg(&i2c->dev, "Disabling charge pump\n"); + wm8903_write(codec, WM8903_CHARGE_PUMP_0, + cp_reg & ~WM8903_CP_ENA); + } + } + return 0; } @@ -533,7 +539,6 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, /* ALSA can only do steps of .01dB */ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); -static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); static const DECLARE_TLV_DB_SCALE(drc_tlv_thresh, 0, 75, 0); @@ -652,16 +657,6 @@ static const struct soc_enum rinput_inv_enum = SOC_ENUM_SINGLE(WM8903_ANALOGUE_RIGHT_INPUT_1, 4, 3, rinput_mux_text); -static const char *sidetone_text[] = { - "None", "Left", "Right" -}; - -static const struct soc_enum lsidetone_enum = - SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 2, 3, sidetone_text); - -static const struct soc_enum rsidetone_enum = - SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); - static const struct snd_kcontrol_new wm8903_snd_controls[] = { /* Input PGAs - No TLV since the scale depends on PGA mode */ @@ -705,9 +700,6 @@ SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, SOC_ENUM("ADC Companding Mode", adc_companding), SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), -SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, - 12, 0, digital_sidetone_tlv), - /* DAC */ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), @@ -770,12 +762,6 @@ static const struct snd_kcontrol_new rinput_mux = static const struct snd_kcontrol_new rinput_inv_mux = SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum); -static const struct snd_kcontrol_new lsidetone_mux = - SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum); - -static const struct snd_kcontrol_new rsidetone_mux = - SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); - 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), @@ -842,9 +828,6 @@ SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), -SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), -SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), - SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), @@ -861,29 +844,26 @@ SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 1, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, 0, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, NULL, 0, wm8903_output_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | - SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, NULL, 0), SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, - wm8903_cp_event, SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), }; static const struct snd_soc_dapm_route intercon[] = { @@ -929,19 +909,7 @@ static const struct snd_soc_dapm_route intercon[] = { { "Right Input PGA", NULL, "Right Input Mode Mux" }, { "ADCL", NULL, "Left Input PGA" }, - { "ADCL", NULL, "CLK_DSP" }, { "ADCR", NULL, "Right Input PGA" }, - { "ADCR", NULL, "CLK_DSP" }, - - { "DACL Sidetone", "Left", "ADCL" }, - { "DACL Sidetone", "Right", "ADCR" }, - { "DACR Sidetone", "Left", "ADCL" }, - { "DACR Sidetone", "Right", "ADCR" }, - - { "DACL", NULL, "DACL Sidetone" }, - { "DACL", NULL, "CLK_DSP" }, - { "DACR", NULL, "DACR Sidetone" }, - { "DACR", NULL, "CLK_DSP" }, { "Left Output Mixer", "Left Bypass Switch", "Left Input PGA" }, { "Left Output Mixer", "Right Bypass Switch", "Right Input PGA" }, @@ -983,11 +951,6 @@ static const struct snd_soc_dapm_route intercon[] = { { "ROP", NULL, "Right Speaker PGA" }, { "RON", NULL, "Right Speaker PGA" }, - - { "Left Headphone Output PGA", NULL, "Charge Pump" }, - { "Right Headphone Output PGA", NULL, "Charge Pump" }, - { "Left Line Output PGA", NULL, "Charge Pump" }, - { "Right Line Output PGA", NULL, "Charge Pump" }, }; static int wm8903_add_widgets(struct snd_soc_codec *codec) @@ -1022,11 +985,6 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA); - /* Change DC servo dither level in startup sequence */ - wm8903_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); - wm8903_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); - wm8903_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); - wm8903_run_sequence(codec, 0); wm8903_sync_reg_cache(codec, codec->reg_cache); @@ -1319,8 +1277,14 @@ static int wm8903_startup(struct snd_pcm_substream *substream, if (wm8903->master_substream) { master_runtime = wm8903->master_substream->runtime; - dev_dbg(&i2c->dev, "Constraining to %d bits\n", - master_runtime->sample_bits); + 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, + master_runtime->rate); snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_SAMPLE_BITS, @@ -1559,7 +1523,6 @@ struct snd_soc_dai wm8903_dai = { .formats = WM8903_FORMATS, }, .ops = &wm8903_dai_ops, - .symmetric_rates = 1, }; EXPORT_SYMBOL_GPL(wm8903_dai); diff --git a/trunk/sound/soc/codecs/wm8940.c b/trunk/sound/soc/codecs/wm8940.c deleted file mode 100644 index b8e17d6bc1f7..000000000000 --- a/trunk/sound/soc/codecs/wm8940.c +++ /dev/null @@ -1,955 +0,0 @@ -/* - * wm8940.c -- WM8940 ALSA Soc Audio driver - * - * Author: Jonathan Cameron - * - * Based on wm8510.c - * Copyright 2006 Wolfson Microelectronics PLC. - * Author: Liam Girdwood - * - * 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. - * - * Not currently handled: - * Notch filter control - * AUXMode (inverting vs mixer) - * No means to obtain current gain if alc enabled. - * No use made of gpio - * Fast VMID discharge for power down - * Soft Start - * DLR and ALR Swaps not enabled - * Digital Sidetone not supported - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8940.h" - -struct wm8940_priv { - unsigned int sysclk; - u16 reg_cache[WM8940_CACHEREGNUM]; - struct snd_soc_codec codec; -}; - -static u16 wm8940_reg_defaults[] = { - 0x8940, /* Soft Reset */ - 0x0000, /* Power 1 */ - 0x0000, /* Power 2 */ - 0x0000, /* Power 3 */ - 0x0010, /* Interface Control */ - 0x0000, /* Companding Control */ - 0x0140, /* Clock Control */ - 0x0000, /* Additional Controls */ - 0x0000, /* GPIO Control */ - 0x0002, /* Auto Increment Control */ - 0x0000, /* DAC Control */ - 0x00FF, /* DAC Volume */ - 0, - 0, - 0x0100, /* ADC Control */ - 0x00FF, /* ADC Volume */ - 0x0000, /* Notch Filter 1 Control 1 */ - 0x0000, /* Notch Filter 1 Control 2 */ - 0x0000, /* Notch Filter 2 Control 1 */ - 0x0000, /* Notch Filter 2 Control 2 */ - 0x0000, /* Notch Filter 3 Control 1 */ - 0x0000, /* Notch Filter 3 Control 2 */ - 0x0000, /* Notch Filter 4 Control 1 */ - 0x0000, /* Notch Filter 4 Control 2 */ - 0x0032, /* DAC Limit Control 1 */ - 0x0000, /* DAC Limit Control 2 */ - 0, - 0, - 0, - 0, - 0, - 0, - 0x0038, /* ALC Control 1 */ - 0x000B, /* ALC Control 2 */ - 0x0032, /* ALC Control 3 */ - 0x0000, /* Noise Gate */ - 0x0041, /* PLLN */ - 0x000C, /* PLLK1 */ - 0x0093, /* PLLK2 */ - 0x00E9, /* PLLK3 */ - 0, - 0, - 0x0030, /* ALC Control 4 */ - 0, - 0x0002, /* Input Control */ - 0x0050, /* PGA Gain */ - 0, - 0x0002, /* ADC Boost Control */ - 0, - 0x0002, /* Output Control */ - 0x0000, /* Speaker Mixer Control */ - 0, - 0, - 0, - 0x0079, /* Speaker Volume */ - 0, - 0x0000, /* Mono Mixer Control */ -}; - -static inline unsigned int wm8940_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - - if (reg >= ARRAY_SIZE(wm8940_reg_defaults)) - return -1; - - return cache[reg]; -} - -static inline int wm8940_write_reg_cache(struct snd_soc_codec *codec, - u16 reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - - if (reg >= ARRAY_SIZE(wm8940_reg_defaults)) - return -1; - - cache[reg] = value; - - return 0; -} - -static int wm8940_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - int ret; - u8 data[3] = { reg, - (value & 0xff00) >> 8, - (value & 0x00ff) - }; - - wm8940_write_reg_cache(codec, reg, value); - - ret = codec->hw_write(codec->control_data, data, 3); - - if (ret < 0) - return ret; - else if (ret != 3) - return -EIO; - return 0; -} - -static const char *wm8940_companding[] = { "Off", "NC", "u-law", "A-law" }; -static const struct soc_enum wm8940_adc_companding_enum -= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 1, 4, wm8940_companding); -static const struct soc_enum wm8940_dac_companding_enum -= SOC_ENUM_SINGLE(WM8940_COMPANDINGCTL, 3, 4, wm8940_companding); - -static const char *wm8940_alc_mode_text[] = {"ALC", "Limiter"}; -static const struct soc_enum wm8940_alc_mode_enum -= SOC_ENUM_SINGLE(WM8940_ALC3, 8, 2, wm8940_alc_mode_text); - -static const char *wm8940_mic_bias_level_text[] = {"0.9", "0.65"}; -static const struct soc_enum wm8940_mic_bias_level_enum -= SOC_ENUM_SINGLE(WM8940_INPUTCTL, 8, 2, wm8940_mic_bias_level_text); - -static const char *wm8940_filter_mode_text[] = {"Audio", "Application"}; -static const struct soc_enum wm8940_filter_mode_enum -= SOC_ENUM_SINGLE(WM8940_ADC, 7, 2, wm8940_filter_mode_text); - -static DECLARE_TLV_DB_SCALE(wm8940_spk_vol_tlv, -5700, 100, 1); -static DECLARE_TLV_DB_SCALE(wm8940_att_tlv, -1000, 1000, 0); -static DECLARE_TLV_DB_SCALE(wm8940_pga_vol_tlv, -1200, 75, 0); -static DECLARE_TLV_DB_SCALE(wm8940_alc_min_tlv, -1200, 600, 0); -static DECLARE_TLV_DB_SCALE(wm8940_alc_max_tlv, 675, 600, 0); -static DECLARE_TLV_DB_SCALE(wm8940_alc_tar_tlv, -2250, 50, 0); -static DECLARE_TLV_DB_SCALE(wm8940_lim_boost_tlv, 0, 100, 0); -static DECLARE_TLV_DB_SCALE(wm8940_lim_thresh_tlv, -600, 100, 0); -static DECLARE_TLV_DB_SCALE(wm8940_adc_tlv, -12750, 50, 1); -static DECLARE_TLV_DB_SCALE(wm8940_capture_boost_vol_tlv, 0, 2000, 0); - -static const struct snd_kcontrol_new wm8940_snd_controls[] = { - SOC_SINGLE("Digital Loopback Switch", WM8940_COMPANDINGCTL, - 6, 1, 0), - SOC_ENUM("DAC Companding", wm8940_dac_companding_enum), - SOC_ENUM("ADC Companding", wm8940_adc_companding_enum), - - SOC_ENUM("ALC Mode", wm8940_alc_mode_enum), - SOC_SINGLE("ALC Switch", WM8940_ALC1, 8, 1, 0), - SOC_SINGLE_TLV("ALC Capture Max Gain", WM8940_ALC1, - 3, 7, 1, wm8940_alc_max_tlv), - SOC_SINGLE_TLV("ALC Capture Min Gain", WM8940_ALC1, - 0, 7, 0, wm8940_alc_min_tlv), - SOC_SINGLE_TLV("ALC Capture Target", WM8940_ALC2, - 0, 14, 0, wm8940_alc_tar_tlv), - SOC_SINGLE("ALC Capture Hold", WM8940_ALC2, 4, 10, 0), - SOC_SINGLE("ALC Capture Decay", WM8940_ALC3, 4, 10, 0), - SOC_SINGLE("ALC Capture Attach", WM8940_ALC3, 0, 10, 0), - SOC_SINGLE("ALC ZC Switch", WM8940_ALC4, 1, 1, 0), - SOC_SINGLE("ALC Capture Noise Gate Switch", WM8940_NOISEGATE, - 3, 1, 0), - SOC_SINGLE("ALC Capture Noise Gate Threshold", WM8940_NOISEGATE, - 0, 7, 0), - - SOC_SINGLE("DAC Playback Limiter Switch", WM8940_DACLIM1, 8, 1, 0), - SOC_SINGLE("DAC Playback Limiter Attack", WM8940_DACLIM1, 0, 9, 0), - SOC_SINGLE("DAC Playback Limiter Decay", WM8940_DACLIM1, 4, 11, 0), - SOC_SINGLE_TLV("DAC Playback Limiter Threshold", WM8940_DACLIM2, - 4, 9, 1, wm8940_lim_thresh_tlv), - SOC_SINGLE_TLV("DAC Playback Limiter Boost", WM8940_DACLIM2, - 0, 12, 0, wm8940_lim_boost_tlv), - - SOC_SINGLE("Capture PGA ZC Switch", WM8940_PGAGAIN, 7, 1, 0), - SOC_SINGLE_TLV("Capture PGA Volume", WM8940_PGAGAIN, - 0, 63, 0, wm8940_pga_vol_tlv), - SOC_SINGLE_TLV("Digital Playback Volume", WM8940_DACVOL, - 0, 255, 0, wm8940_adc_tlv), - SOC_SINGLE_TLV("Digital Capture Volume", WM8940_ADCVOL, - 0, 255, 0, wm8940_adc_tlv), - SOC_ENUM("Mic Bias Level", wm8940_mic_bias_level_enum), - SOC_SINGLE_TLV("Capture Boost Volue", WM8940_ADCBOOST, - 8, 1, 0, wm8940_capture_boost_vol_tlv), - SOC_SINGLE_TLV("Speaker Playback Volume", WM8940_SPKVOL, - 0, 63, 0, wm8940_spk_vol_tlv), - SOC_SINGLE("Speaker Playback Switch", WM8940_SPKVOL, 6, 1, 1), - - SOC_SINGLE_TLV("Speaker Mixer Line Bypass Volume", WM8940_SPKVOL, - 8, 1, 1, wm8940_att_tlv), - SOC_SINGLE("Speaker Playback ZC Switch", WM8940_SPKVOL, 7, 1, 0), - - SOC_SINGLE("Mono Out Switch", WM8940_MONOMIX, 6, 1, 1), - SOC_SINGLE_TLV("Mono Mixer Line Bypass Volume", WM8940_MONOMIX, - 7, 1, 1, wm8940_att_tlv), - - SOC_SINGLE("High Pass Filter Switch", WM8940_ADC, 8, 1, 0), - SOC_ENUM("High Pass Filter Mode", wm8940_filter_mode_enum), - SOC_SINGLE("High Pass Filter Cut Off", WM8940_ADC, 4, 7, 0), - SOC_SINGLE("ADC Inversion Switch", WM8940_ADC, 0, 1, 0), - SOC_SINGLE("DAC Inversion Switch", WM8940_DAC, 0, 1, 0), - SOC_SINGLE("DAC Auto Mute Switch", WM8940_DAC, 2, 1, 0), - SOC_SINGLE("ZC Timeout Clock Switch", WM8940_ADDCNTRL, 0, 1, 0), -}; - -static const struct snd_kcontrol_new wm8940_speaker_mixer_controls[] = { - SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_SPKMIX, 1, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_SPKMIX, 5, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_SPKMIX, 0, 1, 0), -}; - -static const struct snd_kcontrol_new wm8940_mono_mixer_controls[] = { - SOC_DAPM_SINGLE("Line Bypass Switch", WM8940_MONOMIX, 1, 1, 0), - SOC_DAPM_SINGLE("Aux Playback Switch", WM8940_MONOMIX, 2, 1, 0), - SOC_DAPM_SINGLE("PCM Playback Switch", WM8940_MONOMIX, 0, 1, 0), -}; - -static DECLARE_TLV_DB_SCALE(wm8940_boost_vol_tlv, -1500, 300, 1); -static const struct snd_kcontrol_new wm8940_input_boost_controls[] = { - SOC_DAPM_SINGLE("Mic PGA Switch", WM8940_PGAGAIN, 6, 1, 1), - SOC_DAPM_SINGLE_TLV("Aux Volume", WM8940_ADCBOOST, - 0, 7, 0, wm8940_boost_vol_tlv), - SOC_DAPM_SINGLE_TLV("Mic Volume", WM8940_ADCBOOST, - 4, 7, 0, wm8940_boost_vol_tlv), -}; - -static const struct snd_kcontrol_new wm8940_micpga_controls[] = { - SOC_DAPM_SINGLE("AUX Switch", WM8940_INPUTCTL, 2, 1, 0), - SOC_DAPM_SINGLE("MICP Switch", WM8940_INPUTCTL, 0, 1, 0), - SOC_DAPM_SINGLE("MICN Switch", WM8940_INPUTCTL, 1, 1, 0), -}; - -static const struct snd_soc_dapm_widget wm8940_dapm_widgets[] = { - SND_SOC_DAPM_MIXER("Speaker Mixer", WM8940_POWER3, 2, 0, - &wm8940_speaker_mixer_controls[0], - ARRAY_SIZE(wm8940_speaker_mixer_controls)), - SND_SOC_DAPM_MIXER("Mono Mixer", WM8940_POWER3, 3, 0, - &wm8940_mono_mixer_controls[0], - ARRAY_SIZE(wm8940_mono_mixer_controls)), - SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8940_POWER3, 0, 0), - - SND_SOC_DAPM_PGA("SpkN Out", WM8940_POWER3, 5, 0, NULL, 0), - SND_SOC_DAPM_PGA("SpkP Out", WM8940_POWER3, 6, 0, NULL, 0), - SND_SOC_DAPM_PGA("Mono Out", WM8940_POWER3, 7, 0, NULL, 0), - SND_SOC_DAPM_OUTPUT("MONOOUT"), - SND_SOC_DAPM_OUTPUT("SPKOUTP"), - SND_SOC_DAPM_OUTPUT("SPKOUTN"), - - SND_SOC_DAPM_PGA("Aux Input", WM8940_POWER1, 6, 0, NULL, 0), - SND_SOC_DAPM_ADC("ADC", "HiFi Capture", WM8940_POWER2, 0, 0), - SND_SOC_DAPM_MIXER("Mic PGA", WM8940_POWER2, 2, 0, - &wm8940_micpga_controls[0], - ARRAY_SIZE(wm8940_micpga_controls)), - SND_SOC_DAPM_MIXER("Boost Mixer", WM8940_POWER2, 4, 0, - &wm8940_input_boost_controls[0], - ARRAY_SIZE(wm8940_input_boost_controls)), - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8940_POWER1, 4, 0), - - SND_SOC_DAPM_INPUT("MICN"), - SND_SOC_DAPM_INPUT("MICP"), - SND_SOC_DAPM_INPUT("AUX"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Mono output mixer */ - {"Mono Mixer", "PCM Playback Switch", "DAC"}, - {"Mono Mixer", "Aux Playback Switch", "Aux Input"}, - {"Mono Mixer", "Line Bypass Switch", "Boost Mixer"}, - - /* Speaker output mixer */ - {"Speaker Mixer", "PCM Playback Switch", "DAC"}, - {"Speaker Mixer", "Aux Playback Switch", "Aux Input"}, - {"Speaker Mixer", "Line Bypass Switch", "Boost Mixer"}, - - /* Outputs */ - {"Mono Out", NULL, "Mono Mixer"}, - {"MONOOUT", NULL, "Mono Out"}, - {"SpkN Out", NULL, "Speaker Mixer"}, - {"SpkP Out", NULL, "Speaker Mixer"}, - {"SPKOUTN", NULL, "SpkN Out"}, - {"SPKOUTP", NULL, "SpkP Out"}, - - /* Microphone PGA */ - {"Mic PGA", "MICN Switch", "MICN"}, - {"Mic PGA", "MICP Switch", "MICP"}, - {"Mic PGA", "AUX Switch", "AUX"}, - - /* Boost Mixer */ - {"Boost Mixer", "Mic PGA Switch", "Mic PGA"}, - {"Boost Mixer", "Mic Volume", "MICP"}, - {"Boost Mixer", "Aux Volume", "Aux Input"}, - - {"ADC", NULL, "Boost Mixer"}, -}; - -static int wm8940_add_widgets(struct snd_soc_codec *codec) -{ - int ret; - - ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, - ARRAY_SIZE(wm8940_dapm_widgets)); - if (ret) - goto error_ret; - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - if (ret) - goto error_ret; - ret = snd_soc_dapm_new_widgets(codec); - -error_ret: - return ret; -} - -#define wm8940_reset(c) wm8940_write(c, WM8940_SOFTRESET, 0); - -static int wm8940_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFE67; - u16 clk = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0x1fe; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - clk |= 1; - break; - case SND_SOC_DAIFMT_CBS_CFS: - break; - default: - return -EINVAL; - } - wm8940_write(codec, WM8940_CLOCK, clk); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - iface |= (2 << 3); - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= (1 << 3); - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= (3 << 3); - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= (3 << 3) | (1 << 7); - break; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= (1 << 7); - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= (1 << 8); - break; - case SND_SOC_DAIFMT_IB_IF: - iface |= (1 << 8) | (1 << 7); - break; - } - - wm8940_write(codec, WM8940_IFACE, iface); - - return 0; -} - -static int wm8940_i2s_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->card->codec; - u16 iface = wm8940_read_reg_cache(codec, WM8940_IFACE) & 0xFD9F; - u16 addcntrl = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFF1; - u16 companding = wm8940_read_reg_cache(codec, - WM8940_COMPANDINGCTL) & 0xFFDF; - int ret; - - /* LoutR control */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE - && params_channels(params) == 2) - iface |= (1 << 9); - - switch (params_rate(params)) { - case SNDRV_PCM_RATE_8000: - addcntrl |= (0x5 << 1); - break; - case SNDRV_PCM_RATE_11025: - addcntrl |= (0x4 << 1); - break; - case SNDRV_PCM_RATE_16000: - addcntrl |= (0x3 << 1); - break; - case SNDRV_PCM_RATE_22050: - addcntrl |= (0x2 << 1); - break; - case SNDRV_PCM_RATE_32000: - addcntrl |= (0x1 << 1); - break; - case SNDRV_PCM_RATE_44100: - case SNDRV_PCM_RATE_48000: - break; - } - ret = wm8940_write(codec, WM8940_ADDCNTRL, addcntrl); - if (ret) - goto error_ret; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - companding = companding | (1 << 5); - break; - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= (1 << 5); - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= (2 << 5); - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= (3 << 5); - break; - } - ret = wm8940_write(codec, WM8940_COMPANDINGCTL, companding); - if (ret) - goto error_ret; - ret = wm8940_write(codec, WM8940_IFACE, iface); - -error_ret: - return ret; -} - -static int wm8940_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8940_read_reg_cache(codec, WM8940_DAC) & 0xffbf; - - if (mute) - mute_reg |= 0x40; - - return wm8940_write(codec, WM8940_DAC, mute_reg); -} - -static int wm8940_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - u16 val; - u16 pwr_reg = wm8940_read_reg_cache(codec, WM8940_POWER1) & 0x1F0; - int ret = 0; - - switch (level) { - case SND_SOC_BIAS_ON: - /* ensure bufioen and biasen */ - pwr_reg |= (1 << 2) | (1 << 3); - /* Enable thermal shutdown */ - val = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); - ret = wm8940_write(codec, WM8940_OUTPUTCTL, val | 0x2); - if (ret) - break; - /* set vmid to 75k */ - ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); - break; - case SND_SOC_BIAS_PREPARE: - /* ensure bufioen and biasen */ - pwr_reg |= (1 << 2) | (1 << 3); - ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x1); - break; - case SND_SOC_BIAS_STANDBY: - /* ensure bufioen and biasen */ - pwr_reg |= (1 << 2) | (1 << 3); - /* set vmid to 300k for standby */ - ret = wm8940_write(codec, WM8940_POWER1, pwr_reg | 0x2); - break; - case SND_SOC_BIAS_OFF: - ret = wm8940_write(codec, WM8940_POWER1, pwr_reg); - break; - } - - return ret; -} - -struct pll_ { - unsigned int pre_scale:2; - unsigned int n:4; - unsigned int k; -}; - -static struct pll_ pll_div; - -/* The size in bits of the pll divide multiplied by 10 - * to allow rounding later */ -#define FIXED_PLL_SIZE ((1 << 24) * 10) -static void pll_factors(unsigned int target, unsigned int source) -{ - unsigned long long Kpart; - unsigned int K, Ndiv, Nmod; - /* The left shift ist to avoid accuracy loss when right shifting */ - Ndiv = target / source; - - if (Ndiv > 12) { - source <<= 1; - /* Multiply by 2 */ - pll_div.pre_scale = 0; - Ndiv = target / source; - } else if (Ndiv < 3) { - source >>= 2; - /* Divide by 4 */ - pll_div.pre_scale = 3; - Ndiv = target / source; - } else if (Ndiv < 6) { - source >>= 1; - /* divide by 2 */ - pll_div.pre_scale = 2; - Ndiv = target / source; - } else - pll_div.pre_scale = 1; - - if ((Ndiv < 6) || (Ndiv > 12)) - printk(KERN_WARNING - "WM8940 N value %d outwith recommended range!d\n", - Ndiv); - - pll_div.n = Ndiv; - Nmod = target % source; - Kpart = FIXED_PLL_SIZE * (long long)Nmod; - - do_div(Kpart, source); - - 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; - - pll_div.k = K; -} - -/* Untested at the moment */ -static int wm8940_set_dai_pll(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; - u16 reg; - - /* Turn off PLL */ - reg = wm8940_read_reg_cache(codec, WM8940_POWER1); - wm8940_write(codec, WM8940_POWER1, reg & 0x1df); - - if (freq_in == 0 || freq_out == 0) { - /* Clock CODEC directly from MCLK */ - reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); - wm8940_write(codec, WM8940_CLOCK, reg & 0x0ff); - /* Pll power down */ - wm8940_write(codec, WM8940_PLLN, (1 << 7)); - return 0; - } - - /* Pll is followed by a frequency divide by 4 */ - pll_factors(freq_out*4, freq_in); - if (pll_div.k) - wm8940_write(codec, WM8940_PLLN, - (pll_div.pre_scale << 4) | pll_div.n | (1 << 6)); - else /* No factional component */ - wm8940_write(codec, WM8940_PLLN, - (pll_div.pre_scale << 4) | pll_div.n); - wm8940_write(codec, WM8940_PLLK1, pll_div.k >> 18); - wm8940_write(codec, WM8940_PLLK2, (pll_div.k >> 9) & 0x1ff); - wm8940_write(codec, WM8940_PLLK3, pll_div.k & 0x1ff); - /* Enable the PLL */ - reg = wm8940_read_reg_cache(codec, WM8940_POWER1); - wm8940_write(codec, WM8940_POWER1, reg | 0x020); - - /* Run CODEC from PLL instead of MCLK */ - reg = wm8940_read_reg_cache(codec, WM8940_CLOCK); - wm8940_write(codec, WM8940_CLOCK, reg | 0x100); - - return 0; -} - -static int wm8940_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 wm8940_priv *wm8940 = codec->private_data; - - switch (freq) { - case 11289600: - case 12000000: - case 12288000: - case 16934400: - case 18432000: - wm8940->sysclk = freq; - return 0; - } - return -EINVAL; -} - -static int wm8940_set_dai_clkdiv(struct snd_soc_dai *codec_dai, - int div_id, int div) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 reg; - int ret = 0; - - switch (div_id) { - case WM8940_BCLKDIV: - reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFFEF3; - ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 2)); - break; - case WM8940_MCLKDIV: - reg = wm8940_read_reg_cache(codec, WM8940_CLOCK) & 0xFF1F; - ret = wm8940_write(codec, WM8940_CLOCK, reg | (div << 5)); - break; - case WM8940_OPCLKDIV: - reg = wm8940_read_reg_cache(codec, WM8940_ADDCNTRL) & 0xFFCF; - ret = wm8940_write(codec, WM8940_ADDCNTRL, reg | (div << 4)); - break; - } - return ret; -} - -#define WM8940_RATES SNDRV_PCM_RATE_8000_48000 - -#define WM8940_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ - SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE | \ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops wm8940_dai_ops = { - .hw_params = wm8940_i2s_hw_params, - .set_sysclk = wm8940_set_dai_sysclk, - .digital_mute = wm8940_mute, - .set_fmt = wm8940_set_dai_fmt, - .set_clkdiv = wm8940_set_dai_clkdiv, - .set_pll = wm8940_set_dai_pll, -}; - -struct snd_soc_dai wm8940_dai = { - .name = "WM8940", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8940_RATES, - .formats = WM8940_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8940_RATES, - .formats = WM8940_FORMATS, - }, - .ops = &wm8940_dai_ops, - .symmetric_rates = 1, -}; -EXPORT_SYMBOL_GPL(wm8940_dai); - -static int wm8940_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - return wm8940_set_bias_level(codec, SND_SOC_BIAS_OFF); -} - -static int wm8940_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - int i; - int ret; - u8 data[3]; - u16 *cache = codec->reg_cache; - - /* Sync reg_cache with the hardware - * Could use auto incremented writes to speed this up - */ - for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) { - data[0] = i; - data[1] = (cache[i] & 0xFF00) >> 8; - data[2] = cache[i] & 0x00FF; - ret = codec->hw_write(codec->control_data, data, 3); - if (ret < 0) - goto error_ret; - else if (ret != 3) { - ret = -EIO; - goto error_ret; - } - } - ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - if (ret) - goto error_ret; - ret = wm8940_set_bias_level(codec, codec->suspend_bias_level); - -error_ret: - return ret; -} - -static struct snd_soc_codec *wm8940_codec; - -static int wm8940_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - - int ret = 0; - - if (wm8940_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } - - socdev->card->codec = wm8940_codec; - codec = wm8940_codec; - - mutex_init(&codec->mutex); - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - ret = snd_soc_add_controls(codec, wm8940_snd_controls, - ARRAY_SIZE(wm8940_snd_controls)); - if (ret) - goto error_free_pcms; - ret = wm8940_add_widgets(codec); - if (ret) - goto error_free_pcms; - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto error_free_pcms; - } - - return ret; - -error_free_pcms: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -static int wm8940_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8940 = { - .probe = wm8940_probe, - .remove = wm8940_remove, - .suspend = wm8940_suspend, - .resume = wm8940_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8940); - -static int wm8940_register(struct wm8940_priv *wm8940) -{ - struct wm8940_setup_data *pdata = wm8940->codec.dev->platform_data; - struct snd_soc_codec *codec = &wm8940->codec; - int ret; - u16 reg; - if (wm8940_codec) { - dev_err(codec->dev, "Another WM8940 is registered\n"); - return -EINVAL; - } - - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = wm8940; - codec->name = "WM8940"; - codec->owner = THIS_MODULE; - codec->read = wm8940_read_reg_cache; - codec->write = wm8940_write; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8940_set_bias_level; - codec->dai = &wm8940_dai; - codec->num_dai = 1; - codec->reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults); - codec->reg_cache = &wm8940->reg_cache; - - memcpy(codec->reg_cache, wm8940_reg_defaults, - sizeof(wm8940_reg_defaults)); - - ret = wm8940_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - - wm8940_dai.dev = codec->dev; - - wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - ret = wm8940_write(codec, WM8940_POWER1, 0x180); - if (ret < 0) - return ret; - - if (!pdata) - dev_warn(codec->dev, "No platform data supplied\n"); - else { - reg = wm8940_read_reg_cache(codec, WM8940_OUTPUTCTL); - ret = wm8940_write(codec, WM8940_OUTPUTCTL, reg | pdata->vroi); - if (ret < 0) - return ret; - } - - - wm8940_codec = codec; - - ret = snd_soc_register_codec(codec); - if (ret) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - return ret; - } - - ret = snd_soc_register_dai(&wm8940_dai); - if (ret) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - return ret; - } - - return 0; -} - -static void wm8940_unregister(struct wm8940_priv *wm8940) -{ - wm8940_set_bias_level(&wm8940->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm8940_dai); - snd_soc_unregister_codec(&wm8940->codec); - kfree(wm8940); - wm8940_codec = NULL; -} - -static int wm8940_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8940_priv *wm8940; - struct snd_soc_codec *codec; - - wm8940 = kzalloc(sizeof *wm8940, GFP_KERNEL); - if (wm8940 == NULL) - return -ENOMEM; - - codec = &wm8940->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - i2c_set_clientdata(i2c, wm8940); - codec->control_data = i2c; - codec->dev = &i2c->dev; - - return wm8940_register(wm8940); -} - -static int __devexit wm8940_i2c_remove(struct i2c_client *client) -{ - struct wm8940_priv *wm8940 = i2c_get_clientdata(client); - - wm8940_unregister(wm8940); - - return 0; -} - -static const struct i2c_device_id wm8940_i2c_id[] = { - { "wm8940", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8940_i2c_id); - -static struct i2c_driver wm8940_i2c_driver = { - .driver = { - .name = "WM8940 I2C Codec", - .owner = THIS_MODULE, - }, - .probe = wm8940_i2c_probe, - .remove = __devexit_p(wm8940_i2c_remove), - .id_table = wm8940_i2c_id, -}; - -static int __init wm8940_modinit(void) -{ - int ret; - - ret = i2c_add_driver(&wm8940_i2c_driver); - if (ret) - printk(KERN_ERR "Failed to register WM8940 I2C driver: %d\n", - ret); - return ret; -} -module_init(wm8940_modinit); - -static void __exit wm8940_exit(void) -{ - i2c_del_driver(&wm8940_i2c_driver); -} -module_exit(wm8940_exit); - -MODULE_DESCRIPTION("ASoC WM8940 driver"); -MODULE_AUTHOR("Jonathan Cameron"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8940.h b/trunk/sound/soc/codecs/wm8940.h deleted file mode 100644 index 8410eed3ef84..000000000000 --- a/trunk/sound/soc/codecs/wm8940.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * wm8940.h -- WM8940 Soc Audio driver - * - * 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 _WM8940_H -#define _WM8940_H - -struct wm8940_setup_data { - /* Vref to analogue output resistance */ -#define WM8940_VROI_1K 0 -#define WM8940_VROI_30K 1 - unsigned int vroi:1; -}; -extern struct snd_soc_dai wm8940_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8940; - -/* WM8940 register space */ -#define WM8940_SOFTRESET 0x00 -#define WM8940_POWER1 0x01 -#define WM8940_POWER2 0x02 -#define WM8940_POWER3 0x03 -#define WM8940_IFACE 0x04 -#define WM8940_COMPANDINGCTL 0x05 -#define WM8940_CLOCK 0x06 -#define WM8940_ADDCNTRL 0x07 -#define WM8940_GPIO 0x08 -#define WM8940_CTLINT 0x09 -#define WM8940_DAC 0x0A -#define WM8940_DACVOL 0x0B - -#define WM8940_ADC 0x0E -#define WM8940_ADCVOL 0x0F -#define WM8940_NOTCH1 0x10 -#define WM8940_NOTCH2 0x11 -#define WM8940_NOTCH3 0x12 -#define WM8940_NOTCH4 0x13 -#define WM8940_NOTCH5 0x14 -#define WM8940_NOTCH6 0x15 -#define WM8940_NOTCH7 0x16 -#define WM8940_NOTCH8 0x17 -#define WM8940_DACLIM1 0x18 -#define WM8940_DACLIM2 0x19 - -#define WM8940_ALC1 0x20 -#define WM8940_ALC2 0x21 -#define WM8940_ALC3 0x22 -#define WM8940_NOISEGATE 0x23 -#define WM8940_PLLN 0x24 -#define WM8940_PLLK1 0x25 -#define WM8940_PLLK2 0x26 -#define WM8940_PLLK3 0x27 - -#define WM8940_ALC4 0x2A - -#define WM8940_INPUTCTL 0x2C -#define WM8940_PGAGAIN 0x2D - -#define WM8940_ADCBOOST 0x2F - -#define WM8940_OUTPUTCTL 0x31 -#define WM8940_SPKMIX 0x32 - -#define WM8940_SPKVOL 0x36 - -#define WM8940_MONOMIX 0x38 - -#define WM8940_CACHEREGNUM 0x57 - - -/* Clock divider Id's */ -#define WM8940_BCLKDIV 0 -#define WM8940_MCLKDIV 1 -#define WM8940_OPCLKDIV 2 - -/* MCLK clock dividers */ -#define WM8940_MCLKDIV_1 0 -#define WM8940_MCLKDIV_1_5 1 -#define WM8940_MCLKDIV_2 2 -#define WM8940_MCLKDIV_3 3 -#define WM8940_MCLKDIV_4 4 -#define WM8940_MCLKDIV_6 5 -#define WM8940_MCLKDIV_8 6 -#define WM8940_MCLKDIV_12 7 - -/* BCLK clock dividers */ -#define WM8940_BCLKDIV_1 0 -#define WM8940_BCLKDIV_2 1 -#define WM8940_BCLKDIV_4 2 -#define WM8940_BCLKDIV_8 3 -#define WM8940_BCLKDIV_16 4 -#define WM8940_BCLKDIV_32 5 - -/* PLL Out Dividers */ -#define WM8940_OPCLKDIV_1 0 -#define WM8940_OPCLKDIV_2 1 -#define WM8940_OPCLKDIV_3 2 -#define WM8940_OPCLKDIV_4 3 - -#endif /* _WM8940_H */ - diff --git a/trunk/sound/soc/codecs/wm8960.c b/trunk/sound/soc/codecs/wm8960.c deleted file mode 100644 index e224d8add170..000000000000 --- a/trunk/sound/soc/codecs/wm8960.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * wm8960.c -- WM8960 ALSA SoC Audio driver - * - * Author: Liam Girdwood - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8960.h" - -#define AUDIO_NAME "wm8960" - -struct snd_soc_codec_device soc_codec_dev_wm8960; - -/* R25 - Power 1 */ -#define WM8960_VREF 0x40 - -/* R28 - Anti-pop 1 */ -#define WM8960_POBCTRL 0x80 -#define WM8960_BUFDCOPEN 0x10 -#define WM8960_BUFIOEN 0x08 -#define WM8960_SOFT_ST 0x04 -#define WM8960_HPSTBY 0x01 - -/* R29 - Anti-pop 2 */ -#define WM8960_DISOP 0x40 - -/* - * wm8960 register cache - * We can't read the WM8960 register space when we are - * using 2 wire for device control, so we cache them instead. - */ -static const u16 wm8960_reg[WM8960_CACHEREGNUM] = { - 0x0097, 0x0097, 0x0000, 0x0000, - 0x0000, 0x0008, 0x0000, 0x000a, - 0x01c0, 0x0000, 0x00ff, 0x00ff, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x007b, 0x0100, 0x0032, - 0x0000, 0x00c3, 0x00c3, 0x01c0, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0100, 0x0100, 0x0050, 0x0050, - 0x0050, 0x0050, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0040, 0x0000, - 0x0000, 0x0050, 0x0050, 0x0000, - 0x0002, 0x0037, 0x004d, 0x0080, - 0x0008, 0x0031, 0x0026, 0x00e9, -}; - -struct wm8960_priv { - u16 reg_cache[WM8960_CACHEREGNUM]; - struct snd_soc_codec codec; -}; - -/* - * read wm8960 register cache - */ -static inline unsigned int wm8960_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg == WM8960_RESET) - return 0; - if (reg >= WM8960_CACHEREGNUM) - return -1; - return cache[reg]; -} - -/* - * write wm8960 register cache - */ -static inline void wm8960_write_reg_cache(struct snd_soc_codec *codec, - u16 reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg >= WM8960_CACHEREGNUM) - return; - cache[reg] = value; -} - -static inline unsigned int wm8960_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return wm8960_read_reg_cache(codec, reg); -} - -/* - * write to the WM8960 register space - */ -static int wm8960_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D9 WM8960 register offset - * D8...D0 register data - */ - data[0] = (reg << 1) | ((value >> 8) & 0x0001); - data[1] = value & 0x00ff; - - wm8960_write_reg_cache(codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define wm8960_reset(c) wm8960_write(c, WM8960_RESET, 0) - -/* enumerated controls */ -static const char *wm8960_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; -static const char *wm8960_polarity[] = {"No Inversion", "Left Inverted", - "Right Inverted", "Stereo Inversion"}; -static const char *wm8960_3d_upper_cutoff[] = {"High", "Low"}; -static const char *wm8960_3d_lower_cutoff[] = {"Low", "High"}; -static const char *wm8960_alcfunc[] = {"Off", "Right", "Left", "Stereo"}; -static const char *wm8960_alcmode[] = {"ALC", "Limiter"}; - -static const struct soc_enum wm8960_enum[] = { - SOC_ENUM_SINGLE(WM8960_DACCTL1, 1, 4, wm8960_deemph), - SOC_ENUM_SINGLE(WM8960_DACCTL1, 5, 4, wm8960_polarity), - SOC_ENUM_SINGLE(WM8960_DACCTL2, 5, 4, wm8960_polarity), - SOC_ENUM_SINGLE(WM8960_3D, 6, 2, wm8960_3d_upper_cutoff), - SOC_ENUM_SINGLE(WM8960_3D, 5, 2, wm8960_3d_lower_cutoff), - SOC_ENUM_SINGLE(WM8960_ALC1, 7, 4, wm8960_alcfunc), - SOC_ENUM_SINGLE(WM8960_ALC3, 8, 2, wm8960_alcmode), -}; - -static const DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 50, 0); -static const DECLARE_TLV_DB_SCALE(dac_tlv, -12700, 50, 1); -static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0); -static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); - -static const struct snd_kcontrol_new wm8960_snd_controls[] = { -SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL, - 0, 63, 0, adc_tlv), -SOC_DOUBLE_R("Capture Volume ZC Switch", WM8960_LINVOL, WM8960_RINVOL, - 6, 1, 0), -SOC_DOUBLE_R("Capture Switch", WM8960_LINVOL, WM8960_RINVOL, - 7, 1, 0), - -SOC_DOUBLE_R_TLV("Playback Volume", WM8960_LDAC, WM8960_RDAC, - 0, 255, 0, dac_tlv), - -SOC_DOUBLE_R_TLV("Headphone Playback Volume", WM8960_LOUT1, WM8960_ROUT1, - 0, 127, 0, out_tlv), -SOC_DOUBLE_R("Headphone Playback ZC Switch", WM8960_LOUT1, WM8960_ROUT1, - 7, 1, 0), - -SOC_DOUBLE_R_TLV("Speaker Playback Volume", WM8960_LOUT2, WM8960_ROUT2, - 0, 127, 0, out_tlv), -SOC_DOUBLE_R("Speaker Playback ZC Switch", WM8960_LOUT2, WM8960_ROUT2, - 7, 1, 0), -SOC_SINGLE("Speaker DC Volume", WM8960_CLASSD3, 3, 5, 0), -SOC_SINGLE("Speaker AC Volume", WM8960_CLASSD3, 0, 5, 0), - -SOC_SINGLE("PCM Playback -6dB Switch", WM8960_DACCTL1, 7, 1, 0), -SOC_ENUM("ADC Polarity", wm8960_enum[1]), -SOC_ENUM("Playback De-emphasis", wm8960_enum[0]), -SOC_SINGLE("ADC High Pass Filter Switch", WM8960_DACCTL1, 0, 1, 0), - -SOC_ENUM("DAC Polarity", wm8960_enum[2]), - -SOC_ENUM("3D Filter Upper Cut-Off", wm8960_enum[3]), -SOC_ENUM("3D Filter Lower Cut-Off", wm8960_enum[4]), -SOC_SINGLE("3D Volume", WM8960_3D, 1, 15, 0), -SOC_SINGLE("3D Switch", WM8960_3D, 0, 1, 0), - -SOC_ENUM("ALC Function", wm8960_enum[5]), -SOC_SINGLE("ALC Max Gain", WM8960_ALC1, 4, 7, 0), -SOC_SINGLE("ALC Target", WM8960_ALC1, 0, 15, 1), -SOC_SINGLE("ALC Min Gain", WM8960_ALC2, 4, 7, 0), -SOC_SINGLE("ALC Hold Time", WM8960_ALC2, 0, 15, 0), -SOC_ENUM("ALC Mode", wm8960_enum[6]), -SOC_SINGLE("ALC Decay", WM8960_ALC3, 4, 15, 0), -SOC_SINGLE("ALC Attack", WM8960_ALC3, 0, 15, 0), - -SOC_SINGLE("Noise Gate Threshold", WM8960_NOISEG, 3, 31, 0), -SOC_SINGLE("Noise Gate Switch", WM8960_NOISEG, 0, 1, 0), - -SOC_DOUBLE_R("ADC PCM Capture Volume", WM8960_LINPATH, WM8960_RINPATH, - 0, 127, 0), - -SOC_SINGLE_TLV("Left Output Mixer Boost Bypass Volume", - WM8960_BYPASS1, 4, 7, 1, bypass_tlv), -SOC_SINGLE_TLV("Left Output Mixer LINPUT3 Volume", - WM8960_LOUTMIX, 4, 7, 1, bypass_tlv), -SOC_SINGLE_TLV("Right Output Mixer Boost Bypass Volume", - WM8960_BYPASS2, 4, 7, 1, bypass_tlv), -SOC_SINGLE_TLV("Right Output Mixer RINPUT3 Volume", - WM8960_ROUTMIX, 4, 7, 1, bypass_tlv), -}; - -static const struct snd_kcontrol_new wm8960_lin_boost[] = { -SOC_DAPM_SINGLE("LINPUT2 Switch", WM8960_LINPATH, 6, 1, 0), -SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LINPATH, 7, 1, 0), -SOC_DAPM_SINGLE("LINPUT1 Switch", WM8960_LINPATH, 8, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_lin[] = { -SOC_DAPM_SINGLE("Boost Switch", WM8960_LINPATH, 3, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_rin_boost[] = { -SOC_DAPM_SINGLE("RINPUT2 Switch", WM8960_RINPATH, 6, 1, 0), -SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_RINPATH, 7, 1, 0), -SOC_DAPM_SINGLE("RINPUT1 Switch", WM8960_RINPATH, 8, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_rin[] = { -SOC_DAPM_SINGLE("Boost Switch", WM8960_RINPATH, 3, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_loutput_mixer[] = { -SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0), -SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0), -SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_routput_mixer[] = { -SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0), -SOC_DAPM_SINGLE("RINPUT3 Switch", WM8960_ROUTMIX, 7, 1, 0), -SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS2, 7, 1, 0), -}; - -static const struct snd_kcontrol_new wm8960_mono_out[] = { -SOC_DAPM_SINGLE("Left Switch", WM8960_MONOMIX1, 7, 1, 0), -SOC_DAPM_SINGLE("Right Switch", WM8960_MONOMIX2, 7, 1, 0), -}; - -static const struct snd_soc_dapm_widget wm8960_dapm_widgets[] = { -SND_SOC_DAPM_INPUT("LINPUT1"), -SND_SOC_DAPM_INPUT("RINPUT1"), -SND_SOC_DAPM_INPUT("LINPUT2"), -SND_SOC_DAPM_INPUT("RINPUT2"), -SND_SOC_DAPM_INPUT("LINPUT3"), -SND_SOC_DAPM_INPUT("RINPUT3"), - -SND_SOC_DAPM_MICBIAS("MICB", WM8960_POWER1, 1, 0), - -SND_SOC_DAPM_MIXER("Left Boost Mixer", WM8960_POWER1, 5, 0, - wm8960_lin_boost, ARRAY_SIZE(wm8960_lin_boost)), -SND_SOC_DAPM_MIXER("Right Boost Mixer", WM8960_POWER1, 4, 0, - wm8960_rin_boost, ARRAY_SIZE(wm8960_rin_boost)), - -SND_SOC_DAPM_MIXER("Left Input Mixer", WM8960_POWER3, 5, 0, - wm8960_lin, ARRAY_SIZE(wm8960_lin)), -SND_SOC_DAPM_MIXER("Right Input Mixer", WM8960_POWER3, 4, 0, - wm8960_rin, ARRAY_SIZE(wm8960_rin)), - -SND_SOC_DAPM_ADC("Left ADC", "Capture", WM8960_POWER2, 3, 0), -SND_SOC_DAPM_ADC("Right ADC", "Capture", WM8960_POWER2, 2, 0), - -SND_SOC_DAPM_DAC("Left DAC", "Playback", WM8960_POWER2, 8, 0), -SND_SOC_DAPM_DAC("Right DAC", "Playback", WM8960_POWER2, 7, 0), - -SND_SOC_DAPM_MIXER("Left Output Mixer", WM8960_POWER3, 3, 0, - &wm8960_loutput_mixer[0], - ARRAY_SIZE(wm8960_loutput_mixer)), -SND_SOC_DAPM_MIXER("Right Output Mixer", WM8960_POWER3, 2, 0, - &wm8960_routput_mixer[0], - ARRAY_SIZE(wm8960_routput_mixer)), - -SND_SOC_DAPM_MIXER("Mono Output Mixer", WM8960_POWER2, 1, 0, - &wm8960_mono_out[0], - ARRAY_SIZE(wm8960_mono_out)), - -SND_SOC_DAPM_PGA("LOUT1 PGA", WM8960_POWER2, 6, 0, NULL, 0), -SND_SOC_DAPM_PGA("ROUT1 PGA", WM8960_POWER2, 5, 0, NULL, 0), - -SND_SOC_DAPM_PGA("Left Speaker PGA", WM8960_POWER2, 4, 0, NULL, 0), -SND_SOC_DAPM_PGA("Right Speaker PGA", WM8960_POWER2, 3, 0, NULL, 0), - -SND_SOC_DAPM_PGA("Right Speaker Output", WM8960_CLASSD1, 7, 0, NULL, 0), -SND_SOC_DAPM_PGA("Left Speaker Output", WM8960_CLASSD1, 6, 0, NULL, 0), - -SND_SOC_DAPM_OUTPUT("SPK_LP"), -SND_SOC_DAPM_OUTPUT("SPK_LN"), -SND_SOC_DAPM_OUTPUT("HP_L"), -SND_SOC_DAPM_OUTPUT("HP_R"), -SND_SOC_DAPM_OUTPUT("SPK_RP"), -SND_SOC_DAPM_OUTPUT("SPK_RN"), -SND_SOC_DAPM_OUTPUT("OUT3"), -}; - -static const struct snd_soc_dapm_route audio_paths[] = { - { "Left Boost Mixer", "LINPUT1 Switch", "LINPUT1" }, - { "Left Boost Mixer", "LINPUT2 Switch", "LINPUT2" }, - { "Left Boost Mixer", "LINPUT3 Switch", "LINPUT3" }, - - { "Left Input Mixer", "Boost Switch", "Left Boost Mixer", }, - { "Left Input Mixer", NULL, "LINPUT1", }, /* Really Boost Switch */ - { "Left Input Mixer", NULL, "LINPUT2" }, - { "Left Input Mixer", NULL, "LINPUT3" }, - - { "Right Boost Mixer", "RINPUT1 Switch", "RINPUT1" }, - { "Right Boost Mixer", "RINPUT2 Switch", "RINPUT2" }, - { "Right Boost Mixer", "RINPUT3 Switch", "RINPUT3" }, - - { "Right Input Mixer", "Boost Switch", "Right Boost Mixer", }, - { "Right Input Mixer", NULL, "RINPUT1", }, /* Really Boost Switch */ - { "Right Input Mixer", NULL, "RINPUT2" }, - { "Right Input Mixer", NULL, "LINPUT3" }, - - { "Left ADC", NULL, "Left Input Mixer" }, - { "Right ADC", NULL, "Right Input Mixer" }, - - { "Left Output Mixer", "LINPUT3 Switch", "LINPUT3" }, - { "Left Output Mixer", "Boost Bypass Switch", "Left Boost Mixer"} , - { "Left Output Mixer", "PCM Playback Switch", "Left DAC" }, - - { "Right Output Mixer", "RINPUT3 Switch", "RINPUT3" }, - { "Right Output Mixer", "Boost Bypass Switch", "Right Boost Mixer" } , - { "Right Output Mixer", "PCM Playback Switch", "Right DAC" }, - - { "Mono Output Mixer", "Left Switch", "Left Output Mixer" }, - { "Mono Output Mixer", "Right Switch", "Right Output Mixer" }, - - { "LOUT1 PGA", NULL, "Left Output Mixer" }, - { "ROUT1 PGA", NULL, "Right Output Mixer" }, - - { "HP_L", NULL, "LOUT1 PGA" }, - { "HP_R", NULL, "ROUT1 PGA" }, - - { "Left Speaker PGA", NULL, "Left Output Mixer" }, - { "Right Speaker PGA", NULL, "Right Output Mixer" }, - - { "Left Speaker Output", NULL, "Left Speaker PGA" }, - { "Right Speaker Output", NULL, "Right Speaker PGA" }, - - { "SPK_LN", NULL, "Left Speaker Output" }, - { "SPK_LP", NULL, "Left Speaker Output" }, - { "SPK_RN", NULL, "Right Speaker Output" }, - { "SPK_RP", NULL, "Right Speaker Output" }, - - { "OUT3", NULL, "Mono Output Mixer", } -}; - -static int wm8960_add_widgets(struct snd_soc_codec *codec) -{ - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, - ARRAY_SIZE(wm8960_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); - - snd_soc_dapm_new_widgets(codec); - return 0; -} - -static int wm8960_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface |= 0x0040; - 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 |= 0x0002; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x0013; - 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 |= 0x0090; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0080; - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= 0x0010; - break; - default: - return -EINVAL; - } - - /* set iface */ - wm8960_write(codec, WM8960_IFACE1, iface); - return 0; -} - -static int wm8960_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->card->codec; - u16 iface = wm8960_read(codec, WM8960_IFACE1) & 0xfff3; - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - } - - /* set iface */ - wm8960_write(codec, WM8960_IFACE1, iface); - return 0; -} - -static int wm8960_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8960_read(codec, WM8960_DACCTL1) & 0xfff7; - - if (mute) - wm8960_write(codec, WM8960_DACCTL1, mute_reg | 0x8); - else - wm8960_write(codec, WM8960_DACCTL1, mute_reg); - return 0; -} - -static int wm8960_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - struct wm8960_data *pdata = codec->dev->platform_data; - u16 reg; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - /* Set VMID to 2x50k */ - reg = wm8960_read(codec, WM8960_POWER1); - reg &= ~0x180; - reg |= 0x80; - wm8960_write(codec, WM8960_POWER1, reg); - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { - /* Enable anti-pop features */ - wm8960_write(codec, WM8960_APOP1, - WM8960_POBCTRL | WM8960_SOFT_ST | - WM8960_BUFDCOPEN | WM8960_BUFIOEN); - - /* Discharge HP output */ - reg = WM8960_DISOP; - if (pdata) - reg |= pdata->dres << 4; - wm8960_write(codec, WM8960_APOP2, reg); - - msleep(400); - - wm8960_write(codec, WM8960_APOP2, 0); - - /* Enable & ramp VMID at 2x50k */ - reg = wm8960_read(codec, WM8960_POWER1); - reg |= 0x80; - wm8960_write(codec, WM8960_POWER1, reg); - msleep(100); - - /* Enable VREF */ - wm8960_write(codec, WM8960_POWER1, reg | WM8960_VREF); - - /* Disable anti-pop features */ - wm8960_write(codec, WM8960_APOP1, WM8960_BUFIOEN); - } - - /* Set VMID to 2x250k */ - reg = wm8960_read(codec, WM8960_POWER1); - reg &= ~0x180; - reg |= 0x100; - wm8960_write(codec, WM8960_POWER1, reg); - break; - - case SND_SOC_BIAS_OFF: - /* Enable anti-pop features */ - wm8960_write(codec, WM8960_APOP1, - WM8960_POBCTRL | WM8960_SOFT_ST | - WM8960_BUFDCOPEN | WM8960_BUFIOEN); - - /* Disable VMID and VREF, let them discharge */ - wm8960_write(codec, WM8960_POWER1, 0); - msleep(600); - - wm8960_write(codec, WM8960_APOP1, 0); - break; - } - - codec->bias_level = level; - - return 0; -} - -/* PLL divisors */ -struct _pll_div { - u32 pre_div:1; - u32 n:4; - u32 k:24; -}; - -/* The size in bits of the pll divide multiplied by 10 - * to allow rounding later */ -#define FIXED_PLL_SIZE ((1 << 24) * 10) - -static int pll_factors(unsigned int source, unsigned int target, - struct _pll_div *pll_div) -{ - unsigned long long Kpart; - unsigned int K, Ndiv, Nmod; - - pr_debug("WM8960 PLL: setting %dHz->%dHz\n", source, target); - - /* Scale up target to PLL operating frequency */ - target *= 4; - - Ndiv = target / source; - if (Ndiv < 6) { - source >>= 1; - pll_div->pre_div = 1; - Ndiv = target / source; - } else - pll_div->pre_div = 0; - - if ((Ndiv < 6) || (Ndiv > 12)) { - pr_err("WM8960 PLL: Unsupported N=%d\n", Ndiv); - return -EINVAL; - } - - pll_div->n = Ndiv; - Nmod = target % source; - Kpart = FIXED_PLL_SIZE * (long long)Nmod; - - do_div(Kpart, source); - - 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; - - pll_div->k = K; - - pr_debug("WM8960 PLL: N=%x K=%x pre_div=%d\n", - pll_div->n, pll_div->k, pll_div->pre_div); - - return 0; -} - -static int wm8960_set_dai_pll(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; - u16 reg; - static struct _pll_div pll_div; - int ret; - - if (freq_in && freq_out) { - ret = pll_factors(freq_in, freq_out, &pll_div); - if (ret != 0) - return ret; - } - - /* Disable the PLL: even if we are changing the frequency the - * PLL needs to be disabled while we do so. */ - wm8960_write(codec, WM8960_CLOCK1, - wm8960_read(codec, WM8960_CLOCK1) & ~1); - wm8960_write(codec, WM8960_POWER2, - wm8960_read(codec, WM8960_POWER2) & ~1); - - if (!freq_in || !freq_out) - return 0; - - reg = wm8960_read(codec, WM8960_PLL1) & ~0x3f; - reg |= pll_div.pre_div << 4; - reg |= pll_div.n; - - if (pll_div.k) { - reg |= 0x20; - - wm8960_write(codec, WM8960_PLL2, (pll_div.k >> 18) & 0x3f); - wm8960_write(codec, WM8960_PLL3, (pll_div.k >> 9) & 0x1ff); - wm8960_write(codec, WM8960_PLL4, pll_div.k & 0x1ff); - } - wm8960_write(codec, WM8960_PLL1, reg); - - /* Turn it on */ - wm8960_write(codec, WM8960_POWER2, - wm8960_read(codec, WM8960_POWER2) | 1); - msleep(250); - wm8960_write(codec, WM8960_CLOCK1, - wm8960_read(codec, WM8960_CLOCK1) | 1); - - return 0; -} - -static int wm8960_set_dai_clkdiv(struct snd_soc_dai *codec_dai, - int div_id, int div) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 reg; - - switch (div_id) { - case WM8960_SYSCLKSEL: - reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1fe; - wm8960_write(codec, WM8960_CLOCK1, reg | div); - break; - case WM8960_SYSCLKDIV: - reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1f9; - wm8960_write(codec, WM8960_CLOCK1, reg | div); - break; - case WM8960_DACDIV: - reg = wm8960_read(codec, WM8960_CLOCK1) & 0x1c7; - wm8960_write(codec, WM8960_CLOCK1, reg | div); - break; - case WM8960_OPCLKDIV: - reg = wm8960_read(codec, WM8960_PLL1) & 0x03f; - wm8960_write(codec, WM8960_PLL1, reg | div); - break; - case WM8960_DCLKDIV: - reg = wm8960_read(codec, WM8960_CLOCK2) & 0x03f; - wm8960_write(codec, WM8960_CLOCK2, reg | div); - break; - case WM8960_TOCLKSEL: - reg = wm8960_read(codec, WM8960_ADDCTL1) & 0x1fd; - wm8960_write(codec, WM8960_ADDCTL1, reg | div); - break; - default: - return -EINVAL; - } - - return 0; -} - -#define WM8960_RATES SNDRV_PCM_RATE_8000_48000 - -#define WM8960_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_ops wm8960_dai_ops = { - .hw_params = wm8960_hw_params, - .digital_mute = wm8960_mute, - .set_fmt = wm8960_set_dai_fmt, - .set_clkdiv = wm8960_set_dai_clkdiv, - .set_pll = wm8960_set_dai_pll, -}; - -struct snd_soc_dai wm8960_dai = { - .name = "WM8960", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8960_RATES, - .formats = WM8960_FORMATS,}, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8960_RATES, - .formats = WM8960_FORMATS,}, - .ops = &wm8960_dai_ops, - .symmetric_rates = 1, -}; -EXPORT_SYMBOL_GPL(wm8960_dai); - -static int wm8960_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - wm8960_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8960_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - int i; - u8 data[2]; - u16 *cache = codec->reg_cache; - - /* Sync reg_cache with the hardware */ - for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) { - data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); - } - - wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - wm8960_set_bias_level(codec, codec->suspend_bias_level); - return 0; -} - -static struct snd_soc_codec *wm8960_codec; - -static int wm8960_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - if (wm8960_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } - - socdev->card->codec = wm8960_codec; - codec = wm8960_codec; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - snd_soc_add_controls(codec, wm8960_snd_controls, - ARRAY_SIZE(wm8960_snd_controls)); - wm8960_add_widgets(codec); - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto card_err; - } - - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -/* power down chip */ -static int wm8960_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8960 = { - .probe = wm8960_probe, - .remove = wm8960_remove, - .suspend = wm8960_suspend, - .resume = wm8960_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8960); - -static int wm8960_register(struct wm8960_priv *wm8960) -{ - struct wm8960_data *pdata = wm8960->codec.dev->platform_data; - struct snd_soc_codec *codec = &wm8960->codec; - int ret; - u16 reg; - - if (wm8960_codec) { - dev_err(codec->dev, "Another WM8960 is registered\n"); - return -EINVAL; - } - - if (!pdata) { - dev_warn(codec->dev, "No platform data supplied\n"); - } else { - if (pdata->dres > WM8960_DRES_MAX) { - dev_err(codec->dev, "Invalid DRES: %d\n", pdata->dres); - pdata->dres = 0; - } - } - - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = wm8960; - codec->name = "WM8960"; - codec->owner = THIS_MODULE; - codec->read = wm8960_read_reg_cache; - codec->write = wm8960_write; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8960_set_bias_level; - codec->dai = &wm8960_dai; - codec->num_dai = 1; - codec->reg_cache_size = WM8960_CACHEREGNUM; - codec->reg_cache = &wm8960->reg_cache; - - memcpy(codec->reg_cache, wm8960_reg, sizeof(wm8960_reg)); - - ret = wm8960_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - - wm8960_dai.dev = codec->dev; - - wm8960_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* Latch the update bits */ - reg = wm8960_read(codec, WM8960_LINVOL); - wm8960_write(codec, WM8960_LINVOL, reg | 0x100); - reg = wm8960_read(codec, WM8960_RINVOL); - wm8960_write(codec, WM8960_RINVOL, reg | 0x100); - reg = wm8960_read(codec, WM8960_LADC); - wm8960_write(codec, WM8960_LADC, reg | 0x100); - reg = wm8960_read(codec, WM8960_RADC); - wm8960_write(codec, WM8960_RADC, reg | 0x100); - reg = wm8960_read(codec, WM8960_LDAC); - wm8960_write(codec, WM8960_LDAC, reg | 0x100); - reg = wm8960_read(codec, WM8960_RDAC); - wm8960_write(codec, WM8960_RDAC, reg | 0x100); - reg = wm8960_read(codec, WM8960_LOUT1); - wm8960_write(codec, WM8960_LOUT1, reg | 0x100); - reg = wm8960_read(codec, WM8960_ROUT1); - wm8960_write(codec, WM8960_ROUT1, reg | 0x100); - reg = wm8960_read(codec, WM8960_LOUT2); - wm8960_write(codec, WM8960_LOUT2, reg | 0x100); - reg = wm8960_read(codec, WM8960_ROUT2); - wm8960_write(codec, WM8960_ROUT2, reg | 0x100); - - wm8960_codec = codec; - - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - return ret; - } - - ret = snd_soc_register_dai(&wm8960_dai); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - return ret; - } - - return 0; -} - -static void wm8960_unregister(struct wm8960_priv *wm8960) -{ - wm8960_set_bias_level(&wm8960->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm8960_dai); - snd_soc_unregister_codec(&wm8960->codec); - kfree(wm8960); - wm8960_codec = NULL; -} - -static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8960_priv *wm8960; - struct snd_soc_codec *codec; - - wm8960 = kzalloc(sizeof(struct wm8960_priv), GFP_KERNEL); - if (wm8960 == NULL) - return -ENOMEM; - - codec = &wm8960->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - - i2c_set_clientdata(i2c, wm8960); - codec->control_data = i2c; - - codec->dev = &i2c->dev; - - return wm8960_register(wm8960); -} - -static __devexit int wm8960_i2c_remove(struct i2c_client *client) -{ - struct wm8960_priv *wm8960 = i2c_get_clientdata(client); - wm8960_unregister(wm8960); - return 0; -} - -static const struct i2c_device_id wm8960_i2c_id[] = { - { "wm8960", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8960_i2c_id); - -static struct i2c_driver wm8960_i2c_driver = { - .driver = { - .name = "WM8960 I2C Codec", - .owner = THIS_MODULE, - }, - .probe = wm8960_i2c_probe, - .remove = __devexit_p(wm8960_i2c_remove), - .id_table = wm8960_i2c_id, -}; - -static int __init wm8960_modinit(void) -{ - int ret; - - ret = i2c_add_driver(&wm8960_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8960 I2C driver: %d\n", - ret); - } - - return ret; -} -module_init(wm8960_modinit); - -static void __exit wm8960_exit(void) -{ - i2c_del_driver(&wm8960_i2c_driver); -} -module_exit(wm8960_exit); - - -MODULE_DESCRIPTION("ASoC WM8960 driver"); -MODULE_AUTHOR("Liam Girdwood"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8960.h b/trunk/sound/soc/codecs/wm8960.h deleted file mode 100644 index c9af56c9d9d4..000000000000 --- a/trunk/sound/soc/codecs/wm8960.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * wm8960.h -- WM8960 Soc Audio driver - * - * 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 _WM8960_H -#define _WM8960_H - -/* WM8960 register space */ - - -#define WM8960_CACHEREGNUM 56 - -#define WM8960_LINVOL 0x0 -#define WM8960_RINVOL 0x1 -#define WM8960_LOUT1 0x2 -#define WM8960_ROUT1 0x3 -#define WM8960_CLOCK1 0x4 -#define WM8960_DACCTL1 0x5 -#define WM8960_DACCTL2 0x6 -#define WM8960_IFACE1 0x7 -#define WM8960_CLOCK2 0x8 -#define WM8960_IFACE2 0x9 -#define WM8960_LDAC 0xa -#define WM8960_RDAC 0xb - -#define WM8960_RESET 0xf -#define WM8960_3D 0x10 -#define WM8960_ALC1 0x11 -#define WM8960_ALC2 0x12 -#define WM8960_ALC3 0x13 -#define WM8960_NOISEG 0x14 -#define WM8960_LADC 0x15 -#define WM8960_RADC 0x16 -#define WM8960_ADDCTL1 0x17 -#define WM8960_ADDCTL2 0x18 -#define WM8960_POWER1 0x19 -#define WM8960_POWER2 0x1a -#define WM8960_ADDCTL3 0x1b -#define WM8960_APOP1 0x1c -#define WM8960_APOP2 0x1d - -#define WM8960_LINPATH 0x20 -#define WM8960_RINPATH 0x21 -#define WM8960_LOUTMIX 0x22 - -#define WM8960_ROUTMIX 0x25 -#define WM8960_MONOMIX1 0x26 -#define WM8960_MONOMIX2 0x27 -#define WM8960_LOUT2 0x28 -#define WM8960_ROUT2 0x29 -#define WM8960_MONO 0x2a -#define WM8960_INBMIX1 0x2b -#define WM8960_INBMIX2 0x2c -#define WM8960_BYPASS1 0x2d -#define WM8960_BYPASS2 0x2e -#define WM8960_POWER3 0x2f -#define WM8960_ADDCTL4 0x30 -#define WM8960_CLASSD1 0x31 - -#define WM8960_CLASSD3 0x33 -#define WM8960_PLL1 0x34 -#define WM8960_PLL2 0x35 -#define WM8960_PLL3 0x36 -#define WM8960_PLL4 0x37 - - -/* - * WM8960 Clock dividers - */ -#define WM8960_SYSCLKDIV 0 -#define WM8960_DACDIV 1 -#define WM8960_OPCLKDIV 2 -#define WM8960_DCLKDIV 3 -#define WM8960_TOCLKSEL 4 -#define WM8960_SYSCLKSEL 5 - -#define WM8960_SYSCLK_DIV_1 (0 << 1) -#define WM8960_SYSCLK_DIV_2 (2 << 1) - -#define WM8960_SYSCLK_MCLK (0 << 0) -#define WM8960_SYSCLK_PLL (1 << 0) - -#define WM8960_DAC_DIV_1 (0 << 3) -#define WM8960_DAC_DIV_1_5 (1 << 3) -#define WM8960_DAC_DIV_2 (2 << 3) -#define WM8960_DAC_DIV_3 (3 << 3) -#define WM8960_DAC_DIV_4 (4 << 3) -#define WM8960_DAC_DIV_5_5 (5 << 3) -#define WM8960_DAC_DIV_6 (6 << 3) - -#define WM8960_DCLK_DIV_1_5 (0 << 6) -#define WM8960_DCLK_DIV_2 (1 << 6) -#define WM8960_DCLK_DIV_3 (2 << 6) -#define WM8960_DCLK_DIV_4 (3 << 6) -#define WM8960_DCLK_DIV_6 (4 << 6) -#define WM8960_DCLK_DIV_8 (5 << 6) -#define WM8960_DCLK_DIV_12 (6 << 6) -#define WM8960_DCLK_DIV_16 (7 << 6) - -#define WM8960_TOCLK_F19 (0 << 1) -#define WM8960_TOCLK_F21 (1 << 1) - -#define WM8960_OPCLK_DIV_1 (0 << 0) -#define WM8960_OPCLK_DIV_2 (1 << 0) -#define WM8960_OPCLK_DIV_3 (2 << 0) -#define WM8960_OPCLK_DIV_4 (3 << 0) -#define WM8960_OPCLK_DIV_5_5 (4 << 0) -#define WM8960_OPCLK_DIV_6 (5 << 0) - -extern struct snd_soc_dai wm8960_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8960; - -#define WM8960_DRES_400R 0 -#define WM8960_DRES_200R 1 -#define WM8960_DRES_600R 2 -#define WM8960_DRES_150R 3 -#define WM8960_DRES_MAX 3 - -struct wm8960_data { - int dres; -}; - -#endif diff --git a/trunk/sound/soc/codecs/wm8988.c b/trunk/sound/soc/codecs/wm8988.c deleted file mode 100644 index c05f71803aa8..000000000000 --- a/trunk/sound/soc/codecs/wm8988.c +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * wm8988.c -- WM8988 ALSA SoC audio driver - * - * Copyright 2009 Wolfson Microelectronics plc - * Copyright 2005 Openedhand Ltd. - * - * Author: Mark Brown - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wm8988.h" - -/* - * wm8988 register cache - * We can't read the WM8988 register space when we - * are using 2 wire for device control, so we cache them instead. - */ -static const u16 wm8988_reg[] = { - 0x0097, 0x0097, 0x0079, 0x0079, /* 0 */ - 0x0000, 0x0008, 0x0000, 0x000a, /* 4 */ - 0x0000, 0x0000, 0x00ff, 0x00ff, /* 8 */ - 0x000f, 0x000f, 0x0000, 0x0000, /* 12 */ - 0x0000, 0x007b, 0x0000, 0x0032, /* 16 */ - 0x0000, 0x00c3, 0x00c3, 0x00c0, /* 20 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 24 */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 28 */ - 0x0000, 0x0000, 0x0050, 0x0050, /* 32 */ - 0x0050, 0x0050, 0x0050, 0x0050, /* 36 */ - 0x0079, 0x0079, 0x0079, /* 40 */ -}; - -/* codec private data */ -struct wm8988_priv { - unsigned int sysclk; - struct snd_soc_codec codec; - struct snd_pcm_hw_constraint_list *sysclk_constraints; - u16 reg_cache[WM8988_NUM_REG]; -}; - - -/* - * read wm8988 register cache - */ -static inline unsigned int wm8988_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - if (reg > WM8988_NUM_REG) - return -1; - return cache[reg]; -} - -/* - * write wm8988 register cache - */ -static inline void wm8988_write_reg_cache(struct snd_soc_codec *codec, - unsigned int reg, unsigned int value) -{ - u16 *cache = codec->reg_cache; - if (reg > WM8988_NUM_REG) - return; - cache[reg] = value; -} - -static int wm8988_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u8 data[2]; - - /* data is - * D15..D9 WM8753 register offset - * D8...D0 register data - */ - data[0] = (reg << 1) | ((value >> 8) & 0x0001); - data[1] = value & 0x00ff; - - wm8988_write_reg_cache(codec, reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) - return 0; - else - return -EIO; -} - -#define wm8988_reset(c) wm8988_write(c, WM8988_RESET, 0) - -/* - * WM8988 Controls - */ - -static const char *bass_boost_txt[] = {"Linear Control", "Adaptive Boost"}; -static const struct soc_enum bass_boost = - SOC_ENUM_SINGLE(WM8988_BASS, 7, 2, bass_boost_txt); - -static const char *bass_filter_txt[] = { "130Hz @ 48kHz", "200Hz @ 48kHz" }; -static const struct soc_enum bass_filter = - SOC_ENUM_SINGLE(WM8988_BASS, 6, 2, bass_filter_txt); - -static const char *treble_txt[] = {"8kHz", "4kHz"}; -static const struct soc_enum treble = - SOC_ENUM_SINGLE(WM8988_TREBLE, 6, 2, treble_txt); - -static const char *stereo_3d_lc_txt[] = {"200Hz", "500Hz"}; -static const struct soc_enum stereo_3d_lc = - SOC_ENUM_SINGLE(WM8988_3D, 5, 2, stereo_3d_lc_txt); - -static const char *stereo_3d_uc_txt[] = {"2.2kHz", "1.5kHz"}; -static const struct soc_enum stereo_3d_uc = - SOC_ENUM_SINGLE(WM8988_3D, 6, 2, stereo_3d_uc_txt); - -static const char *stereo_3d_func_txt[] = {"Capture", "Playback"}; -static const struct soc_enum stereo_3d_func = - SOC_ENUM_SINGLE(WM8988_3D, 7, 2, stereo_3d_func_txt); - -static const char *alc_func_txt[] = {"Off", "Right", "Left", "Stereo"}; -static const struct soc_enum alc_func = - SOC_ENUM_SINGLE(WM8988_ALC1, 7, 4, alc_func_txt); - -static const char *ng_type_txt[] = {"Constant PGA Gain", - "Mute ADC Output"}; -static const struct soc_enum ng_type = - SOC_ENUM_SINGLE(WM8988_NGATE, 1, 2, ng_type_txt); - -static const char *deemph_txt[] = {"None", "32Khz", "44.1Khz", "48Khz"}; -static const struct soc_enum deemph = - SOC_ENUM_SINGLE(WM8988_ADCDAC, 1, 4, deemph_txt); - -static const char *adcpol_txt[] = {"Normal", "L Invert", "R Invert", - "L + R Invert"}; -static const struct soc_enum adcpol = - SOC_ENUM_SINGLE(WM8988_ADCDAC, 5, 4, adcpol_txt); - -static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0); -static const DECLARE_TLV_DB_SCALE(adc_tlv, -9750, 50, 1); -static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1); -static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); -static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); - -static const struct snd_kcontrol_new wm8988_snd_controls[] = { - -SOC_ENUM("Bass Boost", bass_boost), -SOC_ENUM("Bass Filter", bass_filter), -SOC_SINGLE("Bass Volume", WM8988_BASS, 0, 15, 1), - -SOC_SINGLE("Treble Volume", WM8988_TREBLE, 0, 15, 0), -SOC_ENUM("Treble Cut-off", treble), - -SOC_SINGLE("3D Switch", WM8988_3D, 0, 1, 0), -SOC_SINGLE("3D Volume", WM8988_3D, 1, 15, 0), -SOC_ENUM("3D Lower Cut-off", stereo_3d_lc), -SOC_ENUM("3D Upper Cut-off", stereo_3d_uc), -SOC_ENUM("3D Mode", stereo_3d_func), - -SOC_SINGLE("ALC Capture Target Volume", WM8988_ALC1, 0, 7, 0), -SOC_SINGLE("ALC Capture Max Volume", WM8988_ALC1, 4, 7, 0), -SOC_ENUM("ALC Capture Function", alc_func), -SOC_SINGLE("ALC Capture ZC Switch", WM8988_ALC2, 7, 1, 0), -SOC_SINGLE("ALC Capture Hold Time", WM8988_ALC2, 0, 15, 0), -SOC_SINGLE("ALC Capture Decay Time", WM8988_ALC3, 4, 15, 0), -SOC_SINGLE("ALC Capture Attack Time", WM8988_ALC3, 0, 15, 0), -SOC_SINGLE("ALC Capture NG Threshold", WM8988_NGATE, 3, 31, 0), -SOC_ENUM("ALC Capture NG Type", ng_type), -SOC_SINGLE("ALC Capture NG Switch", WM8988_NGATE, 0, 1, 0), - -SOC_SINGLE("ZC Timeout Switch", WM8988_ADCTL1, 0, 1, 0), - -SOC_DOUBLE_R_TLV("Capture Digital Volume", WM8988_LADC, WM8988_RADC, - 0, 255, 0, adc_tlv), -SOC_DOUBLE_R_TLV("Capture Volume", WM8988_LINVOL, WM8988_RINVOL, - 0, 63, 0, pga_tlv), -SOC_DOUBLE_R("Capture ZC Switch", WM8988_LINVOL, WM8988_RINVOL, 6, 1, 0), -SOC_DOUBLE_R("Capture Switch", WM8988_LINVOL, WM8988_RINVOL, 7, 1, 1), - -SOC_ENUM("Playback De-emphasis", deemph), - -SOC_ENUM("Capture Polarity", adcpol), -SOC_SINGLE("Playback 6dB Attenuate", WM8988_ADCDAC, 7, 1, 0), -SOC_SINGLE("Capture 6dB Attenuate", WM8988_ADCDAC, 8, 1, 0), - -SOC_DOUBLE_R_TLV("PCM Volume", WM8988_LDAC, WM8988_RDAC, 0, 255, 0, dac_tlv), - -SOC_SINGLE_TLV("Left Mixer Left Bypass Volume", WM8988_LOUTM1, 4, 7, 1, - bypass_tlv), -SOC_SINGLE_TLV("Left Mixer Right Bypass Volume", WM8988_LOUTM2, 4, 7, 1, - bypass_tlv), -SOC_SINGLE_TLV("Right Mixer Left Bypass Volume", WM8988_ROUTM1, 4, 7, 1, - bypass_tlv), -SOC_SINGLE_TLV("Right Mixer Right Bypass Volume", WM8988_ROUTM2, 4, 7, 1, - bypass_tlv), - -SOC_DOUBLE_R("Output 1 Playback ZC Switch", WM8988_LOUT1V, - WM8988_ROUT1V, 7, 1, 0), -SOC_DOUBLE_R_TLV("Output 1 Playback Volume", WM8988_LOUT1V, WM8988_ROUT1V, - 0, 127, 0, out_tlv), - -SOC_DOUBLE_R("Output 2 Playback ZC Switch", WM8988_LOUT2V, - WM8988_ROUT2V, 7, 1, 0), -SOC_DOUBLE_R_TLV("Output 2 Playback Volume", WM8988_LOUT2V, WM8988_ROUT2V, - 0, 127, 0, out_tlv), - -}; - -/* - * DAPM Controls - */ - -static int wm8988_lrc_control(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - u16 adctl2 = wm8988_read_reg_cache(codec, WM8988_ADCTL2); - - /* Use the DAC to gate LRC if active, otherwise use ADC */ - if (wm8988_read_reg_cache(codec, WM8988_PWR2) & 0x180) - adctl2 &= ~0x4; - else - adctl2 |= 0x4; - - return wm8988_write(codec, WM8988_ADCTL2, adctl2); -} - -static const char *wm8988_line_texts[] = { - "Line 1", "Line 2", "PGA", "Differential"}; - -static const unsigned int wm8988_line_values[] = { - 0, 1, 3, 4}; - -static const struct soc_enum wm8988_lline_enum = - SOC_VALUE_ENUM_SINGLE(WM8988_LOUTM1, 0, 7, - ARRAY_SIZE(wm8988_line_texts), - wm8988_line_texts, - wm8988_line_values); -static const struct snd_kcontrol_new wm8988_left_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); - -static const struct soc_enum wm8988_rline_enum = - SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, - ARRAY_SIZE(wm8988_line_texts), - wm8988_line_texts, - wm8988_line_values); -static const struct snd_kcontrol_new wm8988_right_line_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); - -/* Left Mixer */ -static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { - SOC_DAPM_SINGLE("Playback Switch", WM8988_LOUTM1, 8, 1, 0), - SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_LOUTM1, 7, 1, 0), - SOC_DAPM_SINGLE("Right Playback Switch", WM8988_LOUTM2, 8, 1, 0), - SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_LOUTM2, 7, 1, 0), -}; - -/* Right Mixer */ -static const struct snd_kcontrol_new wm8988_right_mixer_controls[] = { - SOC_DAPM_SINGLE("Left Playback Switch", WM8988_ROUTM1, 8, 1, 0), - SOC_DAPM_SINGLE("Left Bypass Switch", WM8988_ROUTM1, 7, 1, 0), - SOC_DAPM_SINGLE("Playback Switch", WM8988_ROUTM2, 8, 1, 0), - SOC_DAPM_SINGLE("Right Bypass Switch", WM8988_ROUTM2, 7, 1, 0), -}; - -static const char *wm8988_pga_sel[] = {"Line 1", "Line 2", "Differential"}; -static const unsigned int wm8988_pga_val[] = { 0, 1, 3 }; - -/* Left PGA Mux */ -static const struct soc_enum wm8988_lpga_enum = - SOC_VALUE_ENUM_SINGLE(WM8988_LADCIN, 6, 3, - ARRAY_SIZE(wm8988_pga_sel), - wm8988_pga_sel, - wm8988_pga_val); -static const struct snd_kcontrol_new wm8988_left_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum); - -/* Right PGA Mux */ -static const struct soc_enum wm8988_rpga_enum = - SOC_VALUE_ENUM_SINGLE(WM8988_RADCIN, 6, 3, - ARRAY_SIZE(wm8988_pga_sel), - wm8988_pga_sel, - wm8988_pga_val); -static const struct snd_kcontrol_new wm8988_right_pga_controls = - SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum); - -/* Differential Mux */ -static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; -static const struct soc_enum diffmux = - SOC_ENUM_SINGLE(WM8988_ADCIN, 8, 2, wm8988_diff_sel); -static const struct snd_kcontrol_new wm8988_diffmux_controls = - SOC_DAPM_ENUM("Route", diffmux); - -/* Mono ADC Mux */ -static const char *wm8988_mono_mux[] = {"Stereo", "Mono (Left)", - "Mono (Right)", "Digital Mono"}; -static const struct soc_enum monomux = - SOC_ENUM_SINGLE(WM8988_ADCIN, 6, 4, wm8988_mono_mux); -static const struct snd_kcontrol_new wm8988_monomux_controls = - SOC_DAPM_ENUM("Route", monomux); - -static const struct snd_soc_dapm_widget wm8988_dapm_widgets[] = { - SND_SOC_DAPM_MICBIAS("Mic Bias", WM8988_PWR1, 1, 0), - - SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0, - &wm8988_diffmux_controls), - SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0, - &wm8988_monomux_controls), - SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0, - &wm8988_monomux_controls), - - SND_SOC_DAPM_MUX("Left PGA Mux", WM8988_PWR1, 5, 0, - &wm8988_left_pga_controls), - SND_SOC_DAPM_MUX("Right PGA Mux", WM8988_PWR1, 4, 0, - &wm8988_right_pga_controls), - - SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0, - &wm8988_left_line_controls), - SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0, - &wm8988_right_line_controls), - - SND_SOC_DAPM_ADC("Right ADC", "Right Capture", WM8988_PWR1, 2, 0), - SND_SOC_DAPM_ADC("Left ADC", "Left Capture", WM8988_PWR1, 3, 0), - - SND_SOC_DAPM_DAC("Right DAC", "Right Playback", WM8988_PWR2, 7, 0), - SND_SOC_DAPM_DAC("Left DAC", "Left Playback", WM8988_PWR2, 8, 0), - - SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, - &wm8988_left_mixer_controls[0], - ARRAY_SIZE(wm8988_left_mixer_controls)), - SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, - &wm8988_right_mixer_controls[0], - ARRAY_SIZE(wm8988_right_mixer_controls)), - - SND_SOC_DAPM_PGA("Right Out 2", WM8988_PWR2, 3, 0, NULL, 0), - SND_SOC_DAPM_PGA("Left Out 2", WM8988_PWR2, 4, 0, NULL, 0), - SND_SOC_DAPM_PGA("Right Out 1", WM8988_PWR2, 5, 0, NULL, 0), - SND_SOC_DAPM_PGA("Left Out 1", WM8988_PWR2, 6, 0, NULL, 0), - - SND_SOC_DAPM_POST("LRC control", wm8988_lrc_control), - - SND_SOC_DAPM_OUTPUT("LOUT1"), - SND_SOC_DAPM_OUTPUT("ROUT1"), - SND_SOC_DAPM_OUTPUT("LOUT2"), - SND_SOC_DAPM_OUTPUT("ROUT2"), - SND_SOC_DAPM_OUTPUT("VREF"), - - SND_SOC_DAPM_INPUT("LINPUT1"), - SND_SOC_DAPM_INPUT("LINPUT2"), - SND_SOC_DAPM_INPUT("RINPUT1"), - SND_SOC_DAPM_INPUT("RINPUT2"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - - { "Left Line Mux", "Line 1", "LINPUT1" }, - { "Left Line Mux", "Line 2", "LINPUT2" }, - { "Left Line Mux", "PGA", "Left PGA Mux" }, - { "Left Line Mux", "Differential", "Differential Mux" }, - - { "Right Line Mux", "Line 1", "RINPUT1" }, - { "Right Line Mux", "Line 2", "RINPUT2" }, - { "Right Line Mux", "PGA", "Right PGA Mux" }, - { "Right Line Mux", "Differential", "Differential Mux" }, - - { "Left PGA Mux", "Line 1", "LINPUT1" }, - { "Left PGA Mux", "Line 2", "LINPUT2" }, - { "Left PGA Mux", "Differential", "Differential Mux" }, - - { "Right PGA Mux", "Line 1", "RINPUT1" }, - { "Right PGA Mux", "Line 2", "RINPUT2" }, - { "Right PGA Mux", "Differential", "Differential Mux" }, - - { "Differential Mux", "Line 1", "LINPUT1" }, - { "Differential Mux", "Line 1", "RINPUT1" }, - { "Differential Mux", "Line 2", "LINPUT2" }, - { "Differential Mux", "Line 2", "RINPUT2" }, - - { "Left ADC Mux", "Stereo", "Left PGA Mux" }, - { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" }, - { "Left ADC Mux", "Digital Mono", "Left PGA Mux" }, - - { "Right ADC Mux", "Stereo", "Right PGA Mux" }, - { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" }, - { "Right ADC Mux", "Digital Mono", "Right PGA Mux" }, - - { "Left ADC", NULL, "Left ADC Mux" }, - { "Right ADC", NULL, "Right ADC Mux" }, - - { "Left Line Mux", "Line 1", "LINPUT1" }, - { "Left Line Mux", "Line 2", "LINPUT2" }, - { "Left Line Mux", "PGA", "Left PGA Mux" }, - { "Left Line Mux", "Differential", "Differential Mux" }, - - { "Right Line Mux", "Line 1", "RINPUT1" }, - { "Right Line Mux", "Line 2", "RINPUT2" }, - { "Right Line Mux", "PGA", "Right PGA Mux" }, - { "Right Line Mux", "Differential", "Differential Mux" }, - - { "Left Mixer", "Playback Switch", "Left DAC" }, - { "Left Mixer", "Left Bypass Switch", "Left Line Mux" }, - { "Left Mixer", "Right Playback Switch", "Right DAC" }, - { "Left Mixer", "Right Bypass Switch", "Right Line Mux" }, - - { "Right Mixer", "Left Playback Switch", "Left DAC" }, - { "Right Mixer", "Left Bypass Switch", "Left Line Mux" }, - { "Right Mixer", "Playback Switch", "Right DAC" }, - { "Right Mixer", "Right Bypass Switch", "Right Line Mux" }, - - { "Left Out 1", NULL, "Left Mixer" }, - { "LOUT1", NULL, "Left Out 1" }, - { "Right Out 1", NULL, "Right Mixer" }, - { "ROUT1", NULL, "Right Out 1" }, - - { "Left Out 2", NULL, "Left Mixer" }, - { "LOUT2", NULL, "Left Out 2" }, - { "Right Out 2", NULL, "Right Mixer" }, - { "ROUT2", NULL, "Right Out 2" }, -}; - -struct _coeff_div { - u32 mclk; - u32 rate; - u16 fs; - u8 sr:5; - u8 usb:1; -}; - -/* codec hifi mclk clock divider coefficients */ -static const struct _coeff_div coeff_div[] = { - /* 8k */ - {12288000, 8000, 1536, 0x6, 0x0}, - {11289600, 8000, 1408, 0x16, 0x0}, - {18432000, 8000, 2304, 0x7, 0x0}, - {16934400, 8000, 2112, 0x17, 0x0}, - {12000000, 8000, 1500, 0x6, 0x1}, - - /* 11.025k */ - {11289600, 11025, 1024, 0x18, 0x0}, - {16934400, 11025, 1536, 0x19, 0x0}, - {12000000, 11025, 1088, 0x19, 0x1}, - - /* 16k */ - {12288000, 16000, 768, 0xa, 0x0}, - {18432000, 16000, 1152, 0xb, 0x0}, - {12000000, 16000, 750, 0xa, 0x1}, - - /* 22.05k */ - {11289600, 22050, 512, 0x1a, 0x0}, - {16934400, 22050, 768, 0x1b, 0x0}, - {12000000, 22050, 544, 0x1b, 0x1}, - - /* 32k */ - {12288000, 32000, 384, 0xc, 0x0}, - {18432000, 32000, 576, 0xd, 0x0}, - {12000000, 32000, 375, 0xa, 0x1}, - - /* 44.1k */ - {11289600, 44100, 256, 0x10, 0x0}, - {16934400, 44100, 384, 0x11, 0x0}, - {12000000, 44100, 272, 0x11, 0x1}, - - /* 48k */ - {12288000, 48000, 256, 0x0, 0x0}, - {18432000, 48000, 384, 0x1, 0x0}, - {12000000, 48000, 250, 0x0, 0x1}, - - /* 88.2k */ - {11289600, 88200, 128, 0x1e, 0x0}, - {16934400, 88200, 192, 0x1f, 0x0}, - {12000000, 88200, 136, 0x1f, 0x1}, - - /* 96k */ - {12288000, 96000, 128, 0xe, 0x0}, - {18432000, 96000, 192, 0xf, 0x0}, - {12000000, 96000, 125, 0xe, 0x1}, -}; - -static inline int get_coeff(int mclk, int rate) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { - if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) - return i; - } - - return -EINVAL; -} - -/* The set of rates we can generate from the above for each SYSCLK */ - -static unsigned int rates_12288[] = { - 8000, 12000, 16000, 24000, 24000, 32000, 48000, 96000, -}; - -static struct snd_pcm_hw_constraint_list constraints_12288 = { - .count = ARRAY_SIZE(rates_12288), - .list = rates_12288, -}; - -static unsigned int rates_112896[] = { - 8000, 11025, 22050, 44100, -}; - -static struct snd_pcm_hw_constraint_list constraints_112896 = { - .count = ARRAY_SIZE(rates_112896), - .list = rates_112896, -}; - -static unsigned int rates_12[] = { - 8000, 11025, 12000, 16000, 22050, 2400, 32000, 41100, 48000, - 48000, 88235, 96000, -}; - -static struct snd_pcm_hw_constraint_list constraints_12 = { - .count = ARRAY_SIZE(rates_12), - .list = rates_12, -}; - -/* - * Note that this should be called from init rather than from hw_params. - */ -static int wm8988_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 wm8988_priv *wm8988 = codec->private_data; - - switch (freq) { - case 11289600: - case 18432000: - case 22579200: - case 36864000: - wm8988->sysclk_constraints = &constraints_112896; - wm8988->sysclk = freq; - return 0; - - case 12288000: - case 16934400: - case 24576000: - case 33868800: - wm8988->sysclk_constraints = &constraints_12288; - wm8988->sysclk = freq; - return 0; - - case 12000000: - case 24000000: - wm8988->sysclk_constraints = &constraints_12; - wm8988->sysclk = freq; - return 0; - } - return -EINVAL; -} - -static int wm8988_set_dai_fmt(struct snd_soc_dai *codec_dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = codec_dai->codec; - u16 iface = 0; - - /* set master/slave audio interface */ - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iface = 0x0040; - 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 |= 0x0002; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - iface |= 0x0001; - break; - case SND_SOC_DAIFMT_DSP_A: - iface |= 0x0003; - break; - case SND_SOC_DAIFMT_DSP_B: - iface |= 0x0013; - 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 |= 0x0090; - break; - case SND_SOC_DAIFMT_IB_NF: - iface |= 0x0080; - break; - case SND_SOC_DAIFMT_NB_IF: - iface |= 0x0010; - break; - default: - return -EINVAL; - } - - wm8988_write(codec, WM8988_IFACE, iface); - return 0; -} - -static int wm8988_pcm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm8988_priv *wm8988 = codec->private_data; - - /* The set of sample rates that can be supported depends on the - * MCLK supplied to the CODEC - enforce this. - */ - if (!wm8988->sysclk) { - dev_err(codec->dev, - "No MCLK configured, call set_sysclk() on init\n"); - return -EINVAL; - } - - snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - wm8988->sysclk_constraints); - - return 0; -} - -static int wm8988_pcm_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->card->codec; - struct wm8988_priv *wm8988 = codec->private_data; - u16 iface = wm8988_read_reg_cache(codec, WM8988_IFACE) & 0x1f3; - u16 srate = wm8988_read_reg_cache(codec, WM8988_SRATE) & 0x180; - int coeff; - - coeff = get_coeff(wm8988->sysclk, params_rate(params)); - if (coeff < 0) { - coeff = get_coeff(wm8988->sysclk / 2, params_rate(params)); - srate |= 0x40; - } - if (coeff < 0) { - dev_err(codec->dev, - "Unable to configure sample rate %dHz with %dHz MCLK\n", - params_rate(params), wm8988->sysclk); - return coeff; - } - - /* bit size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S20_3LE: - iface |= 0x0004; - break; - case SNDRV_PCM_FORMAT_S24_LE: - iface |= 0x0008; - break; - case SNDRV_PCM_FORMAT_S32_LE: - iface |= 0x000c; - break; - } - - /* set iface & srate */ - wm8988_write(codec, WM8988_IFACE, iface); - if (coeff >= 0) - wm8988_write(codec, WM8988_SRATE, srate | - (coeff_div[coeff].sr << 1) | coeff_div[coeff].usb); - - return 0; -} - -static int wm8988_mute(struct snd_soc_dai *dai, int mute) -{ - struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = wm8988_read_reg_cache(codec, WM8988_ADCDAC) & 0xfff7; - - if (mute) - wm8988_write(codec, WM8988_ADCDAC, mute_reg | 0x8); - else - wm8988_write(codec, WM8988_ADCDAC, mute_reg); - return 0; -} - -static int wm8988_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - u16 pwr_reg = wm8988_read_reg_cache(codec, WM8988_PWR1) & ~0x1c1; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - /* VREF, VMID=2x50k, digital enabled */ - wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x00c0); - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { - /* VREF, VMID=2x5k */ - wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); - - /* Charge caps */ - msleep(100); - } - - /* VREF, VMID=2*500k, digital stopped */ - wm8988_write(codec, WM8988_PWR1, pwr_reg | 0x0141); - break; - - case SND_SOC_BIAS_OFF: - wm8988_write(codec, WM8988_PWR1, 0x0000); - break; - } - codec->bias_level = level; - return 0; -} - -#define WM8988_RATES SNDRV_PCM_RATE_8000_96000 - -#define WM8988_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -static struct snd_soc_dai_ops wm8988_ops = { - .startup = wm8988_pcm_startup, - .hw_params = wm8988_pcm_hw_params, - .set_fmt = wm8988_set_dai_fmt, - .set_sysclk = wm8988_set_dai_sysclk, - .digital_mute = wm8988_mute, -}; - -struct snd_soc_dai wm8988_dai = { - .name = "WM8988", - .playback = { - .stream_name = "Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8988_RATES, - .formats = WM8988_FORMATS, - }, - .capture = { - .stream_name = "Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8988_RATES, - .formats = WM8988_FORMATS, - }, - .ops = &wm8988_ops, - .symmetric_rates = 1, -}; -EXPORT_SYMBOL_GPL(wm8988_dai); - -static int wm8988_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - wm8988_set_bias_level(codec, SND_SOC_BIAS_OFF); - return 0; -} - -static int wm8988_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - int i; - u8 data[2]; - u16 *cache = codec->reg_cache; - - /* Sync reg_cache with the hardware */ - for (i = 0; i < WM8988_NUM_REG; i++) { - if (i == WM8988_RESET) - continue; - data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); - data[1] = cache[i] & 0x00ff; - codec->hw_write(codec->control_data, data, 2); - } - - wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} - -static struct snd_soc_codec *wm8988_codec; - -static int wm8988_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - int ret = 0; - - if (wm8988_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } - - socdev->card->codec = wm8988_codec; - codec = wm8988_codec; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - snd_soc_add_controls(codec, wm8988_snd_controls, - ARRAY_SIZE(wm8988_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, - ARRAY_SIZE(wm8988_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_new_widgets(codec); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto card_err; - } - - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -static int wm8988_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -struct snd_soc_codec_device soc_codec_dev_wm8988 = { - .probe = wm8988_probe, - .remove = wm8988_remove, - .suspend = wm8988_suspend, - .resume = wm8988_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm8988); - -static int wm8988_register(struct wm8988_priv *wm8988) -{ - struct snd_soc_codec *codec = &wm8988->codec; - int ret; - u16 reg; - - if (wm8988_codec) { - dev_err(codec->dev, "Another WM8988 is registered\n"); - ret = -EINVAL; - goto err; - } - - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = wm8988; - codec->name = "WM8988"; - codec->owner = THIS_MODULE; - codec->read = wm8988_read_reg_cache; - codec->write = wm8988_write; - codec->dai = &wm8988_dai; - codec->num_dai = 1; - codec->reg_cache_size = ARRAY_SIZE(wm8988->reg_cache); - codec->reg_cache = &wm8988->reg_cache; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm8988_set_bias_level; - - memcpy(codec->reg_cache, wm8988_reg, - sizeof(wm8988_reg)); - - ret = wm8988_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - - /* set the update bits (we always update left then right) */ - reg = wm8988_read_reg_cache(codec, WM8988_RADC); - wm8988_write(codec, WM8988_RADC, reg | 0x100); - reg = wm8988_read_reg_cache(codec, WM8988_RDAC); - wm8988_write(codec, WM8988_RDAC, reg | 0x0100); - reg = wm8988_read_reg_cache(codec, WM8988_ROUT1V); - wm8988_write(codec, WM8988_ROUT1V, reg | 0x0100); - reg = wm8988_read_reg_cache(codec, WM8988_ROUT2V); - wm8988_write(codec, WM8988_ROUT2V, reg | 0x0100); - reg = wm8988_read_reg_cache(codec, WM8988_RINVOL); - wm8988_write(codec, WM8988_RINVOL, reg | 0x0100); - - wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_STANDBY); - - wm8988_dai.dev = codec->dev; - - wm8988_codec = codec; - - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - return ret; - } - - ret = snd_soc_register_dai(&wm8988_dai); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - return ret; - } - - return 0; - -err: - kfree(wm8988); - return ret; -} - -static void wm8988_unregister(struct wm8988_priv *wm8988) -{ - wm8988_set_bias_level(&wm8988->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm8988_dai); - snd_soc_unregister_codec(&wm8988->codec); - kfree(wm8988); - wm8988_codec = NULL; -} - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -static int wm8988_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8988_priv *wm8988; - struct snd_soc_codec *codec; - - wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); - if (wm8988 == NULL) - return -ENOMEM; - - codec = &wm8988->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - - i2c_set_clientdata(i2c, wm8988); - codec->control_data = i2c; - - codec->dev = &i2c->dev; - - return wm8988_register(wm8988); -} - -static int wm8988_i2c_remove(struct i2c_client *client) -{ - struct wm8988_priv *wm8988 = i2c_get_clientdata(client); - wm8988_unregister(wm8988); - return 0; -} - -static const struct i2c_device_id wm8988_i2c_id[] = { - { "wm8988", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8988_i2c_id); - -static struct i2c_driver wm8988_i2c_driver = { - .driver = { - .name = "WM8988", - .owner = THIS_MODULE, - }, - .probe = wm8988_i2c_probe, - .remove = wm8988_i2c_remove, - .id_table = wm8988_i2c_id, -}; -#endif - -#if defined(CONFIG_SPI_MASTER) -static int wm8988_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; -} - -static int __devinit wm8988_spi_probe(struct spi_device *spi) -{ - struct wm8988_priv *wm8988; - struct snd_soc_codec *codec; - - wm8988 = kzalloc(sizeof(struct wm8988_priv), GFP_KERNEL); - if (wm8988 == NULL) - return -ENOMEM; - - codec = &wm8988->codec; - codec->hw_write = (hw_write_t)wm8988_spi_write; - codec->control_data = spi; - codec->dev = &spi->dev; - - spi->dev.driver_data = wm8988; - - return wm8988_register(wm8988); -} - -static int __devexit wm8988_spi_remove(struct spi_device *spi) -{ - struct wm8988_priv *wm8988 = spi->dev.driver_data; - - wm8988_unregister(wm8988); - - return 0; -} - -static struct spi_driver wm8988_spi_driver = { - .driver = { - .name = "wm8988", - .bus = &spi_bus_type, - .owner = THIS_MODULE, - }, - .probe = wm8988_spi_probe, - .remove = __devexit_p(wm8988_spi_remove), -}; -#endif - -static int __init wm8988_modinit(void) -{ - int ret; - -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - ret = i2c_add_driver(&wm8988_i2c_driver); - if (ret != 0) - pr_err("WM8988: Unable to register I2C driver: %d\n", ret); -#endif -#if defined(CONFIG_SPI_MASTER) - ret = spi_register_driver(&wm8988_spi_driver); - if (ret != 0) - pr_err("WM8988: Unable to register SPI driver: %d\n", ret); -#endif - return ret; -} -module_init(wm8988_modinit); - -static void __exit wm8988_exit(void) -{ -#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) - i2c_del_driver(&wm8988_i2c_driver); -#endif -#if defined(CONFIG_SPI_MASTER) - spi_unregister_driver(&wm8988_spi_driver); -#endif -} -module_exit(wm8988_exit); - - -MODULE_DESCRIPTION("ASoC WM8988 driver"); -MODULE_AUTHOR("Mark Brown "); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8988.h b/trunk/sound/soc/codecs/wm8988.h deleted file mode 100644 index 4552d37fdd41..000000000000 --- a/trunk/sound/soc/codecs/wm8988.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2005 Openedhand Ltd. - * - * Author: Richard Purdie - * - * Based on WM8753.h - * - * 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 _WM8988_H -#define _WM8988_H - -/* WM8988 register space */ - -#define WM8988_LINVOL 0x00 -#define WM8988_RINVOL 0x01 -#define WM8988_LOUT1V 0x02 -#define WM8988_ROUT1V 0x03 -#define WM8988_ADCDAC 0x05 -#define WM8988_IFACE 0x07 -#define WM8988_SRATE 0x08 -#define WM8988_LDAC 0x0a -#define WM8988_RDAC 0x0b -#define WM8988_BASS 0x0c -#define WM8988_TREBLE 0x0d -#define WM8988_RESET 0x0f -#define WM8988_3D 0x10 -#define WM8988_ALC1 0x11 -#define WM8988_ALC2 0x12 -#define WM8988_ALC3 0x13 -#define WM8988_NGATE 0x14 -#define WM8988_LADC 0x15 -#define WM8988_RADC 0x16 -#define WM8988_ADCTL1 0x17 -#define WM8988_ADCTL2 0x18 -#define WM8988_PWR1 0x19 -#define WM8988_PWR2 0x1a -#define WM8988_ADCTL3 0x1b -#define WM8988_ADCIN 0x1f -#define WM8988_LADCIN 0x20 -#define WM8988_RADCIN 0x21 -#define WM8988_LOUTM1 0x22 -#define WM8988_LOUTM2 0x23 -#define WM8988_ROUTM1 0x24 -#define WM8988_ROUTM2 0x25 -#define WM8988_LOUT2V 0x28 -#define WM8988_ROUT2V 0x29 -#define WM8988_LPPB 0x43 -#define WM8988_NUM_REG 0x44 - -#define WM8988_SYSCLK 0 - -extern struct snd_soc_dai wm8988_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm8988; - -#endif diff --git a/trunk/sound/soc/codecs/wm8990.c b/trunk/sound/soc/codecs/wm8990.c index d029818350e9..40cd274eb1ef 100644 --- a/trunk/sound/soc/codecs/wm8990.c +++ b/trunk/sound/soc/codecs/wm8990.c @@ -998,7 +998,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, if ((Ndiv < 6) || (Ndiv > 12)) printk(KERN_WARNING - "WM8990 N value outwith recommended range! N = %u\n", Ndiv); + "WM8990 N value outwith recommended range! N = %d\n", Ndiv); pll_div->n = Ndiv; Nmod = target % source; diff --git a/trunk/sound/soc/codecs/wm9081.c b/trunk/sound/soc/codecs/wm9081.c deleted file mode 100644 index 86fc57e25f97..000000000000 --- a/trunk/sound/soc/codecs/wm9081.c +++ /dev/null @@ -1,1534 +0,0 @@ -/* - * wm9081.c -- WM9081 ALSA SoC Audio driver - * - * Author: Mark Brown - * - * Copyright 2009 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "wm9081.h" - -static u16 wm9081_reg_defaults[] = { - 0x0000, /* R0 - Software Reset */ - 0x0000, /* R1 */ - 0x00B9, /* R2 - Analogue Lineout */ - 0x00B9, /* R3 - Analogue Speaker PGA */ - 0x0001, /* R4 - VMID Control */ - 0x0068, /* R5 - Bias Control 1 */ - 0x0000, /* R6 */ - 0x0000, /* R7 - Analogue Mixer */ - 0x0000, /* R8 - Anti Pop Control */ - 0x01DB, /* R9 - Analogue Speaker 1 */ - 0x0018, /* R10 - Analogue Speaker 2 */ - 0x0180, /* R11 - Power Management */ - 0x0000, /* R12 - Clock Control 1 */ - 0x0038, /* R13 - Clock Control 2 */ - 0x4000, /* R14 - Clock Control 3 */ - 0x0000, /* R15 */ - 0x0000, /* R16 - FLL Control 1 */ - 0x0200, /* R17 - FLL Control 2 */ - 0x0000, /* R18 - FLL Control 3 */ - 0x0204, /* R19 - FLL Control 4 */ - 0x0000, /* R20 - FLL Control 5 */ - 0x0000, /* R21 */ - 0x0000, /* R22 - Audio Interface 1 */ - 0x0002, /* R23 - Audio Interface 2 */ - 0x0008, /* R24 - Audio Interface 3 */ - 0x0022, /* R25 - Audio Interface 4 */ - 0x0000, /* R26 - Interrupt Status */ - 0x0006, /* R27 - Interrupt Status Mask */ - 0x0000, /* R28 - Interrupt Polarity */ - 0x0000, /* R29 - Interrupt Control */ - 0x00C0, /* R30 - DAC Digital 1 */ - 0x0008, /* R31 - DAC Digital 2 */ - 0x09AF, /* R32 - DRC 1 */ - 0x4201, /* R33 - DRC 2 */ - 0x0000, /* R34 - DRC 3 */ - 0x0000, /* R35 - DRC 4 */ - 0x0000, /* R36 */ - 0x0000, /* R37 */ - 0x0000, /* R38 - Write Sequencer 1 */ - 0x0000, /* R39 - Write Sequencer 2 */ - 0x0002, /* R40 - MW Slave 1 */ - 0x0000, /* R41 */ - 0x0000, /* R42 - EQ 1 */ - 0x0000, /* R43 - EQ 2 */ - 0x0FCA, /* R44 - EQ 3 */ - 0x0400, /* R45 - EQ 4 */ - 0x00B8, /* R46 - EQ 5 */ - 0x1EB5, /* R47 - EQ 6 */ - 0xF145, /* R48 - EQ 7 */ - 0x0B75, /* R49 - EQ 8 */ - 0x01C5, /* R50 - EQ 9 */ - 0x169E, /* R51 - EQ 10 */ - 0xF829, /* R52 - EQ 11 */ - 0x07AD, /* R53 - EQ 12 */ - 0x1103, /* R54 - EQ 13 */ - 0x1C58, /* R55 - EQ 14 */ - 0xF373, /* R56 - EQ 15 */ - 0x0A54, /* R57 - EQ 16 */ - 0x0558, /* R58 - EQ 17 */ - 0x0564, /* R59 - EQ 18 */ - 0x0559, /* R60 - EQ 19 */ - 0x4000, /* R61 - EQ 20 */ -}; - -static struct { - int ratio; - int clk_sys_rate; -} clk_sys_rates[] = { - { 64, 0 }, - { 128, 1 }, - { 192, 2 }, - { 256, 3 }, - { 384, 4 }, - { 512, 5 }, - { 768, 6 }, - { 1024, 7 }, - { 1408, 8 }, - { 1536, 9 }, -}; - -static struct { - int rate; - int sample_rate; -} sample_rates[] = { - { 8000, 0 }, - { 11025, 1 }, - { 12000, 2 }, - { 16000, 3 }, - { 22050, 4 }, - { 24000, 5 }, - { 32000, 6 }, - { 44100, 7 }, - { 48000, 8 }, - { 88200, 9 }, - { 96000, 10 }, -}; - -static struct { - int div; /* *10 due to .5s */ - int bclk_div; -} bclk_divs[] = { - { 10, 0 }, - { 15, 1 }, - { 20, 2 }, - { 30, 3 }, - { 40, 4 }, - { 50, 5 }, - { 55, 6 }, - { 60, 7 }, - { 80, 8 }, - { 100, 9 }, - { 110, 10 }, - { 120, 11 }, - { 160, 12 }, - { 200, 13 }, - { 220, 14 }, - { 240, 15 }, - { 250, 16 }, - { 300, 17 }, - { 320, 18 }, - { 440, 19 }, - { 480, 20 }, -}; - -struct wm9081_priv { - struct snd_soc_codec codec; - u16 reg_cache[WM9081_MAX_REGISTER + 1]; - int sysclk_source; - int mclk_rate; - int sysclk_rate; - int fs; - int bclk; - int master; - int fll_fref; - int fll_fout; - struct wm9081_retune_mobile_config *retune; -}; - -static int wm9081_reg_is_volatile(int reg) -{ - switch (reg) { - default: - return 0; - } -} - -static unsigned int wm9081_read_reg_cache(struct snd_soc_codec *codec, - unsigned int reg) -{ - u16 *cache = codec->reg_cache; - BUG_ON(reg > WM9081_MAX_REGISTER); - return cache[reg]; -} - -static unsigned int wm9081_read_hw(struct snd_soc_codec *codec, u8 reg) -{ - struct i2c_msg xfer[2]; - u16 data; - int ret; - struct i2c_client *client = codec->control_data; - - BUG_ON(reg > WM9081_MAX_REGISTER); - - /* Write register */ - xfer[0].addr = client->addr; - xfer[0].flags = 0; - xfer[0].len = 1; - xfer[0].buf = ® - - /* Read data */ - xfer[1].addr = client->addr; - xfer[1].flags = I2C_M_RD; - xfer[1].len = 2; - xfer[1].buf = (u8 *)&data; - - ret = i2c_transfer(client->adapter, xfer, 2); - if (ret != 2) { - dev_err(&client->dev, "i2c_transfer() returned %d\n", ret); - return 0; - } - - return (data >> 8) | ((data & 0xff) << 8); -} - -static unsigned int wm9081_read(struct snd_soc_codec *codec, unsigned int reg) -{ - if (wm9081_reg_is_volatile(reg)) - return wm9081_read_hw(codec, reg); - else - return wm9081_read_reg_cache(codec, reg); -} - -static int wm9081_write(struct snd_soc_codec *codec, unsigned int reg, - unsigned int value) -{ - u16 *cache = codec->reg_cache; - u8 data[3]; - - BUG_ON(reg > WM9081_MAX_REGISTER); - - if (!wm9081_reg_is_volatile(reg)) - cache[reg] = value; - - data[0] = reg; - data[1] = value >> 8; - data[2] = value & 0x00ff; - - if (codec->hw_write(codec->control_data, data, 3) == 3) - return 0; - else - return -EIO; -} - -static int wm9081_reset(struct snd_soc_codec *codec) -{ - return wm9081_write(codec, WM9081_SOFTWARE_RESET, 0); -} - -static const DECLARE_TLV_DB_SCALE(drc_in_tlv, -4500, 75, 0); -static const DECLARE_TLV_DB_SCALE(drc_out_tlv, -2250, 75, 0); -static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); -static unsigned int drc_max_tlv[] = { - TLV_DB_RANGE_HEAD(4), - 0, 0, TLV_DB_SCALE_ITEM(1200, 0, 0), - 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), - 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), - 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0), -}; -static const DECLARE_TLV_DB_SCALE(drc_qr_tlv, 1200, 600, 0); -static const DECLARE_TLV_DB_SCALE(drc_startup_tlv, -300, 50, 0); - -static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); - -static const DECLARE_TLV_DB_SCALE(in_tlv, -600, 600, 0); -static const DECLARE_TLV_DB_SCALE(dac_tlv, -7200, 75, 1); -static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); - -static const char *drc_high_text[] = { - "1", - "1/2", - "1/4", - "1/8", - "1/16", - "0", -}; - -static const struct soc_enum drc_high = - SOC_ENUM_SINGLE(WM9081_DRC_3, 3, 6, drc_high_text); - -static const char *drc_low_text[] = { - "1", - "1/2", - "1/4", - "1/8", - "0", -}; - -static const struct soc_enum drc_low = - SOC_ENUM_SINGLE(WM9081_DRC_3, 0, 5, drc_low_text); - -static const char *drc_atk_text[] = { - "181us", - "181us", - "363us", - "726us", - "1.45ms", - "2.9ms", - "5.8ms", - "11.6ms", - "23.2ms", - "46.4ms", - "92.8ms", - "185.6ms", -}; - -static const struct soc_enum drc_atk = - SOC_ENUM_SINGLE(WM9081_DRC_2, 12, 12, drc_atk_text); - -static const char *drc_dcy_text[] = { - "186ms", - "372ms", - "743ms", - "1.49s", - "2.97s", - "5.94s", - "11.89s", - "23.78s", - "47.56s", -}; - -static const struct soc_enum drc_dcy = - SOC_ENUM_SINGLE(WM9081_DRC_2, 8, 9, drc_dcy_text); - -static const char *drc_qr_dcy_text[] = { - "0.725ms", - "1.45ms", - "5.8ms", -}; - -static const struct soc_enum drc_qr_dcy = - SOC_ENUM_SINGLE(WM9081_DRC_2, 4, 3, drc_qr_dcy_text); - -static const char *dac_deemph_text[] = { - "None", - "32kHz", - "44.1kHz", - "48kHz", -}; - -static const struct soc_enum dac_deemph = - SOC_ENUM_SINGLE(WM9081_DAC_DIGITAL_2, 1, 4, dac_deemph_text); - -static const char *speaker_mode_text[] = { - "Class D", - "Class AB", -}; - -static const struct soc_enum speaker_mode = - SOC_ENUM_SINGLE(WM9081_ANALOGUE_SPEAKER_2, 6, 2, speaker_mode_text); - -static int speaker_mode_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int reg; - - reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); - if (reg & WM9081_SPK_MODE) - ucontrol->value.integer.value[0] = 1; - else - ucontrol->value.integer.value[0] = 0; - - return 0; -} - -/* - * Stop any attempts to change speaker mode while the speaker is enabled. - * - * We also have some special anti-pop controls dependant on speaker - * mode which must be changed along with the mode. - */ -static int speaker_mode_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int reg_pwr = wm9081_read(codec, WM9081_POWER_MANAGEMENT); - unsigned int reg2 = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_2); - - /* Are we changing anything? */ - if (ucontrol->value.integer.value[0] == - ((reg2 & WM9081_SPK_MODE) != 0)) - return 0; - - /* Don't try to change modes while enabled */ - if (reg_pwr & WM9081_SPK_ENA) - return -EINVAL; - - if (ucontrol->value.integer.value[0]) { - /* Class AB */ - reg2 &= ~(WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL); - reg2 |= WM9081_SPK_MODE; - } else { - /* Class D */ - reg2 |= WM9081_SPK_INV_MUTE | WM9081_OUT_SPK_CTRL; - reg2 &= ~WM9081_SPK_MODE; - } - - wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_2, reg2); - - return 0; -} - -static const struct snd_kcontrol_new wm9081_snd_controls[] = { -SOC_SINGLE_TLV("IN1 Volume", WM9081_ANALOGUE_MIXER, 1, 1, 1, in_tlv), -SOC_SINGLE_TLV("IN2 Volume", WM9081_ANALOGUE_MIXER, 3, 1, 1, in_tlv), - -SOC_SINGLE_TLV("Playback Volume", WM9081_DAC_DIGITAL_1, 1, 96, 0, dac_tlv), - -SOC_SINGLE("LINEOUT Switch", WM9081_ANALOGUE_LINEOUT, 7, 1, 1), -SOC_SINGLE("LINEOUT ZC Switch", WM9081_ANALOGUE_LINEOUT, 6, 1, 0), -SOC_SINGLE_TLV("LINEOUT Volume", WM9081_ANALOGUE_LINEOUT, 0, 63, 0, out_tlv), - -SOC_SINGLE("DRC Switch", WM9081_DRC_1, 15, 1, 0), -SOC_ENUM("DRC High Slope", drc_high), -SOC_ENUM("DRC Low Slope", drc_low), -SOC_SINGLE_TLV("DRC Input Volume", WM9081_DRC_4, 5, 60, 1, drc_in_tlv), -SOC_SINGLE_TLV("DRC Output Volume", WM9081_DRC_4, 0, 30, 1, drc_out_tlv), -SOC_SINGLE_TLV("DRC Minimum Volume", WM9081_DRC_2, 2, 3, 1, drc_min_tlv), -SOC_SINGLE_TLV("DRC Maximum Volume", WM9081_DRC_2, 0, 3, 0, drc_max_tlv), -SOC_ENUM("DRC Attack", drc_atk), -SOC_ENUM("DRC Decay", drc_dcy), -SOC_SINGLE("DRC Quick Release Switch", WM9081_DRC_1, 2, 1, 0), -SOC_SINGLE_TLV("DRC Quick Release Volume", WM9081_DRC_2, 6, 3, 0, drc_qr_tlv), -SOC_ENUM("DRC Quick Release Decay", drc_qr_dcy), -SOC_SINGLE_TLV("DRC Startup Volume", WM9081_DRC_1, 6, 18, 0, drc_startup_tlv), - -SOC_SINGLE("EQ Switch", WM9081_EQ_1, 0, 1, 0), - -SOC_SINGLE("Speaker DC Volume", WM9081_ANALOGUE_SPEAKER_1, 3, 5, 0), -SOC_SINGLE("Speaker AC Volume", WM9081_ANALOGUE_SPEAKER_1, 0, 5, 0), -SOC_SINGLE("Speaker Switch", WM9081_ANALOGUE_SPEAKER_PGA, 7, 1, 1), -SOC_SINGLE("Speaker ZC Switch", WM9081_ANALOGUE_SPEAKER_PGA, 6, 1, 0), -SOC_SINGLE_TLV("Speaker Volume", WM9081_ANALOGUE_SPEAKER_PGA, 0, 63, 0, - out_tlv), -SOC_ENUM("DAC Deemphasis", dac_deemph), -SOC_ENUM_EXT("Speaker Mode", speaker_mode, speaker_mode_get, speaker_mode_put), -}; - -static const struct snd_kcontrol_new wm9081_eq_controls[] = { -SOC_SINGLE_TLV("EQ1 Volume", WM9081_EQ_1, 11, 24, 0, eq_tlv), -SOC_SINGLE_TLV("EQ2 Volume", WM9081_EQ_1, 6, 24, 0, eq_tlv), -SOC_SINGLE_TLV("EQ3 Volume", WM9081_EQ_1, 1, 24, 0, eq_tlv), -SOC_SINGLE_TLV("EQ4 Volume", WM9081_EQ_2, 11, 24, 0, eq_tlv), -SOC_SINGLE_TLV("EQ5 Volume", WM9081_EQ_2, 6, 24, 0, eq_tlv), -}; - -static const struct snd_kcontrol_new mixer[] = { -SOC_DAPM_SINGLE("IN1 Switch", WM9081_ANALOGUE_MIXER, 0, 1, 0), -SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0), -SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), -}; - -static int speaker_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - unsigned int reg = wm9081_read(codec, WM9081_POWER_MANAGEMENT); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - reg |= WM9081_SPK_ENA; - break; - - case SND_SOC_DAPM_PRE_PMD: - reg &= ~WM9081_SPK_ENA; - break; - } - - wm9081_write(codec, WM9081_POWER_MANAGEMENT, reg); - - return 0; -} - -struct _fll_div { - u16 fll_fratio; - u16 fll_outdiv; - u16 fll_clk_ref_div; - u16 n; - u16 k; -}; - -/* The size in bits of the FLL divide multiplied by 10 - * to allow rounding later */ -#define FIXED_FLL_SIZE ((1 << 16) * 10) - -static struct { - unsigned int min; - unsigned int max; - u16 fll_fratio; - int ratio; -} fll_fratios[] = { - { 0, 64000, 4, 16 }, - { 64000, 128000, 3, 8 }, - { 128000, 256000, 2, 4 }, - { 256000, 1000000, 1, 2 }, - { 1000000, 13500000, 0, 1 }, -}; - -static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, - unsigned int Fout) -{ - u64 Kpart; - unsigned int K, Ndiv, Nmod, target; - unsigned int div; - int i; - - /* Fref must be <=13.5MHz */ - div = 1; - while ((Fref / div) > 13500000) { - div *= 2; - - if (div > 8) { - pr_err("Can't scale %dMHz input down to <=13.5MHz\n", - Fref); - return -EINVAL; - } - } - fll_div->fll_clk_ref_div = div / 2; - - pr_debug("Fref=%u Fout=%u\n", Fref, Fout); - - /* Apply the division for our remaining calculations */ - Fref /= div; - - /* Fvco should be 90-100MHz; don't check the upper bound */ - div = 0; - target = Fout * 2; - while (target < 90000000) { - div++; - target *= 2; - if (div > 7) { - pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", - Fout); - return -EINVAL; - } - } - fll_div->fll_outdiv = div; - - pr_debug("Fvco=%dHz\n", target); - - /* Find an appropraite FLL_FRATIO and factor it out of the target */ - for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { - if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { - fll_div->fll_fratio = fll_fratios[i].fll_fratio; - target /= fll_fratios[i].ratio; - break; - } - } - if (i == ARRAY_SIZE(fll_fratios)) { - pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); - return -EINVAL; - } - - /* Now, calculate N.K */ - Ndiv = target / Fref; - - fll_div->n = Ndiv; - Nmod = target % Fref; - pr_debug("Nmod=%d\n", Nmod); - - /* Calculate fractional part - scale up so we can round. */ - Kpart = FIXED_FLL_SIZE * (long long)Nmod; - - do_div(Kpart, Fref); - - K = Kpart & 0xFFFFFFFF; - - if ((K % 10) >= 5) - K += 5; - - /* Move down to proper range now rounding is done */ - fll_div->k = K / 10; - - pr_debug("N=%x K=%x FLL_FRATIO=%x FLL_OUTDIV=%x FLL_CLK_REF_DIV=%x\n", - fll_div->n, fll_div->k, - fll_div->fll_fratio, fll_div->fll_outdiv, - fll_div->fll_clk_ref_div); - - return 0; -} - -static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id, - unsigned int Fref, unsigned int Fout) -{ - struct wm9081_priv *wm9081 = codec->private_data; - u16 reg1, reg4, reg5; - struct _fll_div fll_div; - int ret; - int clk_sys_reg; - - /* Any change? */ - if (Fref == wm9081->fll_fref && Fout == wm9081->fll_fout) - return 0; - - /* Disable the FLL */ - if (Fout == 0) { - dev_dbg(codec->dev, "FLL disabled\n"); - wm9081->fll_fref = 0; - wm9081->fll_fout = 0; - - return 0; - } - - ret = fll_factors(&fll_div, Fref, Fout); - if (ret != 0) - return ret; - - reg5 = wm9081_read(codec, WM9081_FLL_CONTROL_5); - reg5 &= ~WM9081_FLL_CLK_SRC_MASK; - - switch (fll_id) { - case WM9081_SYSCLK_FLL_MCLK: - reg5 |= 0x1; - break; - - default: - dev_err(codec->dev, "Unknown FLL ID %d\n", fll_id); - return -EINVAL; - } - - /* Disable CLK_SYS while we reconfigure */ - clk_sys_reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); - if (clk_sys_reg & WM9081_CLK_SYS_ENA) - wm9081_write(codec, WM9081_CLOCK_CONTROL_3, - clk_sys_reg & ~WM9081_CLK_SYS_ENA); - - /* Any FLL configuration change requires that the FLL be - * disabled first. */ - reg1 = wm9081_read(codec, WM9081_FLL_CONTROL_1); - reg1 &= ~WM9081_FLL_ENA; - wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); - - /* Apply the configuration */ - if (fll_div.k) - reg1 |= WM9081_FLL_FRAC_MASK; - else - reg1 &= ~WM9081_FLL_FRAC_MASK; - wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1); - - wm9081_write(codec, WM9081_FLL_CONTROL_2, - (fll_div.fll_outdiv << WM9081_FLL_OUTDIV_SHIFT) | - (fll_div.fll_fratio << WM9081_FLL_FRATIO_SHIFT)); - wm9081_write(codec, WM9081_FLL_CONTROL_3, fll_div.k); - - reg4 = wm9081_read(codec, WM9081_FLL_CONTROL_4); - reg4 &= ~WM9081_FLL_N_MASK; - reg4 |= fll_div.n << WM9081_FLL_N_SHIFT; - wm9081_write(codec, WM9081_FLL_CONTROL_4, reg4); - - reg5 &= ~WM9081_FLL_CLK_REF_DIV_MASK; - reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; - wm9081_write(codec, WM9081_FLL_CONTROL_5, reg5); - - /* Enable the FLL */ - wm9081_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); - - /* Then bring CLK_SYS up again if it was disabled */ - if (clk_sys_reg & WM9081_CLK_SYS_ENA) - wm9081_write(codec, WM9081_CLOCK_CONTROL_3, clk_sys_reg); - - dev_dbg(codec->dev, "FLL enabled at %dHz->%dHz\n", Fref, Fout); - - wm9081->fll_fref = Fref; - wm9081->fll_fout = Fout; - - return 0; -} - -static int configure_clock(struct snd_soc_codec *codec) -{ - struct wm9081_priv *wm9081 = codec->private_data; - int new_sysclk, i, target; - unsigned int reg; - int ret = 0; - int mclkdiv = 0; - int fll = 0; - - switch (wm9081->sysclk_source) { - case WM9081_SYSCLK_MCLK: - if (wm9081->mclk_rate > 12225000) { - mclkdiv = 1; - wm9081->sysclk_rate = wm9081->mclk_rate / 2; - } else { - wm9081->sysclk_rate = wm9081->mclk_rate; - } - wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK, 0, 0); - break; - - case WM9081_SYSCLK_FLL_MCLK: - /* If we have a sample rate calculate a CLK_SYS that - * gives us a suitable DAC configuration, plus BCLK. - * Ideally we would check to see if we can clock - * directly from MCLK and only use the FLL if this is - * not the case, though care must be taken with free - * running mode. - */ - if (wm9081->master && wm9081->bclk) { - /* Make sure we can generate CLK_SYS and BCLK - * and that we've got 3MHz for optimal - * performance. */ - for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { - target = wm9081->fs * clk_sys_rates[i].ratio; - new_sysclk = target; - if (target >= wm9081->bclk && - target > 3000000) - break; - } - } else if (wm9081->fs) { - for (i = 0; i < ARRAY_SIZE(clk_sys_rates); i++) { - new_sysclk = clk_sys_rates[i].ratio - * wm9081->fs; - if (new_sysclk > 3000000) - break; - } - } else { - new_sysclk = 12288000; - } - - ret = wm9081_set_fll(codec, WM9081_SYSCLK_FLL_MCLK, - wm9081->mclk_rate, new_sysclk); - if (ret == 0) { - wm9081->sysclk_rate = new_sysclk; - - /* Switch SYSCLK over to FLL */ - fll = 1; - } else { - wm9081->sysclk_rate = wm9081->mclk_rate; - } - break; - - default: - return -EINVAL; - } - - reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_1); - if (mclkdiv) - reg |= WM9081_MCLKDIV2; - else - reg &= ~WM9081_MCLKDIV2; - wm9081_write(codec, WM9081_CLOCK_CONTROL_1, reg); - - reg = wm9081_read(codec, WM9081_CLOCK_CONTROL_3); - if (fll) - reg |= WM9081_CLK_SRC_SEL; - else - reg &= ~WM9081_CLK_SRC_SEL; - wm9081_write(codec, WM9081_CLOCK_CONTROL_3, reg); - - dev_dbg(codec->dev, "CLK_SYS is %dHz\n", wm9081->sysclk_rate); - - return ret; -} - -static int clk_sys_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - struct wm9081_priv *wm9081 = codec->private_data; - - /* This should be done on init() for bypass paths */ - switch (wm9081->sysclk_source) { - case WM9081_SYSCLK_MCLK: - dev_dbg(codec->dev, "Using %dHz MCLK\n", wm9081->mclk_rate); - break; - case WM9081_SYSCLK_FLL_MCLK: - dev_dbg(codec->dev, "Using %dHz MCLK with FLL\n", - wm9081->mclk_rate); - break; - default: - dev_err(codec->dev, "System clock not configured\n"); - return -EINVAL; - } - - switch (event) { - case SND_SOC_DAPM_PRE_PMU: - configure_clock(codec); - break; - - case SND_SOC_DAPM_POST_PMD: - /* Disable the FLL if it's running */ - wm9081_set_fll(codec, 0, 0, 0); - break; - } - - return 0; -} - -static const struct snd_soc_dapm_widget wm9081_dapm_widgets[] = { -SND_SOC_DAPM_INPUT("IN1"), -SND_SOC_DAPM_INPUT("IN2"), - -SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM9081_POWER_MANAGEMENT, 0, 0), - -SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0, - mixer, ARRAY_SIZE(mixer)), - -SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), - -SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, - speaker_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - -SND_SOC_DAPM_OUTPUT("LINEOUT"), -SND_SOC_DAPM_OUTPUT("SPKN"), -SND_SOC_DAPM_OUTPUT("SPKP"), - -SND_SOC_DAPM_SUPPLY("CLK_SYS", WM9081_CLOCK_CONTROL_3, 0, 0, clk_sys_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), -SND_SOC_DAPM_SUPPLY("CLK_DSP", WM9081_CLOCK_CONTROL_3, 1, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0), -}; - - -static const struct snd_soc_dapm_route audio_paths[] = { - { "DAC", NULL, "CLK_SYS" }, - { "DAC", NULL, "CLK_DSP" }, - - { "Mixer", "IN1 Switch", "IN1" }, - { "Mixer", "IN2 Switch", "IN2" }, - { "Mixer", "Playback Switch", "DAC" }, - - { "LINEOUT PGA", NULL, "Mixer" }, - { "LINEOUT PGA", NULL, "TOCLK" }, - { "LINEOUT PGA", NULL, "CLK_SYS" }, - - { "LINEOUT", NULL, "LINEOUT PGA" }, - - { "Speaker PGA", NULL, "Mixer" }, - { "Speaker PGA", NULL, "TOCLK" }, - { "Speaker PGA", NULL, "CLK_SYS" }, - - { "SPKN", NULL, "Speaker PGA" }, - { "SPKP", NULL, "Speaker PGA" }, -}; - -static int wm9081_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - u16 reg; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - /* VMID=2*40k */ - reg = wm9081_read(codec, WM9081_VMID_CONTROL); - reg &= ~WM9081_VMID_SEL_MASK; - reg |= 0x2; - wm9081_write(codec, WM9081_VMID_CONTROL, reg); - - /* Normal bias current */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_STBY_BIAS_ENA; - wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); - break; - - case SND_SOC_BIAS_STANDBY: - /* Initial cold start */ - if (codec->bias_level == SND_SOC_BIAS_OFF) { - /* Disable LINEOUT discharge */ - reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); - reg &= ~WM9081_LINEOUT_DISCH; - wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); - - /* Select startup bias source */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_BIAS_SRC | WM9081_BIAS_ENA; - wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); - - /* VMID 2*4k; Soft VMID ramp enable */ - reg = wm9081_read(codec, WM9081_VMID_CONTROL); - reg |= WM9081_VMID_RAMP | 0x6; - wm9081_write(codec, WM9081_VMID_CONTROL, reg); - - mdelay(100); - - /* Normal bias enable & soft start off */ - reg |= WM9081_BIAS_ENA; - reg &= ~WM9081_VMID_RAMP; - wm9081_write(codec, WM9081_VMID_CONTROL, reg); - - /* Standard bias source */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_BIAS_SRC; - wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); - } - - /* VMID 2*240k */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg &= ~WM9081_VMID_SEL_MASK; - reg |= 0x40; - wm9081_write(codec, WM9081_VMID_CONTROL, reg); - - /* Standby bias current on */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_STBY_BIAS_ENA; - wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); - break; - - case SND_SOC_BIAS_OFF: - /* Startup bias source */ - reg = wm9081_read(codec, WM9081_BIAS_CONTROL_1); - reg |= WM9081_BIAS_SRC; - wm9081_write(codec, WM9081_BIAS_CONTROL_1, reg); - - /* Disable VMID and biases with soft ramping */ - reg = wm9081_read(codec, WM9081_VMID_CONTROL); - reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); - reg |= WM9081_VMID_RAMP; - wm9081_write(codec, WM9081_VMID_CONTROL, reg); - - /* Actively discharge LINEOUT */ - reg = wm9081_read(codec, WM9081_ANTI_POP_CONTROL); - reg |= WM9081_LINEOUT_DISCH; - wm9081_write(codec, WM9081_ANTI_POP_CONTROL, reg); - break; - } - - codec->bias_level = level; - - return 0; -} - -static int wm9081_set_dai_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm9081_priv *wm9081 = codec->private_data; - unsigned int aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); - - aif2 &= ~(WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV | - WM9081_BCLK_DIR | WM9081_LRCLK_DIR | WM9081_AIF_FMT_MASK); - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - wm9081->master = 0; - break; - case SND_SOC_DAIFMT_CBS_CFM: - aif2 |= WM9081_LRCLK_DIR; - wm9081->master = 1; - break; - case SND_SOC_DAIFMT_CBM_CFS: - aif2 |= WM9081_BCLK_DIR; - wm9081->master = 1; - break; - case SND_SOC_DAIFMT_CBM_CFM: - aif2 |= WM9081_LRCLK_DIR | WM9081_BCLK_DIR; - wm9081->master = 1; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_B: - aif2 |= WM9081_AIF_LRCLK_INV; - case SND_SOC_DAIFMT_DSP_A: - aif2 |= 0x3; - break; - case SND_SOC_DAIFMT_I2S: - aif2 |= 0x2; - break; - case SND_SOC_DAIFMT_RIGHT_J: - break; - case SND_SOC_DAIFMT_LEFT_J: - aif2 |= 0x1; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - case SND_SOC_DAIFMT_DSP_B: - /* frame inversion not valid for DSP modes */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - aif2 |= WM9081_AIF_BCLK_INV; - break; - default: - return -EINVAL; - } - break; - - case SND_SOC_DAIFMT_I2S: - case SND_SOC_DAIFMT_RIGHT_J: - case SND_SOC_DAIFMT_LEFT_J: - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - aif2 |= WM9081_AIF_BCLK_INV | WM9081_AIF_LRCLK_INV; - break; - case SND_SOC_DAIFMT_IB_NF: - aif2 |= WM9081_AIF_BCLK_INV; - break; - case SND_SOC_DAIFMT_NB_IF: - aif2 |= WM9081_AIF_LRCLK_INV; - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - - wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); - - return 0; -} - -static int wm9081_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm9081_priv *wm9081 = codec->private_data; - int ret, i, best, best_val, cur_val; - unsigned int clk_ctrl2, aif1, aif2, aif3, aif4; - - clk_ctrl2 = wm9081_read(codec, WM9081_CLOCK_CONTROL_2); - clk_ctrl2 &= ~(WM9081_CLK_SYS_RATE_MASK | WM9081_SAMPLE_RATE_MASK); - - aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); - - aif2 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_2); - aif2 &= ~WM9081_AIF_WL_MASK; - - aif3 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_3); - aif3 &= ~WM9081_BCLK_DIV_MASK; - - aif4 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_4); - aif4 &= ~WM9081_LRCLK_RATE_MASK; - - /* What BCLK do we need? */ - wm9081->fs = params_rate(params); - wm9081->bclk = 2 * wm9081->fs; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - wm9081->bclk *= 16; - break; - case SNDRV_PCM_FORMAT_S20_3LE: - wm9081->bclk *= 20; - aif2 |= 0x4; - break; - case SNDRV_PCM_FORMAT_S24_LE: - wm9081->bclk *= 24; - aif2 |= 0x8; - break; - case SNDRV_PCM_FORMAT_S32_LE: - wm9081->bclk *= 32; - aif2 |= 0xc; - break; - default: - return -EINVAL; - } - - if (aif1 & WM9081_AIFDAC_TDM_MODE_MASK) { - int slots = ((aif1 & WM9081_AIFDAC_TDM_MODE_MASK) >> - WM9081_AIFDAC_TDM_MODE_SHIFT) + 1; - wm9081->bclk *= slots; - } - - dev_dbg(codec->dev, "Target BCLK is %dHz\n", wm9081->bclk); - - ret = configure_clock(codec); - if (ret != 0) - return ret; - - /* Select nearest CLK_SYS_RATE */ - best = 0; - best_val = abs((wm9081->sysclk_rate / clk_sys_rates[0].ratio) - - wm9081->fs); - for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { - cur_val = abs((wm9081->sysclk_rate / - clk_sys_rates[i].ratio) - wm9081->fs);; - if (cur_val < best_val) { - best = i; - best_val = cur_val; - } - } - dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n", - clk_sys_rates[best].ratio); - clk_ctrl2 |= (clk_sys_rates[best].clk_sys_rate - << WM9081_CLK_SYS_RATE_SHIFT); - - /* SAMPLE_RATE */ - best = 0; - best_val = abs(wm9081->fs - sample_rates[0].rate); - for (i = 1; i < ARRAY_SIZE(sample_rates); i++) { - /* Closest match */ - cur_val = abs(wm9081->fs - sample_rates[i].rate); - if (cur_val < best_val) { - best = i; - best_val = cur_val; - } - } - dev_dbg(codec->dev, "Selected SAMPLE_RATE of %dHz\n", - sample_rates[best].rate); - clk_ctrl2 |= (sample_rates[best].sample_rate - << WM9081_SAMPLE_RATE_SHIFT); - - /* BCLK_DIV */ - best = 0; - best_val = INT_MAX; - for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { - cur_val = ((wm9081->sysclk_rate * 10) / bclk_divs[i].div) - - wm9081->bclk; - if (cur_val < 0) /* Table is sorted */ - break; - if (cur_val < best_val) { - best = i; - best_val = cur_val; - } - } - wm9081->bclk = (wm9081->sysclk_rate * 10) / bclk_divs[best].div; - dev_dbg(codec->dev, "Selected BCLK_DIV of %d for %dHz BCLK\n", - bclk_divs[best].div, wm9081->bclk); - aif3 |= bclk_divs[best].bclk_div; - - /* LRCLK is a simple fraction of BCLK */ - dev_dbg(codec->dev, "LRCLK_RATE is %d\n", wm9081->bclk / wm9081->fs); - aif4 |= wm9081->bclk / wm9081->fs; - - /* Apply a ReTune Mobile configuration if it's in use */ - if (wm9081->retune) { - struct wm9081_retune_mobile_config *retune = wm9081->retune; - struct wm9081_retune_mobile_setting *s; - int eq1; - - best = 0; - best_val = abs(retune->configs[0].rate - wm9081->fs); - for (i = 0; i < retune->num_configs; i++) { - cur_val = abs(retune->configs[i].rate - wm9081->fs); - if (cur_val < best_val) { - best_val = cur_val; - best = i; - } - } - s = &retune->configs[best]; - - dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", - s->name, s->rate); - - /* If the EQ is enabled then disable it while we write out */ - eq1 = wm9081_read(codec, WM9081_EQ_1) & WM9081_EQ_ENA; - if (eq1 & WM9081_EQ_ENA) - wm9081_write(codec, WM9081_EQ_1, 0); - - /* Write out the other values */ - for (i = 1; i < ARRAY_SIZE(s->config); i++) - wm9081_write(codec, WM9081_EQ_1 + i, s->config[i]); - - eq1 |= (s->config[0] & ~WM9081_EQ_ENA); - wm9081_write(codec, WM9081_EQ_1, eq1); - } - - wm9081_write(codec, WM9081_CLOCK_CONTROL_2, clk_ctrl2); - wm9081_write(codec, WM9081_AUDIO_INTERFACE_2, aif2); - wm9081_write(codec, WM9081_AUDIO_INTERFACE_3, aif3); - wm9081_write(codec, WM9081_AUDIO_INTERFACE_4, aif4); - - return 0; -} - -static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute) -{ - struct snd_soc_codec *codec = codec_dai->codec; - unsigned int reg; - - reg = wm9081_read(codec, WM9081_DAC_DIGITAL_2); - - if (mute) - reg |= WM9081_DAC_MUTE; - else - reg &= ~WM9081_DAC_MUTE; - - wm9081_write(codec, WM9081_DAC_DIGITAL_2, reg); - - return 0; -} - -static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = codec_dai->codec; - struct wm9081_priv *wm9081 = codec->private_data; - - switch (clk_id) { - case WM9081_SYSCLK_MCLK: - case WM9081_SYSCLK_FLL_MCLK: - wm9081->sysclk_source = clk_id; - wm9081->mclk_rate = freq; - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int wm9081_set_tdm_slot(struct snd_soc_dai *dai, - unsigned int mask, int slots) -{ - struct snd_soc_codec *codec = dai->codec; - unsigned int aif1 = wm9081_read(codec, WM9081_AUDIO_INTERFACE_1); - - aif1 &= ~(WM9081_AIFDAC_TDM_SLOT_MASK | WM9081_AIFDAC_TDM_MODE_MASK); - - if (slots < 1 || slots > 4) - return -EINVAL; - - aif1 |= (slots - 1) << WM9081_AIFDAC_TDM_MODE_SHIFT; - - switch (mask) { - case 1: - break; - case 2: - aif1 |= 0x10; - break; - case 4: - aif1 |= 0x20; - break; - case 8: - aif1 |= 0x30; - break; - default: - return -EINVAL; - } - - wm9081_write(codec, WM9081_AUDIO_INTERFACE_1, aif1); - - return 0; -} - -#define WM9081_RATES SNDRV_PCM_RATE_8000_96000 - -#define WM9081_FORMATS \ - (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops wm9081_dai_ops = { - .hw_params = wm9081_hw_params, - .set_sysclk = wm9081_set_sysclk, - .set_fmt = wm9081_set_dai_fmt, - .digital_mute = wm9081_digital_mute, - .set_tdm_slot = wm9081_set_tdm_slot, -}; - -/* We report two channels because the CODEC processes a stereo signal, even - * though it is only capable of handling a mono output. - */ -struct snd_soc_dai wm9081_dai = { - .name = "WM9081", - .playback = { - .stream_name = "HiFi Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM9081_RATES, - .formats = WM9081_FORMATS, - }, - .ops = &wm9081_dai_ops, -}; -EXPORT_SYMBOL_GPL(wm9081_dai); - - -static struct snd_soc_codec *wm9081_codec; - -static int wm9081_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec; - struct wm9081_priv *wm9081; - int ret = 0; - - if (wm9081_codec == NULL) { - dev_err(&pdev->dev, "Codec device not registered\n"); - return -ENODEV; - } - - socdev->card->codec = wm9081_codec; - codec = wm9081_codec; - wm9081 = codec->private_data; - - /* register pcms */ - ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); - if (ret < 0) { - dev_err(codec->dev, "failed to create pcms: %d\n", ret); - goto pcm_err; - } - - snd_soc_add_controls(codec, wm9081_snd_controls, - ARRAY_SIZE(wm9081_snd_controls)); - if (!wm9081->retune) { - dev_dbg(codec->dev, - "No ReTune Mobile data, using normal EQ\n"); - snd_soc_add_controls(codec, wm9081_eq_controls, - ARRAY_SIZE(wm9081_eq_controls)); - } - - snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, - ARRAY_SIZE(wm9081_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); - snd_soc_dapm_new_widgets(codec); - - ret = snd_soc_init_card(socdev); - if (ret < 0) { - dev_err(codec->dev, "failed to register card: %d\n", ret); - goto card_err; - } - - return ret; - -card_err: - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); -pcm_err: - return ret; -} - -static int wm9081_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - - snd_soc_free_pcms(socdev); - snd_soc_dapm_free(socdev); - - return 0; -} - -#ifdef CONFIG_PM -static int wm9081_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - - wm9081_set_bias_level(codec, SND_SOC_BIAS_OFF); - - return 0; -} - -static int wm9081_resume(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct snd_soc_codec *codec = socdev->card->codec; - u16 *reg_cache = codec->reg_cache; - int i; - - for (i = 0; i < codec->reg_cache_size; i++) { - if (i == WM9081_SOFTWARE_RESET) - continue; - - wm9081_write(codec, i, reg_cache[i]); - } - - wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - return 0; -} -#else -#define wm9081_suspend NULL -#define wm9081_resume NULL -#endif - -struct snd_soc_codec_device soc_codec_dev_wm9081 = { - .probe = wm9081_probe, - .remove = wm9081_remove, - .suspend = wm9081_suspend, - .resume = wm9081_resume, -}; -EXPORT_SYMBOL_GPL(soc_codec_dev_wm9081); - -static int wm9081_register(struct wm9081_priv *wm9081) -{ - struct snd_soc_codec *codec = &wm9081->codec; - int ret; - u16 reg; - - if (wm9081_codec) { - dev_err(codec->dev, "Another WM9081 is registered\n"); - ret = -EINVAL; - goto err; - } - - mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); - - codec->private_data = wm9081; - codec->name = "WM9081"; - codec->owner = THIS_MODULE; - codec->read = wm9081_read; - codec->write = wm9081_write; - codec->dai = &wm9081_dai; - codec->num_dai = 1; - codec->reg_cache_size = ARRAY_SIZE(wm9081->reg_cache); - codec->reg_cache = &wm9081->reg_cache; - codec->bias_level = SND_SOC_BIAS_OFF; - codec->set_bias_level = wm9081_set_bias_level; - - memcpy(codec->reg_cache, wm9081_reg_defaults, - sizeof(wm9081_reg_defaults)); - - reg = wm9081_read_hw(codec, WM9081_SOFTWARE_RESET); - if (reg != 0x9081) { - dev_err(codec->dev, "Device is not a WM9081: ID=0x%x\n", reg); - ret = -EINVAL; - goto err; - } - - ret = wm9081_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - return ret; - } - - wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - - /* Enable zero cross by default */ - reg = wm9081_read(codec, WM9081_ANALOGUE_LINEOUT); - wm9081_write(codec, WM9081_ANALOGUE_LINEOUT, reg | WM9081_LINEOUTZC); - reg = wm9081_read(codec, WM9081_ANALOGUE_SPEAKER_PGA); - wm9081_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, - reg | WM9081_SPKPGAZC); - - wm9081_dai.dev = codec->dev; - - wm9081_codec = codec; - - ret = snd_soc_register_codec(codec); - if (ret != 0) { - dev_err(codec->dev, "Failed to register codec: %d\n", ret); - return ret; - } - - ret = snd_soc_register_dai(&wm9081_dai); - if (ret != 0) { - dev_err(codec->dev, "Failed to register DAI: %d\n", ret); - snd_soc_unregister_codec(codec); - return ret; - } - - return 0; - -err: - kfree(wm9081); - return ret; -} - -static void wm9081_unregister(struct wm9081_priv *wm9081) -{ - wm9081_set_bias_level(&wm9081->codec, SND_SOC_BIAS_OFF); - snd_soc_unregister_dai(&wm9081_dai); - snd_soc_unregister_codec(&wm9081->codec); - kfree(wm9081); - wm9081_codec = NULL; -} - -static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm9081_priv *wm9081; - struct snd_soc_codec *codec; - - wm9081 = kzalloc(sizeof(struct wm9081_priv), GFP_KERNEL); - if (wm9081 == NULL) - return -ENOMEM; - - codec = &wm9081->codec; - codec->hw_write = (hw_write_t)i2c_master_send; - wm9081->retune = i2c->dev.platform_data; - - i2c_set_clientdata(i2c, wm9081); - codec->control_data = i2c; - - codec->dev = &i2c->dev; - - return wm9081_register(wm9081); -} - -static __devexit int wm9081_i2c_remove(struct i2c_client *client) -{ - struct wm9081_priv *wm9081 = i2c_get_clientdata(client); - wm9081_unregister(wm9081); - return 0; -} - -static const struct i2c_device_id wm9081_i2c_id[] = { - { "wm9081", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id); - -static struct i2c_driver wm9081_i2c_driver = { - .driver = { - .name = "wm9081", - .owner = THIS_MODULE, - }, - .probe = wm9081_i2c_probe, - .remove = __devexit_p(wm9081_i2c_remove), - .id_table = wm9081_i2c_id, -}; - -static int __init wm9081_modinit(void) -{ - int ret; - - ret = i2c_add_driver(&wm9081_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM9081 I2C driver: %d\n", - ret); - } - - return ret; -} -module_init(wm9081_modinit); - -static void __exit wm9081_exit(void) -{ - i2c_del_driver(&wm9081_i2c_driver); -} -module_exit(wm9081_exit); - - -MODULE_DESCRIPTION("ASoC WM9081 driver"); -MODULE_AUTHOR("Mark Brown "); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm9081.h b/trunk/sound/soc/codecs/wm9081.h deleted file mode 100644 index 42d3bc757021..000000000000 --- a/trunk/sound/soc/codecs/wm9081.h +++ /dev/null @@ -1,787 +0,0 @@ -#ifndef WM9081_H -#define WM9081_H - -/* - * wm9081.c -- WM9081 ALSA SoC Audio driver - * - * Author: Mark Brown - * - * Copyright 2009 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. - */ - -#include - -extern struct snd_soc_dai wm9081_dai; -extern struct snd_soc_codec_device soc_codec_dev_wm9081; - -/* - * SYSCLK sources - */ -#define WM9081_SYSCLK_MCLK 1 /* Use MCLK without FLL */ -#define WM9081_SYSCLK_FLL_MCLK 2 /* Use MCLK, enabling FLL if required */ - -/* - * Register values. - */ -#define WM9081_SOFTWARE_RESET 0x00 -#define WM9081_ANALOGUE_LINEOUT 0x02 -#define WM9081_ANALOGUE_SPEAKER_PGA 0x03 -#define WM9081_VMID_CONTROL 0x04 -#define WM9081_BIAS_CONTROL_1 0x05 -#define WM9081_ANALOGUE_MIXER 0x07 -#define WM9081_ANTI_POP_CONTROL 0x08 -#define WM9081_ANALOGUE_SPEAKER_1 0x09 -#define WM9081_ANALOGUE_SPEAKER_2 0x0A -#define WM9081_POWER_MANAGEMENT 0x0B -#define WM9081_CLOCK_CONTROL_1 0x0C -#define WM9081_CLOCK_CONTROL_2 0x0D -#define WM9081_CLOCK_CONTROL_3 0x0E -#define WM9081_FLL_CONTROL_1 0x10 -#define WM9081_FLL_CONTROL_2 0x11 -#define WM9081_FLL_CONTROL_3 0x12 -#define WM9081_FLL_CONTROL_4 0x13 -#define WM9081_FLL_CONTROL_5 0x14 -#define WM9081_AUDIO_INTERFACE_1 0x16 -#define WM9081_AUDIO_INTERFACE_2 0x17 -#define WM9081_AUDIO_INTERFACE_3 0x18 -#define WM9081_AUDIO_INTERFACE_4 0x19 -#define WM9081_INTERRUPT_STATUS 0x1A -#define WM9081_INTERRUPT_STATUS_MASK 0x1B -#define WM9081_INTERRUPT_POLARITY 0x1C -#define WM9081_INTERRUPT_CONTROL 0x1D -#define WM9081_DAC_DIGITAL_1 0x1E -#define WM9081_DAC_DIGITAL_2 0x1F -#define WM9081_DRC_1 0x20 -#define WM9081_DRC_2 0x21 -#define WM9081_DRC_3 0x22 -#define WM9081_DRC_4 0x23 -#define WM9081_WRITE_SEQUENCER_1 0x26 -#define WM9081_WRITE_SEQUENCER_2 0x27 -#define WM9081_MW_SLAVE_1 0x28 -#define WM9081_EQ_1 0x2A -#define WM9081_EQ_2 0x2B -#define WM9081_EQ_3 0x2C -#define WM9081_EQ_4 0x2D -#define WM9081_EQ_5 0x2E -#define WM9081_EQ_6 0x2F -#define WM9081_EQ_7 0x30 -#define WM9081_EQ_8 0x31 -#define WM9081_EQ_9 0x32 -#define WM9081_EQ_10 0x33 -#define WM9081_EQ_11 0x34 -#define WM9081_EQ_12 0x35 -#define WM9081_EQ_13 0x36 -#define WM9081_EQ_14 0x37 -#define WM9081_EQ_15 0x38 -#define WM9081_EQ_16 0x39 -#define WM9081_EQ_17 0x3A -#define WM9081_EQ_18 0x3B -#define WM9081_EQ_19 0x3C -#define WM9081_EQ_20 0x3D - -#define WM9081_REGISTER_COUNT 55 -#define WM9081_MAX_REGISTER 0x3D - -/* - * Field Definitions. - */ - -/* - * R0 (0x00) - Software Reset - */ -#define WM9081_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */ -#define WM9081_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */ -#define WM9081_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */ - -/* - * R2 (0x02) - Analogue Lineout - */ -#define WM9081_LINEOUT_MUTE 0x0080 /* LINEOUT_MUTE */ -#define WM9081_LINEOUT_MUTE_MASK 0x0080 /* LINEOUT_MUTE */ -#define WM9081_LINEOUT_MUTE_SHIFT 7 /* LINEOUT_MUTE */ -#define WM9081_LINEOUT_MUTE_WIDTH 1 /* LINEOUT_MUTE */ -#define WM9081_LINEOUTZC 0x0040 /* LINEOUTZC */ -#define WM9081_LINEOUTZC_MASK 0x0040 /* LINEOUTZC */ -#define WM9081_LINEOUTZC_SHIFT 6 /* LINEOUTZC */ -#define WM9081_LINEOUTZC_WIDTH 1 /* LINEOUTZC */ -#define WM9081_LINEOUT_VOL_MASK 0x003F /* LINEOUT_VOL - [5:0] */ -#define WM9081_LINEOUT_VOL_SHIFT 0 /* LINEOUT_VOL - [5:0] */ -#define WM9081_LINEOUT_VOL_WIDTH 6 /* LINEOUT_VOL - [5:0] */ - -/* - * R3 (0x03) - Analogue Speaker PGA - */ -#define WM9081_SPKPGA_MUTE 0x0080 /* SPKPGA_MUTE */ -#define WM9081_SPKPGA_MUTE_MASK 0x0080 /* SPKPGA_MUTE */ -#define WM9081_SPKPGA_MUTE_SHIFT 7 /* SPKPGA_MUTE */ -#define WM9081_SPKPGA_MUTE_WIDTH 1 /* SPKPGA_MUTE */ -#define WM9081_SPKPGAZC 0x0040 /* SPKPGAZC */ -#define WM9081_SPKPGAZC_MASK 0x0040 /* SPKPGAZC */ -#define WM9081_SPKPGAZC_SHIFT 6 /* SPKPGAZC */ -#define WM9081_SPKPGAZC_WIDTH 1 /* SPKPGAZC */ -#define WM9081_SPKPGA_VOL_MASK 0x003F /* SPKPGA_VOL - [5:0] */ -#define WM9081_SPKPGA_VOL_SHIFT 0 /* SPKPGA_VOL - [5:0] */ -#define WM9081_SPKPGA_VOL_WIDTH 6 /* SPKPGA_VOL - [5:0] */ - -/* - * R4 (0x04) - VMID Control - */ -#define WM9081_VMID_BUF_ENA 0x0020 /* VMID_BUF_ENA */ -#define WM9081_VMID_BUF_ENA_MASK 0x0020 /* VMID_BUF_ENA */ -#define WM9081_VMID_BUF_ENA_SHIFT 5 /* VMID_BUF_ENA */ -#define WM9081_VMID_BUF_ENA_WIDTH 1 /* VMID_BUF_ENA */ -#define WM9081_VMID_RAMP 0x0008 /* VMID_RAMP */ -#define WM9081_VMID_RAMP_MASK 0x0008 /* VMID_RAMP */ -#define WM9081_VMID_RAMP_SHIFT 3 /* VMID_RAMP */ -#define WM9081_VMID_RAMP_WIDTH 1 /* VMID_RAMP */ -#define WM9081_VMID_SEL_MASK 0x0006 /* VMID_SEL - [2:1] */ -#define WM9081_VMID_SEL_SHIFT 1 /* VMID_SEL - [2:1] */ -#define WM9081_VMID_SEL_WIDTH 2 /* VMID_SEL - [2:1] */ -#define WM9081_VMID_FAST_ST 0x0001 /* VMID_FAST_ST */ -#define WM9081_VMID_FAST_ST_MASK 0x0001 /* VMID_FAST_ST */ -#define WM9081_VMID_FAST_ST_SHIFT 0 /* VMID_FAST_ST */ -#define WM9081_VMID_FAST_ST_WIDTH 1 /* VMID_FAST_ST */ - -/* - * R5 (0x05) - Bias Control 1 - */ -#define WM9081_BIAS_SRC 0x0040 /* BIAS_SRC */ -#define WM9081_BIAS_SRC_MASK 0x0040 /* BIAS_SRC */ -#define WM9081_BIAS_SRC_SHIFT 6 /* BIAS_SRC */ -#define WM9081_BIAS_SRC_WIDTH 1 /* BIAS_SRC */ -#define WM9081_STBY_BIAS_LVL 0x0020 /* STBY_BIAS_LVL */ -#define WM9081_STBY_BIAS_LVL_MASK 0x0020 /* STBY_BIAS_LVL */ -#define WM9081_STBY_BIAS_LVL_SHIFT 5 /* STBY_BIAS_LVL */ -#define WM9081_STBY_BIAS_LVL_WIDTH 1 /* STBY_BIAS_LVL */ -#define WM9081_STBY_BIAS_ENA 0x0010 /* STBY_BIAS_ENA */ -#define WM9081_STBY_BIAS_ENA_MASK 0x0010 /* STBY_BIAS_ENA */ -#define WM9081_STBY_BIAS_ENA_SHIFT 4 /* STBY_BIAS_ENA */ -#define WM9081_STBY_BIAS_ENA_WIDTH 1 /* STBY_BIAS_ENA */ -#define WM9081_BIAS_LVL_MASK 0x000C /* BIAS_LVL - [3:2] */ -#define WM9081_BIAS_LVL_SHIFT 2 /* BIAS_LVL - [3:2] */ -#define WM9081_BIAS_LVL_WIDTH 2 /* BIAS_LVL - [3:2] */ -#define WM9081_BIAS_ENA 0x0002 /* BIAS_ENA */ -#define WM9081_BIAS_ENA_MASK 0x0002 /* BIAS_ENA */ -#define WM9081_BIAS_ENA_SHIFT 1 /* BIAS_ENA */ -#define WM9081_BIAS_ENA_WIDTH 1 /* BIAS_ENA */ -#define WM9081_STARTUP_BIAS_ENA 0x0001 /* STARTUP_BIAS_ENA */ -#define WM9081_STARTUP_BIAS_ENA_MASK 0x0001 /* STARTUP_BIAS_ENA */ -#define WM9081_STARTUP_BIAS_ENA_SHIFT 0 /* STARTUP_BIAS_ENA */ -#define WM9081_STARTUP_BIAS_ENA_WIDTH 1 /* STARTUP_BIAS_ENA */ - -/* - * R7 (0x07) - Analogue Mixer - */ -#define WM9081_DAC_SEL 0x0010 /* DAC_SEL */ -#define WM9081_DAC_SEL_MASK 0x0010 /* DAC_SEL */ -#define WM9081_DAC_SEL_SHIFT 4 /* DAC_SEL */ -#define WM9081_DAC_SEL_WIDTH 1 /* DAC_SEL */ -#define WM9081_IN2_VOL 0x0008 /* IN2_VOL */ -#define WM9081_IN2_VOL_MASK 0x0008 /* IN2_VOL */ -#define WM9081_IN2_VOL_SHIFT 3 /* IN2_VOL */ -#define WM9081_IN2_VOL_WIDTH 1 /* IN2_VOL */ -#define WM9081_IN2_ENA 0x0004 /* IN2_ENA */ -#define WM9081_IN2_ENA_MASK 0x0004 /* IN2_ENA */ -#define WM9081_IN2_ENA_SHIFT 2 /* IN2_ENA */ -#define WM9081_IN2_ENA_WIDTH 1 /* IN2_ENA */ -#define WM9081_IN1_VOL 0x0002 /* IN1_VOL */ -#define WM9081_IN1_VOL_MASK 0x0002 /* IN1_VOL */ -#define WM9081_IN1_VOL_SHIFT 1 /* IN1_VOL */ -#define WM9081_IN1_VOL_WIDTH 1 /* IN1_VOL */ -#define WM9081_IN1_ENA 0x0001 /* IN1_ENA */ -#define WM9081_IN1_ENA_MASK 0x0001 /* IN1_ENA */ -#define WM9081_IN1_ENA_SHIFT 0 /* IN1_ENA */ -#define WM9081_IN1_ENA_WIDTH 1 /* IN1_ENA */ - -/* - * R8 (0x08) - Anti Pop Control - */ -#define WM9081_LINEOUT_DISCH 0x0004 /* LINEOUT_DISCH */ -#define WM9081_LINEOUT_DISCH_MASK 0x0004 /* LINEOUT_DISCH */ -#define WM9081_LINEOUT_DISCH_SHIFT 2 /* LINEOUT_DISCH */ -#define WM9081_LINEOUT_DISCH_WIDTH 1 /* LINEOUT_DISCH */ -#define WM9081_LINEOUT_VROI 0x0002 /* LINEOUT_VROI */ -#define WM9081_LINEOUT_VROI_MASK 0x0002 /* LINEOUT_VROI */ -#define WM9081_LINEOUT_VROI_SHIFT 1 /* LINEOUT_VROI */ -#define WM9081_LINEOUT_VROI_WIDTH 1 /* LINEOUT_VROI */ -#define WM9081_LINEOUT_CLAMP 0x0001 /* LINEOUT_CLAMP */ -#define WM9081_LINEOUT_CLAMP_MASK 0x0001 /* LINEOUT_CLAMP */ -#define WM9081_LINEOUT_CLAMP_SHIFT 0 /* LINEOUT_CLAMP */ -#define WM9081_LINEOUT_CLAMP_WIDTH 1 /* LINEOUT_CLAMP */ - -/* - * R9 (0x09) - Analogue Speaker 1 - */ -#define WM9081_SPK_DCGAIN_MASK 0x0038 /* SPK_DCGAIN - [5:3] */ -#define WM9081_SPK_DCGAIN_SHIFT 3 /* SPK_DCGAIN - [5:3] */ -#define WM9081_SPK_DCGAIN_WIDTH 3 /* SPK_DCGAIN - [5:3] */ -#define WM9081_SPK_ACGAIN_MASK 0x0007 /* SPK_ACGAIN - [2:0] */ -#define WM9081_SPK_ACGAIN_SHIFT 0 /* SPK_ACGAIN - [2:0] */ -#define WM9081_SPK_ACGAIN_WIDTH 3 /* SPK_ACGAIN - [2:0] */ - -/* - * R10 (0x0A) - Analogue Speaker 2 - */ -#define WM9081_SPK_MODE 0x0040 /* SPK_MODE */ -#define WM9081_SPK_MODE_MASK 0x0040 /* SPK_MODE */ -#define WM9081_SPK_MODE_SHIFT 6 /* SPK_MODE */ -#define WM9081_SPK_MODE_WIDTH 1 /* SPK_MODE */ -#define WM9081_SPK_INV_MUTE 0x0010 /* SPK_INV_MUTE */ -#define WM9081_SPK_INV_MUTE_MASK 0x0010 /* SPK_INV_MUTE */ -#define WM9081_SPK_INV_MUTE_SHIFT 4 /* SPK_INV_MUTE */ -#define WM9081_SPK_INV_MUTE_WIDTH 1 /* SPK_INV_MUTE */ -#define WM9081_OUT_SPK_CTRL 0x0008 /* OUT_SPK_CTRL */ -#define WM9081_OUT_SPK_CTRL_MASK 0x0008 /* OUT_SPK_CTRL */ -#define WM9081_OUT_SPK_CTRL_SHIFT 3 /* OUT_SPK_CTRL */ -#define WM9081_OUT_SPK_CTRL_WIDTH 1 /* OUT_SPK_CTRL */ - -/* - * R11 (0x0B) - Power Management - */ -#define WM9081_TSHUT_ENA 0x0100 /* TSHUT_ENA */ -#define WM9081_TSHUT_ENA_MASK 0x0100 /* TSHUT_ENA */ -#define WM9081_TSHUT_ENA_SHIFT 8 /* TSHUT_ENA */ -#define WM9081_TSHUT_ENA_WIDTH 1 /* TSHUT_ENA */ -#define WM9081_TSENSE_ENA 0x0080 /* TSENSE_ENA */ -#define WM9081_TSENSE_ENA_MASK 0x0080 /* TSENSE_ENA */ -#define WM9081_TSENSE_ENA_SHIFT 7 /* TSENSE_ENA */ -#define WM9081_TSENSE_ENA_WIDTH 1 /* TSENSE_ENA */ -#define WM9081_TEMP_SHUT 0x0040 /* TEMP_SHUT */ -#define WM9081_TEMP_SHUT_MASK 0x0040 /* TEMP_SHUT */ -#define WM9081_TEMP_SHUT_SHIFT 6 /* TEMP_SHUT */ -#define WM9081_TEMP_SHUT_WIDTH 1 /* TEMP_SHUT */ -#define WM9081_LINEOUT_ENA 0x0010 /* LINEOUT_ENA */ -#define WM9081_LINEOUT_ENA_MASK 0x0010 /* LINEOUT_ENA */ -#define WM9081_LINEOUT_ENA_SHIFT 4 /* LINEOUT_ENA */ -#define WM9081_LINEOUT_ENA_WIDTH 1 /* LINEOUT_ENA */ -#define WM9081_SPKPGA_ENA 0x0004 /* SPKPGA_ENA */ -#define WM9081_SPKPGA_ENA_MASK 0x0004 /* SPKPGA_ENA */ -#define WM9081_SPKPGA_ENA_SHIFT 2 /* SPKPGA_ENA */ -#define WM9081_SPKPGA_ENA_WIDTH 1 /* SPKPGA_ENA */ -#define WM9081_SPK_ENA 0x0002 /* SPK_ENA */ -#define WM9081_SPK_ENA_MASK 0x0002 /* SPK_ENA */ -#define WM9081_SPK_ENA_SHIFT 1 /* SPK_ENA */ -#define WM9081_SPK_ENA_WIDTH 1 /* SPK_ENA */ -#define WM9081_DAC_ENA 0x0001 /* DAC_ENA */ -#define WM9081_DAC_ENA_MASK 0x0001 /* DAC_ENA */ -#define WM9081_DAC_ENA_SHIFT 0 /* DAC_ENA */ -#define WM9081_DAC_ENA_WIDTH 1 /* DAC_ENA */ - -/* - * R12 (0x0C) - Clock Control 1 - */ -#define WM9081_CLK_OP_DIV_MASK 0x1C00 /* CLK_OP_DIV - [12:10] */ -#define WM9081_CLK_OP_DIV_SHIFT 10 /* CLK_OP_DIV - [12:10] */ -#define WM9081_CLK_OP_DIV_WIDTH 3 /* CLK_OP_DIV - [12:10] */ -#define WM9081_CLK_TO_DIV_MASK 0x0300 /* CLK_TO_DIV - [9:8] */ -#define WM9081_CLK_TO_DIV_SHIFT 8 /* CLK_TO_DIV - [9:8] */ -#define WM9081_CLK_TO_DIV_WIDTH 2 /* CLK_TO_DIV - [9:8] */ -#define WM9081_MCLKDIV2 0x0080 /* MCLKDIV2 */ -#define WM9081_MCLKDIV2_MASK 0x0080 /* MCLKDIV2 */ -#define WM9081_MCLKDIV2_SHIFT 7 /* MCLKDIV2 */ -#define WM9081_MCLKDIV2_WIDTH 1 /* MCLKDIV2 */ - -/* - * R13 (0x0D) - Clock Control 2 - */ -#define WM9081_CLK_SYS_RATE_MASK 0x00F0 /* CLK_SYS_RATE - [7:4] */ -#define WM9081_CLK_SYS_RATE_SHIFT 4 /* CLK_SYS_RATE - [7:4] */ -#define WM9081_CLK_SYS_RATE_WIDTH 4 /* CLK_SYS_RATE - [7:4] */ -#define WM9081_SAMPLE_RATE_MASK 0x000F /* SAMPLE_RATE - [3:0] */ -#define WM9081_SAMPLE_RATE_SHIFT 0 /* SAMPLE_RATE - [3:0] */ -#define WM9081_SAMPLE_RATE_WIDTH 4 /* SAMPLE_RATE - [3:0] */ - -/* - * R14 (0x0E) - Clock Control 3 - */ -#define WM9081_CLK_SRC_SEL 0x2000 /* CLK_SRC_SEL */ -#define WM9081_CLK_SRC_SEL_MASK 0x2000 /* CLK_SRC_SEL */ -#define WM9081_CLK_SRC_SEL_SHIFT 13 /* CLK_SRC_SEL */ -#define WM9081_CLK_SRC_SEL_WIDTH 1 /* CLK_SRC_SEL */ -#define WM9081_CLK_OP_ENA 0x0020 /* CLK_OP_ENA */ -#define WM9081_CLK_OP_ENA_MASK 0x0020 /* CLK_OP_ENA */ -#define WM9081_CLK_OP_ENA_SHIFT 5 /* CLK_OP_ENA */ -#define WM9081_CLK_OP_ENA_WIDTH 1 /* CLK_OP_ENA */ -#define WM9081_CLK_TO_ENA 0x0004 /* CLK_TO_ENA */ -#define WM9081_CLK_TO_ENA_MASK 0x0004 /* CLK_TO_ENA */ -#define WM9081_CLK_TO_ENA_SHIFT 2 /* CLK_TO_ENA */ -#define WM9081_CLK_TO_ENA_WIDTH 1 /* CLK_TO_ENA */ -#define WM9081_CLK_DSP_ENA 0x0002 /* CLK_DSP_ENA */ -#define WM9081_CLK_DSP_ENA_MASK 0x0002 /* CLK_DSP_ENA */ -#define WM9081_CLK_DSP_ENA_SHIFT 1 /* CLK_DSP_ENA */ -#define WM9081_CLK_DSP_ENA_WIDTH 1 /* CLK_DSP_ENA */ -#define WM9081_CLK_SYS_ENA 0x0001 /* CLK_SYS_ENA */ -#define WM9081_CLK_SYS_ENA_MASK 0x0001 /* CLK_SYS_ENA */ -#define WM9081_CLK_SYS_ENA_SHIFT 0 /* CLK_SYS_ENA */ -#define WM9081_CLK_SYS_ENA_WIDTH 1 /* CLK_SYS_ENA */ - -/* - * R16 (0x10) - FLL Control 1 - */ -#define WM9081_FLL_HOLD 0x0008 /* FLL_HOLD */ -#define WM9081_FLL_HOLD_MASK 0x0008 /* FLL_HOLD */ -#define WM9081_FLL_HOLD_SHIFT 3 /* FLL_HOLD */ -#define WM9081_FLL_HOLD_WIDTH 1 /* FLL_HOLD */ -#define WM9081_FLL_FRAC 0x0004 /* FLL_FRAC */ -#define WM9081_FLL_FRAC_MASK 0x0004 /* FLL_FRAC */ -#define WM9081_FLL_FRAC_SHIFT 2 /* FLL_FRAC */ -#define WM9081_FLL_FRAC_WIDTH 1 /* FLL_FRAC */ -#define WM9081_FLL_ENA 0x0001 /* FLL_ENA */ -#define WM9081_FLL_ENA_MASK 0x0001 /* FLL_ENA */ -#define WM9081_FLL_ENA_SHIFT 0 /* FLL_ENA */ -#define WM9081_FLL_ENA_WIDTH 1 /* FLL_ENA */ - -/* - * R17 (0x11) - FLL Control 2 - */ -#define WM9081_FLL_OUTDIV_MASK 0x0700 /* FLL_OUTDIV - [10:8] */ -#define WM9081_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [10:8] */ -#define WM9081_FLL_OUTDIV_WIDTH 3 /* FLL_OUTDIV - [10:8] */ -#define WM9081_FLL_CTRL_RATE_MASK 0x0070 /* FLL_CTRL_RATE - [6:4] */ -#define WM9081_FLL_CTRL_RATE_SHIFT 4 /* FLL_CTRL_RATE - [6:4] */ -#define WM9081_FLL_CTRL_RATE_WIDTH 3 /* FLL_CTRL_RATE - [6:4] */ -#define WM9081_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ -#define WM9081_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ -#define WM9081_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ - -/* - * R18 (0x12) - FLL Control 3 - */ -#define WM9081_FLL_K_MASK 0xFFFF /* FLL_K - [15:0] */ -#define WM9081_FLL_K_SHIFT 0 /* FLL_K - [15:0] */ -#define WM9081_FLL_K_WIDTH 16 /* FLL_K - [15:0] */ - -/* - * R19 (0x13) - FLL Control 4 - */ -#define WM9081_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */ -#define WM9081_FLL_N_SHIFT 5 /* FLL_N - [14:5] */ -#define WM9081_FLL_N_WIDTH 10 /* FLL_N - [14:5] */ -#define WM9081_FLL_GAIN_MASK 0x000F /* FLL_GAIN - [3:0] */ -#define WM9081_FLL_GAIN_SHIFT 0 /* FLL_GAIN - [3:0] */ -#define WM9081_FLL_GAIN_WIDTH 4 /* FLL_GAIN - [3:0] */ - -/* - * R20 (0x14) - FLL Control 5 - */ -#define WM9081_FLL_CLK_REF_DIV_MASK 0x0018 /* FLL_CLK_REF_DIV - [4:3] */ -#define WM9081_FLL_CLK_REF_DIV_SHIFT 3 /* FLL_CLK_REF_DIV - [4:3] */ -#define WM9081_FLL_CLK_REF_DIV_WIDTH 2 /* FLL_CLK_REF_DIV - [4:3] */ -#define WM9081_FLL_CLK_SRC_MASK 0x0003 /* FLL_CLK_SRC - [1:0] */ -#define WM9081_FLL_CLK_SRC_SHIFT 0 /* FLL_CLK_SRC - [1:0] */ -#define WM9081_FLL_CLK_SRC_WIDTH 2 /* FLL_CLK_SRC - [1:0] */ - -/* - * R22 (0x16) - Audio Interface 1 - */ -#define WM9081_AIFDAC_CHAN 0x0040 /* AIFDAC_CHAN */ -#define WM9081_AIFDAC_CHAN_MASK 0x0040 /* AIFDAC_CHAN */ -#define WM9081_AIFDAC_CHAN_SHIFT 6 /* AIFDAC_CHAN */ -#define WM9081_AIFDAC_CHAN_WIDTH 1 /* AIFDAC_CHAN */ -#define WM9081_AIFDAC_TDM_SLOT_MASK 0x0030 /* AIFDAC_TDM_SLOT - [5:4] */ -#define WM9081_AIFDAC_TDM_SLOT_SHIFT 4 /* AIFDAC_TDM_SLOT - [5:4] */ -#define WM9081_AIFDAC_TDM_SLOT_WIDTH 2 /* AIFDAC_TDM_SLOT - [5:4] */ -#define WM9081_AIFDAC_TDM_MODE_MASK 0x000C /* AIFDAC_TDM_MODE - [3:2] */ -#define WM9081_AIFDAC_TDM_MODE_SHIFT 2 /* AIFDAC_TDM_MODE - [3:2] */ -#define WM9081_AIFDAC_TDM_MODE_WIDTH 2 /* AIFDAC_TDM_MODE - [3:2] */ -#define WM9081_DAC_COMP 0x0002 /* DAC_COMP */ -#define WM9081_DAC_COMP_MASK 0x0002 /* DAC_COMP */ -#define WM9081_DAC_COMP_SHIFT 1 /* DAC_COMP */ -#define WM9081_DAC_COMP_WIDTH 1 /* DAC_COMP */ -#define WM9081_DAC_COMPMODE 0x0001 /* DAC_COMPMODE */ -#define WM9081_DAC_COMPMODE_MASK 0x0001 /* DAC_COMPMODE */ -#define WM9081_DAC_COMPMODE_SHIFT 0 /* DAC_COMPMODE */ -#define WM9081_DAC_COMPMODE_WIDTH 1 /* DAC_COMPMODE */ - -/* - * R23 (0x17) - Audio Interface 2 - */ -#define WM9081_AIF_TRIS 0x0200 /* AIF_TRIS */ -#define WM9081_AIF_TRIS_MASK 0x0200 /* AIF_TRIS */ -#define WM9081_AIF_TRIS_SHIFT 9 /* AIF_TRIS */ -#define WM9081_AIF_TRIS_WIDTH 1 /* AIF_TRIS */ -#define WM9081_DAC_DAT_INV 0x0100 /* DAC_DAT_INV */ -#define WM9081_DAC_DAT_INV_MASK 0x0100 /* DAC_DAT_INV */ -#define WM9081_DAC_DAT_INV_SHIFT 8 /* DAC_DAT_INV */ -#define WM9081_DAC_DAT_INV_WIDTH 1 /* DAC_DAT_INV */ -#define WM9081_AIF_BCLK_INV 0x0080 /* AIF_BCLK_INV */ -#define WM9081_AIF_BCLK_INV_MASK 0x0080 /* AIF_BCLK_INV */ -#define WM9081_AIF_BCLK_INV_SHIFT 7 /* AIF_BCLK_INV */ -#define WM9081_AIF_BCLK_INV_WIDTH 1 /* AIF_BCLK_INV */ -#define WM9081_BCLK_DIR 0x0040 /* BCLK_DIR */ -#define WM9081_BCLK_DIR_MASK 0x0040 /* BCLK_DIR */ -#define WM9081_BCLK_DIR_SHIFT 6 /* BCLK_DIR */ -#define WM9081_BCLK_DIR_WIDTH 1 /* BCLK_DIR */ -#define WM9081_LRCLK_DIR 0x0020 /* LRCLK_DIR */ -#define WM9081_LRCLK_DIR_MASK 0x0020 /* LRCLK_DIR */ -#define WM9081_LRCLK_DIR_SHIFT 5 /* LRCLK_DIR */ -#define WM9081_LRCLK_DIR_WIDTH 1 /* LRCLK_DIR */ -#define WM9081_AIF_LRCLK_INV 0x0010 /* AIF_LRCLK_INV */ -#define WM9081_AIF_LRCLK_INV_MASK 0x0010 /* AIF_LRCLK_INV */ -#define WM9081_AIF_LRCLK_INV_SHIFT 4 /* AIF_LRCLK_INV */ -#define WM9081_AIF_LRCLK_INV_WIDTH 1 /* AIF_LRCLK_INV */ -#define WM9081_AIF_WL_MASK 0x000C /* AIF_WL - [3:2] */ -#define WM9081_AIF_WL_SHIFT 2 /* AIF_WL - [3:2] */ -#define WM9081_AIF_WL_WIDTH 2 /* AIF_WL - [3:2] */ -#define WM9081_AIF_FMT_MASK 0x0003 /* AIF_FMT - [1:0] */ -#define WM9081_AIF_FMT_SHIFT 0 /* AIF_FMT - [1:0] */ -#define WM9081_AIF_FMT_WIDTH 2 /* AIF_FMT - [1:0] */ - -/* - * R24 (0x18) - Audio Interface 3 - */ -#define WM9081_BCLK_DIV_MASK 0x001F /* BCLK_DIV - [4:0] */ -#define WM9081_BCLK_DIV_SHIFT 0 /* BCLK_DIV - [4:0] */ -#define WM9081_BCLK_DIV_WIDTH 5 /* BCLK_DIV - [4:0] */ - -/* - * R25 (0x19) - Audio Interface 4 - */ -#define WM9081_LRCLK_RATE_MASK 0x07FF /* LRCLK_RATE - [10:0] */ -#define WM9081_LRCLK_RATE_SHIFT 0 /* LRCLK_RATE - [10:0] */ -#define WM9081_LRCLK_RATE_WIDTH 11 /* LRCLK_RATE - [10:0] */ - -/* - * R26 (0x1A) - Interrupt Status - */ -#define WM9081_WSEQ_BUSY_EINT 0x0004 /* WSEQ_BUSY_EINT */ -#define WM9081_WSEQ_BUSY_EINT_MASK 0x0004 /* WSEQ_BUSY_EINT */ -#define WM9081_WSEQ_BUSY_EINT_SHIFT 2 /* WSEQ_BUSY_EINT */ -#define WM9081_WSEQ_BUSY_EINT_WIDTH 1 /* WSEQ_BUSY_EINT */ -#define WM9081_TSHUT_EINT 0x0001 /* TSHUT_EINT */ -#define WM9081_TSHUT_EINT_MASK 0x0001 /* TSHUT_EINT */ -#define WM9081_TSHUT_EINT_SHIFT 0 /* TSHUT_EINT */ -#define WM9081_TSHUT_EINT_WIDTH 1 /* TSHUT_EINT */ - -/* - * R27 (0x1B) - Interrupt Status Mask - */ -#define WM9081_IM_WSEQ_BUSY_EINT 0x0004 /* IM_WSEQ_BUSY_EINT */ -#define WM9081_IM_WSEQ_BUSY_EINT_MASK 0x0004 /* IM_WSEQ_BUSY_EINT */ -#define WM9081_IM_WSEQ_BUSY_EINT_SHIFT 2 /* IM_WSEQ_BUSY_EINT */ -#define WM9081_IM_WSEQ_BUSY_EINT_WIDTH 1 /* IM_WSEQ_BUSY_EINT */ -#define WM9081_IM_TSHUT_EINT 0x0001 /* IM_TSHUT_EINT */ -#define WM9081_IM_TSHUT_EINT_MASK 0x0001 /* IM_TSHUT_EINT */ -#define WM9081_IM_TSHUT_EINT_SHIFT 0 /* IM_TSHUT_EINT */ -#define WM9081_IM_TSHUT_EINT_WIDTH 1 /* IM_TSHUT_EINT */ - -/* - * R28 (0x1C) - Interrupt Polarity - */ -#define WM9081_TSHUT_INV 0x0001 /* TSHUT_INV */ -#define WM9081_TSHUT_INV_MASK 0x0001 /* TSHUT_INV */ -#define WM9081_TSHUT_INV_SHIFT 0 /* TSHUT_INV */ -#define WM9081_TSHUT_INV_WIDTH 1 /* TSHUT_INV */ - -/* - * R29 (0x1D) - Interrupt Control - */ -#define WM9081_IRQ_POL 0x8000 /* IRQ_POL */ -#define WM9081_IRQ_POL_MASK 0x8000 /* IRQ_POL */ -#define WM9081_IRQ_POL_SHIFT 15 /* IRQ_POL */ -#define WM9081_IRQ_POL_WIDTH 1 /* IRQ_POL */ -#define WM9081_IRQ_OP_CTRL 0x0001 /* IRQ_OP_CTRL */ -#define WM9081_IRQ_OP_CTRL_MASK 0x0001 /* IRQ_OP_CTRL */ -#define WM9081_IRQ_OP_CTRL_SHIFT 0 /* IRQ_OP_CTRL */ -#define WM9081_IRQ_OP_CTRL_WIDTH 1 /* IRQ_OP_CTRL */ - -/* - * R30 (0x1E) - DAC Digital 1 - */ -#define WM9081_DAC_VOL_MASK 0x00FF /* DAC_VOL - [7:0] */ -#define WM9081_DAC_VOL_SHIFT 0 /* DAC_VOL - [7:0] */ -#define WM9081_DAC_VOL_WIDTH 8 /* DAC_VOL - [7:0] */ - -/* - * R31 (0x1F) - DAC Digital 2 - */ -#define WM9081_DAC_MUTERATE 0x0400 /* DAC_MUTERATE */ -#define WM9081_DAC_MUTERATE_MASK 0x0400 /* DAC_MUTERATE */ -#define WM9081_DAC_MUTERATE_SHIFT 10 /* DAC_MUTERATE */ -#define WM9081_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ -#define WM9081_DAC_MUTEMODE 0x0200 /* DAC_MUTEMODE */ -#define WM9081_DAC_MUTEMODE_MASK 0x0200 /* DAC_MUTEMODE */ -#define WM9081_DAC_MUTEMODE_SHIFT 9 /* DAC_MUTEMODE */ -#define WM9081_DAC_MUTEMODE_WIDTH 1 /* DAC_MUTEMODE */ -#define WM9081_DAC_MUTE 0x0008 /* DAC_MUTE */ -#define WM9081_DAC_MUTE_MASK 0x0008 /* DAC_MUTE */ -#define WM9081_DAC_MUTE_SHIFT 3 /* DAC_MUTE */ -#define WM9081_DAC_MUTE_WIDTH 1 /* DAC_MUTE */ -#define WM9081_DEEMPH_MASK 0x0006 /* DEEMPH - [2:1] */ -#define WM9081_DEEMPH_SHIFT 1 /* DEEMPH - [2:1] */ -#define WM9081_DEEMPH_WIDTH 2 /* DEEMPH - [2:1] */ - -/* - * R32 (0x20) - DRC 1 - */ -#define WM9081_DRC_ENA 0x8000 /* DRC_ENA */ -#define WM9081_DRC_ENA_MASK 0x8000 /* DRC_ENA */ -#define WM9081_DRC_ENA_SHIFT 15 /* DRC_ENA */ -#define WM9081_DRC_ENA_WIDTH 1 /* DRC_ENA */ -#define WM9081_DRC_STARTUP_GAIN_MASK 0x07C0 /* DRC_STARTUP_GAIN - [10:6] */ -#define WM9081_DRC_STARTUP_GAIN_SHIFT 6 /* DRC_STARTUP_GAIN - [10:6] */ -#define WM9081_DRC_STARTUP_GAIN_WIDTH 5 /* DRC_STARTUP_GAIN - [10:6] */ -#define WM9081_DRC_FF_DLY 0x0020 /* DRC_FF_DLY */ -#define WM9081_DRC_FF_DLY_MASK 0x0020 /* DRC_FF_DLY */ -#define WM9081_DRC_FF_DLY_SHIFT 5 /* DRC_FF_DLY */ -#define WM9081_DRC_FF_DLY_WIDTH 1 /* DRC_FF_DLY */ -#define WM9081_DRC_QR 0x0004 /* DRC_QR */ -#define WM9081_DRC_QR_MASK 0x0004 /* DRC_QR */ -#define WM9081_DRC_QR_SHIFT 2 /* DRC_QR */ -#define WM9081_DRC_QR_WIDTH 1 /* DRC_QR */ -#define WM9081_DRC_ANTICLIP 0x0002 /* DRC_ANTICLIP */ -#define WM9081_DRC_ANTICLIP_MASK 0x0002 /* DRC_ANTICLIP */ -#define WM9081_DRC_ANTICLIP_SHIFT 1 /* DRC_ANTICLIP */ -#define WM9081_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */ - -/* - * R33 (0x21) - DRC 2 - */ -#define WM9081_DRC_ATK_MASK 0xF000 /* DRC_ATK - [15:12] */ -#define WM9081_DRC_ATK_SHIFT 12 /* DRC_ATK - [15:12] */ -#define WM9081_DRC_ATK_WIDTH 4 /* DRC_ATK - [15:12] */ -#define WM9081_DRC_DCY_MASK 0x0F00 /* DRC_DCY - [11:8] */ -#define WM9081_DRC_DCY_SHIFT 8 /* DRC_DCY - [11:8] */ -#define WM9081_DRC_DCY_WIDTH 4 /* DRC_DCY - [11:8] */ -#define WM9081_DRC_QR_THR_MASK 0x00C0 /* DRC_QR_THR - [7:6] */ -#define WM9081_DRC_QR_THR_SHIFT 6 /* DRC_QR_THR - [7:6] */ -#define WM9081_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [7:6] */ -#define WM9081_DRC_QR_DCY_MASK 0x0030 /* DRC_QR_DCY - [5:4] */ -#define WM9081_DRC_QR_DCY_SHIFT 4 /* DRC_QR_DCY - [5:4] */ -#define WM9081_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [5:4] */ -#define WM9081_DRC_MINGAIN_MASK 0x000C /* DRC_MINGAIN - [3:2] */ -#define WM9081_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [3:2] */ -#define WM9081_DRC_MINGAIN_WIDTH 2 /* DRC_MINGAIN - [3:2] */ -#define WM9081_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */ -#define WM9081_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */ -#define WM9081_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */ - -/* - * R34 (0x22) - DRC 3 - */ -#define WM9081_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */ -#define WM9081_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */ -#define WM9081_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */ -#define WM9081_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */ -#define WM9081_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */ -#define WM9081_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */ - -/* - * R35 (0x23) - DRC 4 - */ -#define WM9081_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */ -#define WM9081_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */ -#define WM9081_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */ -#define WM9081_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */ -#define WM9081_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */ -#define WM9081_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */ - -/* - * R38 (0x26) - Write Sequencer 1 - */ -#define WM9081_WSEQ_ENA 0x8000 /* WSEQ_ENA */ -#define WM9081_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ -#define WM9081_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ -#define WM9081_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ -#define WM9081_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ -#define WM9081_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ -#define WM9081_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ -#define WM9081_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ -#define WM9081_WSEQ_START 0x0100 /* WSEQ_START */ -#define WM9081_WSEQ_START_MASK 0x0100 /* WSEQ_START */ -#define WM9081_WSEQ_START_SHIFT 8 /* WSEQ_START */ -#define WM9081_WSEQ_START_WIDTH 1 /* WSEQ_START */ -#define WM9081_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ -#define WM9081_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ -#define WM9081_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ - -/* - * R39 (0x27) - Write Sequencer 2 - */ -#define WM9081_WSEQ_CURRENT_INDEX_MASK 0x07F0 /* WSEQ_CURRENT_INDEX - [10:4] */ -#define WM9081_WSEQ_CURRENT_INDEX_SHIFT 4 /* WSEQ_CURRENT_INDEX - [10:4] */ -#define WM9081_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [10:4] */ -#define WM9081_WSEQ_BUSY 0x0001 /* WSEQ_BUSY */ -#define WM9081_WSEQ_BUSY_MASK 0x0001 /* WSEQ_BUSY */ -#define WM9081_WSEQ_BUSY_SHIFT 0 /* WSEQ_BUSY */ -#define WM9081_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ - -/* - * R40 (0x28) - MW Slave 1 - */ -#define WM9081_SPI_CFG 0x0020 /* SPI_CFG */ -#define WM9081_SPI_CFG_MASK 0x0020 /* SPI_CFG */ -#define WM9081_SPI_CFG_SHIFT 5 /* SPI_CFG */ -#define WM9081_SPI_CFG_WIDTH 1 /* SPI_CFG */ -#define WM9081_SPI_4WIRE 0x0010 /* SPI_4WIRE */ -#define WM9081_SPI_4WIRE_MASK 0x0010 /* SPI_4WIRE */ -#define WM9081_SPI_4WIRE_SHIFT 4 /* SPI_4WIRE */ -#define WM9081_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */ -#define WM9081_ARA_ENA 0x0008 /* ARA_ENA */ -#define WM9081_ARA_ENA_MASK 0x0008 /* ARA_ENA */ -#define WM9081_ARA_ENA_SHIFT 3 /* ARA_ENA */ -#define WM9081_ARA_ENA_WIDTH 1 /* ARA_ENA */ -#define WM9081_AUTO_INC 0x0002 /* AUTO_INC */ -#define WM9081_AUTO_INC_MASK 0x0002 /* AUTO_INC */ -#define WM9081_AUTO_INC_SHIFT 1 /* AUTO_INC */ -#define WM9081_AUTO_INC_WIDTH 1 /* AUTO_INC */ - -/* - * R42 (0x2A) - EQ 1 - */ -#define WM9081_EQ_B1_GAIN_MASK 0xF800 /* EQ_B1_GAIN - [15:11] */ -#define WM9081_EQ_B1_GAIN_SHIFT 11 /* EQ_B1_GAIN - [15:11] */ -#define WM9081_EQ_B1_GAIN_WIDTH 5 /* EQ_B1_GAIN - [15:11] */ -#define WM9081_EQ_B2_GAIN_MASK 0x07C0 /* EQ_B2_GAIN - [10:6] */ -#define WM9081_EQ_B2_GAIN_SHIFT 6 /* EQ_B2_GAIN - [10:6] */ -#define WM9081_EQ_B2_GAIN_WIDTH 5 /* EQ_B2_GAIN - [10:6] */ -#define WM9081_EQ_B4_GAIN_MASK 0x003E /* EQ_B4_GAIN - [5:1] */ -#define WM9081_EQ_B4_GAIN_SHIFT 1 /* EQ_B4_GAIN - [5:1] */ -#define WM9081_EQ_B4_GAIN_WIDTH 5 /* EQ_B4_GAIN - [5:1] */ -#define WM9081_EQ_ENA 0x0001 /* EQ_ENA */ -#define WM9081_EQ_ENA_MASK 0x0001 /* EQ_ENA */ -#define WM9081_EQ_ENA_SHIFT 0 /* EQ_ENA */ -#define WM9081_EQ_ENA_WIDTH 1 /* EQ_ENA */ - -/* - * R43 (0x2B) - EQ 2 - */ -#define WM9081_EQ_B3_GAIN_MASK 0xF800 /* EQ_B3_GAIN - [15:11] */ -#define WM9081_EQ_B3_GAIN_SHIFT 11 /* EQ_B3_GAIN - [15:11] */ -#define WM9081_EQ_B3_GAIN_WIDTH 5 /* EQ_B3_GAIN - [15:11] */ -#define WM9081_EQ_B5_GAIN_MASK 0x07C0 /* EQ_B5_GAIN - [10:6] */ -#define WM9081_EQ_B5_GAIN_SHIFT 6 /* EQ_B5_GAIN - [10:6] */ -#define WM9081_EQ_B5_GAIN_WIDTH 5 /* EQ_B5_GAIN - [10:6] */ - -/* - * R44 (0x2C) - EQ 3 - */ -#define WM9081_EQ_B1_A_MASK 0xFFFF /* EQ_B1_A - [15:0] */ -#define WM9081_EQ_B1_A_SHIFT 0 /* EQ_B1_A - [15:0] */ -#define WM9081_EQ_B1_A_WIDTH 16 /* EQ_B1_A - [15:0] */ - -/* - * R45 (0x2D) - EQ 4 - */ -#define WM9081_EQ_B1_B_MASK 0xFFFF /* EQ_B1_B - [15:0] */ -#define WM9081_EQ_B1_B_SHIFT 0 /* EQ_B1_B - [15:0] */ -#define WM9081_EQ_B1_B_WIDTH 16 /* EQ_B1_B - [15:0] */ - -/* - * R46 (0x2E) - EQ 5 - */ -#define WM9081_EQ_B1_PG_MASK 0xFFFF /* EQ_B1_PG - [15:0] */ -#define WM9081_EQ_B1_PG_SHIFT 0 /* EQ_B1_PG - [15:0] */ -#define WM9081_EQ_B1_PG_WIDTH 16 /* EQ_B1_PG - [15:0] */ - -/* - * R47 (0x2F) - EQ 6 - */ -#define WM9081_EQ_B2_A_MASK 0xFFFF /* EQ_B2_A - [15:0] */ -#define WM9081_EQ_B2_A_SHIFT 0 /* EQ_B2_A - [15:0] */ -#define WM9081_EQ_B2_A_WIDTH 16 /* EQ_B2_A - [15:0] */ - -/* - * R48 (0x30) - EQ 7 - */ -#define WM9081_EQ_B2_B_MASK 0xFFFF /* EQ_B2_B - [15:0] */ -#define WM9081_EQ_B2_B_SHIFT 0 /* EQ_B2_B - [15:0] */ -#define WM9081_EQ_B2_B_WIDTH 16 /* EQ_B2_B - [15:0] */ - -/* - * R49 (0x31) - EQ 8 - */ -#define WM9081_EQ_B2_C_MASK 0xFFFF /* EQ_B2_C - [15:0] */ -#define WM9081_EQ_B2_C_SHIFT 0 /* EQ_B2_C - [15:0] */ -#define WM9081_EQ_B2_C_WIDTH 16 /* EQ_B2_C - [15:0] */ - -/* - * R50 (0x32) - EQ 9 - */ -#define WM9081_EQ_B2_PG_MASK 0xFFFF /* EQ_B2_PG - [15:0] */ -#define WM9081_EQ_B2_PG_SHIFT 0 /* EQ_B2_PG - [15:0] */ -#define WM9081_EQ_B2_PG_WIDTH 16 /* EQ_B2_PG - [15:0] */ - -/* - * R51 (0x33) - EQ 10 - */ -#define WM9081_EQ_B4_A_MASK 0xFFFF /* EQ_B4_A - [15:0] */ -#define WM9081_EQ_B4_A_SHIFT 0 /* EQ_B4_A - [15:0] */ -#define WM9081_EQ_B4_A_WIDTH 16 /* EQ_B4_A - [15:0] */ - -/* - * R52 (0x34) - EQ 11 - */ -#define WM9081_EQ_B4_B_MASK 0xFFFF /* EQ_B4_B - [15:0] */ -#define WM9081_EQ_B4_B_SHIFT 0 /* EQ_B4_B - [15:0] */ -#define WM9081_EQ_B4_B_WIDTH 16 /* EQ_B4_B - [15:0] */ - -/* - * R53 (0x35) - EQ 12 - */ -#define WM9081_EQ_B4_C_MASK 0xFFFF /* EQ_B4_C - [15:0] */ -#define WM9081_EQ_B4_C_SHIFT 0 /* EQ_B4_C - [15:0] */ -#define WM9081_EQ_B4_C_WIDTH 16 /* EQ_B4_C - [15:0] */ - -/* - * R54 (0x36) - EQ 13 - */ -#define WM9081_EQ_B4_PG_MASK 0xFFFF /* EQ_B4_PG - [15:0] */ -#define WM9081_EQ_B4_PG_SHIFT 0 /* EQ_B4_PG - [15:0] */ -#define WM9081_EQ_B4_PG_WIDTH 16 /* EQ_B4_PG - [15:0] */ - -/* - * R55 (0x37) - EQ 14 - */ -#define WM9081_EQ_B3_A_MASK 0xFFFF /* EQ_B3_A - [15:0] */ -#define WM9081_EQ_B3_A_SHIFT 0 /* EQ_B3_A - [15:0] */ -#define WM9081_EQ_B3_A_WIDTH 16 /* EQ_B3_A - [15:0] */ - -/* - * R56 (0x38) - EQ 15 - */ -#define WM9081_EQ_B3_B_MASK 0xFFFF /* EQ_B3_B - [15:0] */ -#define WM9081_EQ_B3_B_SHIFT 0 /* EQ_B3_B - [15:0] */ -#define WM9081_EQ_B3_B_WIDTH 16 /* EQ_B3_B - [15:0] */ - -/* - * R57 (0x39) - EQ 16 - */ -#define WM9081_EQ_B3_C_MASK 0xFFFF /* EQ_B3_C - [15:0] */ -#define WM9081_EQ_B3_C_SHIFT 0 /* EQ_B3_C - [15:0] */ -#define WM9081_EQ_B3_C_WIDTH 16 /* EQ_B3_C - [15:0] */ - -/* - * R58 (0x3A) - EQ 17 - */ -#define WM9081_EQ_B3_PG_MASK 0xFFFF /* EQ_B3_PG - [15:0] */ -#define WM9081_EQ_B3_PG_SHIFT 0 /* EQ_B3_PG - [15:0] */ -#define WM9081_EQ_B3_PG_WIDTH 16 /* EQ_B3_PG - [15:0] */ - -/* - * R59 (0x3B) - EQ 18 - */ -#define WM9081_EQ_B5_A_MASK 0xFFFF /* EQ_B5_A - [15:0] */ -#define WM9081_EQ_B5_A_SHIFT 0 /* EQ_B5_A - [15:0] */ -#define WM9081_EQ_B5_A_WIDTH 16 /* EQ_B5_A - [15:0] */ - -/* - * R60 (0x3C) - EQ 19 - */ -#define WM9081_EQ_B5_B_MASK 0xFFFF /* EQ_B5_B - [15:0] */ -#define WM9081_EQ_B5_B_SHIFT 0 /* EQ_B5_B - [15:0] */ -#define WM9081_EQ_B5_B_WIDTH 16 /* EQ_B5_B - [15:0] */ - -/* - * R61 (0x3D) - EQ 20 - */ -#define WM9081_EQ_B5_PG_MASK 0xFFFF /* EQ_B5_PG - [15:0] */ -#define WM9081_EQ_B5_PG_SHIFT 0 /* EQ_B5_PG - [15:0] */ -#define WM9081_EQ_B5_PG_WIDTH 16 /* EQ_B5_PG - [15:0] */ - - -#endif diff --git a/trunk/sound/soc/codecs/wm9705.c b/trunk/sound/soc/codecs/wm9705.c index fa88b463e71f..c2d1a7a18fa3 100644 --- a/trunk/sound/soc/codecs/wm9705.c +++ b/trunk/sound/soc/codecs/wm9705.c @@ -282,14 +282,14 @@ struct snd_soc_dai wm9705_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9705_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9705_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS, + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .ops = &wm9705_dai_ops, }, diff --git a/trunk/sound/soc/codecs/wm9712.c b/trunk/sound/soc/codecs/wm9712.c index 1fd4e88f50cf..765cf1e7369e 100644 --- a/trunk/sound/soc/codecs/wm9712.c +++ b/trunk/sound/soc/codecs/wm9712.c @@ -534,13 +534,13 @@ struct snd_soc_dai wm9712_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9712_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9712_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &wm9712_dai_ops_hifi, }, { @@ -550,7 +550,7 @@ struct snd_soc_dai wm9712_dai[] = { .channels_min = 1, .channels_max = 1, .rates = WM9712_AC97_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &wm9712_dai_ops_aux, } }; @@ -585,8 +585,6 @@ static int wm9712_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) != wm9712_reg[0]) goto err; return 0; diff --git a/trunk/sound/soc/codecs/wm9713.c b/trunk/sound/soc/codecs/wm9713.c index abed37acf787..523bad077fa0 100644 --- a/trunk/sound/soc/codecs/wm9713.c +++ b/trunk/sound/soc/codecs/wm9713.c @@ -189,26 +189,6 @@ SOC_SINGLE("3D Lower Cut-off Switch", AC97_REC_GAIN_MIC, 4, 1, 0), SOC_SINGLE("3D Depth", AC97_REC_GAIN_MIC, 0, 15, 1), }; -static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct snd_soc_codec *codec = w->codec; - u16 status, rate; - - BUG_ON(event != SND_SOC_DAPM_PRE_PMD); - - /* Gracefully shut down the voice interface. */ - status = ac97_read(codec, AC97_EXTENDED_MID) | 0x1000; - rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); - schedule_timeout_interruptible(msecs_to_jiffies(1)); - ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); - ac97_write(codec, AC97_EXTENDED_MID, status); - - return 0; -} - - /* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path using the current @@ -420,8 +400,7 @@ SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("HP Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Line Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), SND_SOC_DAPM_MIXER("Capture Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_DAC_E("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1, - wm9713_voice_shutdown, SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AC97_EXTENDED_MID, 12, 1), SND_SOC_DAPM_DAC("Aux DAC", "Aux Playback", AC97_EXTENDED_MID, 11, 1), SND_SOC_DAPM_PGA("Left ADC", AC97_EXTENDED_MID, 5, 1, NULL, 0), SND_SOC_DAPM_PGA("Right ADC", AC97_EXTENDED_MID, 4, 1, NULL, 0), @@ -710,7 +689,7 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int source) Ndiv = target / source; if ((Ndiv < 5) || (Ndiv > 12)) printk(KERN_WARNING - "WM9713 PLL N value %u out of recommended range!\n", + "WM9713 PLL N value %d out of recommended range!\n", Ndiv); pll_div->n = Ndiv; @@ -957,6 +936,21 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, return 0; } +static void wm9713_voiceshutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + u16 status, rate; + + /* Gracefully shut down the voice interface. */ + status = ac97_read(codec, AC97_EXTENDED_STATUS) | 0x1000; + rate = ac97_read(codec, AC97_HANDSET_RATE) & 0xF0FF; + ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0200); + schedule_timeout_interruptible(msecs_to_jiffies(1)); + ac97_write(codec, AC97_HANDSET_RATE, rate | 0x0F00); + ac97_write(codec, AC97_EXTENDED_MID, status); +} + static int ac97_hifi_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -1025,6 +1019,7 @@ static struct snd_soc_dai_ops wm9713_dai_ops_aux = { static struct snd_soc_dai_ops wm9713_dai_ops_voice = { .hw_params = wm9713_pcm_hw_params, + .shutdown = wm9713_voiceshutdown, .set_clkdiv = wm9713_set_dai_clkdiv, .set_pll = wm9713_set_dai_pll, .set_fmt = wm9713_set_dai_fmt, @@ -1040,13 +1035,13 @@ struct snd_soc_dai wm9713_dai[] = { .channels_min = 1, .channels_max = 2, .rates = WM9713_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .capture = { .stream_name = "HiFi Capture", .channels_min = 1, .channels_max = 2, .rates = WM9713_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &wm9713_dai_ops_hifi, }, { @@ -1056,7 +1051,7 @@ struct snd_soc_dai wm9713_dai[] = { .channels_min = 1, .channels_max = 1, .rates = WM9713_RATES, - .formats = SND_SOC_STD_AC97_FMTS,}, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &wm9713_dai_ops_aux, }, { @@ -1074,7 +1069,6 @@ struct snd_soc_dai wm9713_dai[] = { .rates = WM9713_PCM_RATES, .formats = WM9713_PCM_FORMATS,}, .ops = &wm9713_dai_ops_voice, - .symmetric_rates = 1, }, }; EXPORT_SYMBOL_GPL(wm9713_dai); diff --git a/trunk/sound/soc/fsl/Kconfig b/trunk/sound/soc/fsl/Kconfig index 5dbebf82249c..9fc908283371 100644 --- a/trunk/sound/soc/fsl/Kconfig +++ b/trunk/sound/soc/fsl/Kconfig @@ -1,8 +1,5 @@ config SND_SOC_OF_SIMPLE tristate - -config SND_MPC52xx_DMA - tristate # ASoC platform support for the Freescale MPC8610 SOC. This compiles drivers # for the SSI and the Elo DMA controller. You will still need to select @@ -25,34 +22,7 @@ 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_MPC52xx_DMA + select SND_SOC_OF_SIMPLE select PPC_BESTCOMM_GEN_BD help Say Y here to support the MPC5200 PSCs in I2S mode. - -config SND_SOC_MPC5200_AC97 - tristate "Freescale MPC5200 PSC in AC97 mode driver" - depends on PPC_MPC52xx && PPC_BESTCOMM - select AC97_BUS - select SND_MPC52xx_DMA - select PPC_BESTCOMM_GEN_BD - help - Say Y here to support the MPC5200 PSCs in AC97 mode. - -config SND_MPC52xx_SOC_PCM030 - tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712" - depends on PPC_MPC5200_SIMPLE && BROKEN - select SND_SOC_MPC5200_AC97 - select SND_SOC_WM9712 - help - Say Y if you want to add support for sound on the Phytec pcm030 - baseboard. - -config SND_MPC52xx_SOC_EFIKA - tristate "SoC AC97 Audio support for bbplan Efika and STAC9766" - depends on PPC_EFIKA && BROKEN - select SND_SOC_MPC5200_AC97 - select SND_SOC_STAC9766 - help - Say Y if you want to add support for sound on the Efika. - diff --git a/trunk/sound/soc/fsl/Makefile b/trunk/sound/soc/fsl/Makefile index a83a73967ec6..f85134c86387 100644 --- a/trunk/sound/soc/fsl/Makefile +++ b/trunk/sound/soc/fsl/Makefile @@ -10,12 +10,5 @@ snd-soc-fsl-ssi-objs := fsl_ssi.o snd-soc-fsl-dma-objs := fsl_dma.o obj-$(CONFIG_SND_SOC_MPC8610) += snd-soc-fsl-ssi.o snd-soc-fsl-dma.o -# MPC5200 Platform Support -obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o -obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o - -# MPC5200 Machine Support -obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o -obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o diff --git a/trunk/sound/soc/fsl/efika-audio-fabric.c b/trunk/sound/soc/fsl/efika-audio-fabric.c deleted file mode 100644 index 85b0e7569504..000000000000 --- a/trunk/sound/soc/fsl/efika-audio-fabric.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Efika driver for the PSC of the Freescale MPC52xx - * configured as AC97 interface - * - * Copyright 2008 Jon Smirl, Digispeaker - * Author: Jon Smirl - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "mpc5200_dma.h" -#include "mpc5200_psc_ac97.h" -#include "../codecs/stac9766.h" - -static struct snd_soc_device device; -static struct snd_soc_card card; - -static struct snd_soc_dai_link efika_fabric_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 Analog", - .codec_dai = &stac9766_dai[STAC9766_DAI_AC97_ANALOG], - .cpu_dai = &psc_ac97_dai[MPC5200_AC97_NORMAL], -}, -{ - .name = "AC97", - .stream_name = "AC97 IEC958", - .codec_dai = &stac9766_dai[STAC9766_DAI_AC97_DIGITAL], - .cpu_dai = &psc_ac97_dai[MPC5200_AC97_SPDIF], -}, -}; - -static __init int efika_fabric_init(void) -{ - struct platform_device *pdev; - int rc; - - if (!machine_is_compatible("bplan,efika")) - return -ENODEV; - - card.platform = &mpc5200_audio_dma_platform; - card.name = "Efika"; - card.dai_link = efika_fabric_dai; - card.num_links = ARRAY_SIZE(efika_fabric_dai); - - device.card = &card; - device.codec_dev = &soc_codec_dev_stac9766; - - pdev = platform_device_alloc("soc-audio", 1); - if (!pdev) { - pr_err("efika_fabric_init: platform_device_alloc() failed\n"); - return -ENODEV; - } - - platform_set_drvdata(pdev, &device); - device.dev = &pdev->dev; - - rc = platform_device_add(pdev); - if (rc) { - pr_err("efika_fabric_init: platform_device_add() failed\n"); - return -ENODEV; - } - return 0; -} - -module_init(efika_fabric_init); - - -MODULE_AUTHOR("Jon Smirl "); -MODULE_DESCRIPTION(DRV_NAME ": mpc5200 Efika fabric driver"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/sound/soc/fsl/fsl_ssi.c b/trunk/sound/soc/fsl/fsl_ssi.c index 93f0f38a32c9..3711d8454d96 100644 --- a/trunk/sound/soc/fsl/fsl_ssi.c +++ b/trunk/sound/soc/fsl/fsl_ssi.c @@ -375,14 +375,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, struct snd_pcm_runtime *first_runtime = ssi_private->first_stream->runtime; - if (!first_runtime->sample_bits) { + if (!first_runtime->rate || !first_runtime->sample_bits) { dev_err(substream->pcm->card->dev, - "set sample size in %s stream first\n", + "set sample rate and size in %s stream first\n", substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "capture" : "playback"); return -EAGAIN; } + snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + first_runtime->rate, first_runtime->rate); + /* If we're in synchronous mode, then we need to constrain * the sample size as well. We don't support independent sample * rates in asynchronous mode. @@ -670,7 +674,7 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) ssi_private->dev = ssi_info->dev; ssi_private->asynchronous = ssi_info->asynchronous; - dev_set_drvdata(ssi_private->dev, fsl_ssi_dai); + ssi_private->dev->driver_data = fsl_ssi_dai; /* Initialize the the device_attribute structure */ dev_attr->attr.name = "ssi-stats"; @@ -689,7 +693,6 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info) fsl_ssi_dai->name = ssi_private->name; fsl_ssi_dai->id = ssi_info->id; fsl_ssi_dai->dev = ssi_info->dev; - fsl_ssi_dai->symmetric_rates = 1; ret = snd_soc_register_dai(fsl_ssi_dai); if (ret != 0) { diff --git a/trunk/sound/soc/fsl/mpc5200_dma.c b/trunk/sound/soc/fsl/mpc5200_dma.c deleted file mode 100644 index efec33a1c5bd..000000000000 --- a/trunk/sound/soc/fsl/mpc5200_dma.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Freescale MPC5200 PSC DMA - * ALSA SoC Platform driver - * - * Copyright (C) 2008 Secret Lab Technologies Ltd. - * Copyright (C) 2009 Jon Smirl, Digispeaker - */ - -#include -#include - -#include - -#include -#include -#include - -#include "mpc5200_dma.h" - -/* - * Interrupt handlers - */ -static irqreturn_t psc_dma_status_irq(int irq, void *_psc_dma) -{ - struct psc_dma *psc_dma = _psc_dma; - struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; - u16 isr; - - isr = in_be16(®s->mpc52xx_psc_isr); - - /* Playback underrun error */ - if (psc_dma->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP)) - psc_dma->stats.underrun_count++; - - /* Capture overrun error */ - if (psc_dma->capture.active && (isr & MPC52xx_PSC_IMR_ORERR)) - psc_dma->stats.overrun_count++; - - out_8(®s->command, MPC52xx_PSC_RST_ERR_STAT); - - return IRQ_HANDLED; -} - -/** - * psc_dma_bcom_enqueue_next_buffer - Enqueue another audio buffer - * @s: pointer to stream private data structure - * - * Enqueues another audio period buffer into the bestcomm queue. - * - * Note: The routine must only be called when there is space available in - * the queue. Otherwise the enqueue will fail and the audio ring buffer - * will get out of sync - */ -static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s) -{ - struct bcom_bd *bd; - - /* Prepare and enqueue the next buffer descriptor */ - bd = bcom_prepare_next_buffer(s->bcom_task); - bd->status = s->period_bytes; - bd->data[0] = s->period_next_pt; - bcom_submit_next_buffer(s->bcom_task, NULL); - - /* Update for next period */ - s->period_next_pt += s->period_bytes; - if (s->period_next_pt >= s->period_end) - s->period_next_pt = s->period_start; -} - -static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s) -{ - while (s->appl_ptr < s->runtime->control->appl_ptr) { - - if (bcom_queue_full(s->bcom_task)) - return; - - s->appl_ptr += s->period_size; - - psc_dma_bcom_enqueue_next_buffer(s); - } -} - -/* Bestcomm DMA irq handler */ -static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream) -{ - struct psc_dma_stream *s = _psc_dma_stream; - - spin_lock(&s->psc_dma->lock); - /* For each finished period, dequeue the completed period buffer - * and enqueue a new one in it's place. */ - while (bcom_buffer_done(s->bcom_task)) { - bcom_retrieve_buffer(s->bcom_task, NULL, NULL); - - s->period_current_pt += s->period_bytes; - if (s->period_current_pt >= s->period_end) - s->period_current_pt = s->period_start; - } - psc_dma_bcom_enqueue_tx(s); - spin_unlock(&s->psc_dma->lock); - - /* If the stream is active, then also inform the PCM middle layer - * of the period finished event. */ - if (s->active) - snd_pcm_period_elapsed(s->stream); - - return IRQ_HANDLED; -} - -static irqreturn_t psc_dma_bcom_irq_rx(int irq, void *_psc_dma_stream) -{ - struct psc_dma_stream *s = _psc_dma_stream; - - spin_lock(&s->psc_dma->lock); - /* For each finished period, dequeue the completed period buffer - * and enqueue a new one in it's place. */ - while (bcom_buffer_done(s->bcom_task)) { - bcom_retrieve_buffer(s->bcom_task, NULL, NULL); - - s->period_current_pt += s->period_bytes; - if (s->period_current_pt >= s->period_end) - s->period_current_pt = s->period_start; - - psc_dma_bcom_enqueue_next_buffer(s); - } - spin_unlock(&s->psc_dma->lock); - - /* If the stream is active, then also inform the PCM middle layer - * of the period finished event. */ - if (s->active) - snd_pcm_period_elapsed(s->stream); - - return IRQ_HANDLED; -} - -static int psc_dma_hw_free(struct snd_pcm_substream *substream) -{ - snd_pcm_set_runtime_buffer(substream, NULL); - return 0; -} - -/** - * psc_dma_trigger: start and stop the DMA transfer. - * - * This function is called by ALSA to start, stop, pause, and resume the DMA - * transfer of data. - */ -static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct psc_dma_stream *s; - struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; - u16 imr; - unsigned long flags; - int i; - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - s = &psc_dma->capture; - else - s = &psc_dma->playback; - - dev_dbg(psc_dma->dev, "psc_dma_trigger(substream=%p, cmd=%i)" - " stream_id=%i\n", - substream, cmd, substream->pstr->stream); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - s->period_bytes = frames_to_bytes(runtime, - runtime->period_size); - s->period_start = virt_to_phys(runtime->dma_area); - s->period_end = s->period_start + - (s->period_bytes * runtime->periods); - s->period_next_pt = s->period_start; - s->period_current_pt = s->period_start; - s->period_size = runtime->period_size; - s->active = 1; - - /* track appl_ptr so that we have a better chance of detecting - * end of stream and not over running it. - */ - s->runtime = runtime; - s->appl_ptr = s->runtime->control->appl_ptr - - (runtime->period_size * runtime->periods); - - /* Fill up the bestcomm bd queue and enable DMA. - * This will begin filling the PSC's fifo. - */ - spin_lock_irqsave(&psc_dma->lock, flags); - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { - bcom_gen_bd_rx_reset(s->bcom_task); - for (i = 0; i < runtime->periods; i++) - if (!bcom_queue_full(s->bcom_task)) - psc_dma_bcom_enqueue_next_buffer(s); - } else { - bcom_gen_bd_tx_reset(s->bcom_task); - psc_dma_bcom_enqueue_tx(s); - } - - bcom_enable(s->bcom_task); - spin_unlock_irqrestore(&psc_dma->lock, flags); - - out_8(®s->command, MPC52xx_PSC_RST_ERR_STAT); - - break; - - case SNDRV_PCM_TRIGGER_STOP: - s->active = 0; - - spin_lock_irqsave(&psc_dma->lock, flags); - bcom_disable(s->bcom_task); - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - bcom_gen_bd_rx_reset(s->bcom_task); - else - bcom_gen_bd_tx_reset(s->bcom_task); - spin_unlock_irqrestore(&psc_dma->lock, flags); - - break; - - default: - dev_dbg(psc_dma->dev, "invalid command\n"); - return -EINVAL; - } - - /* Update interrupt enable settings */ - imr = 0; - if (psc_dma->playback.active) - imr |= MPC52xx_PSC_IMR_TXEMP; - if (psc_dma->capture.active) - imr |= MPC52xx_PSC_IMR_ORERR; - out_be16(®s->isr_imr.imr, psc_dma->imr | imr); - - return 0; -} - - -/* --------------------------------------------------------------------- - * The PSC DMA 'ASoC platform' driver - * - * Can be referenced by an 'ASoC machine' driver - * This driver only deals with the audio bus; it doesn't have any - * interaction with the attached codec - */ - -static const struct snd_pcm_hardware psc_dma_hardware = { - .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_BATCH, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | - SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .period_bytes_max = 1024 * 1024, - .period_bytes_min = 32, - .periods_min = 2, - .periods_max = 256, - .buffer_bytes_max = 2 * 1024 * 1024, - .fifo_size = 512, -}; - -static int psc_dma_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - struct psc_dma_stream *s; - int rc; - - dev_dbg(psc_dma->dev, "psc_dma_open(substream=%p)\n", substream); - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - s = &psc_dma->capture; - else - s = &psc_dma->playback; - - snd_soc_set_runtime_hwparams(substream, &psc_dma_hardware); - - rc = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (rc < 0) { - dev_err(substream->pcm->card->dev, "invalid buffer size\n"); - return rc; - } - - s->stream = substream; - return 0; -} - -static int psc_dma_close(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - struct psc_dma_stream *s; - - dev_dbg(psc_dma->dev, "psc_dma_close(substream=%p)\n", substream); - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - s = &psc_dma->capture; - else - s = &psc_dma->playback; - - if (!psc_dma->playback.active && - !psc_dma->capture.active) { - - /* Disable all interrupts and reset the PSC */ - out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr); - out_8(&psc_dma->psc_regs->command, 4 << 4); /* reset error */ - } - s->stream = NULL; - return 0; -} - -static snd_pcm_uframes_t -psc_dma_pointer(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - struct psc_dma_stream *s; - dma_addr_t count; - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - s = &psc_dma->capture; - else - s = &psc_dma->playback; - - count = s->period_current_pt - s->period_start; - - return bytes_to_frames(substream->runtime, count); -} - -static int -psc_dma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - return 0; -} - -static struct snd_pcm_ops psc_dma_ops = { - .open = psc_dma_open, - .close = psc_dma_close, - .hw_free = psc_dma_hw_free, - .ioctl = snd_pcm_lib_ioctl, - .pointer = psc_dma_pointer, - .trigger = psc_dma_trigger, - .hw_params = psc_dma_hw_params, -}; - -static u64 psc_dma_dmamask = 0xffffffff; -static int psc_dma_new(struct snd_card *card, struct snd_soc_dai *dai, - struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - size_t size = psc_dma_hardware.buffer_bytes_max; - int rc = 0; - - dev_dbg(rtd->socdev->dev, "psc_dma_new(card=%p, dai=%p, pcm=%p)\n", - card, dai, pcm); - - if (!card->dev->dma_mask) - card->dev->dma_mask = &psc_dma_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; - - if (pcm->streams[0].substream) { - rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, - size, &pcm->streams[0].substream->dma_buffer); - if (rc) - goto playback_alloc_err; - } - - if (pcm->streams[1].substream) { - rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->card->dev, - size, &pcm->streams[1].substream->dma_buffer); - if (rc) - goto capture_alloc_err; - } - - if (rtd->socdev->card->codec->ac97) - rtd->socdev->card->codec->ac97->private_data = psc_dma; - - return 0; - - capture_alloc_err: - if (pcm->streams[0].substream) - snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); - - playback_alloc_err: - dev_err(card->dev, "Cannot allocate buffer(s)\n"); - - return -ENOMEM; -} - -static void psc_dma_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *rtd = pcm->private_data; - struct snd_pcm_substream *substream; - int stream; - - dev_dbg(rtd->socdev->dev, "psc_dma_free(pcm=%p)\n", pcm); - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (substream) { - snd_dma_free_pages(&substream->dma_buffer); - substream->dma_buffer.area = NULL; - substream->dma_buffer.addr = 0; - } - } -} - -struct snd_soc_platform mpc5200_audio_dma_platform = { - .name = "mpc5200-psc-audio", - .pcm_ops = &psc_dma_ops, - .pcm_new = &psc_dma_new, - .pcm_free = &psc_dma_free, -}; -EXPORT_SYMBOL_GPL(mpc5200_audio_dma_platform); - -int mpc5200_audio_dma_create(struct of_device *op) -{ - phys_addr_t fifo; - struct psc_dma *psc_dma; - struct resource res; - int size, irq, rc; - const __be32 *prop; - void __iomem *regs; - - /* Fetch the registers and IRQ of the PSC */ - irq = irq_of_parse_and_map(op->node, 0); - if (of_address_to_resource(op->node, 0, &res)) { - dev_err(&op->dev, "Missing reg property\n"); - return -ENODEV; - } - regs = ioremap(res.start, 1 + res.end - res.start); - if (!regs) { - dev_err(&op->dev, "Could not map registers\n"); - return -ENODEV; - } - - /* Allocate and initialize the driver private data */ - psc_dma = kzalloc(sizeof *psc_dma, GFP_KERNEL); - if (!psc_dma) { - iounmap(regs); - return -ENOMEM; - } - - /* Get the PSC ID */ - prop = of_get_property(op->node, "cell-index", &size); - if (!prop || size < sizeof *prop) - return -ENODEV; - - spin_lock_init(&psc_dma->lock); - psc_dma->id = be32_to_cpu(*prop); - psc_dma->irq = irq; - psc_dma->psc_regs = regs; - psc_dma->fifo_regs = regs + sizeof *psc_dma->psc_regs; - psc_dma->dev = &op->dev; - psc_dma->playback.psc_dma = psc_dma; - psc_dma->capture.psc_dma = psc_dma; - snprintf(psc_dma->name, sizeof psc_dma->name, "PSC%u", psc_dma->id); - - /* Find the address of the fifo data registers and setup the - * DMA tasks */ - fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32); - psc_dma->capture.bcom_task = - bcom_psc_gen_bd_rx_init(psc_dma->id, 10, fifo, 512); - psc_dma->playback.bcom_task = - bcom_psc_gen_bd_tx_init(psc_dma->id, 10, fifo); - if (!psc_dma->capture.bcom_task || - !psc_dma->playback.bcom_task) { - dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); - iounmap(regs); - kfree(psc_dma); - return -ENODEV; - } - - /* Disable all interrupts and reset the PSC */ - out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr); - /* reset receiver */ - out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_RX); - /* reset transmitter */ - out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_TX); - /* reset error */ - out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_RST_ERR_STAT); - /* reset mode */ - out_8(&psc_dma->psc_regs->command, MPC52xx_PSC_SEL_MODE_REG_1); - - /* Set up mode register; - * First write: RxRdy (FIFO Alarm) generates rx FIFO irq - * Second write: register Normal mode for non loopback - */ - out_8(&psc_dma->psc_regs->mode, 0); - out_8(&psc_dma->psc_regs->mode, 0); - - /* Set the TX and RX fifo alarm thresholds */ - out_be16(&psc_dma->fifo_regs->rfalarm, 0x100); - out_8(&psc_dma->fifo_regs->rfcntl, 0x4); - out_be16(&psc_dma->fifo_regs->tfalarm, 0x100); - out_8(&psc_dma->fifo_regs->tfcntl, 0x7); - - /* Lookup the IRQ numbers */ - psc_dma->playback.irq = - bcom_get_task_irq(psc_dma->playback.bcom_task); - psc_dma->capture.irq = - bcom_get_task_irq(psc_dma->capture.bcom_task); - - rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED, - "psc-dma-status", psc_dma); - rc |= request_irq(psc_dma->capture.irq, - &psc_dma_bcom_irq_rx, IRQF_SHARED, - "psc-dma-capture", &psc_dma->capture); - rc |= request_irq(psc_dma->playback.irq, - &psc_dma_bcom_irq_tx, IRQF_SHARED, - "psc-dma-playback", &psc_dma->playback); - if (rc) { - free_irq(psc_dma->irq, psc_dma); - free_irq(psc_dma->capture.irq, - &psc_dma->capture); - free_irq(psc_dma->playback.irq, - &psc_dma->playback); - return -ENODEV; - } - - /* Save what we've done so it can be found again later */ - dev_set_drvdata(&op->dev, psc_dma); - - /* Tell the ASoC OF helpers about it */ - return snd_soc_register_platform(&mpc5200_audio_dma_platform); -} -EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create); - -int mpc5200_audio_dma_destroy(struct of_device *op) -{ - struct psc_dma *psc_dma = dev_get_drvdata(&op->dev); - - dev_dbg(&op->dev, "mpc5200_audio_dma_destroy()\n"); - - snd_soc_unregister_platform(&mpc5200_audio_dma_platform); - - bcom_gen_bd_rx_release(psc_dma->capture.bcom_task); - bcom_gen_bd_tx_release(psc_dma->playback.bcom_task); - - /* Release irqs */ - free_irq(psc_dma->irq, psc_dma); - free_irq(psc_dma->capture.irq, &psc_dma->capture); - free_irq(psc_dma->playback.irq, &psc_dma->playback); - - iounmap(psc_dma->psc_regs); - kfree(psc_dma); - dev_set_drvdata(&op->dev, NULL); - - return 0; -} -EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy); - -MODULE_AUTHOR("Grant Likely "); -MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/fsl/mpc5200_dma.h b/trunk/sound/soc/fsl/mpc5200_dma.h deleted file mode 100644 index 2000803f06a7..000000000000 --- a/trunk/sound/soc/fsl/mpc5200_dma.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Freescale MPC5200 Audio DMA driver - */ - -#ifndef __SOUND_SOC_FSL_MPC5200_DMA_H__ -#define __SOUND_SOC_FSL_MPC5200_DMA_H__ - -#define PSC_STREAM_NAME_LEN 32 - -/** - * psc_ac97_stream - Data specific to a single stream (playback or capture) - * @active: flag indicating if the stream is active - * @psc_dma: pointer back to parent psc_dma data structure - * @bcom_task: bestcomm task structure - * @irq: irq number for bestcomm task - * @period_start: physical address of start of DMA region - * @period_end: physical address of end of DMA region - * @period_next_pt: physical address of next DMA buffer to enqueue - * @period_bytes: size of DMA period in bytes - */ -struct psc_dma_stream { - struct snd_pcm_runtime *runtime; - snd_pcm_uframes_t appl_ptr; - - int active; - struct psc_dma *psc_dma; - struct bcom_task *bcom_task; - int irq; - struct snd_pcm_substream *stream; - dma_addr_t period_start; - dma_addr_t period_end; - dma_addr_t period_next_pt; - dma_addr_t period_current_pt; - int period_bytes; - int period_size; -}; - -/** - * psc_dma - Private driver data - * @name: short name for this device ("PSC0", "PSC1", etc) - * @psc_regs: pointer to the PSC's registers - * @fifo_regs: pointer to the PSC's FIFO registers - * @irq: IRQ of this PSC - * @dev: struct device pointer - * @dai: the CPU DAI for this device - * @sicr: Base value used in serial interface control register; mode is ORed - * with this value. - * @playback: Playback stream context data - * @capture: Capture stream context data - */ -struct psc_dma { - char name[32]; - struct mpc52xx_psc __iomem *psc_regs; - struct mpc52xx_psc_fifo __iomem *fifo_regs; - unsigned int irq; - struct device *dev; - spinlock_t lock; - u32 sicr; - uint sysclk; - int imr; - int id; - unsigned int slots; - - /* per-stream data */ - struct psc_dma_stream playback; - struct psc_dma_stream capture; - - /* Statistics */ - struct { - unsigned long overrun_count; - unsigned long underrun_count; - } stats; -}; - -int mpc5200_audio_dma_create(struct of_device *op); -int mpc5200_audio_dma_destroy(struct of_device *op); - -extern struct snd_soc_platform mpc5200_audio_dma_platform; - -#endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */ diff --git a/trunk/sound/soc/fsl/mpc5200_psc_ac97.c b/trunk/sound/soc/fsl/mpc5200_psc_ac97.c deleted file mode 100644 index 794a247b3eb5..000000000000 --- a/trunk/sound/soc/fsl/mpc5200_psc_ac97.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * linux/sound/mpc5200-ac97.c -- AC97 support for the Freescale MPC52xx chip. - * - * Copyright (C) 2009 Jon Smirl, Digispeaker - * Author: Jon Smirl - * - * 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 -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include "mpc5200_dma.h" -#include "mpc5200_psc_ac97.h" - -#define DRV_NAME "mpc5200-psc-ac97" - -/* ALSA only supports a single AC97 device so static is recommend here */ -static struct psc_dma *psc_dma; - -static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg) -{ - int status; - unsigned int val; - - /* Wait for command send status zero = ready */ - status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & - MPC52xx_PSC_SR_CMDSEND), 100, 0); - if (status == 0) { - pr_err("timeout on ac97 bus (rdy)\n"); - return -ENODEV; - } - /* Send the read */ - out_be32(&psc_dma->psc_regs->ac97_cmd, (1<<31) | ((reg & 0x7f) << 24)); - - /* Wait for the answer */ - status = spin_event_timeout((in_be16(&psc_dma->psc_regs->sr_csr.status) & - MPC52xx_PSC_SR_DATA_VAL), 100, 0); - if (status == 0) { - pr_err("timeout on ac97 read (val) %x\n", - in_be16(&psc_dma->psc_regs->sr_csr.status)); - return -ENODEV; - } - /* Get the data */ - val = in_be32(&psc_dma->psc_regs->ac97_data); - if (((val >> 24) & 0x7f) != reg) { - pr_err("reg echo error on ac97 read\n"); - return -ENODEV; - } - val = (val >> 8) & 0xffff; - - return (unsigned short) val; -} - -static void psc_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, unsigned short val) -{ - int status; - - /* Wait for command status zero = ready */ - status = spin_event_timeout(!(in_be16(&psc_dma->psc_regs->sr_csr.status) & - MPC52xx_PSC_SR_CMDSEND), 100, 0); - if (status == 0) { - pr_err("timeout on ac97 bus (write)\n"); - return; - } - /* Write data */ - out_be32(&psc_dma->psc_regs->ac97_cmd, - ((reg & 0x7f) << 24) | (val << 8)); -} - -static void psc_ac97_warm_reset(struct snd_ac97 *ac97) -{ - struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; - - out_be32(®s->sicr, psc_dma->sicr | MPC52xx_PSC_SICR_AWR); - udelay(3); - out_be32(®s->sicr, psc_dma->sicr); -} - -static void psc_ac97_cold_reset(struct snd_ac97 *ac97) -{ - struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; - - /* Do a cold reset */ - out_8(®s->op1, MPC52xx_PSC_OP_RES); - udelay(10); - out_8(®s->op0, MPC52xx_PSC_OP_RES); - udelay(50); - psc_ac97_warm_reset(ac97); -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = psc_ac97_read, - .write = psc_ac97_write, - .reset = psc_ac97_cold_reset, - .warm_reset = psc_ac97_warm_reset, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct psc_dma *psc_dma = cpu_dai->private_data; - - dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" - " periods=%i buffer_size=%i buffer_bytes=%i channels=%i" - " rate=%i format=%i\n", - __func__, substream, params_period_size(params), - params_period_bytes(params), params_periods(params), - params_buffer_size(params), params_buffer_bytes(params), - params_channels(params), params_rate(params), - params_format(params)); - - - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { - if (params_channels(params) == 1) - psc_dma->slots |= 0x00000100; - else - psc_dma->slots |= 0x00000300; - } else { - if (params_channels(params) == 1) - psc_dma->slots |= 0x01000000; - else - psc_dma->slots |= 0x03000000; - } - out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); - - return 0; -} - -static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct psc_dma *psc_dma = cpu_dai->private_data; - - if (params_channels(params) == 1) - out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000); - else - out_be32(&psc_dma->psc_regs->ac97_slots, 0x03000000); - - return 0; -} - -static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) - psc_dma->slots &= 0xFFFF0000; - else - psc_dma->slots &= 0x0000FFFF; - - out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); - break; - } - return 0; -} - -static int psc_ac97_probe(struct platform_device *pdev, - struct snd_soc_dai *cpu_dai) -{ - struct psc_dma *psc_dma = cpu_dai->private_data; - struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; - - /* Go */ - out_8(®s->command, MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); - return 0; -} - -/* --------------------------------------------------------------------- - * ALSA SoC Bindings - * - * - Digital Audio Interface (DAI) template - * - create/destroy dai hooks - */ - -/** - * psc_ac97_dai_template: template CPU Digital Audio Interface - */ -static struct snd_soc_dai_ops psc_ac97_analog_ops = { - .hw_params = psc_ac97_hw_analog_params, - .trigger = psc_ac97_trigger, -}; - -static struct snd_soc_dai_ops psc_ac97_digital_ops = { - .hw_params = psc_ac97_hw_digital_params, -}; - -struct snd_soc_dai psc_ac97_dai[] = { -{ - .name = "AC97", - .ac97_control = 1, - .probe = psc_ac97_probe, - .playback = { - .channels_min = 1, - .channels_max = 6, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S32_BE, - }, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S32_BE, - }, - .ops = &psc_ac97_analog_ops, -}, -{ - .name = "SPDIF", - .ac97_control = 1, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_32000 | \ - SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE, - }, - .ops = &psc_ac97_digital_ops, -} }; -EXPORT_SYMBOL_GPL(psc_ac97_dai); - - - -/* --------------------------------------------------------------------- - * OF platform bus binding code: - * - Probe/remove operations - * - OF device match table - */ -static int __devinit psc_ac97_of_probe(struct of_device *op, - const struct of_device_id *match) -{ - int rc, i; - struct snd_ac97 ac97; - struct mpc52xx_psc __iomem *regs; - - rc = mpc5200_audio_dma_create(op); - if (rc != 0) - return rc; - - for (i = 0; i < ARRAY_SIZE(psc_ac97_dai); i++) - psc_ac97_dai[i].dev = &op->dev; - - rc = snd_soc_register_dais(psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai)); - if (rc != 0) { - dev_err(&op->dev, "Failed to register DAI\n"); - return rc; - } - - psc_dma = dev_get_drvdata(&op->dev); - regs = psc_dma->psc_regs; - ac97.private_data = psc_dma; - - for (i = 0; i < ARRAY_SIZE(psc_ac97_dai); i++) - psc_ac97_dai[i].private_data = psc_dma; - - psc_dma->imr = 0; - out_be16(&psc_dma->psc_regs->isr_imr.imr, psc_dma->imr); - - /* Configure the serial interface mode to AC97 */ - psc_dma->sicr = MPC52xx_PSC_SICR_SIM_AC97 | MPC52xx_PSC_SICR_ENAC97; - out_be32(®s->sicr, psc_dma->sicr); - - /* No slots active */ - out_be32(®s->ac97_slots, 0x00000000); - - return 0; -} - -static int __devexit psc_ac97_of_remove(struct of_device *op) -{ - return mpc5200_audio_dma_destroy(op); -} - -/* Match table for of_platform binding */ -static struct of_device_id psc_ac97_match[] __devinitdata = { - { .compatible = "fsl,mpc5200-psc-ac97", }, - { .compatible = "fsl,mpc5200b-psc-ac97", }, - {} -}; -MODULE_DEVICE_TABLE(of, psc_ac97_match); - -static struct of_platform_driver psc_ac97_driver = { - .match_table = psc_ac97_match, - .probe = psc_ac97_of_probe, - .remove = __devexit_p(psc_ac97_of_remove), - .driver = { - .name = "mpc5200-psc-ac97", - .owner = THIS_MODULE, - }, -}; - -/* --------------------------------------------------------------------- - * Module setup and teardown; simply register the of_platform driver - * for the PSC in AC97 mode. - */ -static int __init psc_ac97_init(void) -{ - return of_register_platform_driver(&psc_ac97_driver); -} -module_init(psc_ac97_init); - -static void __exit psc_ac97_exit(void) -{ - of_unregister_platform_driver(&psc_ac97_driver); -} -module_exit(psc_ac97_exit); - -MODULE_AUTHOR("Jon Smirl "); -MODULE_DESCRIPTION("mpc5200 AC97 module"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/sound/soc/fsl/mpc5200_psc_ac97.h b/trunk/sound/soc/fsl/mpc5200_psc_ac97.h deleted file mode 100644 index 4bc18c35c369..000000000000 --- a/trunk/sound/soc/fsl/mpc5200_psc_ac97.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Freescale MPC5200 PSC in AC97 mode - * ALSA SoC Digital Audio Interface (DAI) driver - * - */ - -#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ -#define __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ - -extern struct snd_soc_dai psc_ac97_dai[]; - -#define MPC5200_AC97_NORMAL 0 -#define MPC5200_AC97_SPDIF 1 - -#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_AC97_H__ */ diff --git a/trunk/sound/soc/fsl/mpc5200_psc_i2s.c b/trunk/sound/soc/fsl/mpc5200_psc_i2s.c index ce8de90fb94a..1111c710118a 100644 --- a/trunk/sound/soc/fsl/mpc5200_psc_i2s.c +++ b/trunk/sound/soc/fsl/mpc5200_psc_i2s.c @@ -3,21 +3,31 @@ * ALSA SoC Digital Audio Interface (DAI) driver * * Copyright (C) 2008 Secret Lab Technologies Ltd. - * Copyright (C) 2009 Jon Smirl, Digispeaker */ +#include #include +#include +#include +#include #include #include +#include +#include #include #include +#include #include +#include +#include +#include #include -#include "mpc5200_psc_i2s.h" -#include "mpc5200_dma.h" +MODULE_AUTHOR("Grant Likely "); +MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver"); +MODULE_LICENSE("GPL"); /** * PSC_I2S_RATES: sample rates supported by the I2S @@ -34,17 +44,191 @@ * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode */ #define PSC_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \ - SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE) + SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S24_BE | \ + SNDRV_PCM_FMTBIT_S32_BE) + +/** + * psc_i2s_stream - Data specific to a single stream (playback or capture) + * @active: flag indicating if the stream is active + * @psc_i2s: pointer back to parent psc_i2s data structure + * @bcom_task: bestcomm task structure + * @irq: irq number for bestcomm task + * @period_start: physical address of start of DMA region + * @period_end: physical address of end of DMA region + * @period_next_pt: physical address of next DMA buffer to enqueue + * @period_bytes: size of DMA period in bytes + */ +struct psc_i2s_stream { + int active; + struct psc_i2s *psc_i2s; + struct bcom_task *bcom_task; + int irq; + struct snd_pcm_substream *stream; + dma_addr_t period_start; + dma_addr_t period_end; + dma_addr_t period_next_pt; + dma_addr_t period_current_pt; + int period_bytes; +}; + +/** + * psc_i2s - Private driver data + * @name: short name for this device ("PSC0", "PSC1", etc) + * @psc_regs: pointer to the PSC's registers + * @fifo_regs: pointer to the PSC's FIFO registers + * @irq: IRQ of this PSC + * @dev: struct device pointer + * @dai: the CPU DAI for this device + * @sicr: Base value used in serial interface control register; mode is ORed + * with this value. + * @playback: Playback stream context data + * @capture: Capture stream context data + */ +struct psc_i2s { + char name[32]; + struct mpc52xx_psc __iomem *psc_regs; + struct mpc52xx_psc_fifo __iomem *fifo_regs; + unsigned int irq; + struct device *dev; + struct snd_soc_dai dai; + spinlock_t lock; + u32 sicr; + + /* per-stream data */ + struct psc_i2s_stream playback; + struct psc_i2s_stream capture; + + /* Statistics */ + struct { + int overrun_count; + int underrun_count; + } stats; +}; + +/* + * Interrupt handlers + */ +static irqreturn_t psc_i2s_status_irq(int irq, void *_psc_i2s) +{ + struct psc_i2s *psc_i2s = _psc_i2s; + struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs; + u16 isr; + + isr = in_be16(®s->mpc52xx_psc_isr); + + /* Playback underrun error */ + if (psc_i2s->playback.active && (isr & MPC52xx_PSC_IMR_TXEMP)) + psc_i2s->stats.underrun_count++; + + /* Capture overrun error */ + if (psc_i2s->capture.active && (isr & MPC52xx_PSC_IMR_ORERR)) + psc_i2s->stats.overrun_count++; + + out_8(®s->command, 4 << 4); /* reset the error status */ + + return IRQ_HANDLED; +} + +/** + * psc_i2s_bcom_enqueue_next_buffer - Enqueue another audio buffer + * @s: pointer to stream private data structure + * + * Enqueues another audio period buffer into the bestcomm queue. + * + * Note: The routine must only be called when there is space available in + * the queue. Otherwise the enqueue will fail and the audio ring buffer + * will get out of sync + */ +static void psc_i2s_bcom_enqueue_next_buffer(struct psc_i2s_stream *s) +{ + struct bcom_bd *bd; + + /* Prepare and enqueue the next buffer descriptor */ + bd = bcom_prepare_next_buffer(s->bcom_task); + bd->status = s->period_bytes; + bd->data[0] = s->period_next_pt; + bcom_submit_next_buffer(s->bcom_task, NULL); + + /* Update for next period */ + s->period_next_pt += s->period_bytes; + if (s->period_next_pt >= s->period_end) + s->period_next_pt = s->period_start; +} + +/* Bestcomm DMA irq handler */ +static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream) +{ + struct psc_i2s_stream *s = _psc_i2s_stream; + + /* For each finished period, dequeue the completed period buffer + * and enqueue a new one in it's place. */ + while (bcom_buffer_done(s->bcom_task)) { + bcom_retrieve_buffer(s->bcom_task, NULL, NULL); + s->period_current_pt += s->period_bytes; + if (s->period_current_pt >= s->period_end) + s->period_current_pt = s->period_start; + psc_i2s_bcom_enqueue_next_buffer(s); + bcom_enable(s->bcom_task); + } + + /* If the stream is active, then also inform the PCM middle layer + * of the period finished event. */ + if (s->active) + snd_pcm_period_elapsed(s->stream); + + return IRQ_HANDLED; +} + +/** + * psc_i2s_startup: create a new substream + * + * This is the first function called when a stream is opened. + * + * 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, + 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; + int rc; + + dev_dbg(psc_i2s->dev, "psc_i2s_startup(substream=%p)\n", substream); + + if (!psc_i2s->playback.active && + !psc_i2s->capture.active) { + /* Setup the IRQs */ + rc = request_irq(psc_i2s->irq, &psc_i2s_status_irq, IRQF_SHARED, + "psc-i2s-status", psc_i2s); + rc |= request_irq(psc_i2s->capture.irq, + &psc_i2s_bcom_irq, IRQF_SHARED, + "psc-i2s-capture", &psc_i2s->capture); + rc |= request_irq(psc_i2s->playback.irq, + &psc_i2s_bcom_irq, IRQF_SHARED, + "psc-i2s-playback", &psc_i2s->playback); + if (rc) { + free_irq(psc_i2s->irq, psc_i2s); + free_irq(psc_i2s->capture.irq, + &psc_i2s->capture); + free_irq(psc_i2s->playback.irq, + &psc_i2s->playback); + return -ENODEV; + } + } + + return 0; +} static int psc_i2s_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 psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; + struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; u32 mode; - dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" + dev_dbg(psc_i2s->dev, "%s(substream=%p) p_size=%i p_bytes=%i" " periods=%i buffer_size=%i buffer_bytes=%i\n", __func__, substream, params_period_size(params), params_period_bytes(params), params_periods(params), @@ -64,14 +248,174 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream, mode = MPC52xx_PSC_SICR_SIM_CODEC_32; break; default: - dev_dbg(psc_dma->dev, "invalid format\n"); + dev_dbg(psc_i2s->dev, "invalid format\n"); + return -EINVAL; + } + out_be32(&psc_i2s->psc_regs->sicr, psc_i2s->sicr | mode); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + return 0; +} + +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; +} + +/** + * psc_i2s_trigger: start and stop the DMA transfer. + * + * 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, + 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; + struct snd_pcm_runtime *runtime = substream->runtime; + struct psc_i2s_stream *s; + struct mpc52xx_psc __iomem *regs = psc_i2s->psc_regs; + u16 imr; + u8 psc_cmd; + unsigned long flags; + + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) + s = &psc_i2s->capture; + else + s = &psc_i2s->playback; + + dev_dbg(psc_i2s->dev, "psc_i2s_trigger(substream=%p, cmd=%i)" + " stream_id=%i\n", + substream, cmd, substream->pstr->stream); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + s->period_bytes = frames_to_bytes(runtime, + runtime->period_size); + s->period_start = virt_to_phys(runtime->dma_area); + s->period_end = s->period_start + + (s->period_bytes * runtime->periods); + s->period_next_pt = s->period_start; + s->period_current_pt = s->period_start; + s->active = 1; + + /* First; reset everything */ + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { + out_8(®s->command, MPC52xx_PSC_RST_RX); + out_8(®s->command, MPC52xx_PSC_RST_ERR_STAT); + } else { + out_8(®s->command, MPC52xx_PSC_RST_TX); + out_8(®s->command, MPC52xx_PSC_RST_ERR_STAT); + } + + /* Next, fill up the bestcomm bd queue and enable DMA. + * This will begin filling the PSC's fifo. */ + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) + bcom_gen_bd_rx_reset(s->bcom_task); + else + bcom_gen_bd_tx_reset(s->bcom_task); + while (!bcom_queue_full(s->bcom_task)) + psc_i2s_bcom_enqueue_next_buffer(s); + bcom_enable(s->bcom_task); + + /* Due to errata in the i2s mode; need to line up enabling + * the transmitter with a transition on the frame sync + * line */ + + spin_lock_irqsave(&psc_i2s->lock, flags); + /* first make sure it is low */ + while ((in_8(®s->ipcr_acr.ipcr) & 0x80) != 0) + ; + /* then wait for the transition to high */ + while ((in_8(®s->ipcr_acr.ipcr) & 0x80) == 0) + ; + /* Finally, enable the PSC. + * Receiver must always be enabled; even when we only want + * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */ + psc_cmd = MPC52xx_PSC_RX_ENABLE; + if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) + psc_cmd |= MPC52xx_PSC_TX_ENABLE; + out_8(®s->command, psc_cmd); + spin_unlock_irqrestore(&psc_i2s->lock, flags); + + break; + + case SNDRV_PCM_TRIGGER_STOP: + /* Turn off the PSC */ + s->active = 0; + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (!psc_i2s->playback.active) { + out_8(®s->command, 2 << 4); /* reset rx */ + out_8(®s->command, 3 << 4); /* reset tx */ + out_8(®s->command, 4 << 4); /* reset err */ + } + } else { + out_8(®s->command, 3 << 4); /* reset tx */ + out_8(®s->command, 4 << 4); /* reset err */ + if (!psc_i2s->capture.active) + out_8(®s->command, 2 << 4); /* reset rx */ + } + + bcom_disable(s->bcom_task); + while (!bcom_queue_empty(s->bcom_task)) + bcom_retrieve_buffer(s->bcom_task, NULL, NULL); + + break; + + default: + dev_dbg(psc_i2s->dev, "invalid command\n"); return -EINVAL; } - out_be32(&psc_dma->psc_regs->sicr, psc_dma->sicr | mode); + + /* Update interrupt enable settings */ + imr = 0; + if (psc_i2s->playback.active) + imr |= MPC52xx_PSC_IMR_TXEMP; + if (psc_i2s->capture.active) + imr |= MPC52xx_PSC_IMR_ORERR; + out_be16(®s->isr_imr.imr, imr); return 0; } +/** + * psc_i2s_shutdown: shutdown the data transfer on a stream + * + * Shutdown the PSC if there are no other substreams open. + */ +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; + + dev_dbg(psc_i2s->dev, "psc_i2s_shutdown(substream=%p)\n", substream); + + /* + * If this is the last active substream, disable the PSC and release + * the IRQ. + */ + if (!psc_i2s->playback.active && + !psc_i2s->capture.active) { + + /* Disable all interrupts and reset the PSC */ + out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0); + out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset tx */ + out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset rx */ + out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */ + out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */ + + /* Release irqs */ + free_irq(psc_i2s->irq, psc_i2s); + free_irq(psc_i2s->capture.irq, &psc_i2s->capture); + free_irq(psc_i2s->playback.irq, &psc_i2s->playback); + } +} + /** * psc_i2s_set_sysclk: set the clock frequency and direction * @@ -89,8 +433,8 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream, static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { - struct psc_dma *psc_dma = cpu_dai->private_data; - dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n", + struct psc_i2s *psc_i2s = cpu_dai->private_data; + dev_dbg(psc_i2s->dev, "psc_i2s_set_sysclk(cpu_dai=%p, dir=%i)\n", cpu_dai, dir); return (dir == SND_SOC_CLOCK_IN) ? 0 : -EINVAL; } @@ -108,8 +452,8 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, */ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format) { - struct psc_dma *psc_dma = cpu_dai->private_data; - dev_dbg(psc_dma->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n", + struct psc_i2s *psc_i2s = cpu_dai->private_data; + dev_dbg(psc_i2s->dev, "psc_i2s_set_fmt(cpu_dai=%p, format=%i)\n", cpu_dai, format); return (format == SND_SOC_DAIFMT_I2S) ? 0 : -EINVAL; } @@ -125,13 +469,16 @@ 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_ops psc_i2s_dai_ops = { + .startup = psc_i2s_startup, .hw_params = psc_i2s_hw_params, + .hw_free = psc_i2s_hw_free, + .shutdown = psc_i2s_shutdown, + .trigger = psc_i2s_trigger, .set_sysclk = psc_i2s_set_sysclk, .set_fmt = psc_i2s_set_fmt, }; -struct snd_soc_dai psc_i2s_dai[] = {{ - .name = "I2S", +static struct snd_soc_dai psc_i2s_dai_template = { .playback = { .channels_min = 2, .channels_max = 2, @@ -145,8 +492,223 @@ struct snd_soc_dai psc_i2s_dai[] = {{ .formats = PSC_I2S_FORMATS, }, .ops = &psc_i2s_dai_ops, -} }; -EXPORT_SYMBOL_GPL(psc_i2s_dai); +}; + +/* --------------------------------------------------------------------- + * The PSC I2S 'ASoC platform' driver + * + * Can be referenced by an 'ASoC machine' driver + * This driver only deals with the audio bus; it doesn't have any + * interaction with the attached codec + */ + +static const struct snd_pcm_hardware psc_i2s_pcm_hardware = { + .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_BATCH, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | + SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, + .rate_min = 8000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + .period_bytes_max = 1024 * 1024, + .period_bytes_min = 32, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 2 * 1024 * 1024, + .fifo_size = 0, +}; + +static int psc_i2s_pcm_open(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; + struct psc_i2s_stream *s; + + dev_dbg(psc_i2s->dev, "psc_i2s_pcm_open(substream=%p)\n", substream); + + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) + s = &psc_i2s->capture; + else + s = &psc_i2s->playback; + + snd_soc_set_runtime_hwparams(substream, &psc_i2s_pcm_hardware); + + s->stream = substream; + return 0; +} + +static int psc_i2s_pcm_close(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; + struct psc_i2s_stream *s; + + dev_dbg(psc_i2s->dev, "psc_i2s_pcm_close(substream=%p)\n", substream); + + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) + s = &psc_i2s->capture; + else + s = &psc_i2s->playback; + + s->stream = NULL; + return 0; +} + +static snd_pcm_uframes_t +psc_i2s_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; + struct psc_i2s_stream *s; + dma_addr_t count; + + if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) + s = &psc_i2s->capture; + else + s = &psc_i2s->playback; + + count = s->period_current_pt - s->period_start; + + return bytes_to_frames(substream->runtime, count); +} + +static struct snd_pcm_ops psc_i2s_pcm_ops = { + .open = psc_i2s_pcm_open, + .close = psc_i2s_pcm_close, + .ioctl = snd_pcm_lib_ioctl, + .pointer = psc_i2s_pcm_pointer, +}; + +static u64 psc_i2s_pcm_dmamask = 0xffffffff; +static int psc_i2s_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, + struct snd_pcm *pcm) +{ + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + size_t size = psc_i2s_pcm_hardware.buffer_bytes_max; + int rc = 0; + + dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_new(card=%p, dai=%p, pcm=%p)\n", + card, dai, pcm); + + if (!card->dev->dma_mask) + card->dev->dma_mask = &psc_i2s_pcm_dmamask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (pcm->streams[0].substream) { + rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size, + &pcm->streams[0].substream->dma_buffer); + if (rc) + goto playback_alloc_err; + } + + if (pcm->streams[1].substream) { + rc = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, pcm->dev, size, + &pcm->streams[1].substream->dma_buffer); + if (rc) + goto capture_alloc_err; + } + + return 0; + + capture_alloc_err: + if (pcm->streams[0].substream) + snd_dma_free_pages(&pcm->streams[0].substream->dma_buffer); + playback_alloc_err: + dev_err(card->dev, "Cannot allocate buffer(s)\n"); + return -ENOMEM; +} + +static void psc_i2s_pcm_free(struct snd_pcm *pcm) +{ + struct snd_soc_pcm_runtime *rtd = pcm->private_data; + struct snd_pcm_substream *substream; + int stream; + + dev_dbg(rtd->socdev->dev, "psc_i2s_pcm_free(pcm=%p)\n", pcm); + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (substream) { + snd_dma_free_pages(&substream->dma_buffer); + substream->dma_buffer.area = NULL; + substream->dma_buffer.addr = 0; + } + } +} + +struct snd_soc_platform psc_i2s_pcm_soc_platform = { + .name = "mpc5200-psc-audio", + .pcm_ops = &psc_i2s_pcm_ops, + .pcm_new = &psc_i2s_pcm_new, + .pcm_free = &psc_i2s_pcm_free, +}; + +/* --------------------------------------------------------------------- + * Sysfs attributes for debugging + */ + +static ssize_t psc_i2s_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct psc_i2s *psc_i2s = dev_get_drvdata(dev); + + return sprintf(buf, "status=%.4x sicr=%.8x rfnum=%i rfstat=0x%.4x " + "tfnum=%i tfstat=0x%.4x\n", + in_be16(&psc_i2s->psc_regs->sr_csr.status), + in_be32(&psc_i2s->psc_regs->sicr), + in_be16(&psc_i2s->fifo_regs->rfnum) & 0x1ff, + in_be16(&psc_i2s->fifo_regs->rfstat), + in_be16(&psc_i2s->fifo_regs->tfnum) & 0x1ff, + in_be16(&psc_i2s->fifo_regs->tfstat)); +} + +static int *psc_i2s_get_stat_attr(struct psc_i2s *psc_i2s, const char *name) +{ + if (strcmp(name, "playback_underrun") == 0) + return &psc_i2s->stats.underrun_count; + if (strcmp(name, "capture_overrun") == 0) + return &psc_i2s->stats.overrun_count; + + return NULL; +} + +static ssize_t psc_i2s_stat_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct psc_i2s *psc_i2s = dev_get_drvdata(dev); + int *attrib; + + attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name); + if (!attrib) + return 0; + + return sprintf(buf, "%i\n", *attrib); +} + +static ssize_t psc_i2s_stat_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t count) +{ + struct psc_i2s *psc_i2s = dev_get_drvdata(dev); + int *attrib; + + attrib = psc_i2s_get_stat_attr(psc_i2s, attr->attr.name); + if (!attrib) + return 0; + + *attrib = simple_strtoul(buf, NULL, 0); + return count; +} + +static DEVICE_ATTR(status, 0644, psc_i2s_status_show, NULL); +static DEVICE_ATTR(playback_underrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); +static DEVICE_ATTR(capture_overrun, 0644, psc_i2s_stat_show, + psc_i2s_stat_store); /* --------------------------------------------------------------------- * OF platform bus binding code: @@ -156,65 +718,150 @@ EXPORT_SYMBOL_GPL(psc_i2s_dai); static int __devinit psc_i2s_of_probe(struct of_device *op, const struct of_device_id *match) { - int rc; - struct psc_dma *psc_dma; - struct mpc52xx_psc __iomem *regs; - - rc = mpc5200_audio_dma_create(op); - if (rc != 0) - return rc; + phys_addr_t fifo; + struct psc_i2s *psc_i2s; + struct resource res; + int size, psc_id, irq, rc; + const __be32 *prop; + void __iomem *regs; + + dev_dbg(&op->dev, "probing psc i2s device\n"); + + /* Get the PSC ID */ + prop = of_get_property(op->node, "cell-index", &size); + if (!prop || size < sizeof *prop) + return -ENODEV; + psc_id = be32_to_cpu(*prop); + + /* Fetch the registers and IRQ of the PSC */ + irq = irq_of_parse_and_map(op->node, 0); + if (of_address_to_resource(op->node, 0, &res)) { + dev_err(&op->dev, "Missing reg property\n"); + return -ENODEV; + } + regs = ioremap(res.start, 1 + res.end - res.start); + if (!regs) { + dev_err(&op->dev, "Could not map registers\n"); + return -ENODEV; + } - rc = snd_soc_register_dais(psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai)); - if (rc != 0) { - pr_err("Failed to register DAI\n"); - return 0; + /* Allocate and initialize the driver private data */ + psc_i2s = kzalloc(sizeof *psc_i2s, GFP_KERNEL); + if (!psc_i2s) { + iounmap(regs); + return -ENOMEM; + } + spin_lock_init(&psc_i2s->lock); + psc_i2s->irq = irq; + psc_i2s->psc_regs = regs; + psc_i2s->fifo_regs = regs + sizeof *psc_i2s->psc_regs; + psc_i2s->dev = &op->dev; + psc_i2s->playback.psc_i2s = psc_i2s; + psc_i2s->capture.psc_i2s = psc_i2s; + snprintf(psc_i2s->name, sizeof psc_i2s->name, "PSC%u", psc_id+1); + + /* Fill out the CPU DAI structure */ + memcpy(&psc_i2s->dai, &psc_i2s_dai_template, sizeof psc_i2s->dai); + psc_i2s->dai.private_data = psc_i2s; + psc_i2s->dai.name = psc_i2s->name; + psc_i2s->dai.id = psc_id; + + /* Find the address of the fifo data registers and setup the + * DMA tasks */ + fifo = res.start + offsetof(struct mpc52xx_psc, buffer.buffer_32); + psc_i2s->capture.bcom_task = + bcom_psc_gen_bd_rx_init(psc_id, 10, fifo, 512); + psc_i2s->playback.bcom_task = + bcom_psc_gen_bd_tx_init(psc_id, 10, fifo); + if (!psc_i2s->capture.bcom_task || + !psc_i2s->playback.bcom_task) { + dev_err(&op->dev, "Could not allocate bestcomm tasks\n"); + iounmap(regs); + kfree(psc_i2s); + return -ENODEV; } - psc_dma = dev_get_drvdata(&op->dev); - regs = psc_dma->psc_regs; + /* Disable all interrupts and reset the PSC */ + out_be16(&psc_i2s->psc_regs->isr_imr.imr, 0); + out_8(&psc_i2s->psc_regs->command, 3 << 4); /* reset transmitter */ + out_8(&psc_i2s->psc_regs->command, 2 << 4); /* reset receiver */ + out_8(&psc_i2s->psc_regs->command, 1 << 4); /* reset mode */ + out_8(&psc_i2s->psc_regs->command, 4 << 4); /* reset error */ /* Configure the serial interface mode; defaulting to CODEC8 mode */ - psc_dma->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S | + psc_i2s->sicr = MPC52xx_PSC_SICR_DTS1 | MPC52xx_PSC_SICR_I2S | MPC52xx_PSC_SICR_CLKPOL; - out_be32(&psc_dma->psc_regs->sicr, - psc_dma->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8); + if (of_get_property(op->node, "fsl,cellslave", NULL)) + psc_i2s->sicr |= MPC52xx_PSC_SICR_CELLSLAVE | + MPC52xx_PSC_SICR_GENCLK; + out_be32(&psc_i2s->psc_regs->sicr, + psc_i2s->sicr | MPC52xx_PSC_SICR_SIM_CODEC_8); /* Check for the codec handle. If it is not present then we * are done */ if (!of_get_property(op->node, "codec-handle", NULL)) return 0; - /* Due to errata in the dma mode; need to line up enabling - * the transmitter with a transition on the frame sync - * line */ - - /* first make sure it is low */ - while ((in_8(®s->ipcr_acr.ipcr) & 0x80) != 0) - ; - /* then wait for the transition to high */ - while ((in_8(®s->ipcr_acr.ipcr) & 0x80) == 0) - ; - /* Finally, enable the PSC. - * Receiver must always be enabled; even when we only want - * transmit. (see 15.3.2.3 of MPC5200B User's Guide) */ - - /* Go */ - out_8(&psc_dma->psc_regs->command, - MPC52xx_PSC_TX_ENABLE | MPC52xx_PSC_RX_ENABLE); + /* Set up mode register; + * First write: RxRdy (FIFO Alarm) generates rx FIFO irq + * Second write: register Normal mode for non loopback + */ + out_8(&psc_i2s->psc_regs->mode, 0); + out_8(&psc_i2s->psc_regs->mode, 0); + + /* Set the TX and RX fifo alarm thresholds */ + out_be16(&psc_i2s->fifo_regs->rfalarm, 0x100); + out_8(&psc_i2s->fifo_regs->rfcntl, 0x4); + out_be16(&psc_i2s->fifo_regs->tfalarm, 0x100); + out_8(&psc_i2s->fifo_regs->tfcntl, 0x7); + + /* Lookup the IRQ numbers */ + psc_i2s->playback.irq = + bcom_get_task_irq(psc_i2s->playback.bcom_task); + psc_i2s->capture.irq = + bcom_get_task_irq(psc_i2s->capture.bcom_task); + + /* Save what we've done so it can be found again later */ + dev_set_drvdata(&op->dev, psc_i2s); + + /* Register the SYSFS files */ + rc = device_create_file(psc_i2s->dev, &dev_attr_status); + rc |= device_create_file(psc_i2s->dev, &dev_attr_capture_overrun); + rc |= device_create_file(psc_i2s->dev, &dev_attr_playback_underrun); + 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); return 0; - } static int __devexit psc_i2s_of_remove(struct of_device *op) { - return mpc5200_audio_dma_destroy(op); + struct psc_i2s *psc_i2s = dev_get_drvdata(&op->dev); + + 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); + + iounmap(psc_i2s->psc_regs); + iounmap(psc_i2s->fifo_regs); + kfree(psc_i2s); + dev_set_drvdata(&op->dev, NULL); + + return 0; } /* Match table for of_platform binding */ static struct of_device_id psc_i2s_match[] __devinitdata = { { .compatible = "fsl,mpc5200-psc-i2s", }, - { .compatible = "fsl,mpc5200b-psc-i2s", }, {} }; MODULE_DEVICE_TABLE(of, psc_i2s_match); @@ -245,7 +892,4 @@ static void __exit psc_i2s_exit(void) } module_exit(psc_i2s_exit); -MODULE_AUTHOR("Grant Likely "); -MODULE_DESCRIPTION("Freescale MPC5200 PSC in I2S mode ASoC Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/fsl/mpc5200_psc_i2s.h b/trunk/sound/soc/fsl/mpc5200_psc_i2s.h deleted file mode 100644 index ce55e070fdf3..000000000000 --- a/trunk/sound/soc/fsl/mpc5200_psc_i2s.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Freescale MPC5200 PSC in I2S mode - * ALSA SoC Digital Audio Interface (DAI) driver - * - */ - -#ifndef __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__ -#define __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__ - -extern struct snd_soc_dai psc_i2s_dai[]; - -#endif /* __SOUND_SOC_FSL_MPC52xx_PSC_I2S_H__ */ diff --git a/trunk/sound/soc/fsl/pcm030-audio-fabric.c b/trunk/sound/soc/fsl/pcm030-audio-fabric.c deleted file mode 100644 index 8766f7a3893d..000000000000 --- a/trunk/sound/soc/fsl/pcm030-audio-fabric.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Phytec pcm030 driver for the PSC of the Freescale MPC52xx - * configured as AC97 interface - * - * Copyright 2008 Jon Smirl, Digispeaker - * Author: Jon Smirl - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "mpc5200_dma.h" -#include "mpc5200_psc_ac97.h" -#include "../codecs/wm9712.h" - -static struct snd_soc_device device; -static struct snd_soc_card card; - -static struct snd_soc_dai_link pcm030_fabric_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 Analog", - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI], - .cpu_dai = &psc_ac97_dai[MPC5200_AC97_NORMAL], -}, -{ - .name = "AC97", - .stream_name = "AC97 IEC958", - .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX], - .cpu_dai = &psc_ac97_dai[MPC5200_AC97_SPDIF], -}, -}; - -static __init int pcm030_fabric_init(void) -{ - struct platform_device *pdev; - int rc; - - if (!machine_is_compatible("phytec,pcm030")) - return -ENODEV; - - card.platform = &mpc5200_audio_dma_platform; - card.name = "pcm030"; - card.dai_link = pcm030_fabric_dai; - card.num_links = ARRAY_SIZE(pcm030_fabric_dai); - - device.card = &card; - device.codec_dev = &soc_codec_dev_wm9712; - - pdev = platform_device_alloc("soc-audio", 1); - if (!pdev) { - pr_err("pcm030_fabric_init: platform_device_alloc() failed\n"); - return -ENODEV; - } - - platform_set_drvdata(pdev, &device); - device.dev = &pdev->dev; - - rc = platform_device_add(pdev); - if (rc) { - pr_err("pcm030_fabric_init: platform_device_add() failed\n"); - return -ENODEV; - } - return 0; -} - -module_init(pcm030_fabric_init); - - -MODULE_AUTHOR("Jon Smirl "); -MODULE_DESCRIPTION(DRV_NAME ": mpc5200 pcm030 fabric driver"); -MODULE_LICENSE("GPL"); - diff --git a/trunk/sound/soc/omap/Kconfig b/trunk/sound/soc/omap/Kconfig index b771238662b6..675732e724d5 100644 --- a/trunk/sound/soc/omap/Kconfig +++ b/trunk/sound/soc/omap/Kconfig @@ -39,14 +39,6 @@ config SND_OMAP_SOC_OMAP2EVM help Say Y if you want to add support for SoC audio on the omap2evm board. -config SND_OMAP_SOC_OMAP3EVM - tristate "SoC Audio support for OMAP3EVM board" - depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM - select SND_OMAP_SOC_MCBSP - select SND_SOC_TWL4030 - help - Say Y if you want to add support for SoC audio on the omap3evm board. - config SND_OMAP_SOC_SDP3430 tristate "SoC Audio support for Texas Instruments SDP3430" depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP diff --git a/trunk/sound/soc/omap/Makefile b/trunk/sound/soc/omap/Makefile index a37f49862389..0c9e4ac37660 100644 --- a/trunk/sound/soc/omap/Makefile +++ b/trunk/sound/soc/omap/Makefile @@ -10,7 +10,6 @@ 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-omap3evm-objs := omap3evm.o snd-soc-sdp3430-objs := sdp3430.o snd-soc-omap3pandora-objs := omap3pandora.o snd-soc-omap3beagle-objs := omap3beagle.o @@ -19,7 +18,6 @@ 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_MACH_OMAP3EVM) += snd-soc-omap3evm.o obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o diff --git a/trunk/sound/soc/omap/n810.c b/trunk/sound/soc/omap/n810.c index b60b1dfbc435..91ef17992de5 100644 --- a/trunk/sound/soc/omap/n810.c +++ b/trunk/sound/soc/omap/n810.c @@ -383,9 +383,10 @@ static int __init n810_soc_init(void) clk_set_parent(sys_clkout2_src, func96m_clk); clk_set_rate(sys_clkout2, 12000000); - BUG_ON((gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) || - (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0)); - + if (gpio_request(N810_HEADSET_AMP_GPIO, "hs_amp") < 0) + BUG(); + if (gpio_request(N810_SPEAKER_AMP_GPIO, "spk_amp") < 0) + BUG(); gpio_direction_output(N810_HEADSET_AMP_GPIO, 0); gpio_direction_output(N810_SPEAKER_AMP_GPIO, 0); diff --git a/trunk/sound/soc/omap/omap-mcbsp.c b/trunk/sound/soc/omap/omap-mcbsp.c index a5d46a7b196a..912614283848 100644 --- a/trunk/sound/soc/omap/omap-mcbsp.c +++ b/trunk/sound/soc/omap/omap-mcbsp.c @@ -215,9 +215,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 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, channels, wpf; + int wlen, channels; unsigned long port; - unsigned int format; if (cpu_class_is_omap1()) { dma = omap1_dma_reqs[bus_id][substream->stream]; @@ -245,24 +244,18 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, return 0; } - format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; - wpf = channels = params_channels(params); + channels = params_channels(params); switch (channels) { case 2: - if (format == SND_SOC_DAIFMT_I2S) { - /* Use dual-phase frames */ - regs->rcr2 |= RPHASE; - regs->xcr2 |= XPHASE; - /* Set 1 word per (McBSP) frame for phase1 and phase2 */ - wpf--; - regs->rcr2 |= RFRLEN2(wpf - 1); - regs->xcr2 |= XFRLEN2(wpf - 1); - } + /* Use dual-phase frames */ + regs->rcr2 |= RPHASE; + regs->xcr2 |= XPHASE; case 1: - case 4: - /* Set word per (McBSP) frame for phase1 */ - regs->rcr1 |= RFRLEN1(wpf - 1); - regs->xcr1 |= XFRLEN1(wpf - 1); + /* Set 1 word per (McBSP) frame */ + regs->rcr2 |= RFRLEN2(1 - 1); + regs->rcr1 |= RFRLEN1(1 - 1); + regs->xcr2 |= XFRLEN2(1 - 1); + regs->xcr1 |= XFRLEN1(1 - 1); break; default: /* Unsupported number of channels */ @@ -284,12 +277,11 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, } /* Set FS period and length in terms of bit clock periods */ - switch (format) { + switch (mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_I2S: - regs->srgr2 |= FPER(wlen * channels - 1); + regs->srgr2 |= FPER(wlen * 2 - 1); regs->srgr1 |= FWID(wlen - 1); break; - case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: regs->srgr2 |= FPER(wlen * channels - 1); regs->srgr1 |= FWID(0); @@ -334,13 +326,6 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, regs->rcr2 |= RDATDLY(1); regs->xcr2 |= XDATDLY(1); break; - case SND_SOC_DAIFMT_DSP_A: - /* 1-bit data delay */ - regs->rcr2 |= RDATDLY(1); - regs->xcr2 |= XDATDLY(1); - /* Invert FS polarity configuration */ - temp_fmt ^= SND_SOC_DAIFMT_NB_IF; - break; case SND_SOC_DAIFMT_DSP_B: /* 0-bit data delay */ regs->rcr2 |= RDATDLY(0); @@ -507,13 +492,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = { .id = (link_id), \ .playback = { \ .channels_min = 1, \ - .channels_max = 4, \ + .channels_max = 2, \ .rates = OMAP_MCBSP_RATES, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ .capture = { \ .channels_min = 1, \ - .channels_max = 4, \ + .channels_max = 2, \ .rates = OMAP_MCBSP_RATES, \ .formats = SNDRV_PCM_FMTBIT_S16_LE, \ }, \ diff --git a/trunk/sound/soc/omap/omap-pcm.c b/trunk/sound/soc/omap/omap-pcm.c index 6454e15f7d28..07cf7f46b584 100644 --- a/trunk/sound/soc/omap/omap-pcm.c +++ b/trunk/sound/soc/omap/omap-pcm.c @@ -87,10 +87,8 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; int err = 0; - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ if (!dma_data) - return 0; + return -ENODEV; snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); runtime->dma_bytes = params_buffer_bytes(params); @@ -136,11 +134,6 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) struct omap_pcm_dma_data *dma_data = prtd->dma_data; struct omap_dma_channel_params dma_params; - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!prtd->dma_data) - return 0; - memset(&dma_params, 0, sizeof(dma_params)); /* * Note: Regardless of interface data formats supported by OMAP McBSP diff --git a/trunk/sound/soc/omap/omap2evm.c b/trunk/sound/soc/omap/omap2evm.c index 027e1a40f8a1..0c2322dcf02a 100644 --- a/trunk/sound/soc/omap/omap2evm.c +++ b/trunk/sound/soc/omap/omap2evm.c @@ -86,7 +86,7 @@ static struct snd_soc_dai_link omap2evm_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], + .codec_dai = &twl4030_dai, .ops = &omap2evm_ops, }; diff --git a/trunk/sound/soc/omap/omap3beagle.c b/trunk/sound/soc/omap/omap3beagle.c index b0cff9f33b7e..fd24a4acd2f5 100644 --- a/trunk/sound/soc/omap/omap3beagle.c +++ b/trunk/sound/soc/omap/omap3beagle.c @@ -41,33 +41,23 @@ static int omap3beagle_hw_params(struct snd_pcm_substream *substream, 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 fmt; int ret; - switch (params_channels(params)) { - case 2: /* Stereo I2S mode */ - fmt = SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM; - break; - case 4: /* Four channel TDM mode */ - fmt = SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBM_CFM; - break; - default: - return -EINVAL; - } - /* Set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, fmt); + 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, fmt); + 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; @@ -93,7 +83,7 @@ static struct snd_soc_dai_link omap3beagle_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], + .codec_dai = &twl4030_dai, .ops = &omap3beagle_ops, }; diff --git a/trunk/sound/soc/omap/omap3evm.c b/trunk/sound/soc/omap/omap3evm.c deleted file mode 100644 index 9114c263077b..000000000000 --- a/trunk/sound/soc/omap/omap3evm.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * omap3evm.c -- ALSA SoC support for OMAP3 EVM - * - * Author: Anuj Aggarwal - * - * Based on sound/soc/omap/beagle.c by Steve Sakoman - * - * Copyright (C) 2008 Texas Instruments, Incorporated - * - * 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 version 2. - * - * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, - * whether express or implied; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "omap-mcbsp.h" -#include "omap-pcm.h" -#include "../codecs/twl4030.h" - -static int omap3evm_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 omap3evm_ops = { - .hw_params = omap3evm_hw_params, -}; - -/* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link omap3evm_dai = { - .name = "TWL4030", - .stream_name = "TWL4030", - .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], - .ops = &omap3evm_ops, -}; - -/* Audio machine driver */ -static struct snd_soc_card snd_soc_omap3evm = { - .name = "omap3evm", - .platform = &omap_soc_platform, - .dai_link = &omap3evm_dai, - .num_links = 1, -}; - -/* Audio subsystem */ -static struct snd_soc_device omap3evm_snd_devdata = { - .card = &snd_soc_omap3evm, - .codec_dev = &soc_codec_dev_twl4030, -}; - -static struct platform_device *omap3evm_snd_device; - -static int __init omap3evm_soc_init(void) -{ - int ret; - - if (!machine_is_omap3evm()) { - pr_err("Not OMAP3 EVM!\n"); - return -ENODEV; - } - pr_info("OMAP3 EVM SoC init\n"); - - omap3evm_snd_device = platform_device_alloc("soc-audio", -1); - if (!omap3evm_snd_device) { - printk(KERN_ERR "Platform device allocation failed\n"); - return -ENOMEM; - } - - platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata); - omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev; - *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1; - - ret = platform_device_add(omap3evm_snd_device); - if (ret) - goto err1; - - return 0; - -err1: - printk(KERN_ERR "Unable to add platform device\n"); - platform_device_put(omap3evm_snd_device); - - return ret; -} - -static void __exit omap3evm_soc_exit(void) -{ - platform_device_unregister(omap3evm_snd_device); -} - -module_init(omap3evm_soc_init); -module_exit(omap3evm_soc_exit); - -MODULE_AUTHOR("Anuj Aggarwal "); -MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); -MODULE_LICENSE("GPLv2"); diff --git a/trunk/sound/soc/omap/omap3pandora.c b/trunk/sound/soc/omap/omap3pandora.c index ad219aaf7cb8..fe282d4ef422 100644 --- a/trunk/sound/soc/omap/omap3pandora.c +++ b/trunk/sound/soc/omap/omap3pandora.c @@ -228,14 +228,14 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { .name = "PCM1773", .stream_name = "HiFi Out", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], + .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[TWL4030_DAI_HIFI], + .codec_dai = &twl4030_dai, .ops = &omap3pandora_in_ops, .init = omap3pandora_in_init, } diff --git a/trunk/sound/soc/omap/overo.c b/trunk/sound/soc/omap/overo.c index ec4f8fd8b3a2..a72dc4e159e5 100644 --- a/trunk/sound/soc/omap/overo.c +++ b/trunk/sound/soc/omap/overo.c @@ -83,7 +83,7 @@ static struct snd_soc_dai_link overo_dai = { .name = "TWL4030", .stream_name = "TWL4030", .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], + .codec_dai = &twl4030_dai, .ops = &overo_ops, }; diff --git a/trunk/sound/soc/omap/sdp3430.c b/trunk/sound/soc/omap/sdp3430.c index b719e5db4f57..10f1c867f11d 100644 --- a/trunk/sound/soc/omap/sdp3430.c +++ b/trunk/sound/soc/omap/sdp3430.c @@ -84,49 +84,6 @@ static struct snd_soc_ops sdp3430_ops = { .hw_params = sdp3430_hw_params, }; -static int sdp3430_hw_voice_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_DSP_A | - SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBS_CFM); - if (ret) { - 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_DSP_A | - SND_SOC_DAIFMT_IB_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_voice_ops = { - .hw_params = sdp3430_hw_voice_params, -}; - /* Headset jack */ static struct snd_soc_jack hs_jack; @@ -235,58 +192,28 @@ static int sdp3430_twl4030_init(struct snd_soc_codec *codec) return ret; } -static int sdp3430_twl4030_voice_init(struct snd_soc_codec *codec) -{ - unsigned short reg; - - /* Enable voice interface */ - reg = codec->read(codec, TWL4030_REG_VOICE_IF); - reg |= TWL4030_VIF_DIN_EN | TWL4030_VIF_DOUT_EN | TWL4030_VIF_EN; - codec->write(codec, TWL4030_REG_VOICE_IF, reg); - - return 0; -} - - /* Digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link sdp3430_dai[] = { - { - .name = "TWL4030 I2S", - .stream_name = "TWL4030 Audio", - .cpu_dai = &omap_mcbsp_dai[0], - .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI], - .init = sdp3430_twl4030_init, - .ops = &sdp3430_ops, - }, - { - .name = "TWL4030 PCM", - .stream_name = "TWL4030 Voice", - .cpu_dai = &omap_mcbsp_dai[1], - .codec_dai = &twl4030_dai[TWL4030_DAI_VOICE], - .init = sdp3430_twl4030_voice_init, - .ops = &sdp3430_voice_ops, - }, +static struct snd_soc_dai_link sdp3430_dai = { + .name = "TWL4030", + .stream_name = "TWL4030", + .cpu_dai = &omap_mcbsp_dai[0], + .codec_dai = &twl4030_dai, + .init = sdp3430_twl4030_init, + .ops = &sdp3430_ops, }; /* Audio machine driver */ static struct snd_soc_card snd_soc_sdp3430 = { .name = "SDP3430", .platform = &omap_soc_platform, - .dai_link = sdp3430_dai, - .num_links = ARRAY_SIZE(sdp3430_dai), -}; - -/* twl4030 setup */ -static struct twl4030_setup_data twl4030_setup = { - .ramp_delay_value = 3, - .sysclk = 26000, + .dai_link = &sdp3430_dai, + .num_links = 1, }; /* Audio subsystem */ static struct snd_soc_device sdp3430_snd_devdata = { .card = &snd_soc_sdp3430, .codec_dev = &soc_codec_dev_twl4030, - .codec_data = &twl4030_setup, }; static struct platform_device *sdp3430_snd_device; @@ -309,8 +236,7 @@ static int __init sdp3430_soc_init(void) platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata); sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev; - *(unsigned int *)sdp3430_dai[0].cpu_dai->private_data = 1; /* McBSP2 */ - *(unsigned int *)sdp3430_dai[1].cpu_dai->private_data = 2; /* McBSP3 */ + *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */ ret = platform_device_add(sdp3430_snd_device); if (ret) diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig index dcd163a4ee9a..ad8a10fe6298 100644 --- a/trunk/sound/soc/pxa/Kconfig +++ b/trunk/sound/soc/pxa/Kconfig @@ -89,13 +89,13 @@ config SND_PXA2XX_SOC_E800 Toshiba e800 PDA config SND_PXA2XX_SOC_EM_X270 - tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300" + tristate "SoC Audio support for CompuLab EM-x270" depends on SND_PXA2XX_SOC && MACH_EM_X270 select SND_PXA2XX_SOC_AC97 select SND_SOC_WM9712 help Say Y if you want to add support for SoC audio on - CompuLab EM-x270, eXeda and CM-X300 machines. + CompuLab EM-x270. config SND_PXA2XX_SOC_PALM27X bool "SoC Audio support for Palm T|X, T5 and LifeDrive" @@ -134,12 +134,3 @@ config SND_PXA2XX_SOC_MIOA701 help Say Y if you want to add support for SoC audio on the MIO A701. - -config SND_PXA2XX_SOC_IMOTE2 - tristate "SoC Audio support for IMote 2" - depends on SND_PXA2XX_SOC && MACH_INTELMOTE2 - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8940 - help - Say Y if you want to add support for SoC audio on the - IMote 2. diff --git a/trunk/sound/soc/pxa/Makefile b/trunk/sound/soc/pxa/Makefile index 6e096b480335..4b90c3ccae45 100644 --- a/trunk/sound/soc/pxa/Makefile +++ b/trunk/sound/soc/pxa/Makefile @@ -22,7 +22,6 @@ snd-soc-palm27x-objs := palm27x.o snd-soc-zylonite-objs := zylonite.o snd-soc-magician-objs := magician.o snd-soc-mioa701-objs := mioa701_wm9713.o -snd-soc-imote2-objs := imote2.o obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o @@ -36,4 +35,3 @@ obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o -obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o diff --git a/trunk/sound/soc/pxa/em-x270.c b/trunk/sound/soc/pxa/em-x270.c index f4756e4025fd..949be9c2a01b 100644 --- a/trunk/sound/soc/pxa/em-x270.c +++ b/trunk/sound/soc/pxa/em-x270.c @@ -1,7 +1,7 @@ /* - * SoC audio driver for EM-X270, eXeda and CM-X300 + * em-x270.c -- SoC audio for EM-X270 * - * Copyright 2007, 2009 CompuLab, Ltd. + * Copyright 2007 CompuLab, Ltd. * * Author: Mike Rapoport * @@ -68,8 +68,7 @@ static int __init em_x270_init(void) { int ret; - if (!(machine_is_em_x270() || machine_is_exeda() - || machine_is_cm_x300())) + if (!machine_is_em_x270()) return -ENODEV; em_x270_snd_device = platform_device_alloc("soc-audio", -1); @@ -96,5 +95,5 @@ module_exit(em_x270_exit); /* Module information */ MODULE_AUTHOR("Mike Rapoport"); -MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300"); +MODULE_DESCRIPTION("ALSA SoC EM-X270"); MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/imote2.c b/trunk/sound/soc/pxa/imote2.c deleted file mode 100644 index 405587a01160..000000000000 --- a/trunk/sound/soc/pxa/imote2.c +++ /dev/null @@ -1,114 +0,0 @@ - -#include -#include - -#include - -#include "../codecs/wm8940.h" -#include "pxa2xx-i2s.h" -#include "pxa2xx-pcm.h" - -static int imote2_asoc_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; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* 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; - - /* CPU should be clock master */ - 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(codec_dai, 0, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, clk, - SND_SOC_CLOCK_OUT); - - return ret; -} - -static struct snd_soc_ops imote2_asoc_ops = { - .hw_params = imote2_asoc_hw_params, -}; - -static struct snd_soc_dai_link imote2_dai = { - .name = "WM8940", - .stream_name = "WM8940", - .cpu_dai = &pxa_i2s_dai, - .codec_dai = &wm8940_dai, - .ops = &imote2_asoc_ops, -}; - -static struct snd_soc_card snd_soc_imote2 = { - .name = "Imote2", - .platform = &pxa2xx_soc_platform, - .dai_link = &imote2_dai, - .num_links = 1, -}; - -static struct snd_soc_device imote2_snd_devdata = { - .card = &snd_soc_imote2, - .codec_dev = &soc_codec_dev_wm8940, -}; - -static struct platform_device *imote2_snd_device; - -static int __init imote2_asoc_init(void) -{ - int ret; - - if (!machine_is_intelmote2()) - return -ENODEV; - imote2_snd_device = platform_device_alloc("soc-audio", -1); - if (!imote2_snd_device) - return -ENOMEM; - - platform_set_drvdata(imote2_snd_device, &imote2_snd_devdata); - imote2_snd_devdata.dev = &imote2_snd_device->dev; - ret = platform_device_add(imote2_snd_device); - if (ret) - platform_device_put(imote2_snd_device); - - return ret; -} -module_init(imote2_asoc_init); - -static void __exit imote2_asoc_exit(void) -{ - platform_device_unregister(imote2_snd_device); -} -module_exit(imote2_asoc_exit); - -MODULE_AUTHOR("Jonathan Cameron"); -MODULE_DESCRIPTION("ALSA SoC Imote 2"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/pxa/magician.c b/trunk/sound/soc/pxa/magician.c index c89a3cdf31e4..0625c342a1c9 100644 --- a/trunk/sound/soc/pxa/magician.c +++ b/trunk/sound/soc/pxa/magician.c @@ -106,7 +106,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* 513156 Hz ~= _2_ * 8000 Hz * 32 (+0.23%) */ acds = PXA_SSP_CLK_AUDIO_DIV_16; break; - default: /* 32 */ + case 32: /* 1026312 Hz ~= _2_ * 8000 Hz * 64 (+0.23%) */ acds = PXA_SSP_CLK_AUDIO_DIV_8; } @@ -118,7 +118,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* 351375 Hz ~= 11025 Hz * 32 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_4; break; - default: /* 32 */ + case 32: /* 702750 Hz ~= 11025 Hz * 64 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_2; } @@ -130,7 +130,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* 702750 Hz ~= 22050 Hz * 32 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_2; break; - default: /* 32 */ + case 32: /* 1405500 Hz ~= 22050 Hz * 64 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_1; } @@ -142,7 +142,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* 1405500 Hz ~= 44100 Hz * 32 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_2; break; - default: /* 32 */ + case 32: /* 2811000 Hz ~= 44100 Hz * 64 (-0.41%) */ acds = PXA_SSP_CLK_AUDIO_DIV_1; } @@ -154,20 +154,19 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, /* 1529375 Hz ~= 48000 Hz * 32 (-0.44%) */ acds = PXA_SSP_CLK_AUDIO_DIV_2; break; - default: /* 32 */ + case 32: /* 3058750 Hz ~= 48000 Hz * 64 (-0.44%) */ acds = PXA_SSP_CLK_AUDIO_DIV_1; } break; case 96000: - default: acps = 12235000; switch (width) { case 16: /* 3058750 Hz ~= 96000 Hz * 32 (-0.44%) */ acds = PXA_SSP_CLK_AUDIO_DIV_1; break; - default: /* 32 */ + case 32: /* 6117500 Hz ~= 96000 Hz * 64 (-0.44%) */ acds = PXA_SSP_CLK_AUDIO_DIV_2; div4 = PXA_SSP_CLK_SCDB_1; diff --git a/trunk/sound/soc/pxa/pxa-ssp.c b/trunk/sound/soc/pxa/pxa-ssp.c index 19c45409d94c..286be31545df 100644 --- a/trunk/sound/soc/pxa/pxa-ssp.c +++ b/trunk/sound/soc/pxa/pxa-ssp.c @@ -50,6 +50,139 @@ struct ssp_priv { #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", @@ -61,33 +194,25 @@ static void dump_registers(struct ssp_device *ssp) ssp_read_reg(ssp, SSACD)); } -struct pxa2xx_pcm_dma_data { - struct pxa2xx_pcm_dma_params params; - char name[20]; +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 struct pxa2xx_pcm_dma_params * -ssp_get_dma_params(struct ssp_device *ssp, int width4, int out) -{ - struct pxa2xx_pcm_dma_data *dma; - - dma = kzalloc(sizeof(struct pxa2xx_pcm_dma_data), GFP_KERNEL); - if (dma == NULL) - return NULL; - - snprintf(dma->name, 20, "SSP%d PCM %s %s", ssp->port_id, - width4 ? "32-bit" : "16-bit", out ? "out" : "in"); - - dma->params.name = dma->name; - dma->params.drcmr = &DRCMR(out ? ssp->drcmr_tx : ssp->drcmr_rx); - dma->params.dcmd = (out ? (DCMD_INCSRCADDR | DCMD_FLOWTRG) : - (DCMD_INCTRGADDR | DCMD_FLOWSRC)) | - (width4 ? DCMD_WIDTH4 : DCMD_WIDTH2) | DCMD_BURST16; - dma->params.dev_addr = ssp->phys_base + SSDR; - - return &dma->params; -} - static int pxa_ssp_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { @@ -102,11 +227,6 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, clk_enable(priv->dev.ssp->clk); ssp_disable(&priv->dev); } - - if (cpu_dai->dma_data) { - kfree(cpu_dai->dma_data); - cpu_dai->dma_data = NULL; - } return ret; } @@ -121,11 +241,6 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, ssp_disable(&priv->dev); clk_disable(priv->dev.ssp->clk); } - - if (cpu_dai->dma_data) { - kfree(cpu_dai->dma_data); - cpu_dai->dma_data = NULL; - } } #ifdef CONFIG_PM @@ -208,7 +323,7 @@ static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai, ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ACS); dev_dbg(&ssp->pdev->dev, - "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %u\n", + "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n", cpu_dai->id, clk_id, freq); switch (clk_id) { @@ -357,7 +472,7 @@ static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, ssacd |= (0x6 << 4); dev_dbg(&ssp->pdev->dev, - "Using SSACDD %x to supply %uHz\n", + "Using SSACDD %x to supply %dHz\n", val, freq_out); break; } @@ -474,10 +589,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_NB_IF: break; case SND_SOC_DAIFMT_IB_IF: - sspsp |= SSPSP_SCMODE(2); - break; - case SND_SOC_DAIFMT_IB_NF: - sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP; + sspsp |= SSPSP_SCMODE(3); break; default: return -EINVAL; @@ -494,13 +606,7 @@ static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_NB_NF: sspsp |= SSPSP_SFRMP; break; - case SND_SOC_DAIFMT_NB_IF: - break; case SND_SOC_DAIFMT_IB_IF: - sspsp |= SSPSP_SCMODE(2); - break; - case SND_SOC_DAIFMT_IB_NF: - sspsp |= SSPSP_SCMODE(2) | SSPSP_SFRMP; break; default: return -EINVAL; @@ -538,23 +644,25 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, 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 chn = params_channels(params); + int dma = 0, chn = params_channels(params); u32 sscr0; u32 sspsp; int width = snd_pcm_format_physical_width(params_format(params)); int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; - /* generate correct DMA params */ - if (cpu_dai->dma_data) - kfree(cpu_dai->dma_data); - + /* select correct DMA params */ + if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK) + dma = 1; /* capture DMA offset is 1,3 */ /* Network mode with one active slot (ttsa == 1) can be used * to force 16-bit frame width on the wire (for S16_LE), even * with two channels. Use 16-bit DMA transfers for this case. */ - cpu_dai->dma_data = ssp_get_dma_params(ssp, - ((chn == 2) && (ttsa != 1)) || (width == 32), - substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + if (((chn == 2) && (ttsa != 1)) || (width == 32)) + dma += 2; /* 32-bit DMA offset is 2, 16-bit 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) diff --git a/trunk/sound/soc/pxa/pxa2xx-i2s.c b/trunk/sound/soc/pxa/pxa2xx-i2s.c index 4743e262895d..2f4b6e489b78 100644 --- a/trunk/sound/soc/pxa/pxa2xx-i2s.c +++ b/trunk/sound/soc/pxa/pxa2xx-i2s.c @@ -106,8 +106,10 @@ static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream, if (IS_ERR(clk_i2s)) return PTR_ERR(clk_i2s); - if (!cpu_dai->active) + if (!cpu_dai->active) { + SACR0 |= SACR0_RST; SACR0 = 0; + } return 0; } @@ -176,7 +178,9 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, /* is port used by another stream */ if (!(SACR0 & SACR0_ENB)) { + SACR0 = 0; + SACR1 = 0; if (pxa_i2s.master) SACR0 |= SACR0_BCKD; @@ -222,10 +226,6 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - SACR1 &= ~SACR1_DRPL; - else - SACR1 &= ~SACR1_DREC; SACR0 |= SACR0_ENB; break; case SNDRV_PCM_TRIGGER_RESUME: @@ -252,16 +252,21 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream, SAIMR &= ~SAIMR_RFS; } - if ((SACR1 & (SACR1_DREC | SACR1_DRPL)) == (SACR1_DREC | SACR1_DRPL)) { + if (SACR1 & (SACR1_DREC | SACR1_DRPL)) { SACR0 &= ~SACR0_ENB; pxa_i2s_wait(); clk_disable(clk_i2s); } + + clk_put(clk_i2s); } #ifdef CONFIG_PM static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) { + if (!dai->active) + return 0; + /* store registers */ pxa_i2s.sacr0 = SACR0; pxa_i2s.sacr1 = SACR1; @@ -276,14 +281,16 @@ static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai) static int pxa2xx_i2s_resume(struct snd_soc_dai *dai) { + if (!dai->active) + return 0; + pxa_i2s_wait(); - SACR0 = pxa_i2s.sacr0 & ~SACR0_ENB; + SACR0 = pxa_i2s.sacr0 &= ~SACR0_ENB; SACR1 = pxa_i2s.sacr1; SAIMR = pxa_i2s.saimr; SADIV = pxa_i2s.sadiv; - - SACR0 = pxa_i2s.sacr0; + SACR0 |= SACR0_ENB; return 0; } @@ -322,7 +329,6 @@ struct snd_soc_dai pxa_i2s_dai = { .rates = PXA2XX_I2S_RATES, .formats = SNDRV_PCM_FMTBIT_S16_LE,}, .ops = &pxa_i2s_dai_ops, - .symmetric_rates = 1, }; EXPORT_SYMBOL_GPL(pxa_i2s_dai); @@ -340,19 +346,6 @@ static int pxa2xx_i2s_probe(struct platform_device *dev) if (ret != 0) clk_put(clk_i2s); - /* - * PXA Developer's Manual: - * If SACR0[ENB] is toggled in the middle of a normal operation, - * the SACR0[RST] bit must also be set and cleared to reset all - * I2S controller registers. - */ - SACR0 = SACR0_RST; - SACR0 = 0; - /* Make sure RPL and REC are disabled */ - SACR1 = SACR1_DRPL | SACR1_DREC; - /* Along with FIFO servicing */ - SAIMR &= ~(SAIMR_RFS | SAIMR_TFS); - return ret; } diff --git a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c b/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c index 1a283170ca92..ab680aac3fcb 100644 --- a/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/trunk/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -37,20 +37,6 @@ #include "s3c-i2s-v2.h" -#undef S3C_IIS_V2_SUPPORTED - -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) -#define S3C_IIS_V2_SUPPORTED -#endif - -#ifdef CONFIG_PLAT_S3C64XX -#define S3C_IIS_V2_SUPPORTED -#endif - -#ifndef S3C_IIS_V2_SUPPORTED -#error Unsupported CPU model -#endif - #define S3C2412_I2S_DEBUG_CON 0 static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) @@ -89,7 +75,7 @@ static inline void dbg_showcon(const char *fn, u32 con) /* Turn on or off the transmission path. */ -static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) +void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -119,9 +105,7 @@ static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; + dev_err(i2s->dev, "TXEN: Invalid MODE in IISMOD\n"); } writel(con, regs + S3C2412_IISCON); @@ -148,9 +132,7 @@ static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; + dev_err(i2s->dev, "TXDIS: Invalid MODE in IISMOD\n"); } writel(mod, regs + S3C2412_IISMOD); @@ -161,8 +143,9 @@ static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) dbg_showcon(__func__, con); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } +EXPORT_SYMBOL_GPL(s3c2412_snd_txctrl); -static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) +void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) { void __iomem *regs = i2s->regs; u32 fic, con, mod; @@ -192,8 +175,7 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); } writel(mod, regs + S3C2412_IISMOD); @@ -217,8 +199,7 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) break; default: - dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); + dev_err(i2s->dev, "RXEN: Invalid MODE in IISMOD\n"); } writel(con, regs + S3C2412_IISCON); @@ -228,6 +209,7 @@ static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) fic = readl(regs + S3C2412_IISFIC); pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); } +EXPORT_SYMBOL_GPL(s3c2412_snd_rxctrl); /* * Wait for the LR signal to allow synchronisation to the L/R clock @@ -284,7 +266,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, */ #define IISMOD_MASTER_MASK (1 << 11) #define IISMOD_SLAVE (1 << 11) -#define IISMOD_MASTER (0 << 11) +#define IISMOD_MASTER (0x0) #endif switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { @@ -299,7 +281,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= IISMOD_MASTER; break; default: - pr_err("unknwon master/slave format\n"); + pr_debug("unknwon master/slave format\n"); return -EINVAL; } @@ -316,7 +298,7 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, iismod |= S3C2412_IISMOD_SDF_IIS; break; default: - pr_err("Unknown data format\n"); + pr_debug("Unknown data format\n"); return -EINVAL; } @@ -345,7 +327,6 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod = readl(i2s->regs + S3C2412_IISMOD); pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) switch (params_format(params)) { case SNDRV_PCM_FORMAT_S8: iismod |= S3C2412_IISMOD_8BIT; @@ -354,25 +335,6 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, iismod &= ~S3C2412_IISMOD_8BIT; break; } -#endif - -#ifdef CONFIG_PLAT_S3C64XX - iismod &= ~0x606; - /* Sample size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - /* 8 bit sample, 16fs BCLK */ - iismod |= 0x2004; - break; - case SNDRV_PCM_FORMAT_S16_LE: - /* 16 bit sample, 32fs BCLK */ - break; - case SNDRV_PCM_FORMAT_S24_LE: - /* 24 bit sample, 48fs BCLK */ - iismod |= 0x4002; - break; - } -#endif writel(iismod, i2s->regs + S3C2412_IISMOD); pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); @@ -527,8 +489,6 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, unsigned int best_rate = 0; unsigned int best_deviation = INT_MAX; - pr_debug("Input clock rate %ldHz\n", clkrate); - if (fstab == NULL) fstab = iis_fs_tab; @@ -547,7 +507,7 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, actual = clkrate / (fsdiv * div); deviation = actual - rate; - printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n", + printk(KERN_DEBUG "%dfs: div %d => result %d, deviation %d\n", fsdiv, div, actual, deviation); deviation = abs(deviation); @@ -563,7 +523,7 @@ int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, break; } - printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n", + printk(KERN_DEBUG "best: fs=%d, div=%d, rate=%d\n", best_fs, best_div, best_rate); info->fs_div = best_fs; @@ -579,31 +539,12 @@ int s3c_i2sv2_probe(struct platform_device *pdev, unsigned long base) { struct device *dev = &pdev->dev; - unsigned int iismod; i2s->dev = dev; /* record our i2s structure for later use in the callbacks */ dai->private_data = i2s; - if (!base) { - struct resource *res = platform_get_resource(pdev, - IORESOURCE_MEM, - 0); - if (!res) { - dev_err(dev, "Unable to get register resource\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s-v4")) { - dev_err(dev, "Unable to request register region\n"); - return -EBUSY; - } - - base = res->start; - } - i2s->regs = ioremap(base, 0x100); if (i2s->regs == NULL) { dev_err(dev, "cannot ioremap registers\n"); @@ -619,16 +560,12 @@ int s3c_i2sv2_probe(struct platform_device *pdev, clk_enable(i2s->iis_pclk); - /* Mark ourselves as in TXRX mode so we can run through our cleanup - * process without warnings. */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - iismod |= S3C2412_IISMOD_MODE_TXRX; - writel(iismod, i2s->regs + S3C2412_IISMOD); s3c2412_snd_txctrl(i2s, 0); s3c2412_snd_rxctrl(i2s, 0); return 0; } + EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); #ifdef CONFIG_PM diff --git a/trunk/sound/soc/s3c24xx/s3c2412-i2s.c b/trunk/sound/soc/s3c24xx/s3c2412-i2s.c index 168a088ba761..b7e0b3f0bfc8 100644 --- a/trunk/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c2412-i2s.c @@ -120,7 +120,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev, s3c2412_i2s.iis_cclk = clk_get(&pdev->dev, "i2sclk"); if (s3c2412_i2s.iis_cclk == NULL) { - pr_err("failed to get i2sclk clock\n"); + pr_debug("failed to get i2sclk clock\n"); iounmap(s3c2412_i2s.regs); return -ENODEV; } diff --git a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c index 3c06c401d0fb..33c5de7e255f 100644 --- a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -108,19 +108,48 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, return 0; } -struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) + +unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *dai) { struct s3c_i2sv2_info *i2s = to_info(dai); - return i2s->iis_cclk; + return clk_get_rate(i2s->iis_cclk); } -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); +EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clockrate); static int s3c64xx_i2s_probe(struct platform_device *pdev, struct snd_soc_dai *dai) { + struct device *dev = &pdev->dev; + struct s3c_i2sv2_info *i2s; + int ret; + + dev_dbg(dev, "%s: probing dai %d\n", __func__, pdev->id); + + if (pdev->id < 0 || pdev->id > ARRAY_SIZE(s3c64xx_i2s)) { + dev_err(dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + i2s = &s3c64xx_i2s[pdev->id]; + + ret = s3c_i2sv2_probe(pdev, dai, i2s, + pdev->id ? S3C64XX_PA_IIS1 : S3C64XX_PA_IIS0); + if (ret) + return ret; + + i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; + i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; + + i2s->iis_cclk = clk_get(dev, "audio-bus"); + if (IS_ERR(i2s->iis_cclk)) { + dev_err(dev, "failed to get audio-bus"); + iounmap(i2s->regs); + return -ENODEV; + } + /* configure GPIO for i2s port */ - switch (dai->id) { + switch (pdev->id) { case 0: s3c_gpio_cfgpin(S3C64XX_GPD(0), S3C64XX_GPD0_I2S0_CLK); s3c_gpio_cfgpin(S3C64XX_GPD(1), S3C64XX_GPD1_I2S0_CDCLK); @@ -146,122 +175,41 @@ static int s3c64xx_i2s_probe(struct platform_device *pdev, SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) #define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE) + (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE) static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops = { .set_sysclk = s3c64xx_i2s_set_sysclk, }; -struct snd_soc_dai s3c64xx_i2s_dai[] = { - { - .name = "s3c64xx-i2s", - .id = 0, - .probe = s3c64xx_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, +struct snd_soc_dai s3c64xx_i2s_dai = { + .name = "s3c64xx-i2s", + .id = 0, + .probe = s3c64xx_i2s_probe, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, }, - { - .name = "s3c64xx-i2s", - .id = 1, - .probe = s3c64xx_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C64XX_I2S_RATES, + .formats = S3C64XX_I2S_FMTS, }, + .ops = &s3c64xx_i2s_dai_ops, }; EXPORT_SYMBOL_GPL(s3c64xx_i2s_dai); -static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) -{ - struct s3c_i2sv2_info *i2s; - struct snd_soc_dai *dai; - int ret; - - if (pdev->id >= ARRAY_SIZE(s3c64xx_i2s)) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[pdev->id]; - dai = &s3c64xx_i2s_dai[pdev->id]; - dai->dev = &pdev->dev; - - i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; - i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - - i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; - } - - ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); - if (ret) - goto err_clk; - - ret = s3c_i2sv2_register_dai(dai); - if (ret != 0) - goto err_i2sv2; - - return 0; - -err_i2sv2: - /* Not implemented for I2Sv2 core yet */ -err_clk: - clk_put(i2s->iis_cclk); -err: - return ret; -} - -static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) -{ - dev_err(&pdev->dev, "Device removal not yet supported\n"); - return 0; -} - -static struct platform_driver s3c64xx_iis_driver = { - .probe = s3c64xx_iis_dev_probe, - .remove = s3c64xx_iis_dev_remove, - .driver = { - .name = "s3c64xx-iis", - .owner = THIS_MODULE, - }, -}; - static int __init s3c64xx_i2s_init(void) { - return platform_driver_register(&s3c64xx_iis_driver); + return s3c_i2sv2_register_dai(&s3c64xx_i2s_dai); } module_init(s3c64xx_i2s_init); static void __exit s3c64xx_i2s_exit(void) { - platform_driver_unregister(&s3c64xx_iis_driver); + snd_soc_unregister_dai(&s3c64xx_i2s_dai); } module_exit(s3c64xx_i2s_exit); @@ -269,3 +217,6 @@ module_exit(s3c64xx_i2s_exit); MODULE_AUTHOR("Ben Dooks, "); MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); MODULE_LICENSE("GPL"); + + + diff --git a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h index 02148cee2613..b7ffe3c38b66 100644 --- a/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h +++ b/trunk/sound/soc/s3c24xx/s3c64xx-i2s.h @@ -15,8 +15,6 @@ #ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H #define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ -struct clk; - #include "s3c-i2s-v2.h" #define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK @@ -26,8 +24,8 @@ struct clk; #define S3C64XX_CLKSRC_PCLK (0) #define S3C64XX_CLKSRC_MUX (1) -extern struct snd_soc_dai s3c64xx_i2s_dai[]; +extern struct snd_soc_dai s3c64xx_i2s_dai; -extern struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); +extern unsigned long s3c64xx_i2s_get_clockrate(struct snd_soc_dai *cpu_dai); #endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ diff --git a/trunk/sound/soc/s6000/Kconfig b/trunk/sound/soc/s6000/Kconfig deleted file mode 100644 index c74eb3d4a47c..000000000000 --- a/trunk/sound/soc/s6000/Kconfig +++ /dev/null @@ -1,19 +0,0 @@ -config SND_S6000_SOC - tristate "SoC Audio for the Stretch s6000 family" - depends on XTENSA_VARIANT_S6000 - help - Say Y or M if you want to add support for codecs attached to - s6000 family chips. You will also need to select the platform - to support below. - -config SND_S6000_SOC_I2S - tristate - -config SND_S6000_SOC_S6IPCAM - tristate "SoC Audio support for Stretch 6105 IP Camera" - depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105 - select SND_S6000_SOC_I2S - select SND_SOC_TLV320AIC3X - help - Say Y if you want to add support for SoC audio on the - Stretch s6105 IP Camera Reference Design. diff --git a/trunk/sound/soc/s6000/Makefile b/trunk/sound/soc/s6000/Makefile deleted file mode 100644 index 7a613612e010..000000000000 --- a/trunk/sound/soc/s6000/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# s6000 Platform Support -snd-soc-s6000-objs := s6000-pcm.o -snd-soc-s6000-i2s-objs := s6000-i2s.o - -obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o -obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o - -# s6105 Machine Support -snd-soc-s6ipcam-objs := s6105-ipcam.o - -obj-$(CONFIG_SND_S6000_SOC_S6IPCAM) += snd-soc-s6ipcam.o diff --git a/trunk/sound/soc/s6000/s6000-i2s.c b/trunk/sound/soc/s6000/s6000-i2s.c deleted file mode 100644 index c5cda187ecab..000000000000 --- a/trunk/sound/soc/s6000/s6000-i2s.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * ALSA SoC I2S Audio Layer for the Stretch S6000 family - * - * Author: Daniel Gloeckner, - * Copyright: (C) 2009 emlix GmbH - * - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "s6000-i2s.h" -#include "s6000-pcm.h" - -struct s6000_i2s_dev { - dma_addr_t sifbase; - u8 __iomem *scbbase; - unsigned int wide; - unsigned int channel_in; - unsigned int channel_out; - unsigned int lines_in; - unsigned int lines_out; - struct s6000_pcm_dma_params dma_params; -}; - -#define S6_I2S_INTERRUPT_STATUS 0x00 -#define S6_I2S_INT_OVERRUN 1 -#define S6_I2S_INT_UNDERRUN 2 -#define S6_I2S_INT_ALIGNMENT 4 -#define S6_I2S_INTERRUPT_ENABLE 0x04 -#define S6_I2S_INTERRUPT_RAW 0x08 -#define S6_I2S_INTERRUPT_CLEAR 0x0C -#define S6_I2S_INTERRUPT_SET 0x10 -#define S6_I2S_MODE 0x20 -#define S6_I2S_DUAL 0 -#define S6_I2S_WIDE 1 -#define S6_I2S_TX_DEFAULT 0x24 -#define S6_I2S_DATA_CFG(c) (0x40 + 0x10 * (c)) -#define S6_I2S_IN 0 -#define S6_I2S_OUT 1 -#define S6_I2S_UNUSED 2 -#define S6_I2S_INTERFACE_CFG(c) (0x44 + 0x10 * (c)) -#define S6_I2S_DIV_MASK 0x001fff -#define S6_I2S_16BIT 0x000000 -#define S6_I2S_20BIT 0x002000 -#define S6_I2S_24BIT 0x004000 -#define S6_I2S_32BIT 0x006000 -#define S6_I2S_BITS_MASK 0x006000 -#define S6_I2S_MEM_16BIT 0x000000 -#define S6_I2S_MEM_32BIT 0x008000 -#define S6_I2S_MEM_MASK 0x008000 -#define S6_I2S_CHANNELS_SHIFT 16 -#define S6_I2S_CHANNELS_MASK 0x030000 -#define S6_I2S_SCK_IN 0x000000 -#define S6_I2S_SCK_OUT 0x040000 -#define S6_I2S_SCK_DIR 0x040000 -#define S6_I2S_WS_IN 0x000000 -#define S6_I2S_WS_OUT 0x080000 -#define S6_I2S_WS_DIR 0x080000 -#define S6_I2S_LEFT_FIRST 0x000000 -#define S6_I2S_RIGHT_FIRST 0x100000 -#define S6_I2S_FIRST 0x100000 -#define S6_I2S_CUR_SCK 0x200000 -#define S6_I2S_CUR_WS 0x400000 -#define S6_I2S_ENABLE(c) (0x48 + 0x10 * (c)) -#define S6_I2S_DISABLE_IF 0x02 -#define S6_I2S_ENABLE_IF 0x03 -#define S6_I2S_IS_BUSY 0x04 -#define S6_I2S_DMA_ACTIVE 0x08 -#define S6_I2S_IS_ENABLED 0x10 - -#define S6_I2S_NUM_LINES 4 - -#define S6_I2S_SIF_PORT0 0x0000000 -#define S6_I2S_SIF_PORT1 0x0000080 /* docs say 0x0000010 */ - -static inline void s6_i2s_write_reg(struct s6000_i2s_dev *dev, int reg, u32 val) -{ - writel(val, dev->scbbase + reg); -} - -static inline u32 s6_i2s_read_reg(struct s6000_i2s_dev *dev, int reg) -{ - return readl(dev->scbbase + reg); -} - -static inline void s6_i2s_mod_reg(struct s6000_i2s_dev *dev, int reg, - u32 mask, u32 val) -{ - val ^= s6_i2s_read_reg(dev, reg) & ~mask; - s6_i2s_write_reg(dev, reg, val); -} - -static void s6000_i2s_start_channel(struct s6000_i2s_dev *dev, int channel) -{ - int i, j, cur, prev; - - /* - * Wait for WCLK to toggle 5 times before enabling the channel - * s6000 Family Datasheet 3.6.4: - * "At least two cycles of WS must occur between commands - * to disable or enable the interface" - */ - j = 0; - prev = ~S6_I2S_CUR_WS; - for (i = 1000000; --i && j < 6; ) { - cur = s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(channel)) - & S6_I2S_CUR_WS; - if (prev != cur) { - prev = cur; - j++; - } - } - if (j < 6) - printk(KERN_WARNING "s6000-i2s: timeout waiting for WCLK\n"); - - s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_ENABLE_IF); -} - -static void s6000_i2s_stop_channel(struct s6000_i2s_dev *dev, int channel) -{ - s6_i2s_write_reg(dev, S6_I2S_ENABLE(channel), S6_I2S_DISABLE_IF); -} - -static void s6000_i2s_start(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; - int channel; - - channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - dev->channel_out : dev->channel_in; - - s6000_i2s_start_channel(dev, channel); -} - -static void s6000_i2s_stop(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s6000_i2s_dev *dev = rtd->dai->cpu_dai->private_data; - int channel; - - channel = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? - dev->channel_out : dev->channel_in; - - s6000_i2s_stop_channel(dev, channel); -} - -static int s6000_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - int after) -{ - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) ^ !after) - s6000_i2s_start(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (!after) - s6000_i2s_stop(substream); - } - return 0; -} - -static unsigned int s6000_i2s_int_sources(struct s6000_i2s_dev *dev) -{ - unsigned int pending; - pending = s6_i2s_read_reg(dev, S6_I2S_INTERRUPT_RAW); - pending &= S6_I2S_INT_ALIGNMENT | - S6_I2S_INT_UNDERRUN | - S6_I2S_INT_OVERRUN; - s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, pending); - - return pending; -} - -static unsigned int s6000_i2s_check_xrun(struct snd_soc_dai *cpu_dai) -{ - struct s6000_i2s_dev *dev = cpu_dai->private_data; - unsigned int errors; - unsigned int ret; - - errors = s6000_i2s_int_sources(dev); - if (likely(!errors)) - return 0; - - ret = 0; - if (errors & S6_I2S_INT_ALIGNMENT) - printk(KERN_ERR "s6000-i2s: WCLK misaligned\n"); - if (errors & S6_I2S_INT_UNDERRUN) - ret |= 1 << SNDRV_PCM_STREAM_PLAYBACK; - if (errors & S6_I2S_INT_OVERRUN) - ret |= 1 << SNDRV_PCM_STREAM_CAPTURE; - return ret; -} - -static void s6000_i2s_wait_disabled(struct s6000_i2s_dev *dev) -{ - int channel; - int n = 50; - for (channel = 0; channel < 2; channel++) { - while (--n >= 0) { - int v = s6_i2s_read_reg(dev, S6_I2S_ENABLE(channel)); - if ((v & S6_I2S_IS_ENABLED) - || !(v & (S6_I2S_DMA_ACTIVE | S6_I2S_IS_BUSY))) - break; - udelay(20); - } - } - if (n < 0) - printk(KERN_WARNING "s6000-i2s: timeout disabling interfaces"); -} - -static int s6000_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s6000_i2s_dev *dev = cpu_dai->private_data; - u32 w; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - w = S6_I2S_SCK_IN | S6_I2S_WS_IN; - break; - case SND_SOC_DAIFMT_CBS_CFM: - w = S6_I2S_SCK_OUT | S6_I2S_WS_IN; - break; - case SND_SOC_DAIFMT_CBM_CFS: - w = S6_I2S_SCK_IN | S6_I2S_WS_OUT; - break; - case SND_SOC_DAIFMT_CBS_CFS: - w = S6_I2S_SCK_OUT | S6_I2S_WS_OUT; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - w |= S6_I2S_LEFT_FIRST; - break; - case SND_SOC_DAIFMT_NB_IF: - w |= S6_I2S_RIGHT_FIRST; - break; - default: - return -EINVAL; - } - - s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(0), - S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w); - s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(1), - S6_I2S_FIRST | S6_I2S_WS_DIR | S6_I2S_SCK_DIR, w); - - return 0; -} - -static int s6000_i2s_set_clkdiv(struct snd_soc_dai *dai, int div_id, int div) -{ - struct s6000_i2s_dev *dev = dai->private_data; - - if (!div || (div & 1) || div > (S6_I2S_DIV_MASK + 1) * 2) - return -EINVAL; - - s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(div_id), - S6_I2S_DIV_MASK, div / 2 - 1); - return 0; -} - -static int s6000_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct s6000_i2s_dev *dev = dai->private_data; - int interf; - u32 w = 0; - - if (dev->wide) - interf = 0; - else { - w |= (((params_channels(params) - 2) / 2) - << S6_I2S_CHANNELS_SHIFT) & S6_I2S_CHANNELS_MASK; - interf = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - ? dev->channel_out : dev->channel_in; - } - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - w |= S6_I2S_16BIT | S6_I2S_MEM_16BIT; - break; - case SNDRV_PCM_FORMAT_S32_LE: - w |= S6_I2S_32BIT | S6_I2S_MEM_32BIT; - break; - default: - printk(KERN_WARNING "s6000-i2s: unsupported PCM format %x\n", - params_format(params)); - return -EINVAL; - } - - if (s6_i2s_read_reg(dev, S6_I2S_INTERFACE_CFG(interf)) - & S6_I2S_IS_ENABLED) { - printk(KERN_ERR "s6000-i2s: interface already enabled\n"); - return -EBUSY; - } - - s6_i2s_mod_reg(dev, S6_I2S_INTERFACE_CFG(interf), - S6_I2S_CHANNELS_MASK|S6_I2S_MEM_MASK|S6_I2S_BITS_MASK, - w); - - return 0; -} - -static int s6000_i2s_dai_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - struct s6000_i2s_dev *dev = dai->private_data; - struct s6000_snd_platform_data *pdata = pdev->dev.platform_data; - - if (!pdata) - return -EINVAL; - - dev->wide = pdata->wide; - dev->channel_in = pdata->channel_in; - dev->channel_out = pdata->channel_out; - dev->lines_in = pdata->lines_in; - dev->lines_out = pdata->lines_out; - - s6_i2s_write_reg(dev, S6_I2S_MODE, - dev->wide ? S6_I2S_WIDE : S6_I2S_DUAL); - - if (dev->wide) { - int i; - - if (dev->lines_in + dev->lines_out > S6_I2S_NUM_LINES) - return -EINVAL; - - dev->channel_in = 0; - dev->channel_out = 1; - dai->capture.channels_min = 2 * dev->lines_in; - dai->capture.channels_max = dai->capture.channels_min; - dai->playback.channels_min = 2 * dev->lines_out; - dai->playback.channels_max = dai->playback.channels_min; - - for (i = 0; i < dev->lines_out; i++) - s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_OUT); - - for (; i < S6_I2S_NUM_LINES - dev->lines_in; i++) - s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), - S6_I2S_UNUSED); - - for (; i < S6_I2S_NUM_LINES; i++) - s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(i), S6_I2S_IN); - } else { - unsigned int cfg[2] = {S6_I2S_UNUSED, S6_I2S_UNUSED}; - - if (dev->lines_in > 1 || dev->lines_out > 1) - return -EINVAL; - - dai->capture.channels_min = 2 * dev->lines_in; - dai->capture.channels_max = 8 * dev->lines_in; - dai->playback.channels_min = 2 * dev->lines_out; - dai->playback.channels_max = 8 * dev->lines_out; - - if (dev->lines_in) - cfg[dev->channel_in] = S6_I2S_IN; - if (dev->lines_out) - cfg[dev->channel_out] = S6_I2S_OUT; - - s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(0), cfg[0]); - s6_i2s_write_reg(dev, S6_I2S_DATA_CFG(1), cfg[1]); - } - - if (dev->lines_out) { - if (dev->lines_in) { - if (!dev->dma_params.dma_out) - return -ENODEV; - } else { - dev->dma_params.dma_out = dev->dma_params.dma_in; - dev->dma_params.dma_in = 0; - } - } - dev->dma_params.sif_in = dev->sifbase + (dev->channel_in ? - S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0); - dev->dma_params.sif_out = dev->sifbase + (dev->channel_out ? - S6_I2S_SIF_PORT1 : S6_I2S_SIF_PORT0); - dev->dma_params.same_rate = pdata->same_rate | pdata->wide; - return 0; -} - -#define S6000_I2S_RATES (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_192000) -#define S6000_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops s6000_i2s_dai_ops = { - .set_fmt = s6000_i2s_set_dai_fmt, - .set_clkdiv = s6000_i2s_set_clkdiv, - .hw_params = s6000_i2s_hw_params, -}; - -struct snd_soc_dai s6000_i2s_dai = { - .name = "s6000-i2s", - .id = 0, - .probe = s6000_i2s_dai_probe, - .playback = { - .channels_min = 2, - .channels_max = 8, - .formats = S6000_I2S_FORMATS, - .rates = S6000_I2S_RATES, - .rate_min = 0, - .rate_max = 1562500, - }, - .capture = { - .channels_min = 2, - .channels_max = 8, - .formats = S6000_I2S_FORMATS, - .rates = S6000_I2S_RATES, - .rate_min = 0, - .rate_max = 1562500, - }, - .ops = &s6000_i2s_dai_ops, -} -EXPORT_SYMBOL_GPL(s6000_i2s_dai); - -static int __devinit s6000_i2s_probe(struct platform_device *pdev) -{ - struct s6000_i2s_dev *dev; - struct resource *scbmem, *sifmem, *region, *dma1, *dma2; - u8 __iomem *mmio; - int ret; - - scbmem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!scbmem) { - dev_err(&pdev->dev, "no mem resource?\n"); - ret = -ENODEV; - goto err_release_none; - } - - region = request_mem_region(scbmem->start, - scbmem->end - scbmem->start + 1, - pdev->name); - if (!region) { - dev_err(&pdev->dev, "I2S SCB region already claimed\n"); - ret = -EBUSY; - goto err_release_none; - } - - mmio = ioremap(scbmem->start, scbmem->end - scbmem->start + 1); - if (!mmio) { - dev_err(&pdev->dev, "can't ioremap SCB region\n"); - ret = -ENOMEM; - goto err_release_scb; - } - - sifmem = platform_get_resource(pdev, IORESOURCE_MEM, 1); - if (!sifmem) { - dev_err(&pdev->dev, "no second mem resource?\n"); - ret = -ENODEV; - goto err_release_map; - } - - region = request_mem_region(sifmem->start, - sifmem->end - sifmem->start + 1, - pdev->name); - if (!region) { - dev_err(&pdev->dev, "I2S SIF region already claimed\n"); - ret = -EBUSY; - goto err_release_map; - } - - dma1 = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dma1) { - dev_err(&pdev->dev, "no dma resource?\n"); - ret = -ENODEV; - goto err_release_sif; - } - - region = request_mem_region(dma1->start, dma1->end - dma1->start + 1, - pdev->name); - if (!region) { - dev_err(&pdev->dev, "I2S DMA region already claimed\n"); - ret = -EBUSY; - goto err_release_sif; - } - - dma2 = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (dma2) { - region = request_mem_region(dma2->start, - dma2->end - dma2->start + 1, - pdev->name); - if (!region) { - dev_err(&pdev->dev, - "I2S DMA region already claimed\n"); - ret = -EBUSY; - goto err_release_dma1; - } - } - - dev = kzalloc(sizeof(struct s6000_i2s_dev), GFP_KERNEL); - if (!dev) { - ret = -ENOMEM; - goto err_release_dma2; - } - - s6000_i2s_dai.dev = &pdev->dev; - s6000_i2s_dai.private_data = dev; - s6000_i2s_dai.dma_data = &dev->dma_params; - - dev->sifbase = sifmem->start; - dev->scbbase = mmio; - - s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); - s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_CLEAR, - S6_I2S_INT_ALIGNMENT | - S6_I2S_INT_UNDERRUN | - S6_I2S_INT_OVERRUN); - - s6000_i2s_stop_channel(dev, 0); - s6000_i2s_stop_channel(dev, 1); - s6000_i2s_wait_disabled(dev); - - dev->dma_params.check_xrun = s6000_i2s_check_xrun; - dev->dma_params.trigger = s6000_i2s_trigger; - dev->dma_params.dma_in = dma1->start; - dev->dma_params.dma_out = dma2 ? dma2->start : 0; - dev->dma_params.irq = platform_get_irq(pdev, 0); - if (dev->dma_params.irq < 0) { - dev_err(&pdev->dev, "no irq resource?\n"); - ret = -ENODEV; - goto err_release_dev; - } - - s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, - S6_I2S_INT_ALIGNMENT | - S6_I2S_INT_UNDERRUN | - S6_I2S_INT_OVERRUN); - - ret = snd_soc_register_dai(&s6000_i2s_dai); - if (ret) - goto err_release_dev; - - return 0; - -err_release_dev: - kfree(dev); -err_release_dma2: - if (dma2) - release_mem_region(dma2->start, dma2->end - dma2->start + 1); -err_release_dma1: - release_mem_region(dma1->start, dma1->end - dma1->start + 1); -err_release_sif: - release_mem_region(sifmem->start, (sifmem->end - sifmem->start) + 1); -err_release_map: - iounmap(mmio); -err_release_scb: - release_mem_region(scbmem->start, (scbmem->end - scbmem->start) + 1); -err_release_none: - return ret; -} - -static void __devexit s6000_i2s_remove(struct platform_device *pdev) -{ - struct s6000_i2s_dev *dev = s6000_i2s_dai.private_data; - struct resource *region; - void __iomem *mmio = dev->scbbase; - - snd_soc_unregister_dai(&s6000_i2s_dai); - - s6000_i2s_stop_channel(dev, 0); - s6000_i2s_stop_channel(dev, 1); - - s6_i2s_write_reg(dev, S6_I2S_INTERRUPT_ENABLE, 0); - s6000_i2s_dai.private_data = 0; - kfree(dev); - - region = platform_get_resource(pdev, IORESOURCE_DMA, 0); - release_mem_region(region->start, region->end - region->start + 1); - - region = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (region) - release_mem_region(region->start, - region->end - region->start + 1); - - region = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(region->start, (region->end - region->start) + 1); - - iounmap(mmio); - region = platform_get_resource(pdev, IORESOURCE_IO, 0); - release_mem_region(region->start, (region->end - region->start) + 1); -} - -static struct platform_driver s6000_i2s_driver = { - .probe = s6000_i2s_probe, - .remove = __devexit_p(s6000_i2s_remove), - .driver = { - .name = "s6000-i2s", - .owner = THIS_MODULE, - }, -}; - -static int __init s6000_i2s_init(void) -{ - return platform_driver_register(&s6000_i2s_driver); -} -module_init(s6000_i2s_init); - -static void __exit s6000_i2s_exit(void) -{ - platform_driver_unregister(&s6000_i2s_driver); -} -module_exit(s6000_i2s_exit); - -MODULE_AUTHOR("Daniel Gloeckner"); -MODULE_DESCRIPTION("Stretch s6000 family I2S SoC Interface"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s6000/s6000-i2s.h b/trunk/sound/soc/s6000/s6000-i2s.h deleted file mode 100644 index 2375fdfe6dba..000000000000 --- a/trunk/sound/soc/s6000/s6000-i2s.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * ALSA SoC I2S Audio Layer for the Stretch s6000 family - * - * Author: Daniel Gloeckner, - * Copyright: (C) 2009 emlix GmbH - * - * 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 _S6000_I2S_H -#define _S6000_I2S_H - -extern struct snd_soc_dai s6000_i2s_dai; - -struct s6000_snd_platform_data { - int lines_in; - int lines_out; - int channel_in; - int channel_out; - int wide; - int same_rate; -}; -#endif diff --git a/trunk/sound/soc/s6000/s6000-pcm.c b/trunk/sound/soc/s6000/s6000-pcm.c deleted file mode 100644 index 83b8028e209d..000000000000 --- a/trunk/sound/soc/s6000/s6000-pcm.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * ALSA PCM interface for the Stetch s6000 family - * - * Author: Daniel Gloeckner, - * Copyright: (C) 2009 emlix GmbH - * - * 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 -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include "s6000-pcm.h" - -#define S6_PCM_PREALLOCATE_SIZE (96 * 1024) -#define S6_PCM_PREALLOCATE_MAX (2048 * 1024) - -static struct snd_pcm_hardware s6000_pcm_hardware = { - .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_JOINT_DUPLEX), - .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE), - .rates = (SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_5512 | \ - SNDRV_PCM_RATE_8000_192000), - .rate_min = 0, - .rate_max = 1562500, - .channels_min = 2, - .channels_max = 8, - .buffer_bytes_max = 0x7ffffff0, - .period_bytes_min = 16, - .period_bytes_max = 0xfffff0, - .periods_min = 2, - .periods_max = 1024, /* no limit */ - .fifo_size = 0, -}; - -struct s6000_runtime_data { - spinlock_t lock; - int period; /* current DMA period */ -}; - -static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s6000_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - int channel; - unsigned int period_size; - unsigned int dma_offset; - dma_addr_t dma_pos; - dma_addr_t src, dst; - - period_size = snd_pcm_lib_period_bytes(substream); - dma_offset = prtd->period * period_size; - dma_pos = runtime->dma_addr + dma_offset; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - src = dma_pos; - dst = par->sif_out; - channel = par->dma_out; - } else { - src = par->sif_in; - dst = dma_pos; - channel = par->dma_in; - } - - if (!s6dmac_channel_enabled(DMA_MASK_DMAC(channel), - DMA_INDEX_CHNL(channel))) - return; - - if (s6dmac_fifo_full(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel))) { - printk(KERN_ERR "s6000-pcm: fifo full\n"); - return; - } - - BUG_ON(period_size & 15); - s6dmac_put_fifo(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel), - src, dst, period_size); - - prtd->period++; - if (unlikely(prtd->period >= runtime->periods)) - prtd->period = 0; -} - -static irqreturn_t s6000_pcm_irq(int irq, void *data) -{ - struct snd_pcm *pcm = data; - struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; - struct s6000_runtime_data *prtd; - unsigned int has_xrun; - int i, ret = IRQ_NONE; - u32 channel[2] = { - [SNDRV_PCM_STREAM_PLAYBACK] = params->dma_out, - [SNDRV_PCM_STREAM_CAPTURE] = params->dma_in - }; - - has_xrun = params->check_xrun(runtime->dai->cpu_dai); - - for (i = 0; i < ARRAY_SIZE(channel); ++i) { - struct snd_pcm_substream *substream = pcm->streams[i].substream; - unsigned int pending; - - if (!channel[i]) - continue; - - if (unlikely(has_xrun & (1 << i)) && - substream->runtime && - snd_pcm_running(substream)) { - dev_dbg(pcm->dev, "xrun\n"); - snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); - ret = IRQ_HANDLED; - } - - pending = s6dmac_int_sources(DMA_MASK_DMAC(channel[i]), - DMA_INDEX_CHNL(channel[i])); - - if (pending & 1) { - ret = IRQ_HANDLED; - if (likely(substream->runtime && - snd_pcm_running(substream))) { - snd_pcm_period_elapsed(substream); - dev_dbg(pcm->dev, "period elapsed %x %x\n", - s6dmac_cur_src(DMA_MASK_DMAC(channel[i]), - DMA_INDEX_CHNL(channel[i])), - s6dmac_cur_dst(DMA_MASK_DMAC(channel[i]), - DMA_INDEX_CHNL(channel[i]))); - prtd = substream->runtime->private_data; - spin_lock(&prtd->lock); - s6000_pcm_enqueue_dma(substream); - spin_unlock(&prtd->lock); - } - } - - if (unlikely(pending & ~7)) { - if (pending & (1 << 3)) - printk(KERN_WARNING - "s6000-pcm: DMA %x Underflow\n", - channel[i]); - if (pending & (1 << 4)) - printk(KERN_WARNING - "s6000-pcm: DMA %x Overflow\n", - channel[i]); - if (pending & 0x1e0) - printk(KERN_WARNING - "s6000-pcm: DMA %x Master Error " - "(mask %x)\n", - channel[i], pending >> 5); - - } - } - - return ret; -} - -static int s6000_pcm_start(struct snd_pcm_substream *substream) -{ - struct s6000_runtime_data *prtd = substream->runtime->private_data; - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - unsigned long flags; - int srcinc; - u32 dma; - - spin_lock_irqsave(&prtd->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - srcinc = 1; - dma = par->dma_out; - } else { - srcinc = 0; - dma = par->dma_in; - } - s6dmac_enable_chan(DMA_MASK_DMAC(dma), DMA_INDEX_CHNL(dma), - 1 /* priority 1 (0 is max) */, - 0 /* peripheral requests w/o xfer length mode */, - srcinc /* source address increment */, - srcinc^1 /* destination address increment */, - 0 /* chunksize 0 (skip impossible on this dma) */, - 0 /* source skip after chunk (impossible) */, - 0 /* destination skip after chunk (impossible) */, - 4 /* 16 byte burst size */, - -1 /* don't conserve bandwidth */, - 0 /* low watermark irq descriptor theshold */, - 0 /* disable hardware timestamps */, - 1 /* enable channel */); - - s6000_pcm_enqueue_dma(substream); - s6000_pcm_enqueue_dma(substream); - - spin_unlock_irqrestore(&prtd->lock, flags); - - return 0; -} - -static int s6000_pcm_stop(struct snd_pcm_substream *substream) -{ - struct s6000_runtime_data *prtd = substream->runtime->private_data; - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - unsigned long flags; - u32 channel; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - channel = par->dma_out; - else - channel = par->dma_in; - - s6dmac_set_terminal_count(DMA_MASK_DMAC(channel), - DMA_INDEX_CHNL(channel), 0); - - spin_lock_irqsave(&prtd->lock, flags); - - s6dmac_disable_chan(DMA_MASK_DMAC(channel), DMA_INDEX_CHNL(channel)); - - spin_unlock_irqrestore(&prtd->lock, flags); - - return 0; -} - -static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - int ret; - - ret = par->trigger(substream, cmd, 0); - if (ret < 0) - return ret; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ret = s6000_pcm_start(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - ret = s6000_pcm_stop(substream); - break; - default: - ret = -EINVAL; - } - if (ret < 0) - return ret; - - return par->trigger(substream, cmd, 1); -} - -static int s6000_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct s6000_runtime_data *prtd = substream->runtime->private_data; - - prtd->period = 0; - - return 0; -} - -static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct s6000_runtime_data *prtd = runtime->private_data; - unsigned long flags; - unsigned int offset; - dma_addr_t count; - - spin_lock_irqsave(&prtd->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - count = s6dmac_cur_src(DMA_MASK_DMAC(par->dma_out), - DMA_INDEX_CHNL(par->dma_out)); - else - count = s6dmac_cur_dst(DMA_MASK_DMAC(par->dma_in), - DMA_INDEX_CHNL(par->dma_in)); - - count -= runtime->dma_addr; - - spin_unlock_irqrestore(&prtd->lock, flags); - - offset = bytes_to_frames(runtime, count); - if (unlikely(offset >= runtime->buffer_size)) - offset = 0; - - return offset; -} - -static int s6000_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - struct snd_pcm_runtime *runtime = substream->runtime; - struct s6000_runtime_data *prtd; - int ret; - - snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); - - ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 16); - if (ret < 0) - return ret; - ret = snd_pcm_hw_constraint_step(runtime, 0, - SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 16); - if (ret < 0) - return ret; - ret = snd_pcm_hw_constraint_integer(runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - return ret; - - if (par->same_rate) { - int rate; - spin_lock(&par->lock); /* needed? */ - rate = par->rate; - spin_unlock(&par->lock); - if (rate != -1) { - ret = snd_pcm_hw_constraint_minmax(runtime, - SNDRV_PCM_HW_PARAM_RATE, - rate, rate); - if (ret < 0) - return ret; - } - } - - prtd = kzalloc(sizeof(struct s6000_runtime_data), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - spin_lock_init(&prtd->lock); - - runtime->private_data = prtd; - - return 0; -} - -static int s6000_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s6000_runtime_data *prtd = runtime->private_data; - - kfree(prtd); - - return 0; -} - -static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - int ret; - ret = snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - if (ret < 0) { - printk(KERN_WARNING "s6000-pcm: allocation of memory failed\n"); - return ret; - } - - if (par->same_rate) { - spin_lock(&par->lock); - if (par->rate == -1 || - !(par->in_use & ~(1 << substream->stream))) { - par->rate = params_rate(hw_params); - par->in_use |= 1 << substream->stream; - } else if (params_rate(hw_params) != par->rate) { - snd_pcm_lib_free_pages(substream); - par->in_use &= ~(1 << substream->stream); - ret = -EBUSY; - } - spin_unlock(&par->lock); - } - return ret; -} - -static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; - struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; - - spin_lock(&par->lock); - par->in_use &= ~(1 << substream->stream); - if (!par->in_use) - par->rate = -1; - spin_unlock(&par->lock); - - return snd_pcm_lib_free_pages(substream); -} - -static struct snd_pcm_ops s6000_pcm_ops = { - .open = s6000_pcm_open, - .close = s6000_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = s6000_pcm_hw_params, - .hw_free = s6000_pcm_hw_free, - .trigger = s6000_pcm_trigger, - .prepare = s6000_pcm_prepare, - .pointer = s6000_pcm_pointer, -}; - -static void s6000_pcm_free(struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; - - free_irq(params->irq, pcm); - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -static u64 s6000_pcm_dmamask = DMA_32BIT_MASK; - -static int s6000_pcm_new(struct snd_card *card, - struct snd_soc_dai *dai, struct snd_pcm *pcm) -{ - struct snd_soc_pcm_runtime *runtime = pcm->private_data; - struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; - int res; - - if (!card->dev->dma_mask) - card->dev->dma_mask = &s6000_pcm_dmamask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = DMA_32BIT_MASK; - - if (params->dma_in) { - s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in), - DMA_INDEX_CHNL(params->dma_in)); - s6dmac_int_sources(DMA_MASK_DMAC(params->dma_in), - DMA_INDEX_CHNL(params->dma_in)); - } - - if (params->dma_out) { - s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_out), - DMA_INDEX_CHNL(params->dma_out)); - s6dmac_int_sources(DMA_MASK_DMAC(params->dma_out), - DMA_INDEX_CHNL(params->dma_out)); - } - - res = request_irq(params->irq, s6000_pcm_irq, IRQF_SHARED, - s6000_soc_platform.name, pcm); - if (res) { - printk(KERN_ERR "s6000-pcm couldn't get IRQ\n"); - return res; - } - - res = snd_pcm_lib_preallocate_pages_for_all(pcm, - SNDRV_DMA_TYPE_DEV, - card->dev, - S6_PCM_PREALLOCATE_SIZE, - S6_PCM_PREALLOCATE_MAX); - if (res) - printk(KERN_WARNING "s6000-pcm: preallocation failed\n"); - - spin_lock_init(¶ms->lock); - params->in_use = 0; - params->rate = -1; - return 0; -} - -struct snd_soc_platform s6000_soc_platform = { - .name = "s6000-audio", - .pcm_ops = &s6000_pcm_ops, - .pcm_new = s6000_pcm_new, - .pcm_free = s6000_pcm_free, -}; -EXPORT_SYMBOL_GPL(s6000_soc_platform); - -static int __init s6000_pcm_init(void) -{ - return snd_soc_register_platform(&s6000_soc_platform); -} -module_init(s6000_pcm_init); - -static void __exit s6000_pcm_exit(void) -{ - snd_soc_unregister_platform(&s6000_soc_platform); -} -module_exit(s6000_pcm_exit); - -MODULE_AUTHOR("Daniel Gloeckner"); -MODULE_DESCRIPTION("Stretch s6000 family PCM DMA module"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/s6000/s6000-pcm.h b/trunk/sound/soc/s6000/s6000-pcm.h deleted file mode 100644 index 96f23f6f52bf..000000000000 --- a/trunk/sound/soc/s6000/s6000-pcm.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * ALSA PCM interface for the Stretch s6000 family - * - * Author: Daniel Gloeckner, - * Copyright: (C) 2009 emlix GmbH - * - * 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 _S6000_PCM_H -#define _S6000_PCM_H - -struct snd_soc_dai; -struct snd_pcm_substream; - -struct s6000_pcm_dma_params { - unsigned int (*check_xrun)(struct snd_soc_dai *cpu_dai); - int (*trigger)(struct snd_pcm_substream *substream, int cmd, int after); - dma_addr_t sif_in; - dma_addr_t sif_out; - u32 dma_in; - u32 dma_out; - int irq; - int same_rate; - - spinlock_t lock; - int in_use; - int rate; -}; - -extern struct snd_soc_platform s6000_soc_platform; - -#endif diff --git a/trunk/sound/soc/s6000/s6105-ipcam.c b/trunk/sound/soc/s6000/s6105-ipcam.c deleted file mode 100644 index b5f95f9781c1..000000000000 --- a/trunk/sound/soc/s6000/s6105-ipcam.c +++ /dev/null @@ -1,244 +0,0 @@ -/* - * ASoC driver for Stretch s6105 IP camera platform - * - * Author: Daniel Gloeckner, - * Copyright: (C) 2009 emlix GmbH - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../codecs/tlv320aic3x.h" -#include "s6000-pcm.h" -#include "s6000-i2s.h" - -#define S6105_CAM_CODEC_CLOCK 12288000 - -static int s6105_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 = 0; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_NB_NF); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, S6105_CAM_CODEC_CLOCK, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops s6105_ops = { - .hw_params = s6105_hw_params, -}; - -/* s6105 machine dapm widgets */ -static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { - SND_SOC_DAPM_LINE("Audio Out Differential", NULL), - SND_SOC_DAPM_LINE("Audio Out Stereo", NULL), - SND_SOC_DAPM_LINE("Audio In", NULL), -}; - -/* s6105 machine audio_mapnections to the codec pins */ -static const struct snd_soc_dapm_route audio_map[] = { - /* Audio Out connected to HPLOUT, HPLCOM, HPROUT */ - {"Audio Out Differential", NULL, "HPLOUT"}, - {"Audio Out Differential", NULL, "HPLCOM"}, - {"Audio Out Stereo", NULL, "HPLOUT"}, - {"Audio Out Stereo", NULL, "HPROUT"}, - - /* Audio In connected to LINE1L, LINE1R */ - {"LINE1L", NULL, "Audio In"}, - {"LINE1R", NULL, "Audio In"}, -}; - -static int output_type_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item) { - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, "HPLOUT/HPROUT"); - } else { - strcpy(uinfo->value.enumerated.name, "HPLOUT/HPLCOM"); - } - return 0; -} - -static int output_type_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = kcontrol->private_value; - return 0; -} - -static int output_type_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = kcontrol->private_data; - unsigned int val = (ucontrol->value.enumerated.item[0] != 0); - char *differential = "Audio Out Differential"; - char *stereo = "Audio Out Stereo"; - - if (kcontrol->private_value == val) - return 0; - kcontrol->private_value = val; - snd_soc_dapm_disable_pin(codec, val ? differential : stereo); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, val ? stereo : differential); - snd_soc_dapm_sync(codec); - - return 1; -} - -static const struct snd_kcontrol_new audio_out_mux = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Output Mux", - .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .info = output_type_info, - .get = output_type_get, - .put = output_type_put, - .private_value = 1 /* default to stereo */ -}; - -/* Logic for a aic3x as connected on the s6105 ip camera ref design */ -static int s6105_aic3x_init(struct snd_soc_codec *codec) -{ - /* Add s6105 specific widgets */ - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, - ARRAY_SIZE(aic3x_dapm_widgets)); - - /* Set up s6105 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - - /* not present */ - snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); - - /* not connected */ - snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ - snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ - snd_soc_dapm_nc_pin(codec, "LLOUT"); - snd_soc_dapm_nc_pin(codec, "RLOUT"); - snd_soc_dapm_nc_pin(codec, "HPRCOM"); - - /* always connected */ - snd_soc_dapm_enable_pin(codec, "Audio In"); - - /* must correspond to audio_out_mux.private_value initializer */ - snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); - - snd_soc_dapm_sync(codec); - - snd_ctl_add(codec->card, snd_ctl_new1(&audio_out_mux, codec)); - - return 0; -} - -/* s6105 digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link s6105_dai = { - .name = "TLV320AIC31", - .stream_name = "AIC31", - .cpu_dai = &s6000_i2s_dai, - .codec_dai = &aic3x_dai, - .init = s6105_aic3x_init, - .ops = &s6105_ops, -}; - -/* s6105 audio machine driver */ -static struct snd_soc_card snd_soc_card_s6105 = { - .name = "Stretch IP Camera", - .platform = &s6000_soc_platform, - .dai_link = &s6105_dai, - .num_links = 1, -}; - -/* s6105 audio private data */ -static struct aic3x_setup_data s6105_aic3x_setup = { - .i2c_bus = 0, - .i2c_address = 0x18, -}; - -/* s6105 audio subsystem */ -static struct snd_soc_device s6105_snd_devdata = { - .card = &snd_soc_card_s6105, - .codec_dev = &soc_codec_dev_aic3x, - .codec_data = &s6105_aic3x_setup, -}; - -static struct s6000_snd_platform_data __initdata s6105_snd_data = { - .wide = 0, - .channel_in = 0, - .channel_out = 1, - .lines_in = 1, - .lines_out = 1, - .same_rate = 1, -}; - -static struct platform_device *s6105_snd_device; - -static int __init s6105_init(void) -{ - int ret; - - s6105_snd_device = platform_device_alloc("soc-audio", -1); - if (!s6105_snd_device) - return -ENOMEM; - - platform_set_drvdata(s6105_snd_device, &s6105_snd_devdata); - s6105_snd_devdata.dev = &s6105_snd_device->dev; - platform_device_add_data(s6105_snd_device, &s6105_snd_data, - sizeof(s6105_snd_data)); - - ret = platform_device_add(s6105_snd_device); - if (ret) - platform_device_put(s6105_snd_device); - - return ret; -} - -static void __exit s6105_exit(void) -{ - platform_device_unregister(s6105_snd_device); -} - -module_init(s6105_init); -module_exit(s6105_exit); - -MODULE_AUTHOR("Daniel Gloeckner"); -MODULE_DESCRIPTION("Stretch s6105 IP camera ASoC driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/sh/ssi.c b/trunk/sound/soc/sh/ssi.c index b378096cadb1..56fa0872abbb 100644 --- a/trunk/sound/soc/sh/ssi.c +++ b/trunk/sound/soc/sh/ssi.c @@ -145,7 +145,7 @@ static int ssi_hw_params(struct snd_pcm_substream *substream, recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); - pr_debug("bits: %u channels: %u\n", bits, channels); + pr_debug("bits: %d channels: %d\n", bits, channels); ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | CR_SWL_MASK); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 3f44150d8e30..1cd149b9ce69 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -113,35 +113,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) } #endif -static int soc_pcm_apply_symmetry(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_dai *cpu_dai = machine->cpu_dai; - struct snd_soc_dai *codec_dai = machine->codec_dai; - int ret; - - if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || - machine->symmetric_rates) { - dev_dbg(card->dev, "Symmetry forces %dHz rate\n", - machine->rate); - - ret = snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, - machine->rate, - machine->rate); - if (ret < 0) { - dev_err(card->dev, - "Unable to apply rate symmetry constraint: %d\n", ret); - return ret; - } - } - - return 0; -} - /* * 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 @@ -250,13 +221,6 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto machine_err; } - /* Symmetry only applies if we've already got an active stream. */ - if (cpu_dai->active || codec_dai->active) { - ret = soc_pcm_apply_symmetry(substream); - if (ret != 0) - goto machine_err; - } - 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, @@ -299,6 +263,7 @@ static void close_delayed_work(struct work_struct *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 = card->codec; struct snd_soc_dai *codec_dai; int i; @@ -314,10 +279,27 @@ static void close_delayed_work(struct work_struct *work) /* are we waiting on this codec DAI stream */ if (codec_dai->pop_wait == 1) { + + /* Reduce power if no longer active */ + if (codec->active == 0) { + 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); + } + codec_dai->pop_wait = 0; snd_soc_dapm_stream_event(codec, codec_dai->playback.stream_name, SND_SOC_DAPM_STREAM_STOP); + + /* Fall into standby if no longer active */ + if (codec->active == 0) { + 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); + } } } mutex_unlock(&pcm_mutex); @@ -381,6 +363,10 @@ static int soc_codec_close(struct snd_pcm_substream *substream) snd_soc_dapm_stream_event(codec, codec_dai->capture.stream_name, SND_SOC_DAPM_STREAM_STOP); + + if (codec->active == 0 && codec_dai->pop_wait == 0) + snd_soc_dapm_set_bias_level(socdev, + SND_SOC_BIAS_STANDBY); } mutex_unlock(&pcm_mutex); @@ -445,16 +431,36 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream) cancel_delayed_work(&card->delayed_work); } - 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, - codec_dai->capture.stream_name, - SND_SOC_DAPM_STREAM_START); + /* 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, + codec_dai->playback.stream_name, + SND_SOC_DAPM_STREAM_START); + 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_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, + codec_dai->playback.stream_name, + SND_SOC_DAPM_STREAM_START); + 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); + } out: mutex_unlock(&pcm_mutex); @@ -515,8 +521,6 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } - machine->rate = params_rate(params); - out: mutex_unlock(&pcm_mutex); return ret; @@ -628,12 +632,6 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state) struct snd_soc_codec *codec = card->codec; int i; - /* If the initialization of this soc device failed, there is no codec - * associated with it. Just bail out in this case. - */ - if (!codec) - return 0; - /* Due to the resume being scheduled into a workqueue we could * suspend before that's finished - wait for it to complete. */ @@ -1336,7 +1334,6 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) return ret; } - codec->socdev = socdev; codec->card->dev = socdev->dev; codec->card->private_data = codec; strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); @@ -1747,7 +1744,7 @@ int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol, { int max = kcontrol->private_value; - if (max == 1 && !strstr(kcontrol->id.name, " Volume")) + if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -1777,7 +1774,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, unsigned int shift = mc->shift; unsigned int rshift = mc->rshift; - if (max == 1 && !strstr(kcontrol->id.name, " Volume")) + if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -1884,7 +1881,7 @@ int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; int max = mc->max; - if (max == 1 && !strstr(kcontrol->id.name, " Volume")) + if (max == 1) uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; else uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -2068,7 +2065,7 @@ 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->ops && dai->ops->set_sysclk) + if (dai->ops->set_sysclk) return dai->ops->set_sysclk(dai, clk_id, freq, dir); else return -EINVAL; @@ -2088,7 +2085,7 @@ 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->ops && dai->ops->set_clkdiv) + if (dai->ops->set_clkdiv) return dai->ops->set_clkdiv(dai, div_id, div); else return -EINVAL; @@ -2107,7 +2104,7 @@ 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->ops && dai->ops->set_pll) + if (dai->ops->set_pll) return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); else return -EINVAL; @@ -2123,7 +2120,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); */ int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - if (dai->ops && dai->ops->set_fmt) + if (dai->ops->set_fmt) return dai->ops->set_fmt(dai, fmt); else return -EINVAL; @@ -2142,7 +2139,7 @@ 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->ops && dai->ops->set_tdm_slot) + if (dai->ops->set_sysclk) return dai->ops->set_tdm_slot(dai, mask, slots); else return -EINVAL; @@ -2158,7 +2155,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); */ int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) { - if (dai->ops && dai->ops->set_tristate) + if (dai->ops->set_sysclk) return dai->ops->set_tristate(dai, tristate); else return -EINVAL; @@ -2174,7 +2171,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate); */ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) { - if (dai->ops && dai->ops->digital_mute) + if (dai->ops->digital_mute) return dai->ops->digital_mute(dai, mute); else return -EINVAL; @@ -2355,39 +2352,6 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform) } EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); -static u64 codec_format_map[] = { - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE, - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE, - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE, - SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE, - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE, - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE, - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, - SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE, - SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE, - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE, - SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE, - SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE, - SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE, - SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE - | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE, -}; - -/* Fix up the DAI formats for endianness: codecs don't actually see - * the endianness of the data but we're using the CPU format - * definitions which do need to include endianness so we ensure that - * codec DAIs always have both big and little endian variants set. - */ -static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(codec_format_map); i++) - if (stream->formats & codec_format_map[i]) - stream->formats |= codec_format_map[i]; -} - /** * snd_soc_register_codec - Register a codec with the ASoC core * @@ -2395,8 +2359,6 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) */ int snd_soc_register_codec(struct snd_soc_codec *codec) { - int i; - if (!codec->name) return -EINVAL; @@ -2406,11 +2368,6 @@ int snd_soc_register_codec(struct snd_soc_codec *codec) INIT_LIST_HEAD(&codec->list); - for (i = 0; i < codec->num_dai; i++) { - fixup_codec_formats(&codec->dai[i].playback); - fixup_codec_formats(&codec->dai[i].capture); - } - mutex_lock(&client_mutex); list_add(&codec->list, &codec_list); snd_soc_instantiate_cards(); diff --git a/trunk/sound/soc/soc-dapm.c b/trunk/sound/soc/soc-dapm.c index 21c69074aa17..735903a74675 100644 --- a/trunk/sound/soc/soc-dapm.c +++ b/trunk/sound/soc/soc-dapm.c @@ -12,7 +12,7 @@ * Features: * o Changes power status of internal codec blocks depending on the * dynamic configuration of codec internal audio paths and active - * DACs/ADCs. + * DAC's/ADC's. * o Platform power domain - can support external components i.e. amps and * mic/meadphone insertion events. * o Automatic Mic Bias support @@ -52,21 +52,23 @@ /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { - snd_soc_dapm_pre, snd_soc_dapm_supply, snd_soc_dapm_micbias, - snd_soc_dapm_mic, snd_soc_dapm_mux, snd_soc_dapm_value_mux, - snd_soc_dapm_dac, snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, - snd_soc_dapm_pga, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, - snd_soc_dapm_post + snd_soc_dapm_pre, snd_soc_dapm_micbias, snd_soc_dapm_mic, + snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_dac, + snd_soc_dapm_mixer, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_pga, + snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_post }; static int dapm_down_seq[] = { snd_soc_dapm_pre, snd_soc_dapm_adc, snd_soc_dapm_hp, snd_soc_dapm_spk, snd_soc_dapm_pga, snd_soc_dapm_mixer_named_ctl, snd_soc_dapm_mixer, snd_soc_dapm_dac, snd_soc_dapm_mic, snd_soc_dapm_micbias, - snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_supply, - snd_soc_dapm_post + snd_soc_dapm_mux, snd_soc_dapm_value_mux, snd_soc_dapm_post }; +static int dapm_status = 1; +module_param(dapm_status, int, 0); +MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); + static void pop_wait(u32 pop_time) { if (pop_time) @@ -94,48 +96,6 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( return kmemdup(_widget, sizeof(*_widget), GFP_KERNEL); } -/** - * snd_soc_dapm_set_bias_level - set the bias level for the system - * @socdev: audio device - * @level: level to configure - * - * Configure the bias (power) levels for the SoC audio device. - * - * Returns 0 for success else error. - */ -static int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, - enum snd_soc_bias_level level) -{ - struct snd_soc_card *card = socdev->card; - struct snd_soc_codec *codec = socdev->card->codec; - int ret = 0; - - switch (level) { - case SND_SOC_BIAS_ON: - dev_dbg(socdev->dev, "Setting full bias\n"); - break; - case SND_SOC_BIAS_PREPARE: - dev_dbg(socdev->dev, "Setting bias prepare\n"); - break; - case SND_SOC_BIAS_STANDBY: - dev_dbg(socdev->dev, "Setting standby bias\n"); - break; - case SND_SOC_BIAS_OFF: - dev_dbg(socdev->dev, "Setting bias off\n"); - break; - default: - dev_err(socdev->dev, "Setting invalid bias %d\n", level); - return -EINVAL; - } - - 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); - - return ret; -} - /* set up initial codec paths */ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, struct snd_soc_dapm_path *p, int i) @@ -205,7 +165,6 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, case snd_soc_dapm_dac: case snd_soc_dapm_micbias: case snd_soc_dapm_vmid: - case snd_soc_dapm_supply: p->connect = 1; break; /* does effect routing - dynamically connected */ @@ -220,7 +179,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, } } -/* connect mux widget to its interconnecting audio paths */ +/* connect mux widget to it's interconnecting audio paths */ static int dapm_connect_mux(struct snd_soc_codec *codec, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name, @@ -243,7 +202,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec, return -ENODEV; } -/* connect mixer widget to its interconnecting audio paths */ +/* connect mixer widget to it's interconnecting audio paths */ static int dapm_connect_mixer(struct snd_soc_codec *codec, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name) @@ -398,9 +357,8 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, path->long_name); ret = snd_ctl_add(codec->card, path->kcontrol); if (ret < 0) { - printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", - path->long_name, - ret); + printk(KERN_ERR "asoc: failed to add dapm kcontrol %s\n", + path->long_name); kfree(path->long_name); path->long_name = NULL; return ret; @@ -476,9 +434,6 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) struct snd_soc_dapm_path *path; int con = 0; - if (widget->id == snd_soc_dapm_supply) - return 0; - if (widget->id == snd_soc_dapm_adc && widget->active) return 1; @@ -515,9 +470,6 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) struct snd_soc_dapm_path *path; int con = 0; - if (widget->id == snd_soc_dapm_supply) - return 0; - /* active stream ? */ if (widget->id == snd_soc_dapm_dac && widget->active) return 1; @@ -569,12 +521,84 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_reg_event); -/* Standard power change method, used to apply power changes to most - * widgets. +/* + * Scan a single DAPM widget for a complete audio path and update the + * power status appropriately. */ -static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) +static int dapm_power_widget(struct snd_soc_codec *codec, int event, + struct snd_soc_dapm_widget *w) { - int ret; + int in, out, power_change, power, ret; + + /* vmid - no action */ + if (w->id == snd_soc_dapm_vmid) + return 0; + + /* active ADC */ + if (w->id == snd_soc_dapm_adc && w->active) { + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + w->power = (in != 0) ? 1 : 0; + dapm_update_bits(w); + return 0; + } + + /* active DAC */ + if (w->id == snd_soc_dapm_dac && w->active) { + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + w->power = (out != 0) ? 1 : 0; + dapm_update_bits(w); + return 0; + } + + /* pre and post event widgets */ + if (w->id == snd_soc_dapm_pre) { + if (!w->event) + return 0; + + if (event == SND_SOC_DAPM_STREAM_START) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMU); + if (ret < 0) + return ret; + } else if (event == SND_SOC_DAPM_STREAM_STOP) { + ret = w->event(w, + NULL, SND_SOC_DAPM_PRE_PMD); + if (ret < 0) + return ret; + } + return 0; + } + if (w->id == snd_soc_dapm_post) { + if (!w->event) + return 0; + + if (event == SND_SOC_DAPM_STREAM_START) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMU); + if (ret < 0) + return ret; + } else if (event == SND_SOC_DAPM_STREAM_STOP) { + ret = w->event(w, + NULL, SND_SOC_DAPM_POST_PMD); + if (ret < 0) + return ret; + } + return 0; + } + + /* all other widgets */ + in = is_connected_input_ep(w); + dapm_clear_walk(w->codec); + out = is_connected_output_ep(w); + dapm_clear_walk(w->codec); + power = (out != 0 && in != 0) ? 1 : 0; + power_change = (w->power == power) ? 0 : 1; + w->power = power; + + if (!power_change) + return 0; /* call any power change event handlers */ if (w->event) @@ -583,7 +607,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) w->name, w->event_flags); /* power up pre event */ - if (w->power && w->event && + if (power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); if (ret < 0) @@ -591,7 +615,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) } /* power down pre event */ - if (!w->power && w->event && + if (!power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); if (ret < 0) @@ -599,17 +623,17 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) } /* Lower PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && !w->power) - dapm_set_pga(w, w->power); + if (w->id == snd_soc_dapm_pga && !power) + dapm_set_pga(w, power); dapm_update_bits(w); /* Raise PGA volume to reduce pops */ - if (w->id == snd_soc_dapm_pga && w->power) - dapm_set_pga(w, w->power); + if (w->id == snd_soc_dapm_pga && power) + dapm_set_pga(w, power); /* power up post event */ - if (w->power && w->event && + if (power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMU)) { ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMU); @@ -618,7 +642,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) } /* power down post event */ - if (!w->power && w->event && + if (!power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMD)) { ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); if (ret < 0) @@ -628,116 +652,6 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) return 0; } -/* Generic check to see if a widget should be powered. - */ -static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) -{ - int in, out; - - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - return out != 0 && in != 0; -} - -/* Check to see if an ADC has power */ -static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) -{ - int in; - - if (w->active) { - in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); - return in != 0; - } else { - return dapm_generic_check_power(w); - } -} - -/* Check to see if a DAC has power */ -static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) -{ - int out; - - if (w->active) { - out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); - return out != 0; - } else { - return dapm_generic_check_power(w); - } -} - -/* Check to see if a power supply is needed */ -static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) -{ - struct snd_soc_dapm_path *path; - int power = 0; - - /* Check if one of our outputs is connected */ - list_for_each_entry(path, &w->sinks, list_source) { - if (path->sink && path->sink->power_check && - path->sink->power_check(path->sink)) { - power = 1; - break; - } - } - - dapm_clear_walk(w->codec); - - return power; -} - -/* - * Scan a single DAPM widget for a complete audio path and update the - * power status appropriately. - */ -static int dapm_power_widget(struct snd_soc_codec *codec, int event, - struct snd_soc_dapm_widget *w) -{ - int ret; - - switch (w->id) { - case snd_soc_dapm_pre: - if (!w->event) - return 0; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, - NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, - NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - return ret; - } - return 0; - - case snd_soc_dapm_post: - if (!w->event) - return 0; - - if (event == SND_SOC_DAPM_STREAM_START) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - return ret; - } else if (event == SND_SOC_DAPM_STREAM_STOP) { - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - return ret; - } - return 0; - - default: - return dapm_generic_apply_power(w); - } -} - /* * Scan each dapm widget for complete audio path. * A complete path is a route that has valid endpoints i.e.:- @@ -749,102 +663,31 @@ static int dapm_power_widget(struct snd_soc_codec *codec, int event, */ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) { - struct snd_soc_device *socdev = codec->socdev; struct snd_soc_dapm_widget *w; - int ret = 0; - int i, power; - int sys_power = 0; - - INIT_LIST_HEAD(&codec->up_list); - INIT_LIST_HEAD(&codec->down_list); - - /* Check which widgets we need to power and store them in - * lists indicating if they should be powered up or down. - */ - list_for_each_entry(w, &codec->dapm_widgets, list) { - switch (w->id) { - case snd_soc_dapm_pre: - list_add_tail(&codec->down_list, &w->power_list); - break; - case snd_soc_dapm_post: - list_add_tail(&codec->up_list, &w->power_list); - break; - - default: - if (!w->power_check) - continue; - - power = w->power_check(w); - if (power) - sys_power = 1; - - if (w->power == power) - continue; - - if (power) - list_add_tail(&w->power_list, &codec->up_list); - else - list_add_tail(&w->power_list, - &codec->down_list); - - w->power = power; - break; - } + int i, c = 1, *seq = NULL, ret = 0; + + /* do we have a sequenced stream event */ + if (event == SND_SOC_DAPM_STREAM_START) { + c = ARRAY_SIZE(dapm_up_seq); + seq = dapm_up_seq; + } else if (event == SND_SOC_DAPM_STREAM_STOP) { + c = ARRAY_SIZE(dapm_down_seq); + seq = dapm_down_seq; } - /* If we're changing to all on or all off then prepare */ - if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || - (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { - ret = snd_soc_dapm_set_bias_level(socdev, - SND_SOC_BIAS_PREPARE); - if (ret != 0) - pr_err("Failed to prepare bias: %d\n", ret); - } + for (i = 0; i < c; i++) { + list_for_each_entry(w, &codec->dapm_widgets, list) { - /* Power down widgets first; try to avoid amplifying pops. */ - for (i = 0; i < ARRAY_SIZE(dapm_down_seq); i++) { - list_for_each_entry(w, &codec->down_list, power_list) { /* is widget in stream order */ - if (w->id != dapm_down_seq[i]) + if (seq && seq[i] && w->id != seq[i]) continue; ret = dapm_power_widget(codec, event, w); if (ret != 0) - pr_err("Failed to power down %s: %d\n", - w->name, ret); - } - } - - /* Now power up. */ - for (i = 0; i < ARRAY_SIZE(dapm_up_seq); i++) { - list_for_each_entry(w, &codec->up_list, power_list) { - /* is widget in stream order */ - if (w->id != dapm_up_seq[i]) - continue; - - ret = dapm_power_widget(codec, event, w); - if (ret != 0) - pr_err("Failed to power up %s: %d\n", - w->name, ret); + return ret; } } - /* If we just powered the last thing off drop to standby bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { - ret = snd_soc_dapm_set_bias_level(socdev, - SND_SOC_BIAS_STANDBY); - if (ret != 0) - pr_err("Failed to apply standby bias: %d\n", ret); - } - - /* If we just powered up then move to active bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { - ret = snd_soc_dapm_set_bias_level(socdev, - SND_SOC_BIAS_ON); - if (ret != 0) - pr_err("Failed to apply active bias: %d\n", ret); - } - return 0; } @@ -880,7 +723,6 @@ static void dbg_dump_dapm(struct snd_soc_codec* codec, const char *action) case snd_soc_dapm_pga: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: - case snd_soc_dapm_supply: if (w->name) { in = is_connected_input_ep(w); dapm_clear_walk(w->codec); @@ -1009,7 +851,6 @@ static ssize_t dapm_widget_show(struct device *dev, case snd_soc_dapm_pga: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: - case snd_soc_dapm_supply: if (w->name) count += sprintf(buf + count, "%s: %s\n", w->name, w->power ? "On":"Off"); @@ -1042,12 +883,16 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL); int snd_soc_dapm_sys_add(struct device *dev) { + if (!dapm_status) + return 0; return device_create_file(dev, &dev_attr_dapm_widget); } static void snd_soc_dapm_sys_remove(struct device *dev) { - device_remove_file(dev, &dev_attr_dapm_widget); + if (dapm_status) { + device_remove_file(dev, &dev_attr_dapm_widget); + } } /* free all dapm widgets and resources */ @@ -1170,7 +1015,6 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_vmid: case snd_soc_dapm_pre: case snd_soc_dapm_post: - case snd_soc_dapm_supply: list_add(&path->list, &codec->dapm_paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); @@ -1264,22 +1108,15 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_switch: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: - w->power_check = dapm_generic_check_power; dapm_new_mixer(codec, w); break; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: - w->power_check = dapm_generic_check_power; dapm_new_mux(codec, w); break; case snd_soc_dapm_adc: - w->power_check = dapm_adc_check_power; - break; case snd_soc_dapm_dac: - w->power_check = dapm_dac_check_power; - break; case snd_soc_dapm_pga: - w->power_check = dapm_generic_check_power; dapm_new_pga(codec, w); break; case snd_soc_dapm_input: @@ -1289,10 +1126,6 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_hp: case snd_soc_dapm_mic: case snd_soc_dapm_line: - w->power_check = dapm_generic_check_power; - break; - case snd_soc_dapm_supply: - w->power_check = dapm_supply_check_power; case snd_soc_dapm_vmid: case snd_soc_dapm_pre: case snd_soc_dapm_post: @@ -1792,12 +1625,36 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); +/** + * snd_soc_dapm_set_bias_level - set the bias level for the system + * @socdev: audio device + * @level: level to configure + * + * Configure the bias (power) levels for the SoC audio device. + * + * Returns 0 for success else error. + */ +int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev, + enum snd_soc_bias_level level) +{ + struct snd_soc_card *card = socdev->card; + struct snd_soc_codec *codec = socdev->card->codec; + int ret = 0; + + 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); + + return ret; +} + /** * snd_soc_dapm_enable_pin - enable pin. * @codec: SoC codec * @pin: pin name * - * Enables input/output pin and its parents or children widgets iff there is + * Enables input/output pin and it's parents or children widgets iff there is * a valid audio route and active audio stream. * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. @@ -1813,7 +1670,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); * @codec: SoC codec * @pin: pin name * - * Disables input/output pin and its parents or children widgets. + * Disables input/output pin and it's parents or children widgets. * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ diff --git a/trunk/sound/soc/txx9/Kconfig b/trunk/sound/soc/txx9/Kconfig deleted file mode 100644 index ebc9327eae71..000000000000 --- a/trunk/sound/soc/txx9/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -## -## TXx9 ACLC -## -config SND_SOC_TXX9ACLC - tristate "SoC Audio for TXx9" - depends on HAS_TXX9_ACLC && TXX9_DMAC - help - This option enables support for the AC Link Controllers in TXx9 SoC. - -config HAS_TXX9_ACLC - bool - -config SND_SOC_TXX9ACLC_AC97 - tristate - select AC97_BUS - select SND_AC97_CODEC - select SND_SOC_AC97_BUS - - -## -## Boards -## -config SND_SOC_TXX9ACLC_GENERIC - tristate "Generic TXx9 ACLC sound machine" - depends on SND_SOC_TXX9ACLC - select SND_SOC_TXX9ACLC_AC97 - select SND_SOC_AC97_CODEC - help - This is a generic AC97 sound machine for use in TXx9 based systems. diff --git a/trunk/sound/soc/txx9/Makefile b/trunk/sound/soc/txx9/Makefile deleted file mode 100644 index 551f16c0c4f9..000000000000 --- a/trunk/sound/soc/txx9/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# Platform -snd-soc-txx9aclc-objs := txx9aclc.o -snd-soc-txx9aclc-ac97-objs := txx9aclc-ac97.o - -obj-$(CONFIG_SND_SOC_TXX9ACLC) += snd-soc-txx9aclc.o -obj-$(CONFIG_SND_SOC_TXX9ACLC_AC97) += snd-soc-txx9aclc-ac97.o - -# Machine -snd-soc-txx9aclc-generic-objs := txx9aclc-generic.o - -obj-$(CONFIG_SND_SOC_TXX9ACLC_GENERIC) += snd-soc-txx9aclc-generic.o diff --git a/trunk/sound/soc/txx9/txx9aclc-ac97.c b/trunk/sound/soc/txx9/txx9aclc-ac97.c deleted file mode 100644 index 0f83bdb9b16f..000000000000 --- a/trunk/sound/soc/txx9/txx9aclc-ac97.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * TXx9 ACLC AC97 driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include "txx9aclc.h" - -#define AC97_DIR \ - (SND_SOC_DAIDIR_PLAYBACK | SND_SOC_DAIDIR_CAPTURE) - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_48000 - -#ifdef __BIG_ENDIAN -#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_BE -#else -#define AC97_FMTS SNDRV_PCM_FMTBIT_S16_LE -#endif - -static DECLARE_WAIT_QUEUE_HEAD(ac97_waitq); - -/* REVISIT: How to find txx9aclc_soc_device from snd_ac97? */ -static struct txx9aclc_soc_device *txx9aclc_soc_dev; - -static int txx9aclc_regready(struct txx9aclc_soc_device *dev) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - - return __raw_readl(drvdata->base + ACINTSTS) & ACINT_REGACCRDY; -} - -/* AC97 controller reads codec register */ -static unsigned short txx9aclc_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - u32 dat; - - if (!(__raw_readl(base + ACINTSTS) & ACINT_CODECRDY(ac97->num))) - return 0xffff; - reg |= ac97->num << 7; - dat = (reg << ACREGACC_REG_SHIFT) | ACREGACC_READ; - __raw_writel(dat, base + ACREGACC); - __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); - dev_err(dev->soc_dev.dev, "ac97 read timeout (reg %#x)\n", reg); - dat = 0xffff; - goto done; - } - dat = __raw_readl(base + ACREGACC); - if (((dat >> ACREGACC_REG_SHIFT) & 0xff) != reg) { - dev_err(dev->soc_dev.dev, "reg mismatch %x with %x\n", - dat, reg); - dat = 0xffff; - goto done; - } - dat = (dat >> ACREGACC_DAT_SHIFT) & 0xffff; -done: - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); - return dat; -} - -/* AC97 controller writes to codec register */ -static void txx9aclc_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - - __raw_writel(((reg | (ac97->num << 7)) << ACREGACC_REG_SHIFT) | - (val << ACREGACC_DAT_SHIFT), - base + ACREGACC); - __raw_writel(ACINT_REGACCRDY, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, txx9aclc_regready(dev), HZ)) { - dev_err(dev->soc_dev.dev, - "ac97 write timeout (reg %#x)\n", reg); - } - __raw_writel(ACINT_REGACCRDY, base + ACINTDIS); -} - -static void txx9aclc_ac97_cold_reset(struct snd_ac97 *ac97) -{ - struct txx9aclc_soc_device *dev = txx9aclc_soc_dev; - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - u32 ready = ACINT_CODECRDY(ac97->num) | ACINT_REGACCRDY; - - __raw_writel(ACCTL_ENLINK, base + ACCTLDIS); - mmiowb(); - udelay(1); - __raw_writel(ACCTL_ENLINK, base + ACCTLEN); - /* wait for primary codec ready status */ - __raw_writel(ready, base + ACINTEN); - if (!wait_event_timeout(ac97_waitq, - (__raw_readl(base + ACINTSTS) & ready) == ready, - HZ)) { - dev_err(&ac97->dev, "primary codec is not ready " - "(status %#x)\n", - __raw_readl(base + ACINTSTS)); - } - __raw_writel(ACINT_REGACCRDY, base + ACINTSTS); - __raw_writel(ready, base + ACINTDIS); -} - -/* AC97 controller operations */ -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = txx9aclc_ac97_read, - .write = txx9aclc_ac97_write, - .reset = txx9aclc_ac97_cold_reset, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static irqreturn_t txx9aclc_ac97_irq(int irq, void *dev_id) -{ - struct txx9aclc_plat_drvdata *drvdata = dev_id; - void __iomem *base = drvdata->base; - - __raw_writel(__raw_readl(base + ACINTMSTS), base + ACINTDIS); - wake_up(&ac97_waitq); - return IRQ_HANDLED; -} - -static int txx9aclc_ac97_probe(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - - dev->aclc_pdev = to_platform_device(dai->dev); - txx9aclc_soc_dev = dev; - return 0; -} - -static void txx9aclc_ac97_remove(struct platform_device *pdev, - struct snd_soc_dai *dai) -{ - struct platform_device *aclc_pdev = to_platform_device(dai->dev); - struct txx9aclc_plat_drvdata *drvdata = platform_get_drvdata(aclc_pdev); - - /* disable AC-link */ - __raw_writel(ACCTL_ENLINK, drvdata->base + ACCTLDIS); - txx9aclc_soc_dev = NULL; -} - -struct snd_soc_dai txx9aclc_ac97_dai = { - .name = "txx9aclc_ac97", - .ac97_control = 1, - .probe = txx9aclc_ac97_probe, - .remove = txx9aclc_ac97_remove, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, -}; -EXPORT_SYMBOL_GPL(txx9aclc_ac97_dai); - -static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) -{ - struct txx9aclc_plat_drvdata *drvdata; - struct resource *r; - int err; - int irq; - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) - return -EBUSY; - - if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r), - dev_name(&pdev->dev))) - return -EBUSY; - - drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); - if (!drvdata) - return -ENOMEM; - platform_set_drvdata(pdev, drvdata); - drvdata->physbase = r->start; - if (sizeof(drvdata->physbase) > sizeof(r->start) && - r->start >= TXX9_DIRECTMAP_BASE && - r->start < TXX9_DIRECTMAP_BASE + 0x400000) - drvdata->physbase |= 0xf00000000ull; - drvdata->base = devm_ioremap(&pdev->dev, r->start, resource_size(r)); - if (!drvdata->base) - return -EBUSY; - err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, - IRQF_DISABLED, dev_name(&pdev->dev), drvdata); - if (err < 0) - return err; - - txx9aclc_ac97_dai.dev = &pdev->dev; - return snd_soc_register_dai(&txx9aclc_ac97_dai); -} - -static int __devexit txx9aclc_ac97_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&txx9aclc_ac97_dai); - return 0; -} - -static struct platform_driver txx9aclc_ac97_driver = { - .probe = txx9aclc_ac97_dev_probe, - .remove = __devexit_p(txx9aclc_ac97_dev_remove), - .driver = { - .name = "txx9aclc-ac97", - .owner = THIS_MODULE, - }, -}; - -static int __init txx9aclc_ac97_init(void) -{ - return platform_driver_register(&txx9aclc_ac97_driver); -} - -static void __exit txx9aclc_ac97_exit(void) -{ - platform_driver_unregister(&txx9aclc_ac97_driver); -} - -module_init(txx9aclc_ac97_init); -module_exit(txx9aclc_ac97_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/txx9/txx9aclc-generic.c b/trunk/sound/soc/txx9/txx9aclc-generic.c deleted file mode 100644 index 3175de9a92cb..000000000000 --- a/trunk/sound/soc/txx9/txx9aclc-generic.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Generic TXx9 ACLC machine driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - * - * 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 is a very generic AC97 sound machine driver for boards which - * have (AC97) audio at ACLC (e.g. RBTX49XX boards). - */ - -#include -#include -#include -#include -#include -#include "../codecs/ac97.h" -#include "txx9aclc.h" - -static struct snd_soc_dai_link txx9aclc_generic_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai = &txx9aclc_ac97_dai, - .codec_dai = &ac97_dai, -}; - -static struct snd_soc_card txx9aclc_generic_card = { - .name = "Generic TXx9 ACLC Audio", - .platform = &txx9aclc_soc_platform, - .dai_link = &txx9aclc_generic_dai, - .num_links = 1, -}; - -static struct txx9aclc_soc_device txx9aclc_generic_soc_device = { - .soc_dev = { - .card = &txx9aclc_generic_card, - .codec_dev = &soc_codec_dev_ac97, - }, -}; - -static int __init txx9aclc_generic_probe(struct platform_device *pdev) -{ - struct txx9aclc_soc_device *dev = &txx9aclc_generic_soc_device; - struct platform_device *soc_pdev; - int ret; - - soc_pdev = platform_device_alloc("soc-audio", -1); - if (!soc_pdev) - return -ENOMEM; - platform_set_drvdata(soc_pdev, &dev->soc_dev); - dev->soc_dev.dev = &soc_pdev->dev; - ret = platform_device_add(soc_pdev); - if (ret) { - platform_device_put(soc_pdev); - return ret; - } - platform_set_drvdata(pdev, soc_pdev); - return 0; -} - -static int __exit txx9aclc_generic_remove(struct platform_device *pdev) -{ - struct platform_device *soc_pdev = platform_get_drvdata(pdev); - - platform_device_unregister(soc_pdev); - return 0; -} - -static struct platform_driver txx9aclc_generic_driver = { - .remove = txx9aclc_generic_remove, - .driver = { - .name = "txx9aclc-generic", - .owner = THIS_MODULE, - }, -}; - -static int __init txx9aclc_generic_init(void) -{ - return platform_driver_probe(&txx9aclc_generic_driver, - txx9aclc_generic_probe); -} - -static void __exit txx9aclc_generic_exit(void) -{ - platform_driver_unregister(&txx9aclc_generic_driver); -} - -module_init(txx9aclc_generic_init); -module_exit(txx9aclc_generic_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/txx9/txx9aclc.c b/trunk/sound/soc/txx9/txx9aclc.c deleted file mode 100644 index fa336616152e..000000000000 --- a/trunk/sound/soc/txx9/txx9aclc.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Generic TXx9 ACLC platform driver - * - * Copyright (C) 2009 Atsushi Nemoto - * - * Based on RBTX49xx patch from CELF patch archive. - * (C) Copyright TOSHIBA CORPORATION 2004-2006 - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include "txx9aclc.h" - -static const struct snd_pcm_hardware txx9aclc_pcm_hardware = { - /* - * REVISIT: SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID - * needs more works for noncoherent MIPS. - */ - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BATCH | - SNDRV_PCM_INFO_PAUSE, -#ifdef __BIG_ENDIAN - .formats = SNDRV_PCM_FMTBIT_S16_BE, -#else - .formats = SNDRV_PCM_FMTBIT_S16_LE, -#endif - .period_bytes_min = 1024, - .period_bytes_max = 8 * 1024, - .periods_min = 2, - .periods_max = 4096, - .buffer_bytes_max = 32 * 1024, -}; - -static int txx9aclc_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream); - struct snd_soc_device *socdev = rtd->socdev; - struct snd_pcm_runtime *runtime = substream->runtime; - struct txx9aclc_dmadata *dmadata = runtime->private_data; - int ret; - - ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); - if (ret < 0) - return ret; - - dev_dbg(socdev->dev, - "runtime->dma_area = %#lx dma_addr = %#lx dma_bytes = %zd " - "runtime->min_align %ld\n", - (unsigned long)runtime->dma_area, - (unsigned long)runtime->dma_addr, runtime->dma_bytes, - runtime->min_align); - dev_dbg(socdev->dev, - "periods %d period_bytes %d stream %d\n", - params_periods(params), params_period_bytes(params), - substream->stream); - - dmadata->substream = substream; - dmadata->pos = 0; - return 0; -} - -static int txx9aclc_pcm_hw_free(struct snd_pcm_substream *substream) -{ - return snd_pcm_lib_free_pages(substream); -} - -static int txx9aclc_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct txx9aclc_dmadata *dmadata = runtime->private_data; - - dmadata->dma_addr = runtime->dma_addr; - dmadata->buffer_bytes = snd_pcm_lib_buffer_bytes(substream); - dmadata->period_bytes = snd_pcm_lib_period_bytes(substream); - - if (dmadata->buffer_bytes == dmadata->period_bytes) { - dmadata->frag_bytes = dmadata->period_bytes >> 1; - dmadata->frags = 2; - } else { - dmadata->frag_bytes = dmadata->period_bytes; - dmadata->frags = dmadata->buffer_bytes / dmadata->period_bytes; - } - dmadata->frag_count = 0; - dmadata->pos = 0; - return 0; -} - -static void txx9aclc_dma_complete(void *arg) -{ - struct txx9aclc_dmadata *dmadata = arg; - unsigned long flags; - - /* dma completion handler cannot submit new operations */ - spin_lock_irqsave(&dmadata->dma_lock, flags); - if (dmadata->frag_count >= 0) { - dmadata->dmacount--; - BUG_ON(dmadata->dmacount < 0); - tasklet_schedule(&dmadata->tasklet); - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); -} - -static struct dma_async_tx_descriptor * -txx9aclc_dma_submit(struct txx9aclc_dmadata *dmadata, dma_addr_t buf_dma_addr) -{ - struct dma_chan *chan = dmadata->dma_chan; - struct dma_async_tx_descriptor *desc; - struct scatterlist sg; - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf_dma_addr)), - dmadata->frag_bytes, buf_dma_addr & (PAGE_SIZE - 1)); - sg_dma_address(&sg) = buf_dma_addr; - desc = chan->device->device_prep_slave_sg(chan, &sg, 1, - dmadata->substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - DMA_TO_DEVICE : DMA_FROM_DEVICE, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(&chan->dev->device, "cannot prepare slave dma\n"); - return NULL; - } - desc->callback = txx9aclc_dma_complete; - desc->callback_param = dmadata; - desc->tx_submit(desc); - return desc; -} - -#define NR_DMA_CHAIN 2 - -static void txx9aclc_dma_tasklet(unsigned long data) -{ - struct txx9aclc_dmadata *dmadata = (struct txx9aclc_dmadata *)data; - struct dma_chan *chan = dmadata->dma_chan; - struct dma_async_tx_descriptor *desc; - struct snd_pcm_substream *substream = dmadata->substream; - u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - ACCTL_AUDODMA : ACCTL_AUDIDMA; - int i; - unsigned long flags; - - spin_lock_irqsave(&dmadata->dma_lock, flags); - if (dmadata->frag_count < 0) { - struct txx9aclc_soc_device *dev = - container_of(dmadata, struct txx9aclc_soc_device, - dmadata[substream->stream]); - struct txx9aclc_plat_drvdata *drvdata = - txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - chan->device->device_terminate_all(chan); - /* first time */ - for (i = 0; i < NR_DMA_CHAIN; i++) { - desc = txx9aclc_dma_submit(dmadata, - dmadata->dma_addr + i * dmadata->frag_bytes); - if (!desc) - return; - } - dmadata->dmacount = NR_DMA_CHAIN; - chan->device->device_issue_pending(chan); - spin_lock_irqsave(&dmadata->dma_lock, flags); - __raw_writel(ctlbit, base + ACCTLEN); - dmadata->frag_count = NR_DMA_CHAIN % dmadata->frags; - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - return; - } - BUG_ON(dmadata->dmacount >= NR_DMA_CHAIN); - while (dmadata->dmacount < NR_DMA_CHAIN) { - dmadata->dmacount++; - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - desc = txx9aclc_dma_submit(dmadata, - dmadata->dma_addr + - dmadata->frag_count * dmadata->frag_bytes); - if (!desc) - return; - chan->device->device_issue_pending(chan); - - spin_lock_irqsave(&dmadata->dma_lock, flags); - dmadata->frag_count++; - dmadata->frag_count %= dmadata->frags; - dmadata->pos += dmadata->frag_bytes; - dmadata->pos %= dmadata->buffer_bytes; - if ((dmadata->frag_count * dmadata->frag_bytes) % - dmadata->period_bytes == 0) - snd_pcm_period_elapsed(substream); - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); -} - -static int txx9aclc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct txx9aclc_soc_device *dev = - container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev); - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - unsigned long flags; - int ret = 0; - u32 ctlbit = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? - ACCTL_AUDODMA : ACCTL_AUDIDMA; - - spin_lock_irqsave(&dmadata->dma_lock, flags); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - dmadata->frag_count = -1; - tasklet_schedule(&dmadata->tasklet); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - case SNDRV_PCM_TRIGGER_SUSPEND: - __raw_writel(ctlbit, base + ACCTLDIS); - break; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: - __raw_writel(ctlbit, base + ACCTLEN); - break; - default: - ret = -EINVAL; - } - spin_unlock_irqrestore(&dmadata->dma_lock, flags); - return ret; -} - -static snd_pcm_uframes_t -txx9aclc_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - - return bytes_to_frames(substream->runtime, dmadata->pos); -} - -static int txx9aclc_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct txx9aclc_soc_device *dev = - container_of(rtd->socdev, struct txx9aclc_soc_device, soc_dev); - struct txx9aclc_dmadata *dmadata = &dev->dmadata[substream->stream]; - int ret; - - ret = snd_soc_set_runtime_hwparams(substream, &txx9aclc_pcm_hardware); - if (ret) - return ret; - /* ensure that buffer size is a multiple of period size */ - ret = snd_pcm_hw_constraint_integer(substream->runtime, - SNDRV_PCM_HW_PARAM_PERIODS); - if (ret < 0) - return ret; - substream->runtime->private_data = dmadata; - return 0; -} - -static int txx9aclc_pcm_close(struct snd_pcm_substream *substream) -{ - struct txx9aclc_dmadata *dmadata = substream->runtime->private_data; - struct dma_chan *chan = dmadata->dma_chan; - - dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); - return 0; -} - -static struct snd_pcm_ops txx9aclc_pcm_ops = { - .open = txx9aclc_pcm_open, - .close = txx9aclc_pcm_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = txx9aclc_pcm_hw_params, - .hw_free = txx9aclc_pcm_hw_free, - .prepare = txx9aclc_pcm_prepare, - .trigger = txx9aclc_pcm_trigger, - .pointer = txx9aclc_pcm_pointer, -}; - -static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - -static int txx9aclc_pcm_new(struct snd_card *card, struct snd_soc_dai *dai, - struct snd_pcm *pcm) -{ - return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - card->dev, 64 * 1024, 4 * 1024 * 1024); -} - -static bool filter(struct dma_chan *chan, void *param) -{ - struct txx9aclc_dmadata *dmadata = param; - char devname[BUS_ID_SIZE + 2]; - - sprintf(devname, "%s.%d", dmadata->dma_res->name, - (int)dmadata->dma_res->start); - if (strcmp(dev_name(chan->device->dev), devname) == 0) { - chan->private = &dmadata->dma_slave; - return true; - } - return false; -} - -static int txx9aclc_dma_init(struct txx9aclc_soc_device *dev, - struct txx9aclc_dmadata *dmadata) -{ - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - struct txx9dmac_slave *ds = &dmadata->dma_slave; - dma_cap_mask_t mask; - - spin_lock_init(&dmadata->dma_lock); - - ds->reg_width = sizeof(u32); - if (dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK) { - ds->tx_reg = drvdata->physbase + ACAUDODAT; - ds->rx_reg = 0; - } else { - ds->tx_reg = 0; - ds->rx_reg = drvdata->physbase + ACAUDIDAT; - } - - /* Try to grab a DMA channel */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dmadata->dma_chan = dma_request_channel(mask, filter, dmadata); - if (!dmadata->dma_chan) { - dev_err(dev->soc_dev.dev, - "DMA channel for %s is not available\n", - dmadata->stream == SNDRV_PCM_STREAM_PLAYBACK ? - "playback" : "capture"); - return -EBUSY; - } - tasklet_init(&dmadata->tasklet, txx9aclc_dma_tasklet, - (unsigned long)dmadata); - return 0; -} - -static int txx9aclc_pcm_probe(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - struct resource *r; - int i; - int ret; - - dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK; - dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE; - for (i = 0; i < 2; i++) { - r = platform_get_resource(dev->aclc_pdev, IORESOURCE_DMA, i); - if (!r) { - ret = -EBUSY; - goto exit; - } - dev->dmadata[i].dma_res = r; - ret = txx9aclc_dma_init(dev, &dev->dmadata[i]); - if (ret) - goto exit; - } - return 0; - -exit: - for (i = 0; i < 2; i++) { - if (dev->dmadata[i].dma_chan) - dma_release_channel(dev->dmadata[i].dma_chan); - dev->dmadata[i].dma_chan = NULL; - } - return ret; -} - -static int txx9aclc_pcm_remove(struct platform_device *pdev) -{ - struct snd_soc_device *socdev = platform_get_drvdata(pdev); - struct txx9aclc_soc_device *dev = - container_of(socdev, struct txx9aclc_soc_device, soc_dev); - struct txx9aclc_plat_drvdata *drvdata = txx9aclc_get_plat_drvdata(dev); - void __iomem *base = drvdata->base; - int i; - - /* disable all FIFO DMAs */ - __raw_writel(ACCTL_AUDODMA | ACCTL_AUDIDMA, base + ACCTLDIS); - /* dummy R/W to clear pending DMAREQ if any */ - __raw_writel(__raw_readl(base + ACAUDIDAT), base + ACAUDODAT); - - for (i = 0; i < 2; i++) { - struct txx9aclc_dmadata *dmadata = &dev->dmadata[i]; - struct dma_chan *chan = dmadata->dma_chan; - if (chan) { - dmadata->frag_count = -1; - chan->device->device_terminate_all(chan); - dma_release_channel(chan); - } - dev->dmadata[i].dma_chan = NULL; - } - return 0; -} - -struct snd_soc_platform txx9aclc_soc_platform = { - .name = "txx9aclc-audio", - .probe = txx9aclc_pcm_probe, - .remove = txx9aclc_pcm_remove, - .pcm_ops = &txx9aclc_pcm_ops, - .pcm_new = txx9aclc_pcm_new, - .pcm_free = txx9aclc_pcm_free_dma_buffers, -}; -EXPORT_SYMBOL_GPL(txx9aclc_soc_platform); - -static int __init txx9aclc_soc_platform_init(void) -{ - return snd_soc_register_platform(&txx9aclc_soc_platform); -} - -static void __exit txx9aclc_soc_platform_exit(void) -{ - snd_soc_unregister_platform(&txx9aclc_soc_platform); -} - -module_init(txx9aclc_soc_platform_init); -module_exit(txx9aclc_soc_platform_exit); - -MODULE_AUTHOR("Atsushi Nemoto "); -MODULE_DESCRIPTION("TXx9 ACLC Audio DMA driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/txx9/txx9aclc.h b/trunk/sound/soc/txx9/txx9aclc.h deleted file mode 100644 index 6769aab41b33..000000000000 --- a/trunk/sound/soc/txx9/txx9aclc.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * TXx9 SoC AC Link Controller - * - * 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 __TXX9ACLC_H -#define __TXX9ACLC_H - -#include -#include - -#define ACCTLEN 0x00 /* control enable */ -#define ACCTLDIS 0x04 /* control disable */ -#define ACCTL_ENLINK 0x00000001 /* enable/disable AC-link */ -#define ACCTL_AUDODMA 0x00000100 /* AUDODMA enable/disable */ -#define ACCTL_AUDIDMA 0x00001000 /* AUDIDMA enable/disable */ -#define ACCTL_AUDOEHLT 0x00010000 /* AUDO error halt - enable/disable */ -#define ACCTL_AUDIEHLT 0x00100000 /* AUDI error halt - enable/disable */ -#define ACREGACC 0x08 /* codec register access */ -#define ACREGACC_DAT_SHIFT 0 /* data field */ -#define ACREGACC_REG_SHIFT 16 /* address field */ -#define ACREGACC_CODECID_SHIFT 24 /* CODEC ID field */ -#define ACREGACC_READ 0x80000000 /* CODEC read */ -#define ACREGACC_WRITE 0x00000000 /* CODEC write */ -#define ACINTSTS 0x10 /* interrupt status */ -#define ACINTMSTS 0x14 /* interrupt masked status */ -#define ACINTEN 0x18 /* interrupt enable */ -#define ACINTDIS 0x1c /* interrupt disable */ -#define ACINT_CODECRDY(n) (0x00000001 << (n)) /* CODECn ready */ -#define ACINT_REGACCRDY 0x00000010 /* ACREGACC ready */ -#define ACINT_AUDOERR 0x00000100 /* AUDO underrun error */ -#define ACINT_AUDIERR 0x00001000 /* AUDI overrun error */ -#define ACDMASTS 0x80 /* DMA request status */ -#define ACDMA_AUDO 0x00000001 /* AUDODMA pending */ -#define ACDMA_AUDI 0x00000010 /* AUDIDMA pending */ -#define ACAUDODAT 0xa0 /* audio out data */ -#define ACAUDIDAT 0xb0 /* audio in data */ -#define ACREVID 0xfc /* revision ID */ - -struct txx9aclc_dmadata { - struct resource *dma_res; - struct txx9dmac_slave dma_slave; - struct dma_chan *dma_chan; - struct tasklet_struct tasklet; - spinlock_t dma_lock; - int stream; /* SNDRV_PCM_STREAM_PLAYBACK or SNDRV_PCM_STREAM_CAPTURE */ - struct snd_pcm_substream *substream; - unsigned long pos; - dma_addr_t dma_addr; - unsigned long buffer_bytes; - unsigned long period_bytes; - unsigned long frag_bytes; - int frags; - int frag_count; - int dmacount; -}; - -struct txx9aclc_plat_drvdata { - void __iomem *base; - u64 physbase; -}; - -struct txx9aclc_soc_device { - struct snd_soc_device soc_dev; - struct platform_device *aclc_pdev; /* for ioresources, drvdata */ - struct txx9aclc_dmadata dmadata[2]; -}; - -static inline struct txx9aclc_plat_drvdata *txx9aclc_get_plat_drvdata( - struct txx9aclc_soc_device *sdev) -{ - return platform_get_drvdata(sdev->aclc_pdev); -} - -extern struct snd_soc_platform txx9aclc_soc_platform; -extern struct snd_soc_dai txx9aclc_ac97_dai; - -#endif /* __TXX9ACLC_H */ diff --git a/trunk/sound/usb/usbaudio.c b/trunk/sound/usb/usbaudio.c index a6b88482637b..823296d7d578 100644 --- a/trunk/sound/usb/usbaudio.c +++ b/trunk/sound/usb/usbaudio.c @@ -3347,7 +3347,7 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip, [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, - [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface, + [QUIRK_MIDI_RAW] = snd_usb_create_midi_interface, [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, diff --git a/trunk/sound/usb/usbaudio.h b/trunk/sound/usb/usbaudio.h index 8e7f78941ba6..36e4f7a29adc 100644 --- a/trunk/sound/usb/usbaudio.h +++ b/trunk/sound/usb/usbaudio.h @@ -153,7 +153,7 @@ enum quirk_type { QUIRK_MIDI_YAMAHA, QUIRK_MIDI_MIDIMAN, QUIRK_MIDI_NOVATION, - QUIRK_MIDI_FASTLANE, + QUIRK_MIDI_RAW, QUIRK_MIDI_EMAGIC, QUIRK_MIDI_CME, QUIRK_MIDI_US122L, diff --git a/trunk/sound/usb/usbmidi.c b/trunk/sound/usb/usbmidi.c index 2fb35cc22a30..26bad373fe65 100644 --- a/trunk/sound/usb/usbmidi.c +++ b/trunk/sound/usb/usbmidi.c @@ -1778,18 +1778,8 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip, umidi->usb_protocol_ops = &snd_usbmidi_novation_ops; err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; - case QUIRK_MIDI_FASTLANE: + case QUIRK_MIDI_RAW: umidi->usb_protocol_ops = &snd_usbmidi_raw_ops; - /* - * Interface 1 contains isochronous endpoints, but with the same - * numbers as in interface 0. Since it is interface 1 that the - * USB core has most recently seen, these descriptors are now - * associated with the endpoint numbers. This will foul up our - * attempts to submit bulk/interrupt URBs to the endpoints in - * interface 0, so we have to make sure that the USB core looks - * again at interface 0 by calling usb_set_interface() on it. - */ - usb_set_interface(umidi->chip->dev, 0, 0); err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); break; case QUIRK_MIDI_EMAGIC: diff --git a/trunk/sound/usb/usbquirks.h b/trunk/sound/usb/usbquirks.h index 5d955aaad85f..647ef5029651 100644 --- a/trunk/sound/usb/usbquirks.h +++ b/trunk/sound/usb/usbquirks.h @@ -1868,7 +1868,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), .data = & (const struct snd_usb_audio_quirk[]) { { .ifnum = 0, - .type = QUIRK_MIDI_FASTLANE + .type = QUIRK_MIDI_RAW }, { .ifnum = 1, diff --git a/trunk/virt/kvm/kvm_main.c b/trunk/virt/kvm/kvm_main.c index 4d0dd390aa50..1ecbe2391c8b 100644 --- a/trunk/virt/kvm/kvm_main.c +++ b/trunk/virt/kvm/kvm_main.c @@ -2301,11 +2301,10 @@ int kvm_init(void *opaque, unsigned int vcpu_size, bad_pfn = page_to_pfn(bad_page); - if (!zalloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) { + if (!alloc_cpumask_var(&cpus_hardware_enabled, GFP_KERNEL)) { r = -ENOMEM; goto out_free_0; } - cpumask_clear(cpus_hardware_enabled); r = kvm_arch_hardware_setup(); if (r < 0)